Skip to content

Commit ec60a10

Browse files
committed
refactor: record #1253 merge (C51)
1 parent db75dd5 commit ec60a10

5 files changed

Lines changed: 10 additions & 6 deletions

File tree

‎doc/05-vendored.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ Revert/restore/unwind code in the non-npm backends totals **about 3,540 lines**:
167167

168168
### 5.5 Security: zip inflate on committed artifacts (fixed, #587)
169169

170-
`zip_bytes_match_after_hashes` now streams each member through the Git SHA-256 reader with an 8 KiB buffer and checks the declared length against the bytes read; it no longer inflates members into a `Vec` sized by the archive's own header (#587). The maintainer ruled that this data is trusted not to be too big, so the fix streams instead of capping. {{C01}} Agent-mode jar verification still buffers each member. {{C51}}
170+
`zip_bytes_match_after_hashes` now streams each member through the Git SHA-256 reader with an 8 KiB buffer and checks the declared length against the bytes read; it no longer inflates members into a `Vec` sized by the archive's own header (#587). The maintainer ruled that this data is trusted not to be too big, so the fix streams instead of capping. {{C01}} Agent-mode jar verification streams through the same hasher since #1253 (`hash::git_sha256::zip_member_git_sha256`); this function still runs its own lookup-and-hash loop. {{C51}}
171171

172172
It runs on:
173173
- committed, tamperable artifacts (the NuGet hot path, `nuget_feed.rs:266`; the committed Maven jar, `maven_repo.rs:736` and `:1464`);

