Skip to content

get <uuid> overrides socket.yml without the documented policy_bypassed warning (purl/CVE/GHSA forms do warn) #453

Description

[agent] Found by the scheduled Pipenv bug-hunt routine (ledger #313).

Summary

The contract says get ignores socket.yml but has to say so when it does. When the repo's socket.yml would have skipped the package, get must warn policy_bypassed, both in warnings[] and on stderr. The purl, CVE and GHSA forms of get do this. The UUID form doesn't. get <uuid> takes an early-return path straight into the mode dispatch, and that path never calls policy_bypass_warnings. The package gets patched in every mode (agent, hosted, vendored) with exit 0, no stderr line, and no warnings key in the --json envelope.

I found this on a Pipenv project, but the code path doesn't depend on the ecosystem.

Impact

policy_bypassed is the only signal that a run overrode the repository's rollout policy (ignorePackages, ecosystems, includePaths/ignorePaths, minSeverity, enabled: false). A UUID is the identifier that dashboards, bots and the scan table all hand out. So the most common scripted get can push a patch the repo explicitly excluded (for example enabled: false during a freeze) and leave nothing in CI logs or JSON output to flag it.

Repro (Linux, main 2463257, Pipenv 2026.8.0 project, local mock patch API)

git init -q proj && cd proj
# Pipfile + Pipfile.lock pinning six==1.16.0 (pipfile-spec 6)
printf 'version: 2\npatches:\n  ignorePackages: ["pkg:pypi/six"]\n' > socket.yml
socket-patch get pkg:pypi/six@1.16.0 --mode hosted --yes --json | jq .warnings
#   ["(policy_bypassed) pkg:pypi/six@1.16.0 would be skipped by socket.yml (policy_package_ignored: pkg:pypi/six (patches.ignorePackages)); get patches it anyway"]
git checkout Pipfile.lock 2>/dev/null || cp Pipfile.lock.orig Pipfile.lock
socket-patch get <uuid-of-that-patch> --mode hosted --yes --json | jq .warnings
#   null   (Pipfile.lock is rewritten, exit 0, nothing on stderr)

Results from two runs, each identical:

Command exit lock patched warnings[] policy_bypassed stderr warning
get pkg:pypi/six@1.16.0 --mode hosted 0 yes yes yes
get pkg:pypi/six@1.16.0 --mode vendored 0 yes yes yes
get <uuid> --mode hosted 0 yes missing missing
get <uuid> --mode vendored 0 yes missing missing
get <uuid> --mode agent 0 n/a (in place) missing missing

Expected vs actual

  • Expected: crates/socket-patch-cli/CLI_CONTRACT.md (socket.yml, "Commands") says: "get is explicit intent: it ignores the policy and warns policy_bypassed (in warnings[], and on stderr) when socket.yml would have skipped the package". docs/configuration.md says the same: "it bypasses policy and warns when a valid policy would exclude its target". Neither carves out the UUID form.
  • Actual: only the search-backed forms warn. The UUID form patches silently.

OS × version

OS Pipenv reproduces
Linux 2026.8.0 (SOCKET_PIPENV_MAJOR=2026) yes (2/2)
macOS / Windows — not probed. The code path is platform-independent.

First bad

socket.yml arrived with #277 (2463257) and isn't in any published release (v4.0.0 predates it). So the bug has been there since the feature landed.

Suspect code

  • crates/socket-patch-cli/src/commands/get.rs:2603-2700: the IdentifierType::Uuid branch returns from the match mode dispatch (save_and_apply_patch / run_get_hosted(…, &[], &[]) / run_get_vendored(…, &[], &[])) with empty warning lists.
  • crates/socket-patch-cli/src/commands/get.rs:2929-2933: the only call site of super::scan::policy::policy_bypass_warnings, which only the search path reaches.

Backlog review — 2026-10-08

Priority: P1 → P2. Explicit get intentionally overrides policy; the bug is the missing bypass warning across target forms. Preserve the functional fix, but P1 overstates the current impact.

Activity

  1. mikolalysenko commented on Oct 1, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Triaged: confirmed on main (2463257). crates/socket-patch-cli/src/commands/get.rs:2603 returns from the UUID branch before the only policy_bypass_warnings call at get.rs:2930, so every mode of get <uuid> skips the warning. The cause is ecosystem-independent, so this is priority:p1 because it covers PyPI and npm. No open PR covers it, and it isn't a duplicate.


    Generated by Claude Code

  2. added
    arch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)
    and removed on Oct 7, 2026
  3. mikolalysenko commented on Oct 7, 2026

    @mikolalysenko
    CollaboratorAuthor

    Relabelled: this is not Pipenv-specific. get <uuid> dispatched to every mode before the only policy_bypass_warnings call, so the warning was missing in every ecosystem (architecture audit B29). The fix is on the target-grammar branch (arch-fix/target-grammar); a draft PR follows.

  4. added
    v5-blockerMust resolve before v5: public interface/migration or ordinary patch-install-undo failure.
    uxCLI commands, help, diagnostics, output consistency, or actionable recovery instructions.
    and removed on Oct 8, 2026
  5. mikolalysenko commented on Oct 9, 2026

    @mikolalysenko
    CollaboratorAuthor

    v5 release blocker (P1). Make explicit get targeting and socket.yml bypass reporting consistent before the v5 CLI contract is frozen. Pending PR #1034 also fixes the exact-name and ecosystem-selection seams.

    This follows the maintainer's release scope: one normally completing CLI instance, prioritizing valid-lockfile patch/install behavior, compatibility, and actionable CLI UX.

    The wider exact-name/all-versions targeting gate is now tracked explicitly in #1280, with the same pending PR #1034.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)bugSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentpriority:p1uxCLI commands, help, diagnostics, output consistency, or actionable recovery instructions.v5-blockerMust resolve before v5: public interface/migration or ordinary patch-install-undo failure.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions