[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: discussion #560 register.
Kind: refactor (mechanical, no behavior change). Source: review 4.4, 4.7 C; register E22. Child 1 of #920.
Problem (verified on 9c43dfc)
Each npm-family vendor driver ends with the same tail: VendorMarker::new("npm", base_purl, record, vendored_at) + write_marker_or_warn, then a 20-field VendorEntry literal in which 14 fields are always None/false (lock, took_over_go_patches, detached, record, uv, poetry, pdm, pipenv, …):
Each time a field is added to VendorEntry, all seven (and the non-npm backends) are edited by hand.
Proposed change
- Add
VendorEntry::npm(base_purl, uuid, artifact: VendorArtifact, wiring, flavor: &str) -> VendorEntry in vendor/state.rs, plus VendorArtifact::tarball(rel_tgz, &PackedTarball) for the six tarball flavors. Flavors set their one meta field afterwards (entry.pnpm = Some(..), entry.artifact.yarn_berry10c0 = ..).
- Add
npm_common::finish_vendored(project_root, coords, record, vendored_at, result, entry, warnings) -> VendorOutcome, which writes the marker and returns Done.
- Delete the seven literals and the seven marker-writing blocks.
Size and scope
npm_common.rs, state.rs and the seven driver files: about +60 / −170 production lines. Out of scope: the generic driver (#920 step 2), non-npm backends, the package.json warning drift (#920 step 2).
Acceptance criteria
Dependencies
None; can start now. Touches the same signatures as #800 only at the call sites, not the tail.
Backlog review — 2026-10-08
Priority: P1 → P3. This is explicitly a behavior-preserving VendorEntry constructor refactor; keep active work in #1008.
[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: discussion #560 register.
Kind: refactor (mechanical, no behavior change). Source: review 4.4, 4.7 C; register E22. Child 1 of #920.
Problem (verified on
9c43dfc)Each npm-family vendor driver ends with the same tail:
VendorMarker::new("npm", base_purl, record, vendored_at)+write_marker_or_warn, then a 20-fieldVendorEntryliteral in which 14 fields are alwaysNone/false(lock,took_over_go_patches,detached,record,uv,poetry,pdm,pipenv, …):npm_lock.rs#L389-L415pnpm_lock.rs#L385-L421(setspnpm)yarn_berry_lock.rs#L432-L491(setsyarn_berry10c0)yarn_classic_lock.rs#L248-L275bun_lock.rs#L610-L641bun_binary.rs#L232-L261vlt_lock.rs#L1356-L1413(directory artifact:file_inventory, emptysha256)Each time a field is added to
VendorEntry, all seven (and the non-npm backends) are edited by hand.Proposed change
VendorEntry::npm(base_purl, uuid, artifact: VendorArtifact, wiring, flavor: &str) -> VendorEntryinvendor/state.rs, plusVendorArtifact::tarball(rel_tgz, &PackedTarball)for the six tarball flavors. Flavors set their one meta field afterwards (entry.pnpm = Some(..),entry.artifact.yarn_berry10c0 = ..).npm_common::finish_vendored(project_root, coords, record, vendored_at, result, entry, warnings) -> VendorOutcome, which writes the marker and returnsDone.Size and scope
npm_common.rs,state.rsand the seven driver files: about +60 / −170 production lines. Out of scope: the generic driver (#920 step 2), non-npm backends, thepackage.jsonwarning drift (#920 step 2).Acceptance criteria
VendorEntry {literal remains in production code ofnpm_lock.rs,pnpm_lock.rs,yarn_berry_lock.rs,yarn_classic_lock.rs,bun_lock.rs,bun_binary.rs,vlt_lock.rs.vendor/state.rsround-trip tests, thelegacy-ledgersfixtures and every flavor's vendor/revert unit tests stay green unchanged.VendorEntry::npmserializing to the same JSON as today's yarn-classic literal.Dependencies
None; can start now. Touches the same signatures as #800 only at the call sites, not the tail.
Backlog review — 2026-10-08
Priority: P1 → P3. This is explicitly a behavior-preserving VendorEntry constructor refactor; keep active work in #1008.