os worktree tests pass env to spawns, share one git seed, and run in parallel (#634b) #708
Labels
No labels
P0
P1
P2
P3
bug
category/code-change
category/cross-repo
category/eval-run
category/investigation
category/no-test-target
category/owner-ruling
category/prose-artifact
category/recurring-chore
category/structure
category/umbrella
crc-refactor
create
delete
enhancement
filed-by/agent
filed-by/user
frozen
lint-rule
needs-info
needs-triage
next
plugin/cc-architect
plugin/os
plugin/os-adr
plugin/os-aidd-lint
plugin/os-backlog
plugin/os-context
plugin/os-doc-hygiene
plugin/os-sdlc
plugin/os-vault
project/cc-os
ready-for-agent
ready-for-human
recurring
review
rule-proposal
update
waiting
wayfinder:grilling
wayfinder:map
wayfinder:map
wayfinder:research
wayfinder:task
wayfinder:task
wontfix
worklist/deviations
worklist/lint-rule
worklist/new-implement-build
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jared/cc-os#708
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Global ENV mutation in
plugins/osworktree test helpers blocks parallel test runs, and each test forks its own git init sequence instead of sharing one seed.Observed
plugins/os/tests/support/worktree_finish_test_case.rb:27-33with_path_prependedmutatesENV['PATH'](5 callers).plugins/os/tests/support/worktree_finish_test_case.rb:35-42seed_reporuns fivesystem('git', ...)calls per test.plugins/os/lib/worktree/binary_locator.rb:8ENV.fetch('PATH', '');plugins/os/lib/worktree/usage_sweep.rbuses it;plugins/os/lib/worktree/finish_command.rbalso spawns a rubocop-server stop; none take an env hash..sdlc/project.yaml:ruby plugins/os/tests/all.rb.plugins/os-sdlc/tests/test_helper.rb:166-168parallelize_me!plus aSerializedChdirmonitor (ADR-0205);plugins/os-sdlc/tests/support/repo_seeder.rbis the mirror target.Reproduce
Approach
Required work:
Worktree::CLI.start(argv, env: ENV)threads env toFinishCommand,UsageSweep,BinaryLocator(search_pathfromenv["PATH"]) and everysystem/Open3call in the finish path passes the env hash — check:grep -rn "ENV" plugins/os/lib/worktreeemptyWorktree::CLI.start(argv, env: {"PATH" => "#{fakebin}:#{ENV['PATH']}"})andwith_path_prependedis deleted — check:grep -rn "ENV\['PATH'\] =" plugins/os/testsemptyplugins/os/tests/support/repo_seeder.rbmirroring the os-sdlc one (seed once per suite,FileUtils.cp_rper test) replacesseed_repo's git calls — check:grep -c "system('git', 'init'" plugins/os/tests/support/worktree_finish_test_case.rbis 0Dir.chdirin tests replaced by cwd injection or aSerializedChdirmonitor — check:grep -rn "Dir.chdir" plugins/os/testsonly inside the monitor helperparallelize_me!inplugins/os/tests/all.rb, suite green 3 consecutive runs — check:for i in 1 2 3; do ruby plugins/os/tests/all.rb || exit 1; doneRejected: tests-only change (lib
system/Open3calls take no env hash today; the fix must thread env through lib, not just rewrite test helpers).VERDICT: CREATE
Acceptance criteria
Worktree::CLI.startwith anenv:keyword, when the finish path spawnsgit,rubocop, oros-sdlc-runner, then each spawn receives the supplied env hash instead of inheriting globalENV.ENV['PATH'] =or asystem('git', 'init'call insideworktree_finish_test_case.rb, then no matches remain.plugins/os/tests/all.rbdeclaresparallelize_me!, when the suite is run three consecutive times, then all three runs pass with no flakes.Owner sketch
Non-goals
plugins/os-backlogCLI/lib env threading (tracked as #634a).Origin
Trigger: split of #634.
Improvised this session: no.
Chain ending at DESIGN ADR-0205.
Root candidate "#634 (split 2026-09-24, session 082c3e8b)".
Where: plugins/os.
Session: 082c3e8b-5598-4c69-9ea6-b717e9c8afb2.
Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/082c3e8b-5598-4c69-9ea6-b717e9c8afb2.jsonl.
Work started in session 082c3e8b on branch ticket-708 via /os-sdlc:implement.
Resolution
Done: Worktree::CLI.start(argv, config, env:) stores env thread-locally and passes it to FinishCommand, which threads it to RepoRoot, ConflictScan, Removal, UsageSweep, BinaryLocator and every system/Open3 call on the finish path; backtick shell-outs became Open3 calls with an env hash. Tests: with_path_prepended deleted, RepoSeeder seeds one template repo per suite and copies it per test, SerializedChdir wraps Dir.chdir in a Monitor, ThreadRoutedIO makes capture_io thread-safe, plugins/os/tests/all.rb enables parallelize_me!.
Evidence: Pipeline implementation 37, 15 dispatches, implementation_complete. Suite green 3 consecutive runs (25 runs, 0 failures). Checks: the only ENV read left in plugins/os/lib/worktree is the CLI's default fallback; no PATH assignment in tests; zero init calls in worktree_finish_test_case.rb. Remaining rubocop offenses are Style/Documentation only, matching existing plugin practice under the repo's no-comment rule. Commit on branch ticket-708.
Follow-ups: ADR-0205 amendment extending affected-components to os and os-backlog: done next by this session (VERDICT: CREATE).