Repository navigation
CI: hermetic spawns in cli/covgap tests (#823) - #1441
Merged
Mikola Lysenko (mikolalysenko) merged 3 commits intoOct 12, 2026
Merged
Conversation
Assisted-by: Claude Code:claude-opus-5-5
5 tasks
Twenty CLI test files spawned socket-patch with a bare Command::new and a hand-rolled SOCKET_* scrub. The copies disagreed: several only removed the global flag vars, so SOCKET_API_TOKEN, SOCKET_API_URL or a per-command var like SOCKET_SKIP_ROLLBACK from a developer shell still reached the child, cli_parse_list's two plain list runs scrubbed nothing, and none forced the update notifier off. All 20 now spawn through the shared hermetic builder in tests/common/hermetic.rs and leave PENDING_RAW_SPAWNS, so the ratchet keeps them hermetic. Deliberate opt-ins stay as caller env: the config layer suites still set SOCKET_NO_CONFIG=0 and the telemetry suite still re-enables telemetry. Suites whose in-process tests mutate SOCKET_* keep their unconditional removals for the spawn race. Refs #823 Assisted-by: Claude Code:claude-opus-5-5
Some test binaries set flag-bound SOCKET_* vars in their own process (apply_env_toggles, env save/restore helpers). The hermetic builder only removed names present when it swept the parent environment, so a var set by a parallel test before the spawn still reached the child, and suites patched that with their own, already diverging, removal lists. hermetic::command now removes every flag-bound var by name, so the per-file lists go away, and SOCKET_CWD joins the hostile seeds. A new contract test sets vars after the builder runs and checks none leak. Refs #823 Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko)
marked this pull request as ready for review
October 12, 2026 18:46
Collaborator
Author
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6d44a29. Configure here.
Collaborator
Author
|
Ready for review (burn-down agent)
Generated by Claude Code |
Tanmay Singla (Tanmay182003)
approved these changes
Oct 12, 2026
Mikola Lysenko (mikolalysenko)
deleted the
agent/fix-ci-hermetic-cli-covgap
branch
October 12, 2026 20:59
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LLM Description written by Claude Code:claude-opus-5-5
Refs #823 (slice 4 of the hermetic-spawn migration; the issue stays open for the remaining files).
What was wrong
20 CLI test files (
cli/,cli_*,coverage_fix_*,covgap_*) spawnedsocket-patchwith a bareCommand::newand their own hand-rolledSOCKET_*scrub. The copies disagreed. Several removed only the global flag vars, soSOCKET_API_TOKEN,SOCKET_API_URLor a per-command var likeSOCKET_SKIP_ROLLBACKfrom a developer shell still reached the child. Two plainlistruns incli_parse_listscrubbed nothing, and none forced the update notifier off.There was also a race in the shared builder.
hermetic::commandremoved only theSOCKET_*names present when it swept the parent env. Test binaries that set flag-bound vars in-process (apply_env_toggles, save/restore helpers) could leak one set between the sweep and the spawn, and each suite patched that with its own removal list. Those lists had already drifted: 4 vars in one place, 2 in another, the full list in a third.Change (test-only)
tests/common/hermetic.rsand leavePENDING_RAW_SPAWNS(126 → 106), so the ratchet keeps them hermetic. Deliberate opt-ins stay as caller env: the config-layer suites still setSOCKET_NO_CONFIG=0, and the telemetry suite still re-enables telemetry.hermetic::commandnow removes every flag-bound var (GLOBAL_ARG_ENV_VARS ∪ LOCAL_ARG_ENV_VARS) by name, which closes the race once and deletes the per-file lists.SOCKET_CWDjoins the hostile seeds (the telemetry suite used to seed it locally). New contract test:command_drops_flag_bound_vars_set_after_it_is_built.Evidence
SOCKET_DRY_RUN=true SOCKET_JSON=true SOCKET_API_TOKEN=… SOCKET_API_URL=http://127.0.0.1:1 SOCKET_PROXY_URL=… SOCKET_SKIP_ROLLBACK=true SOCKET_ALL_RELEASES=true SOCKET_ORG_SLUG=… SOCKET_NO_CONFIG=0) over the 19 affected targets:cli_parse_list(*_via_binary),covgap_commands_vendor::npm_only_human_vendor_does_not_read_composer_lock, plus 4 noted below.cli_parse_list::defaults_match_contract(an in-process clap parse, not a spawn; out of scope here) and the 3 root-only failures below.command_drops_flag_bound_vars_set_after_it_is_builtfails against main'shermetic.rs(SOCKET_OFFLINE set after build leaked) and passes with this change.spawn_env_hygiene: 15/15.cargo test --workspace --all-features --no-fail-fast, 249 targets: everything passes except 13 tests that need a non-root user to make a file unwritable (*_write_failure_*,*unremovable*,relax_loop_must_not_traverse_symlinked_root) ande2e_bun_lockb::binary_shared_bundled_record_hosted_pin_is_managed. My container runs as root. Each of these fails the same way with main'shermetic.rsand test files, so none are from this PR. CI runs as non-root.cargo fmt --all -- --checkandcargo clippy --locked --workspace --all-features -- -D warnings: clean./code-review high: findings not fixed here
portable_pty::CommandBuilder::new(binary()), 7 sites, includingcovgap_commands_scan_mod.rsandcovgap_commands_rollback.rs) keep their own scrubs, and the ratchet does not detect them. That needs aCommandBuildercounterpart of the builder, so it is a separate slice, recorded on Spawn every CLI test child through one hermetic Command builder; 10 test files inherit ambient SOCKET_* today #823.spawn_scrubbed(rollback) doesn't applyjvm_env::isolate_cli. No caller spawns a JVM fixture, and its doc now says so.Follow-ups for #823: the 106 remaining
PENDING_RAW_SPAWNSfiles (mostlye2e_*,in_process_*,vex_*), the PTY spawns, and the in-process parse incli_parse_list.🤖 Generated with Claude Code
https://claude.ai/code/session_01CQp9sCPnUPTSFrEGsvTQmQ
Generated by Claude Code