Skip to content

Tracking: move the pure lock codecs and neutral lock types into formats/ so formats imports nothing from vendor or redirect #833

Description

[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: discussion #560 register.

Kind: tracking. Source: review §2.1; Part 4.5 #2; 4.7 J. Register E20.

Problem

formats/ is meant to be the pure bottom layer (the purity guard at formats/mod.rs#L41-L91). On 045d7ec it imports upward in four directions instead:

formats file imports
cargo/mod.rs, composer/mod.rs, gem/mod.rs, pnpm/mod.rs vendor::lock_inventory::{LockfileEntry, LockIntegrity, SourceKind, http_url} (gem/mod.rs#L28)
bun/mod.rs vendor::bun_lock_text (the grammar formats::bun wraps lives in vendor/, bun/mod.rs#L11)
composer/mod.rs, pnpm/mod.rs vendor::path::parse_vendor_path
cargo/mod.rs vendor::cargo_tag
cargo/, composer/, gem/, pnpm/ hosted.rs patch::redirect::{FileEdit, RewriteWarning, DepOverride, RewriteResult}
composer/mod.rs, gem/manifest.rs crawlers::{composer_crawler::normalize_version, ruby_crawler::bundle_config_setting}

Meanwhile three pure codecs that would pass the purity guard unchanged sit in vendor/ and are imported from redirect/, vex/, crawlers/ and formats/:

  • vendor/bun_lockb.rs (2,342 lines, 13 importers);
  • vendor/bun_lock_text.rs (561 lines, 7 importers);
  • vendor/vlt_lock_text.rs (2,548 lines, 11 importers, including crawlers/npm_crawler.rs).

vex::discover takes LockIntegrity from vendor::lock_inventory in 10 files.

Target design

  • formats/entry.rs: LockfileEntry, LockIntegrity, SourceKind and http_url. These are the neutral "one lock-resolved package" types every reader emits.
  • formats/bun/{text,binary}.rs: today's bun_lock_text and bun_lockb codecs. formats/vlt/ takes vlt_lock_text.
  • formats/edit.rs (or formats/splice.rs): FileEdit and RewriteWarning (and DepOverride if it stays a plain input type), re-exported from redirect during the move.
  • Crawler-owned rules that formats need (normalize_version, bundle_config_setting) move down; E37 (Move the crawler coordinate guards and composer's leading-v rule into utils and delete the copies #630) already proposes the first.
  • Add an architecture_tests guard: no production use crate::{vendor,patch,crawlers,vex} inside formats/.

Each step is a mechanical move with no behavior change. Old paths stay as pub(crate) use re-exports only within the move's PR, so the PR stays reviewable, and the follow-up removes them.

Checklist (one PR each, in order)

Related: #631 (E52) already moves the go.sum codec into formats.

Acceptance criteria

  • After step 6, grep -rn 'crate::\(vendor\|patch\|crawlers\|vex\)' crates/socket-patch-core/src/formats finds only test code, and a guard test enforces it.
  • Every step is a move with an unchanged cargo test -p socket-patch-core result (the 4 root-sandbox failures listed in the refactor register excepted).

Dependencies

Steps 3 and 4 wait for the open Bun/vlt PRs that touch those files. It blocks nothing, but it simplifies E21 (VendorBackend) and E36 (one Inventory), whose shared types land in formats.


Consolidated work — backlog review, 2026-10-08

The following standalone issues are now tracked here. Their closure consolidates scheduling; it does not mean their implementation is complete. Original reports and discussion remain linked below.

#834: Move LockfileEntry, LockIntegrity, SourceKind and http_url from vendor::lock_inventory into formats::entry

Preserved scope and acceptance criteria from #834

Proposed change

  • Create crates/socket-patch-core/src/formats/entry.rs holding the four items verbatim (doc comments included), and pub use them from formats.
  • Update the importers to crate::formats::entry::… (or formats::{LockfileEntry, …}). Keep pub use crate::formats::entry::{…} in vendor::lock_inventory only if the CLI's public paths need it; otherwise delete the old definitions outright.
  • No behavior change. The UnsupportedNpmLayout diagnosis stays in lock_inventory (it is a discovery outcome, not an entry).

Size and scope

~90 moved lines plus roughly 50 one-line use edits. Out of scope: moving the codecs (#833 steps 2–4) and the redirect types (step 5).

Acceptance criteria

  • grep -rn 'crate::vendor' crates/socket-patch-core/src/formats/{gem,pnpm,cargo,composer}/mod.rs no longer lists lock_inventory.
  • The lock_inventory architecture_tests and formats::architecture_tests::format_models_are_pure stay green.
  • cargo test -p socket-patch-core and -p socket-patch-cli give the same results as on main, and cargo clippy --all-targets is clean.

#1012: Move the bounded archive extractors out of vendor::registry_fetch into utils::archive

Coordinate this single archive-extractor move between #959 (vendor backend) and #833 (neutral formats/types); the cross-reference does not require two implementations.

Preserved scope and acceptance criteria from #1012

Proposed change (this issue: the first two families only)

  • Create crates/socket-patch-core/src/utils/archive.rs (or utils/archive/{mod,go_module}.rs). Move the archive extraction and Go module zip families into it verbatim, with the tests that cover them.
  • Keep the vendor::registry_fetch paths for these items through a pub(crate) use crate::utils::archive::* for one release of the code, or update the ~16 import sites directly. Either is fine; update the imports if the diff stays reviewable.
  • Delete the stale read_zip_members comment.

Out of scope, as follow-ups recorded on register row E29:

Size and scope

  • Files: vendor/registry_fetch.rs, the new utils/archive.rs, utils/mod.rs, and the importers (vendor/{cargo,composer_lock,gem,golang,maven_repo,npm_dir,nuget_feed,redownload,service_fetch}.rs, patch/jvm_jar.rs, patch/redirect/upstream/client.rs, api/vendor_prefetch.rs).
  • About 1,000 moved production lines plus their tests. The import edits are about 20 lines. There is no behavior change.

Acceptance criteria

  • git diff --color-moved shows the two families as moved blocks only.
  • No file outside vendor/ imports archive or Go-module-zip items from crate::vendor::registry_fetch.
  • Every archive refusal message and cap value is unchanged; the moved tests (zip, tgz, gem, module-zip and the Sink::Validate vs Sink::Write parity tests) pass unchanged.
  • cargo test -p socket-patch-core and cargo test -p socket-patch-cli pass; cargo clippy --all-targets is clean.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)priority:p3refactorStructural change: duplicated code or logic, missing abstraction, layering, dead code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions