You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 1d3edc2
Browse filesBrowse the repository at this point in the historyBrowse files
Document vendor --force as variant-probe bypass (#1346)
Since vendoring became service-only it commits the patch server's
verified artifact and never reads the installed files, yet vendor
--force help and CLI_CONTRACT.md still promised a missing-file
tolerance and a vendor_content_mismatch_overwritten warning that no
backend implements. Users set --force for nothing.
The help and contract now say --force only bypasses the installed-
variant probe, mark the warning code as no longer emitted, and fix the
stale test docs. A help test pins the new text, and the core test
now shows a missing file vendors alike with and without force (#923).
Assisted-by: Claude Code:claude-opus-5-5
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: crates/socket-patch-cli/CLI_CONTRACT.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -79,7 +79,7 @@ Every subcommand accepts the same set of "global" flags via a single shared `Glo
79
79
80
80
`--offline` means the same thing on every command (v3.0): never contact the network, fail loudly when a required local source is missing. On `repair`, `--offline` and `--download-only` are mutually exclusive (exit 2). `scan` and `get` need remote data for their core function (patch discovery / patch fetch), so `--offline` refuses them up front — exit 1 with an error naming the offline gate (JSON: `status: "error"`), before any crawl, client build, or network contact. This covers `scan --mode vendored` too: offline vendored staging is `vendor --offline`'s job.
81
81
82
-
The `--strict` mismatch policy applies to the in-place apply paths (apply/get/scan --mode agent/hook/go redirect). DEFAULT (v3.4): a file whose on-disk content matches neither the patch's beforeHash nor its afterHash is overwritten with the FULL verified patched content (blob writes are hash-gated to exactly afterHash; the missing blob is downloaded on demand) and surfaced as a `content_mismatch_overwritten` stderr warning + Skipped event (agent-mode `get` / `scan --json`: a `warnings[]` entry, see "Agent-mode mismatch overwrites"). A file the patch adds (empty beforeHash) that already exists with other content is the same case. `--strict` turns that case into a hard error. Rollback of an added file deletes it; the content it replaced is not kept. `--force` overrides `--strict` and additionally skips missing files. Vendor staging is unaffected (it always auto-overwrites into its private stage).
82
+
The `--strict` mismatch policy applies to the in-place apply paths (apply/get/scan --mode agent/hook/go redirect). DEFAULT (v3.4): a file whose on-disk content matches neither the patch's beforeHash nor its afterHash is overwritten with the FULL verified patched content (blob writes are hash-gated to exactly afterHash; the missing blob is downloaded on demand) and surfaced as a `content_mismatch_overwritten` stderr warning + Skipped event (agent-mode `get` / `scan --json`: a `warnings[]` entry, see "Agent-mode mismatch overwrites"). A file the patch adds (empty beforeHash) that already exists with other content is the same case. `--strict` turns that case into a hard error. Rollback of an added file deletes it; the content it replaced is not kept. `--force` overrides `--strict` and additionally skips missing files. Vendoring is unaffected: it commits the patch server's verified artifact and never reads the installed bytes.
83
83
84
84
## Per-subcommand arguments
85
85
@@ -89,7 +89,7 @@ Beyond the globals above, each subcommand defines a small set of local arguments
| `apply` | `--check` | — | Read-only audit that every in-scope (`--ecosystems`) manifest patch is in place, for CI / GitHub-App auditing (v5.0: previously Go-only, which passed on any unpatched non-Go tree). Local Go patches: the committed `.socket/go-patches/` copies and `go.mod` `replace` directives match the manifest (`go_redirect_drift`). Every other patch: each installed copy hashes to the record's `afterHash` — the `vex` verifier over the `vex` copy lookup; the copies are narrowed by `apply`'s own rules: a release variant (a qualified purl such as `?artifact_id=` / `?platform=`) is judged only on the copies holding its distribution, matched against every variant of its base as `apply` matches them, and an installed copy that holds none of them is drift of the base purl (`no_matching_variant`, the copy `apply` fails with "no matching variant found"; a Gradle / Ivy cache dir is exempt, as in `apply`); for gem, once a bundle-store copy exists the `gem env` fallback-home copies are not judged (`apply` treats them as best-effort). Drift is a `failed` event per patch with `errorCode` `not_applied` (still unpatched), `hash_mismatch` (neither the original nor the patched bytes), `file_not_found` or `no_matching_variant`, status `partialFailure`, exit 1, and the human `Error: Patches are OUT OF SYNC:` report (printed even under `--silent`), which ends with the remedy ``Run `socket-patch apply <scope>` to regenerate them.``: `<scope>` repeats the check's own `--cwd`, `--manifest-path`, `-g` / `--global-prefix` and `--ecosystems` (each shell-quoted when needed), so running it verbatim heals the tree that was checked (v5.0, #1219). In sync is exit 0: `Patches are in sync (N checked).` and, under `--json`, a `skipped` event per verified patch (`errorCode: already_patched`). A patch with no installed copy is skipped as `apply` skips it (`package_not_installed`; the human line adds `M not installed, skipped`). Vendor-owned patches are excluded (`vendor --check` audits them). Lock-free, fetch-free, offline-safe; it never writes. An unreadable manifest is drift (`manifest_unreadable`, exit 1) |
92
-
|`vendor`|`--force` / `-f`| — |Tolerate missing patch-target files in the stage + bypass the variant probe. A beforeHash mismatch no longer needs it: vendor staging auto-overwrites with the verified patched content (`vendor_content_mismatch_overwritten` warning) |
92
+
|`vendor`|`--force` / `-f`| — |Bypass the installed-variant probe for multi-release ecosystems. That is its only effect: vendoring commits the patch server's verified artifact and never reads the installed files' content, so a missing or mismatched installed file vendors the same with or without `--force` (no warning) |
93
93
|`vendor`|`--revert`|`SOCKET_VENDOR_REVERT`| Undo vendoring: restore recorded original lockfile fragments + remove `.socket/vendor/` artifacts. Works without a manifest. A package vendored over a hosted pin returns to its upstream registry entry, never to hosted (see "Takeover reconciliation") |
94
94
|`vendor`|`--check`| — | Offline, read-only artifact and wiring audit; exits 1 on drift. Conflicts with `--revert`. |
95
95
|`vendor`|`--local-repo <path>`| — | With `--check`, also inspect suffixed Maven jar/POM copies in this cache for conflicts. |
@@ -1343,7 +1343,7 @@ Every `--json` invocation emits a single JSON object that follows the **unified
1343
1343
|`vendor_yarn_berry_mixed_line_endings`|`failed`| vendor (yarn berry): `yarn.lock` or the root `package.json` mixes CRLF and LF line endings (or holds a bare CR) — no single ending can be kept, and yarn rewrites such a file wholesale on its next install (a mixed lock also fails `--immutable`, YN0028). Refused before any write; `yarn install` normalizes the files. A uniformly CRLF pair is vendored in CRLF. A hosted→vendored takeover (`vendor`, `scan`/`get --mode vendored`) raises this — and the berry `vendor_yarn_berry_cache_unsupported` gates — BEFORE restoring the hosted pin's upstream entry (dry run too), so a refused purl stays hosted. |
1344
1344
|`vendor_override_conflict`|`failed`| vendor (pnpm/yarn-berry): a user-authored override/resolution for the package already exists. pnpm exception: a user exact pin equal to the vendored version, under the bare `<name>` or the `<name>@<version>` key, in package.json `pnpm.overrides` or pnpm-workspace.yaml `overrides:` (#854; there a quoted `'1.3.0'` or a trailing `# comment` is the same pin), is taken over in place (its value becomes the vendored `file:` spec under the user's own key on every override surface) and `vendor --revert` restores it byte-for-byte. A range, another version, a `>` selector, several same-name keys, or package.json and pnpm-workspace.yaml pinning under different keys still refuse; the detail names the file that carries the override. |
1345
1345
|`vendor_integrity_unverified`|`skipped` (warning) | vendor (pipenv): the lockfile format does not hash-check file entries; the committed wheel bytes are the protection. |
1346
-
|`vendor_content_mismatch_overwritten`|`skipped` (warning) | vendor: a staged file matched NEITHER beforeHash nor afterHash (patch built against different bytes, or local edits); the stage was overwritten with the verified patched content and the vendor succeeded. |
1346
+
|`vendor_content_mismatch_overwritten`|— |**No longer emitted** (service-only vendoring): `vendor` commits the patch server's verified artifact without reading the installed bytes, so it has no mismatch to report. Kept so consumers that match on it know it will not appear. |
1347
1347
|`vendor_vlt_transitive_unsupported`|`failed`| vendor (vlt): the target has an inbound edge from another package in `vlt-lock.json` (the detail names it); vendored mode rewires only direct dependencies of the root or a workspace member, because vlt silently reverts transitive lock surgery. Remedy: `--mode hosted`. Refused before any download or write, dry runs included (`would_refuse`). |
1348
1348
|`vendor_vlt_lock_out_of_sync`|`failed`| vendor (vlt): an importer's `package.json` is missing, unparseable, or declares a spec for the dependency that differs from the lock's importer edge. Remedy: `vlt install` first. Refused before any write. |
1349
1349
|`vendor_vlt_build_scripts_unsupported`|`failed`| vendor (vlt): the package declares a `preinstall`, `install`, `postinstall` or `prepare` script, or ships a `binding.gyp`. vlt builds a registry copy in the untracked store, but a vendored `file:` dependency in place, so `vlt build` would rewrite the committed artifact (a platform binary over a JS shim, say) and every later vendor, repair and `vex` would treat it as tampered. Remedy: `--mode hosted`. Refused before any write. |
0 commit comments