[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: discussion #560 register.
Kind: bug. Source: new finding, register E61 (related to the backend-trait tracking row E21).
Problem
scan_vendor_references is the one check that keeps a .socket/vendor/<eco>/<uuid>/ directory with no ledger entry from being deleted while a project file still points at it. It is used by the orphan sweeps (vendor --revert, the vendored gc pass), by repair (vendor_ledger_missing), by vendor (vendor_ledger_entry_missing) and by rollback. It recognizes NuGet and Maven wiring in neither of the two ways it would need to:
-
The file list. It reads registry::paths_with(VENDORED) (repair.rs#L100-L104).`` The three nuget.config spellings and `pom.xml` are `HOSTED | PROBE`, without `VENDORED` (`registry.rs#L123-L125`, `#L142`). Yet those are exactly the files the NuGet and Maven vendored backends rewire.
-
The reference grammar. Even if the files were read, both backends point at the uuid directory, not at a leaf inside it:
parse_vendor_path requires a non-empty leaf after the uuid (path.rs#L102-L108), and the scanner's terminator set has no < (repair.rs#L73-L77),`` so …/maven/<uuid></url> doesn't parse either.
Meanwhile sweep_vendor_dirs does enumerate nuget/ and maven/ (ECOSYSTEM_DIRS), and sweep_orphan_vendor_dirs deletes every unrecorded unit the scan didn't report (vendor.rs#L294-L333). Its doc comment states the invariant this breaks: "Deleting such a dir would break the next install, so every candidate is checked against the wiring-bearing files first".
Also dead: the vendor stranded-reference gate matches eco == "maven2" (vendor.rs#L2134-L2139), but parse_vendor_path only ever yields maven.
Proof by execution (a throwaway #[tokio::test] in commands/vendor.rs, run twice on 045d7ec, then removed). It uses an empty VendorState, one artifact file in the uuid dir, and the backend's own wiring text:
PROBE nuget: refs=[] still_wired=0 removed=1 artifact_exists=false
PROBE maven: refs=[] still_wired=0 removed=1 artifact_exists=false
PROBE npm: refs=[("npm", "1a2b…", ".socket/vendor/npm/1a2b…/left-pad-1.3.0.tgz")] still_wired=1 removed=0 artifact_exists=true
The npm control is kept as still wired; the NuGet and Maven units are deleted while nuget.config / pom.xml still name them.
Symptoms
None filed. When a NuGet or Maven ledger entry is missing (state.json lost, a partial commit, or a merge that drops a row: the case the sweep guards against for every other ecosystem):
vendor --revert and the vendored gc delete the feed or repository, and the next dotnet restore / mvn fails with a missing source;
repair reports nothing (no vendor_ledger_missing);
vendor re-vendors without the vendor_ledger_entry_missing refusal.
Impact: destructive, but it needs a missing ledger entry first. Small fix.
Proposed change
- Give the NuGet config spellings and
pom.xml the VENDORED role (check every reader of paths_with(VENDORED) / has(VENDORED) first). The Maven reactor's module poms live below the root, so add them the way wiring_files already adds the dynamic sets (vlt importers, requirements includes), or from the ledger's recorded wiring files.
- Recognize a uuid-directory reference: a
parse_vendor_dir_ref (or an optional leaf in parse_vendor_path) that yields (eco, uuid) for .socket/vendor/<eco>/<uuid> terminated by ", < or end of value, and add < to the scanner's terminators. Repair can fall back to the uuid dir as the path for these.
- Delete the dead
eco == "maven2" arm.
- Longer term, E21 (the
VendorBackend trait) should own "which files carry my references and how they are spelled", so that this table can't drift from the writers again.
Size and scope
formats/registry.rs, vendor/path.rs, commands/vendored_backend/repair.rs, commands/vendor.rs; under ~80 production lines. The Gradle tree (.socket/vendor/gradle/) is outside ECOSYSTEM_DIRS and out of scope. The registry role change must not widen hosted reads (HOSTED is unchanged).
Acceptance criteria
Dependencies
None. It touches nuget_feed.rs and maven_repo.rs only for tests. Coordinate with #597 (hosted NuGet) only if it changes registry.rs.
[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: discussion #560 register.
Kind: bug. Source: new finding, register E61 (related to the backend-trait tracking row E21).
Problem
scan_vendor_referencesis the one check that keeps a.socket/vendor/<eco>/<uuid>/directory with no ledger entry from being deleted while a project file still points at it. It is used by the orphan sweeps (vendor --revert, the vendored gc pass), byrepair(vendor_ledger_missing), byvendor(vendor_ledger_entry_missing) and by rollback. It recognizes NuGet and Maven wiring in neither of the two ways it would need to:The file list. It reads
registry::paths_with(VENDORED)(repair.rs#L100-L104).`` The threenuget.configspellings and `pom.xml` are `HOSTED | PROBE`, without `VENDORED` (`registry.rs#L123-L125`, `#L142`). Yet those are exactly the files the NuGet and Maven vendored backends rewire.The reference grammar. Even if the files were read, both backends point at the uuid directory, not at a leaf inside it:
<add key="…" value=".socket/vendor/nuget/<uuid>" />(nuget_feed.rs#L950);<url>file://${project.basedir}/.socket/vendor/maven/<uuid></url>(maven_repo.rs#L1644).parse_vendor_pathrequires a non-empty leaf after the uuid (path.rs#L102-L108), and the scanner's terminator set has no<(repair.rs#L73-L77),`` so…/maven/<uuid></url>doesn't parse either.Meanwhile
sweep_vendor_dirsdoes enumeratenuget/andmaven/(ECOSYSTEM_DIRS), andsweep_orphan_vendor_dirsdeletes every unrecorded unit the scan didn't report (vendor.rs#L294-L333). Its doc comment states the invariant this breaks: "Deleting such a dir would break the next install, so every candidate is checked against the wiring-bearing files first".Also dead: the
vendorstranded-reference gate matcheseco == "maven2"(vendor.rs#L2134-L2139), butparse_vendor_pathonly ever yieldsmaven.Proof by execution (a throwaway
#[tokio::test]incommands/vendor.rs, run twice on045d7ec, then removed). It uses an emptyVendorState, one artifact file in the uuid dir, and the backend's own wiring text:The npm control is kept as still wired; the NuGet and Maven units are deleted while
nuget.config/pom.xmlstill name them.Symptoms
None filed. When a NuGet or Maven ledger entry is missing (state.json lost, a partial commit, or a merge that drops a row: the case the sweep guards against for every other ecosystem):
vendor --revertand the vendored gc delete the feed or repository, and the nextdotnet restore/mvnfails with a missing source;repairreports nothing (novendor_ledger_missing);vendorre-vendors without thevendor_ledger_entry_missingrefusal.Impact: destructive, but it needs a missing ledger entry first. Small fix.
Proposed change
pom.xmltheVENDOREDrole (check every reader ofpaths_with(VENDORED)/has(VENDORED)first). The Maven reactor's module poms live below the root, so add them the waywiring_filesalready adds the dynamic sets (vlt importers, requirements includes), or from the ledger's recorded wiring files.parse_vendor_dir_ref(or an optional leaf inparse_vendor_path) that yields(eco, uuid)for.socket/vendor/<eco>/<uuid>terminated by",<or end of value, and add<to the scanner's terminators. Repair can fall back to the uuid dir as the path for these.eco == "maven2"arm.VendorBackendtrait) should own "which files carry my references and how they are spelled", so that this table can't drift from the writers again.Size and scope
formats/registry.rs,vendor/path.rs,commands/vendored_backend/repair.rs,commands/vendor.rs; under ~80 production lines. The Gradle tree (.socket/vendor/gradle/) is outsideECOSYSTEM_DIRSand out of scope. The registry role change must not widen hosted reads (HOSTEDis unchanged).Acceptance criteria
scan_vendor_referencesreports(nuget, uuid)for a vendorednuget.config(all three spellings) and(maven, uuid)for a vendored rootpom.xmland a reactor module pom.sweep_orphan_vendor_dirswith an empty ledger keeps such units instill_wired(regression test mirroringorphan_sweep_keeps_include_referenced_dir), and still removes them once the reference is gone.repairreportsvendor_ledger_missingfor a NuGet/Maven reference with no ledger entry.scan_ignores_non_vendor_socket_mentionsand the existing repair/orphan tests stay green, and the vendored NuGet/Maven e2e suites pass.Dependencies
None. It touches
nuget_feed.rsandmaven_repo.rsonly for tests. Coordinate with #597 (hosted NuGet) only if it changesregistry.rs.