diff --git a/crates/socket-patch-cli/CLI_CONTRACT.md b/crates/socket-patch-cli/CLI_CONTRACT.md index 54bf2197c..ac2539f88 100644 --- a/crates/socket-patch-cli/CLI_CONTRACT.md +++ b/crates/socket-patch-cli/CLI_CONTRACT.md @@ -531,7 +531,7 @@ Discovery is read-only, never touches the network, and never fails the run: a ma | bun | `bun.lock`; `bun.lockb` only when there is no `bun.lock` (bun reads exactly one) | URL tuple / binary remote-tarball resolution; version from the URL leaf. A user URL or `file:` tarball tuple / record whose `-.tgz` leaf names the same `name@version` is installed from its own spec, so every ref for that `name@version` is dropped | `.socket/vendor/npm//-.tgz` tuple / local-tarball resolution | `sha512-…`, required. A 2-tuple that Bun < 1.3.10 re-saved without its digest is still a reference, but it attests only from an installed tree. | | vlt | `vlt-lock.json` (lockfileVersion absent, `0` or `1`; a BOM-prefixed, unparseable, non-object or other-version lock is not read: diagnosed, no ref). `vlt.json` (read only for its `modifiers`) and `node_modules/.vlt-lock.json` are never wiring. | a registry node (any segment) whose slot [3] is a `/patch/npm/…` URL on the patch host with the leaf `-.tgz` of its DepID's `name@version`, whose embedded `/` path (when present) is that `name@version`, and slot [1] == name; version from the DepID | a `file` node `.socket/vendor/npm//-/node_modules/` (or a user-installed `-.tgz`) with slot [1] == name; version from the path. A same-`name@version` registry node, or a diagnosed Socket-shaped one, beside it is diagnosed, no ref. | slot [2] `sha512-…`, required (a hosted node without one is no reference). A same-`name@version` node on another registry, or a diagnosed Socket-shaped one, keeps the reference but withholds the lockfile basis: only an installed tree whose every store copy verifies attests. So does a lock some vlt release discards, the conditions of `redirect_vlt_lockfile_version_missing`, `redirect_vlt_old_lockfile_ignored` and `redirect_vlt_scalar_registry_ignored` (which in-run `--vex` withholds too): every hosted reference in it keeps no pin, and one `patched_ref_unattributable` names them. | | cargo | `Cargo.lock`, `Cargo.toml`, `.cargo/config` (else `.cargo/config.toml`) | `Cargo.lock` `source = "sparse+…//index/"`, confirmed by `Cargo.toml`: a crate the root manifest declares must pin `registry = "socket-patch-"`. A reverted pin is diagnosed, no ref. Another `[[package]]` of the same `name@version` from a non-Socket source (crates.io, git), which cargo locks beside the pin for a dependent added later and builds unpatched (#679), withholds the ref (`patched_ref_unattributable`, never attested) while `rollback` / `remove` still unwind it. | `[patch.] = { path = ".socket/vendor/cargo//-" }` — primarily the root `Cargo.toml` (v5 `vendor`; key-agnostic: `` is `package` when renamed, else the key, so `-socket-` keys count), also the project config (pre-v5 wiring), live only while the lock holds a sourceless entry for it that is not in `[[patch.unused]]`; a manifest entry cargo ignores — the project config redefines its key with another path, or a `[patch."https://github.com/rust-lang/crates.io-index"]` table replaces `[patch.crates-io]` — is diagnosed (`patched_ref_invalid`), no ref | `checksum` (v1: `[metadata]`), required | -| golang | `go.mod`, `go.work`, `go.sum`, `go.work.sum` | `replace M v => patch.socket.dev/gopatch/ ` | `replace M v => ./.socket/vendor/golang//M@v` | the socket module's `/go.mod` go.sum line, required. The zip line (`h1:` of the module tree) is the locked integrity when present; `go mod tidy` prunes it when no package of the module is loaded and the build stays green, so the `/go.mod` line alone still attests from the lockfile, unless the main modules' `require`s or go.sum show the build selects another version (MVS keeps the `/go.mod` line of versions it only reads): then the replace is inert. With a `go.work` the main modules are its `use` members and the build selects by MVS over their module graph: each member's `require`s and the `go.mod` of every dependency go loads (read from its replacement directory or the module cache when the root is on disk). go keeps no member's `go.mod` tidy in workspace mode, so a member's dependency can raise the module past every `require`. A pin, zip line or not, whose replaced version a member's or a dependency's `require` raises is inert, as is one of a module that is itself a `use` member (go builds it from that directory). Sum-file zip lines are no evidence of the selection (go only appends to `go.work.sum`), and a `/go.mod`-only pin is never the lockfile basis in a workspace (`integrity_required = true`). Any mode writes the replace of a module a workspace shares into the root `go.work` (source `go.work`); a `go.work` root without a `go.mod` also reads each in-root member's `go.mod` replaces (source `/go.mod`). The sum files are the ones go reads: the root `go.sum`, or with a `go.work`, `go.work.sum` and each in-root `use` member's `go.sum` (the root's only when `.` is a member); under `GOWORK=off`, `go.work` and its replaces are ignored; a `GOWORK` naming any file other than the root's `go.work` (or a relative path, which go rejects) leaves the workspace unread: each Go ref is reported as `patched_ref_invalid` instead. A conflicting hash or a malformed `h1:` for the socket module+version, or a line of other than three tokens anywhere in a sum file, is no pin. A replace that `require` no longer selects (`require M v'`) is inert: diagnosed, no ref. | +| golang | `go.mod`, `go.work`, `go.sum`, `go.work.sum` | `replace M v => patch.socket.dev/gopatch/ ` | `replace M v => ./.socket/vendor/golang//M@v` | the socket module's `/go.mod` go.sum line, required. The zip line (`h1:` of the module tree) is the locked integrity when present; `go mod tidy` prunes it when no package of the module is loaded and the build stays green, so the `/go.mod` line alone still attests from the lockfile, unless the main modules' `require`s or go.sum show the build selects another version (MVS keeps the `/go.mod` line of versions it only reads): then the replace is inert. With a `go.work` the main modules are its `use` members and the build selects by MVS over their module graph: each member's `require`s and the `go.mod` of every dependency go loads (read from its replacement directory or the module cache when the root is on disk). go keeps no member's `go.mod` tidy in workspace mode, so a member's dependency can raise the module past every `require`. A pin, zip line or not, whose replaced version a member's or a dependency's `require` raises is inert, as is one of a module that is itself a `use` member (go builds it from that directory). Sum-file zip lines are no evidence of the selection (go only appends to `go.work.sum`), and a `/go.mod`-only pin is never the lockfile basis in a workspace (`integrity_required = true`). Any mode writes the replace of a module a workspace shares into the root `go.work` (source `go.work`); a `go.work` root without a `go.mod` also reads each in-root member's `go.mod` replaces (source `/go.mod`). The sum files are the ones go reads: the root `go.sum`, or with a `go.work`, `go.work.sum` and each in-root `use` member's `go.sum` (the root's only when `.` is a member); under `GOWORK=off`, `go.work` and its replaces are ignored; a `GOWORK` naming any file other than the root's `go.work` (or a relative path, which go rejects) leaves the workspace unread: each Go ref is reported as `patched_ref_invalid` instead, as it is when `GOFLAGS` sets a `-modfile` other than the root `go.mod`. A conflicting hash or a malformed `h1:` for the socket module+version, or a line of other than three tokens anywhere in a sum file, is no pin. A replace that `require` no longer selects (`require M v'`) is inert: diagnosed, no ref. | | pypi | `uv.lock` (confirmed by `pyproject.toml` `[tool.uv.sources]` when present), PEP 723 `