‎doc/07-infra-agent.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Added on 2026-10-07 by the October 7 reconciliation; owned by `audit-core`. Thes
164164
| **Writes stay inside the project** | Every vendored and hosted write under `.socket/`, and every agent write, must stay inside the tree it was found in; links are refused, not followed. | One helper, `utils::containment`, now lstats every level from the project root: vendored writes, reverts and ledgers refuse a linked `.socket` (`vendor_dir_symlink_unsupported`), `get` hash-checks and stages inline blobs (#726), and agent writes that resolve outside the package are refused as `OutsideInstallTree` (#1042). #887 is closed as fixed by #1042. Remaining: agent-mode manifest and blob writes still follow a linked `.socket` (a known gap #1042 names), and rollback of an overwritten new file needs a pre-image store. {{C60}} |
165165
| **Bytes are verified before they are trusted** | Patched content is hash-checked before any write; downloaded and inline blobs are checked against their name. | Agent apply verifies before writing; the inline-blob writer did not (fixed in PR #1042). Hosted rollback re-pins integrity from the registry (trust-on-rollback, E33/E45). |
166166
| **No planted binaries** | Tools are resolved with `resolve_tool`, never by bare name in the scanned repo. | Fixed (#617). {{C04}} |
167-
| **Untrusted archives are streamed** | Committed and service archives are hashed by streaming, never inflated into memory by their own header. | Vendored verify streams (#587); agent-mode jar verification still buffers (C51). {{C01}} |
167+
| **Untrusted archives are streamed** | Committed and service archives are hashed by streaming, never inflated into memory by their own header. | Vendored verify streams (#587); agent-mode jar verification streams too since #1253 (C51). {{C01}} |
168168
| **Updates are authentic** | Self-update and `install.sh` should verify a signature or attestation, not only a same-origin checksum. | Only a same-origin `SHA256SUMS`; immutable releases stop swaps of a published release, not a malicious new one. {{C72}} |
169169
| **Tests never reach production** | Test children must not send telemetry or call production endpoints. | The workspace `[env]` table, `hermetic::command` and every workflow env block set `SOCKET_TELEMETRY_DISABLED`, and a test keeps the workflow copies in step (#1046). {{C66}} |
170170

@@ -178,7 +178,7 @@ Added on 2026-10-07 by the October 7 reconciliation; owned by `audit-core`. Thes
178178
- {{C26}} The vendored group-commit journal is replayed only inside `apply_lock::acquire`, so the lock-free readers never see a pending commit: after a crash past the journal, `vendor --check` fails every patch with `vendor_ledger_missing` (whose documented remedy is restoring `state.json` by hand) and pnpm `vex` omits the packages, while one locked command rolls the commit forward to the uninterrupted result (proved twice with `group_commit_file@1`).
179179
- {{C49}} Registry downloads (`build_registry_client`, `maven_repo::fetch_registry_bytes`) now share `ApiTimeouts`' 10 s connect + 60 s idle bound instead of a 60 s total deadline, so a slow but progressing artifact download completes (#876).
180180
- {{C50}} Artifact GC has two retention policies. `ArtifactReferences::after_removal` (rollback, remove) keeps every active patch's beforeHash blobs so offline rollback keeps working (#600), while `for_apply` (repair, `scan --prune`) keeps only afterHash blobs. On `9c43dfc`, `repair --offline` deleted an active patch's original, and `rollback --offline` then exited 1 (twice), telling the user to run `repair`, which only ever downloads afterHash blobs. `cleanup_unused_blobs`/`_archives` and `format_cleanup_result` have no production caller.
181-
- {{C51}} Agent-mode jar verification (`jvm_jar::verify_member_bytes`, used by `apply`, `rollback` and `vex` for Maven/Gradle member records) inflates each patched member into a `Vec` before hashing, while its vendored twin `zip_bytes_match_after_hashes` streams since #587. On `9c43dfc`, a jar with one deflated 1 GiB member peaked at 1,067 MiB RSS through the agent routine and 26 MiB through the vendored one (twice). One streaming member-hash helper replaces both.
181+
- {{C51}} Agent-mode jar verification (`jvm_jar::verify_member_bytes`, used by `apply`, `rollback` and `vex` for Maven/Gradle member records) streams each patched member through `hash::git_sha256::zip_member_git_sha256` since #1253 (302 → 30 MiB peak RSS on a 256 MiB member). The vendored twin `zip_bytes_match_after_hashes` still has its own lookup-and-hash loop; moving it onto the helper is the remaining slice.
182182
- {{C48}} Child processes share one deadline: `utils::process::output_within` bounds the crawler probe runners (`run_resolved`, `PROBE_TIMEOUT` 10 s), `pipenv`, `hatch`, the self-update `sanity_exec` (#886) and the PDM site probe (#1106), so a `gem` shim that never answers no longer hangs a local `scan`. Only the `git check-ignore` exchange in `vendor/npm_dir.rs` still hand-rolls its timeout (#1067).
183183
- {{C77}} The OpenVEX document (`vex --output` and the embedded `--vex` of `apply`/`vendor`/`scan`) is the one CLI write outside `utils::fs`: `generate_vex` calls `tokio::fs::write`, which truncates in place, so a failed write (ENOSPC on `823810a`) leaves a truncated document that starts with an OpenVEX header, and the stale-document cleanup, which removes only a parseable document, keeps it. That breaks the documented failure contract and `durability.rs`'s claim that every write is staged.
184184
- {{C78}} The hosted upstream restore (`rollback`/`remove` of hosted pins, the hosted → vendored takeover and eject) re-resolves every pin from the public registry with an unbounded `join_all` in five formats (npm/vlt, PyPI, cargo, Go, Composer), while `utils::concurrent::registry_concurrency()` (cap 4; 1 under a tight fd limit), added for public registries in #1039, has no caller. On `f3c6313`, 40 npm pins put 40 requests in flight (twice); the registry client has no 429 handling.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[agent] 2026-10-09: architecture refactor run (merge record)
2+
3+
- main: `e9be7462`. #1253 (C51, agent-mode jar members streamed through `hash::git_sha256::zip_member_git_sha256`) merged.
4+
- Register: C51 → partly fixed (#1253); the `vendor/common.rs::zip_bytes_match_after_hashes` caller remains (now free: #1227 merged). Doc passages rewritten: 07 "Untrusted archives are streamed" row and the C51 bullet; 05 #587 paragraph.
5+
- Follow-up for the #914 remainder: the final reviewer asked for a committed test of a member whose declared size disagrees with its stream (`NotFound`), alongside the vendored one near `vendor/common.rs:1154`.

‎register/20-audit-core.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ _Last updated 2026-10-09T09:55Z · main @ a80b89e_
4949
| C48 | 2 | Child processes had no shared deadline; crawler probes called `output()` unbounded, so a hung `gem` shim hung `scan`. | new finding | #845, #1067 | partly fixed (#886, #1106); the `npm_dir` git exchange keeps a hand-rolled deadline (#1067) |
5050
| C49 | 2 | Registry downloads used a 60 s total deadline. | new finding | #872 | fixed (#876) |
5151
| C50 | 2 | Artifact GC has two retention policies: `after_removal` (rollback, remove) keeps active patches' beforeHash blobs for offline rollback, `for_apply` (repair, `scan --prune`) drops them; offline rollback then fails and names `repair`, which never fetches beforeHash blobs. `cleanup_unused_blobs`/`_archives` are dead. | new finding | #893 | filed #893 |
52-
| C51 | 3 | Agent-mode jar verification (`jvm_jar::verify_member_bytes`; apply, rollback, vex) buffers each patched member before hashing, while vendored `zip_bytes_match_after_hashes` streams since #587: 1,067 MiB vs 26 MiB peak RSS on a 1 GiB member. | new finding | #914 | filed #914; in PR #1253 |
52+
| C51 | 3 | Agent-mode jar verification (`jvm_jar::verify_member_bytes`; apply, rollback, vex) buffers each patched member before hashing, while vendored `zip_bytes_match_after_hashes` streams since #587: 1,067 MiB vs 26 MiB peak RSS on a 1 GiB member. | new finding | #914 | filed #914; partly fixed (#1253, agent mode); `vendor/common.rs` caller open |
5353
| C54 | 3 | The contract documents `status: paidRequired` and errorCode `paid_required` for get and scan, but `get` emits legacy `status: "paid_required"` (two hand-written blocks) and `scan` reports only `paidPatches`; `Status::PaidRequired` is never constructed. | new finding | #982 | filed #982 |
5454
| C55 | 3 | Decide: the future of agent mode. Only Deno and `--global` installs need it. | §5; §6 Q2 | #1000 | rejected; #1000 kept agent mode for every ecosystem |
5555
| C56 | 2 | `apply`, `apply --check` and `vendor` treat any stat error on `.socket/manifest.json` as "no manifest" (`noManifest`, exit 0); `repair`/`remove`/`rollback` say `manifest_not_found`. Five `metadata().is_err()` probes bypass `read_manifest`'s NotFound rule. | new finding | #998 | filed #998 |

‎register/90-refactor.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ _Last updated 2026-10-09T14:30Z · main @ e782c9a_
77
- [#1264](https://github.com/SocketDev/socket-patch/pull/1264): Gradle (vendored + hosted) and the Maven reactor pick inserted-line terminators through `line_endings::terminator`; `gradle/eol.rs` deleted (`eol_eq` and `respell` in `line_endings`). #815 slice 3 (E16). +67/−97 prod, +67/−37 tests. `state: ready`.
88
- [#1262](https://github.com/SocketDev/socket-patch/pull/1262): the OpenVEX document is written through `utils::fs::write_user_output` (stage + rename; links through, devices in place). #1144 (C77). +57/−1 prod, +185 tests; CI green, Bugbot clean. `state: ready`.
99
- [#1258](https://github.com/SocketDev/socket-patch/pull/1258): 40 more CLI test files import `tests/common`'s `binary()` / `git_sha256` (31 + 25 copies deleted). #824 children 2–3 slice 2 (C30). +142/−401 tests, 0 prod. `state: ready`.
10-
- [#1253](https://github.com/SocketDev/socket-patch/pull/1253): agent-mode `jvm_jar::verify_member_bytes` streams members through `hash::git_sha256::zip_member_git_sha256` (302 → 30 MiB peak on a 256 MiB member). #914 slice (C51); `vendor/common.rs` caller is free since #1227 merged; it needs #1253's helper. +17/−11 prod, +85 tests. `state: ready`.
1110
- [#1245](https://github.com/SocketDev/socket-patch/pull/1245): `vendor::revert::finish` + `KeepPolicy` (`OnDrift`, `OnDriftWhileReferenced`, `NpmFamily`); gem, composer, Maven legacy, NuGet and pnpm finish through it. #989 item 1 slice (E24). +133/−157 prod (helper 90), +271 tests. `state: ready`.
1211
- [#1239](https://github.com/SocketDev/socket-patch/pull/1239): NuGet crawler `find_by_purls` looks up the global folder and legacy `<Id>.<Version>/` folders by the normalized version (`1.0.0.0` = `1.0.0`) through `normalize_nuget_version`. #1202 crawler slice (E93). +47/−19 prod, +116/−4 tests. `state: ready`.
1312
- [#1188](https://github.com/SocketDev/socket-patch/pull/1188): one `Pipfile.lock` writer (`formats::pipenv::splice_entry`, `formats::json`). Issue #1128 (E14). +303/−235 production. `redirect/mod.rs` wrapper `pipenv_reserialized_around_reference` left for when that file is free. `state: ready`.
1413
- [#1126](https://github.com/SocketDev/socket-patch/pull/1126): 7 inline purl-type checks through `Ecosystem::from_purl` + guard. Issue #747 (C20, slice 1). `state: ready`.
1514
- Maintainer draft: #1049 (#792).
1615

17-
**Merged:** #1227 (E16 slice 2), #1221 (E19 hosted gem), #1230 (E93 `PurlKey`), #1217/#1209/#1205/#1183 (E05 Deno, Go, cargo, NuGet crawls); 32 earlier PRs (#572 … #1191, see `entries/refactor/`). Leftovers: `blob_hash_matches` (#1163), dead `eco == "maven2"` arm in `commands/vendor.rs` (#1015).
16+
**Merged:** #1253 (C51 agent-mode jar streaming; `vendor/common.rs` caller and a size-mismatch test remain), #1227 (E16 slice 2), #1221 (E19 hosted gem), #1230 (E93 `PurlKey`), #1217/#1209/#1205/#1183 (E05 Deno, Go, cargo, NuGet crawls); 32 earlier PRs (#572 … #1191, see `entries/refactor/`). Leftovers: `blob_hash_matches` (#1163), dead `eco == "maven2"` arm in `commands/vendor.rs` (#1015).
1817

1918
**Queue** (score = 3B + 2U + 2D + S − risk). Standalone refactor issues closed `not_planned` live on as tracker checklist items; rank the tracker's next item.
2019

0 commit comments

Comments
 (0)