Repository navigation
Tracking: move the patch engines out of the CLI command modules into core #894
Description
[agent] Filed by the scheduled architecture audit routine (CLI and core). Register: register comment.
Kind: tracking. Source: review §2.1, Part 2.3, R11; register C12. Coordinate with E32 (one hosted pipeline) and E36 (one inventory).
Problem (re-measured on 9c43dfc)
The CLI crate still holds engine code with no output concerns, and command modules call each other as libraries:
ecosystem_dispatch.rs#L1-L950has 950 production lines (816 at the review). It is the only purl → installed-paths locator in the workspace. Core has nofind_by_purlsdispatch of its own, so the Node addon and any future core orchestrator can't locate packages. The only CLI type it depends on isGlobalArgs, which it reads forecosystems,crawler_options(),is_global()andcwd.vendor_records_reusingis 1,044 lines (962 at the review).run_redirect_selectedis 932 lines (836 at the review).- The get ↔ scan cycle is still there.
get.rsnamesscan::33 times. Scan importsget::{download_and_apply_patches_with, DownloadParams, DownloadRun}(scan/mod.rs#L36), as well asdecide_patch_actionandshort_uuid.scan/vendor_flow.rsimportsget::download_patch_records_reusing. getruns the agent apply by building CLI args.run_nested_applyrebuilds aGlobalArgswith..GlobalArgs::default()and anApplyArgs { nested: Some(..) }, then callsapply::run_locked.
Target design
- Core owns the engines: a locator (
crawlers::locate), the agent download + apply pipeline, the vendored orchestrator and one hosted pipeline (E32). - Each engine takes a small typed scope instead of
GlobalArgs, and returns results or events that the CLI renders. - Command modules only parse arguments, build the scope, call core and render. No command module imports another.
Children (in order; each lands as one PR)
- 1. Move
ecosystem_dispatch.rsinto core ascrawlers::locate, behind aLocateScope(mechanical): Move ecosystem_dispatch's purl locator out of the CLI into core as crawlers::locate #895. - 2. Move the agent download engine (
download_and_apply_patches_with,download_patch_records_reusing,DownloadParams,DownloadRun,decide_patch_action,short_uuid) out ofcommands/get.rsinto a sharedcommands/agent_download.rs, so thatscanno longer importsget. This is a mechanical move that breaks the cycle. - 3. Replace
run_nested_apply's fakeApplyArgs/GlobalArgswith a typed apply entry point (apply::run_engine(ApplyPlan, &ApiClient, LockGuard)), and deletenested_apply_args*andNestedApply. This waits on Tracking: build one RunCtx in main and stop mirroring CLI flags into the process environment #793 (RunCtx). - 4. Split
vendor_records_reusinginto plan → stage → commit phases in core's vendored backend. This waits on child 1 and on E-area vendored work. - 5. Move
run_redirect_selectedinto the single hosted pipeline (register E32, which depends on E44), which deletes the CLI copy.
Acceptance
crates/socket-patch-cli/src/commands/*has nosuper::<other command>::engine imports.- No engine function in the CLI is longer than 200 lines.
- The CLI's production line count drops by the moved total.
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.
#895: Move ecosystem_dispatch's purl locator out of the CLI into core as crawlers::locate
- Track the remaining scope from Move ecosystem_dispatch's purl locator out of the CLI into core as crawlers::locate #895 in this issue. Explicit locator-move child of the core-engine tracker; preserve its scope as a checklist step.
Preserved scope and acceptance criteria from #895
Proposed change
- Move the module to
crates/socket-patch-core/src/crawlers/locate.rs, with its tests, as agit mvplus import fixes. - Replace
&GlobalArgswith a coreLocateScope { options: CrawlerOptions, ecosystems: Option<Vec<String>> }.GlobalArgs::locate_scope()builds it inargs.rs.JvmScope::oftakes&LocateScope. - Keep the three stderr lines from
scan_ecosystem!byte-identical. Core already prints status lines in 21 files, so turning them into returned notes is a follow-up, not part of this move. - Update the 11 importing command files (apply, get, rollback, scan/gc, scan/hosted, scan/mod, scan/vendor_flow, vendor, vendored_backend, vex, vex_consumed). Delete
crates/socket-patch-cli/src/ecosystem_dispatch.rsand itsmodline inlib.rs.
Size and scope
About 950 production lines moved, with about 30 lines changed for LocateScope and imports. Tests move with the code. Out of scope: any change to merge rules, ordering or crawler behavior, and E36's inventory unification.
Acceptance criteria
-
crates/socket-patch-cli/src/ecosystem_dispatch.rsno longer exists, andsocket_patch_core::crawlers::locateholds the same public functions. - No
GlobalArgsin core. - The 41 moved tests pass in
cargo test -p socket-patch-core crawlers::locate. - The CLI suites stay green, notably the apply/rollback multi-copy,
vex,scan --pruneand JVM tests. - The diff is a move:
git diff -Mshows a rename with only import, scope-type and visibility edits.
Activity
audit-core: C12 → #894/#895, C50 → #893, C03 fixed (#708), C24 reconc…
Break the command-module import cycles and share UI text helpers (#894)
Catch grouped command imports and name the vendored_backend cycle