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 7995df5
Browse filesBrowse the repository at this point in the historyBrowse files
_Last checked against main @ 203e092 on 2026-10-02 by audit-ecosystems. Owner: `audit-ecosystems`._
5
+
_Last checked against main @ 045d7ec on 2026-10-04 by audit-ecosystems (3.6 vlt dead helpers re-checked; the rest as of `203e092`). Owner: `audit-ecosystems`._
@@ -163,7 +163,7 @@ For uv, pylock, poetry, pdm, hatch, vlt, maven and bun.lockb, the module's own f
163
163
164
164
| Feature | Prod LOC (approx.) | Notes |
165
165
|---|---:|---|
166
-
| vlt hosted | 2,454 + 1,707 tests | The warm-tree heal deletes `node_modules/.vlt` store entries: installed-tree surgery in a lockfile-only mode. vlt never redirects in memory. Contains dead ledger helpers.|
166
+
| vlt hosted | 2,454 + 1,707 tests | The warm-tree heal deletes `node_modules/.vlt` store entries: installed-tree surgery in a lockfile-only mode. vlt never redirects in memory. Contains dead ledger helpers (`edit_dep_id`, `lock_node_ids`, `carried_pin_original`, `vlt_heal::ledger_targets`), orphaned when #277 removed the ledger merge. {{E58}}|
167
167
| npm `allow-remote` auto-config |~900 + 514 tests |`npmrc.rs` re-implements npm's `ini` tokenizer and its user/global/builtin/env config layering, all to decide whether to append one line to `.npmrc`. |
168
168
| pnpm `trustLockfile` auto-config |~450 | Heal-on-rerun, takeover previews, legacy and Rush special cases. Open issues #400, #401, #402 (quoted keys, flow style, duplicate keys) are all here. |
169
169
| Parallel rewriter groups |~260 + 451 equivalence tests | Parallelizes CPU work over a handful of texts that is already single-pass. Benchmark it, or delete it. |
@@ -202,6 +202,7 @@ For uv, pylock, poetry, pdm, hatch, vlt, maven and bun.lockb, the module's own f
202
202
- {{E50}}: hosted `rewrite_nuget` and upstream restore rewrite every `packages.lock.json` entry of the patched id, in every target framework, whatever its `resolved` version; vendored `locked_at` only touches entries at the patched version. `packages.lock.json` has four walkers (hosted, restore, vendored, VEX).
203
203
- {{E52}}: `vendor/go_sum_edit.rs` keeps free `upsert_module_lines` / `has_module_version` / `remove_exact_module_version_lines` with no production caller, re-implemented by the `GoSumEditor` the hosted Go rewriter uses; the free copies survive only as a test oracle, and the pure hosted codec lives in `vendor/`.
204
204
- {{E57}}: the hosted cargo planner `plan_cargo_toml` is a line scanner, gated by a second `toml_edit` classifier of the same declarations. It refuses `serde = { version = "1", features = [⏎ "derive",⏎] }` as "inline table does not close on its line", although cargo and `toml_edit` accept it, so hosted skips a crate that vendored mode handles. Upstream restore unpins with a third, line-level grammar.
205
+
- {{E58}}: the hosted-vlt ledger helpers `edit_dep_id`, `lock_node_ids`, `carried_pin_original` and `vlt_heal::ledger_targets` have no production caller since #277 deleted `rebase_vlt_edits` and the ledger heal; `UpstreamClient::seed_rubygems_sha256` is a test helper compiled into production.
205
206
206
207
---
207
208
_Generated by [Claude Code](https://claude.ai/code)_
Copy file name to clipboardExpand all lines: doc/05-vendored.md
+6-3Lines changed: 6 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
## Part 5: Vendored mode and the non-JS backends
4
4
5
-
_Last checked against main @ 045d7ec on 2026-10-04 by audit-ecosystems (5.4 Python, Cargo and Maven XML). Owner: audit-ecosystems._
5
+
_Last checked against main @ 045d7ec on 2026-10-04 by audit-ecosystems (5.4 Python, Cargo, Maven XML, Gem and Go). Owner: audit-ecosystems._
6
6
7
7
> Scope: `vendor/` framework (`mod`, `common`, `state`, `verify`, `registry_fetch`, `service_fetch`, `prestage`, `reuse`, `redownload`, `ledger_snapshots`, `parse_memo`, `path`, `source`, `toml_surgery`, `lock_inventory`); backends for cargo, gem, pypi (×10 files), golang, composer, nuget, maven and `jvm/`; related `utils/` parsers; and the CLI `vendor.rs` + `vendored_backend/`.
8
8
@@ -141,9 +141,10 @@ Revert/restore/unwind code in the non-npm backends totals **about 3,540 lines**:
141
141
- They have drifted, proven by execution: a BOM manifest is invisible to the crawler but read by VEX and `cargo_tag`; `[project]` and dotted keys are read only by `cargo_tag`; `[package] junk` (invalid TOML) is accepted only by the crawler. {{E15}}
142
142
- Hosted mode plans the dependency pin itself with a line scanner (`plan_cargo_toml`, six regexes), then re-checks it with a second, `toml_edit` classifier (`validate_cargo_toml_pins`). `CargoRegistryPins`, a `#[cfg(test)]` oracle and upstream restore's `unpin_line` are three more line-level readers of the same declarations. Vendored edits only through `toml_edit`. The scanner refuses an inline table whose `features` array spans lines, which is valid TOML and accepted by cargo, so hosted skips a crate that vendors fine. {{E57}}
143
143
144
-
**Gem:**`vendor/gem.rs` imports three token helpers from `formats::gem` and keeps its own section model. `formats/gem` itself has two section models, and there are two DEPENDENCIES-name parsers with different rules.
144
+
**Gem:**`vendor/gem.rs` imports three token helpers from `formats::gem` and keeps its own section model (`section_span` / `section_end`, which take the *first* line equal to a header). With `formats::gem::parse` and hosted's `GemLockSection` that makes three section models and three DEPENDENCIES-name parsers; the name rules agree on Bundler-written entries. {{E19}}
145
+
- The section models have drifted, proven by execution: Bundler 2 writes one `GEM` section per source, and vendored `edit_lock` looks only in the first, so a gem from any later source (rubygems.org, when a private source sorts first) is refused with "GEM specs has no entry", while hosted and the shared parser handle it. {{E59}}
145
146
146
-
**Go:**`go_mod_edit.rs` is properly shared (9 users) but lives under `vendor/`. `crawlers/go_crawler.rs:63` still has its own `parse_go_mod_module`.
147
+
**Go:**`go_mod_edit.rs` is properly shared (9 users) but lives under `vendor/`. `crawlers/go_crawler.rs:63` still has its own `parse_go_mod_module`, which has no production caller; the live `module` reader is `vex/product.rs`'s own, and both misread Go's block form `module ( … )` as the module `(`. {{E19}}
147
148
148
149
**Small helpers:**
149
150
-**CRLF:** four policies for the same "`toml_edit` emits LF" problem:
@@ -249,6 +250,8 @@ Old `kind`s are translated into `SpliceRecord`s when the ledger loads, so legacy
249
250
250
251
### New findings since the review
251
252
253
+
- {{E59}}: vendored gem `edit_lock` searches only the first `GEM` section of `Gemfile.lock`. Bundler 2 writes one per source, so in a project with a private source that sorts first, every rubygems.org gem is refused with "GEM specs has no entry"; see 5.4.
254
+
- {{E58}}: production `pub fn`s with no production caller, orphaned by #277: `VendorEntry::committed_artifact_intact` and `go_sum_edit::remove_lines` (no reference at all), plus test-only helpers compiled into production (`cargo_tag::copy_manifest_tag`, `jvm::apply::read_project_file`). The hosted-vlt half is in Part 3.
252
255
- {{E55}}: vendored Maven decides "is this a reactor?" twice. `jvm::detect` uses the reactor's `Doc`-based `declares_modules`, which ignores plugin `<configuration><modules>`, then the legacy single-pom path re-checks with its own comment-stripping `declares_modules` and refuses `vendor_maven_multimodule_unsupported`. That refusal fires only on the disagreement, so every `maven-ear-plugin` project is refused; see 5.4.
253
256
- {{E54}}: the Poetry and PDM lock rewriters restore line endings with different rules, so a mixed-line-ending lock's edited unit becomes CRLF under Poetry and LF under PDM; see 5.4.
254
257
- {{E49}}: hosted Pipenv used to reject its own pins on path-prefixed `--patch-server-url` origins and sdists. Both private grammars (`owned_url`'s segment count, `is_socket_hosted_reference`) are deleted; Pipenv now uses `hosted_pypi_reference` (#572); see 5.4.
| go.mod |`go_mod_edit`|`module` directive parsed again at `go_crawler.rs:63` and `product.rs:175`|
71
+
| go.mod |`go_mod_edit`|`module` directive parsed again at `product.rs:175` and in `go_crawler.rs:63` (no production caller); both misread the block form `module ( … )` {{E19}}|
72
72
| NuGet |`formats::nuget::parse_open_tag`| vendored has its own XML scanner. The crawler reads `obj/project.assets.json`**only for `packageFolders`**, never `libraries`/`targets`, then enumerates the global `~/.nuget/packages`|
73
73
| Maven |`formats::maven::parse_pom`| vendored `jvm/maven_reactor.rs``Doc::parse` and `gradle.rs`; hosted's own tag scanner; the crawler's own XML parser; `product.rs` again |
[agent] 2026-10-04: architecture audit (ecosystems and formats)
2
+
3
+
**main @ `045d7ec`**, unchanged since the last run. There were no new maintainer replies in the discussion and no handovers for this routine.
4
+
5
+
**Reconciled.** No status changed: E01 (#597), E02/E03 (#574), E06 (#602), E09/E51 (#657), E13/E54 (#703) and E56 (#750) are still in their PRs, and nothing in this area merged. Because main did not move, no open issue needed re-checking.
6
+
7
+
**Verified and filed: E19** (gem and Go parsers), split into two refactors:
8
+
-**[#780](https://github.com/SocketDev/socket-patch/issues/780)** (pm:bundler): `Gemfile.lock` has three section models (`formats::gem::parse`, hosted's `GemLockSection`, vendored's `section_span` / `section_end`) and three DEPENDENCIES-name rules, not two. Target: both writers splice through the shared parse, deleting the copies. Sequenced after PRs #768 and #776.
9
+
-**[#781](https://github.com/SocketDev/socket-patch/issues/781)** (pm:go): `go_crawler::parse_go_mod_module` has no production caller; the live reader is `vex/product.rs`'s own. A unit probe, run twice, shows both read Go's block form `module (⏎\texample.com/blk⏎)` (accepted by `go 1.24.7 list -m`) as `(`, so `--product` becomes `pkg:golang/(`. Target: one `go_mod_edit::module_path` on the shared directive walker.
10
+
11
+
**New findings:**
12
+
-**E59, bug, proved by execution: [#779](https://github.com/SocketDev/socket-patch/issues/779)** (pm:bundler). Vendored gem `edit_lock` looks for the spec only in the first `GEM` section. I generated a real lock with Bundler 4.0.17 for a Gemfile with rubygems.org plus a second (`file://`) source. Bundler sorted the private source first, so `rack` sits in the second `GEM` section. A unit probe on that lock, run twice: vendored refuses with "GEM specs has no entry `rack (2.2.8)`"; the swapped-order control succeeds; `formats::gem::parse().entries()` lists rack; hosted `converge_gem_lock_source` pins it. So every public gem is unvendorable in a project whose private gem source sorts before rubygems.org.
13
+
-**E58, refactor: [#782](https://github.com/SocketDev/socket-patch/issues/782).** I swept every `pub`/`pub(crate)` item in scope for references outside `#[cfg(test)]` code. Production helpers orphaned by #277: `VendorEntry::committed_artifact_intact` and `go_sum_edit::remove_lines` (no reference anywhere; #631 would have moved the latter), the hosted-vlt ledger helpers `edit_dep_id` / `lock_node_ids` / `carried_pin_original` / `vlt_heal::ledger_targets` (the review's "dead vlt ledger helpers", E34), and three test-only helpers compiled into production. `git log -S` on deepened history confirms #277 removed their callers (`rebase_vlt_edits`, `ledger_covers`, the rollback/vendor heal).
14
+
15
+
**Searched without filing:**
16
+
- Go "which version is live" (inventory reads every go.sum zip line; hosted refuses a go.mod require mismatch; VEX uses go.mod `require`): already covered by #392 and #509, so not filed.
17
+
- Gem default-remote rule (`[] → rubygems.org` in `entries()` and `recover.rs`, two spellings of the URL constant): trivial drift only. `same_remote` is shared.
18
+
- Composer reinstall hints (`composer_hints.rs`) walk `composer.lock` with their own vendored-dist rule. It is advisory output only, so not filed.
19
+
- NuGet hostname constants: inside E11.
20
+
21
+
**False positives ruled out:**
22
+
- A backquoted module path is rejected by `go` itself ("invalid quoted string"), and so is a BOM go.mod, so neither is a drift case.
23
+
-`registry_fetch``validate_*` and `reuse::prior_entry_reloading` are `#[cfg(test)]` oracles (E35), not dead production code.
24
+
25
+
**Living document:** Part 5's Gem and Go bullets are rewritten with {{E19}} and {{E59}}, E58/E59 are added under new findings, and the check line now covers Gem and Go. Part 3's vlt row names the dead helpers with {{E58}}, a new-findings bullet is added, and the check line is refreshed (scoped). Part 6's go.mod row is corrected and its check line extended. The register gains E58 and E59; E19 is filed; E34 notes #782.
26
+
27
+
**Next backlog rows:** E16 (CRLF policies), E08 (yarn grammars; after #657), E14 (Pipfile.lock, still unproven), E18 (JS helper copies), E28 (dead vendored scaffolding; fold in anything #782 leaves).
28
+
29
+
---
30
+
_Generated by [Claude Code](https://claude.ai/code)_
| E16 | 2 | CRLF has five policies in the npm family and three for `toml_edit` output, and `common::detect_eol` contradicts `LineEndings::Mixed`. Target: one line-ending policy. | 4.4; 5.4; 7.3 || to verify |
22
22
| E17 | 2 | "Is a bun lock present" is asked at seven sites with three semantics (lstat, `exists`, `is_file`). With a dangling `bun.lock` symlink, Bun and the writers use `bun.lockb`, but the inventory returns nothing. | 4.4 |#735| filed #735|
| E19 | 3 | Gem has three section models and two DEPENDENCIES-name parsers with different rules. Go's `go_mod_edit.rs` lives in `vendor/`, and `go_crawler.rs` has its own `parse_go_mod_module`. | 5.4 || to verify|
24
+
| E19 | 3 | Gem has three section models and three DEPENDENCIES-name parsers (vendored sees only the first `GEM` section, so #779). Go: `go_crawler::parse_go_mod_module` has no production caller; `vex/product.rs` has its own `module` reader that misreads the block form; `go_mod_edit.rs` lives in `vendor/`. | 5.4 |#780, #781| filed #780, #781; gem models (#780), go.mod `module` reader (#781)|
25
25
| E20 | 3 | Pure codecs (`bun_lockb.rs`, `bun_lock_text.rs`, `vlt_lock_text.rs`) and the neutral types (`Edit`, `Warning`, `LockfileEntry`) live outside `formats/`, which creates `formats`↔`vendor`/`redirect`/`vex` cycles. | 2.1; 4.5 #2; 4.7 J || to verify |
26
26
| E21 | 2 | Tracking: `VendorBackend` trait + registry. The ecosystem list is enumerated at 16 production sites, and the `vend!` / `vend_installed!` macros stand in for the trait. | 2.1; 5.2; 5.8 || to verify |
27
27
| E22 | 2 | The JS vendor driver skeleton is copied eight times (`guard_coordinates` → … → a literal `VendorEntry`). Target: one generic driver + `NpmLockBackend`. | 4.4; 4.7 C || to verify |
| E31 | 2 | Tracking: `trait HostedRewriter` + `Outcome { per_dep }`. It replaces the 20 uuid sets in `RewriteResult`, `merge_group_delta`, the 16-rule `confirm()` and eight parallel tables. | 2.1; 3.7 #2|| to verify |
37
37
| E32 | 2 | There are two hosted orchestrators, disk (`run_redirect_selected`) and in-memory (`hosted/memory`), kept equal by parity tests. Target: one pipeline. Depends on E44. | 3.3; 3.7 #4|| to verify |
38
38
| E33 | 3 | Upstream restore rebuilds originals from the network (~7.4K lines, ignores mirrors, 13 open bugs). Target: an originals sidecar or a narrowed restore. Depends on E45. | 2.3; 3.5 || to verify |
39
-
| E34 | 3 | Per-PM auto-config costs more than it's worth: npm `allow-remote` (~900 lines re-implementing npm config), pnpm `trustLockfile`, the vlt warm-tree heal, and the unbenchmarked parallel rewriter groups. | 3.6; 3.7 #7|| to verify |
39
+
| E34 | 3 | Per-PM auto-config costs more than it's worth: npm `allow-remote` (~900 lines re-implementing npm config), pnpm `trustLockfile`, the vlt warm-tree heal, and the unbenchmarked parallel rewriter groups. | 3.6; 3.7 #7|#782| to verify; dead vlt ledger helpers in #782 (E58)|
40
40
| E35 | 3 | Retire the refactor oracles: the redirect equivalence suites and 252 KB of goldens, the crawler oracles (3K lines), and the telescoping entry points (use one `RewriteOptions`). | 3.7 #9; 6.6 || to verify |
41
41
| E36 | 2 | Tracking: one `Inventory`. Today's four discovery systems are merged by fabricating `CrawledPackage`s with fake `node_modules/<name>` paths. Rename `vex::discover` (it is the hosted-state store). | 2.1; 6.2; 6.7 || to verify |
42
42
| E37 | 2 |`is_safe_{cargo,gem,nuget}_coordinate` are byte-identical and duplicate `simple_purl`'s check. `composer_crawler::normalize_version` duplicates `strip_leading_v`. | 6.4 |#630| filed #630|
| E55 | 2 | Vendored Maven has two `declares_modules`: `jvm::detect` (reactor `Doc`, ignores plugin `<configuration><modules>`) routes an EAR pom to the legacy path, whose comment-stripping copy then refuses it as `vendor_maven_multimodule_unsupported`. The legacy refusal fires only on that disagreement. | new finding |#716| filed #716|
61
61
| E56 | 2 | Lock inventory reads only `Gemfile.lock` and VEX discovery reads both locks, while hosted/vendored/crawler use `LoadedManifest::pair`: a `gems.rb` project's `gems.locked` is invisible to the inventory (in-memory hosted, scan supplement, VEX liveness), and a stale `Gemfile.lock` twin is read instead. | new finding |#736| in PR #750|
62
62
| E57 | 2 | Hosted `plan_cargo_toml` is a line scanner gated by a second `toml_edit` classifier (`validate_cargo_toml_pins`), beside three more line-level readers (`CargoRegistryPins`, a test oracle, restore's `unpin_line`). It refuses a valid inline table whose `features` array spans lines, so hosted skips a crate that vendors fine. | new finding |#757| filed #757|
63
+
| E58 | 3 | Production `pub fn`s with no production caller, orphaned by #277: `VendorEntry::committed_artifact_intact` and `go_sum_edit::remove_lines` (no reference at all), the hosted-vlt ledger helpers `edit_dep_id` / `lock_node_ids` / `carried_pin_original` / `vlt_heal::ledger_targets`, plus three test-only helpers compiled into production. | new finding; 3.6 |#782| filed #782|
64
+
| E59 | 2 | Vendored gem `edit_lock` finds the spec only in the first `GEM` section (`section_span(…, "GEM")`); Bundler 2 writes one per source, so a gem from any later source is refused with "GEM specs has no entry". Hosted and the shared parser read every section. | new finding |#779| filed #779|
0 commit comments