Repository navigation
Spawn every CLI test child through one hermetic Command builder; 10 test files inherit ambient SOCKET_* today #823
Description
Activity
- addedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)Filed by a scheduled architecture audit routine (see the architecture review discussion)refactorStructural change: duplicated code or logic, missing abstraction, layering, dead codeStructural change: duplicated code or logic, missing abstraction, layering, dead code
on Oct 5, 2026 mikolalysenko commented
on Oct 5, 2026 CollaboratorAuthorMore actions[agent] Triaged:
priority:p3(test-only refactor, CI hermeticity). Not a duplicate; child of tracking issue #824. No open PR addresses it yet.
Generated by Claude Code
mikolalysenko commented
on Oct 5, 2026 CollaboratorAuthorMore actions[agent] Claiming this issue for the architecture refactor routine (highest leverage: test-only, collapses the per-file
scrub_socket_envcopies into onecommon::hermetic_command, first child of #824). Branch: arch-refactor/823-hermetic-command. Claim-ID: 2026-10-05T11:56:39Z-93d7a1Slice: add
hermetic_command, buildrun_bin_with_envon it, and migrate every spawner file that no openagent/fix-*PR touches. The files that open fix PRs change (#774, #802, #820, #837, #839, #849, #763) stay on an explicit allowlist in a guard test, to be migrated after those PRs land.
Generated by Claude Code
mikolalysenko commented
on Oct 5, 2026 CollaboratorAuthorMore actions- added 2 commits that reference this issue
on Oct 5, 2026 mikolalysenko commented
on Oct 5, 2026 CollaboratorAuthorMore actions[agent] Slice taken in #850:
common::hermetic_commandexists, andrun_bin_with_envis built on it.- 8 of the 15
scrub_socket_envcopies are deleted. - 8 of the 10 unscrubbed files are now hermetic (6 moved, 2 already used
run_installed), pluscli/cli_dry_run_paths_e2e. - A
spawn_env_hygieneratchet guards both lists.
SOCKET_DRY_RUN=truenow gives the same result for--test repairand--test clias running without it.What remains:
- 7 copies (
e2e_redirect_yarn_berry_build,e2e_redirect_yarn_classic_build,e2e_vendor_yarn_berry_build,e2e_vendor_yarn_classic_build,e2e_yarn4_pnpm_linker_build,e2e_yarn4_workspaces_build,scan/covgap_ecosystem_dispatch), plusscan/scan_invariantsandapply/in_process_npm_multicopy. All of these are changed by open fix PRs (Fix yarn berry hosted pin of catalog deps (#632) #763, Fix store-copy fold dropping copy writes (#756, #772) #774, Fix vendored mode replacing symlinked lockfiles (#627) #802, Fix vlt 1.3 brotli lock nodes being refused (#372) #820, Fix vendored npm-family tarballs dropped by .gitignore (#831) #837, Fix hosted yarn classic with an offline mirror (#364) #839, Fix vendored gem rewrite breaking positional args (#847) #849) and will move once those land;--test scanstays ambient-sensitive untilscan_invariantsmoves. - The ~140 other bare
Command::new(binary())spawners on thePENDING_RAW_SPAWNSallowlist.
Generated by Claude Code
mikolalysenko commented
on Oct 7, 2026 CollaboratorAuthorMore actions[agent] Janitor: releasing the stale claim
Claim-ID: 2026-10-05T11:56:39Z-93d7a1. Its PR #850 merged on 2026-10-05 with slice 1 only (8 of 15scrub_socket_envcopies removed). No follow-up PR has been opened and the claimer has been silent for more than 48h. The issue stays open for the remaining files, and any fixer can claim it.
Generated by Claude Code
[agent] Filed by the scheduled architecture audit routine (CLI and core). Register: register comment.
Kind: refactor (test structure). Source: review Part 8.5 D (forked env scrubbers), plus a new finding (test files with no scrub at all); register C30 / C47.
Problem
The CLI test tree already has a hermetic spawner:
common::run_bin_with_envseeds and scrubs the high-risk vars, prefix-sweeps the remainingSOCKET_*(keeping the telemetry opt-outs,SOCKET_NO_CONFIGandSOCKET_NO_UPDATE_CHECK), and forcesSOCKET_NO_CONFIG=1/SOCKET_NO_UPDATE_CHECK=1. But it only returns(code, stdout, stderr), so tests that need aCommand(stdin, PTY, extra env removal,output()bytes) hand-roll their own:scrub_socket_envcopies with 14 different bodies. Some keepSOCKET_NO_CONFIG, some remove it (e2e_redirect_yarn_classic_build.rs#L98`` strips everySOCKET_*, including the `.cargo/config.toml` `SOCKET_NO_CONFIG=1` that keeps a developer's `socket login` token out of test children); none of the per-file copies keep `SOCKET_NO_UPDATE_CHECK`. Their real differences are per-PM extras (`YARN_`, `PNPM_`, `npm_config_*`, `VIRTUAL_ENV`).SOCKET_TELEMETRY_DISABLEDor a token removal):repair/repair_vendor_e2e.rs(L201-L212),``scan/scan_invariants.rs(L53), `scan/scan_sync_e2e.rs`, `cli/api_client_errors_e2e.rs`, `cli_parse_remove.rs`, `apply/in_process_npm_multicopy.rs`, `self_update_e2e.rs`, `self_update_failures_e2e.rs`, `update/covgap_update_swap.rs`, `update/covgap_update_download.rs`. (Some of the update files spawn through a fixture helper; the child PR should check each.)Proof (on
045d7ec, debug build, run twice, as root in a cloud container):repair_vendor_e2e(unscrubbed, 19 tests)repairtarget (scrubbed)SOCKET_DRY_RUN=trueSOCKET_OFFLINE=true*The two baseline failures are the "lock file unremovable" tests, which can't simulate an unremovable file as root; they are unrelated.
So the same ambient shell that the shared helper neutralizes silently changes what the unscrubbed suites exercise. Here it fails loudly; with a variable like
SOCKET_ECOSYSTEMS,SOCKET_GLOBAL_PREFIXorSOCKET_API_TOKENit can instead change the code path or aim a mutation at a real global cache.Symptoms
None filed; contributors hit this as "passes in CI, fails locally".
Impact
Test hermeticity and maintenance: each new
SOCKET_*variable has to be remembered in up to 16 places. Size: test-only, no production change.Proposed change
run_bin_with_envintopub fn hermetic_command(bin: &Path) -> Command(seed, scrub, force the two opt-outs) and the existing runner, which becomeshermetic_command(bin)+ args + caller env +output().scrub_pm_env(&mut cmd, &[Pm::Yarn, Pm::Pnpm]), keeping the seed-then-scrub guards the yarn/pnpm copies document.scrub_socket_envcopies through it, and delete the 15 copies.Size and scope
~25 test files, net negative (~−250 lines). Out of scope:
binary()/git_sha256deduplication and a separate test-support crate (later children of #824), and any production code.Acceptance criteria
common::hermetic_commandexists, andrun_bin_with_envis built on it.grep -rn "fn scrub_socket_env" crates/socket-patch-cli/testsreturns nothing.CARGO_BIN_EXE_socket-patch(or a staged copy of it) does so throughhermetic_commandor therun*helpers; a guard test (or a grep in an existing lint test) keeps it that way.SOCKET_DRY_RUN=true cargo test -p socket-patch-cli --test repairgives the same result as without the variable; the same for--test scanand--test cli.Dependencies
Blocked by nothing. First child of tracking issue #824. Independent of #793 (
RunCtx), though fewer env-reading paths there will shrink what the scrub has to cover.