Co-authored-by: SomSamantray <> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Trevin Chow <trevin@trevinchow.com>
7.4 KiB
title, type, status, date, origin, artifact_contract, artifact_readiness, product_contract_source, execution
| title | type | status | date | origin | artifact_contract | artifact_readiness | product_contract_source | execution |
|---|---|---|---|---|---|---|---|---|
| fix: Preserve explicit absolute non-WSL bash on Windows | fix | active | 2026-07-31 | PR #1292 Codex P2 (discussion_r3690011704); follow-up to docs/plans/2026-07-31-002-fix-prefer-git-bash-over-wsl-plan.md | ce-unified-plan/v1 | implementation-ready | ce-plan-bootstrap | code |
fix: Preserve explicit absolute non-WSL bash on Windows
Goal Capsule
- Objective: When a Windows peer worker argv already names an absolute non-System32 bash/sh (e.g. portable Git), keep that path — do not substitute the preferred resolver result or fail closed because the portable path is undiscoverable.
- Authority: Codex P2 on PR #1292; origin plan edge case “explicit absolute non-System32 bash prefix left as-is”; session-settled KD2 from #1268 applies to bare bash/sh only.
- Stop when: Absolute non-WSL bash is kept at
cmd_startand spawn; System32 absolute bash still rewritten/fail-closed; bare names still resolve; six runners stay byte-identical; unit coverage proves both behaviors.
Debug Summary (carried into planning)
Problem: start -- C:\PortableGit\bin\bash.exe script.sh … (or any absolute non-WSL bash) is treated like bare bash.
Root cause: cmd_start keys only on basename(argv0) in {bash,sh,…} and always calls _resolve_windows_posix_shell(), so the absolute-path branch never runs for …\bash.exe. Same basename gate in _popen_argv and _rewrite_windows_env_bash_argv substitutes preferred Git Bash or raises if the portable path is not in env/well-known/PATH.
Evidence: Origin plan U2 edge: “explicit absolute non-System32 bash prefix left as-is (already preferred).” Goal capsule of #1268: explicit Git Bash path already worked before this PR.
Fix direction: Treat absolute (drive/sep) bash/sh as caller-supplied: accept if file exists and not System32 WSL; reject System32; resolve only bare names.
Product Contract
Summary
Keep #1268 Git-Bash preference for bare bash/sh and System32 WSL rewrites, but honor an explicitly supplied absolute non-WSL shell so portable Git and other installs are not silently replaced or spuriously fail-closed.
Product Contract preservation: N/A (bootstrap). Does not reopen fail-closed / no-WSL-fallback / bare-rewrite product decisions — it restores the absolute-path exception already implied by those decisions and the #1268 plan’s edge case.
Requirements
- R1. On Windows, if worker argv0 (or env-prefixed bash token) is an absolute path to an existing non-System32 bash/sh, use that path unchanged for meta and spawn.
- R2. If that absolute path is System32 WSL bash/sh, do not use it — rewrite via the existing resolver or fail closed (same as bare System32).
- R3. Bare
bash/sh/bash.exe/sh.execontinue to resolve via_resolve_windows_posix_shell()(env → well-known → PATH walk). - R4. Production change is in canonical
peer-job-runner.pythen byte-copied to all consumer skills; no product change outside shell selection.
Scope Boundaries
- In:
cmd_startbash/sh branch,_popen_argvbash/sh head,_rewrite_windows_env_bash_argv; unit tests; parity copy. - Out: WindowsApps/Sysnative alias residual; changing resolver precedence; skipping Linux path tests; unrelated PR hygiene.
Key Decisions
- KD1. Absolute path detection uses the same Windows absolute rule already used elsewhere in
cmd_start(os.sep in pathor drive-letterX:), not “looks like bash basename only.” - KD2. Prefer a small shared helper (e.g. resolve-or-keep argv0 / token) used by start + spawn + env-rewrite so the three sites cannot drift.
Planning Contract
Key Technical Decisions
- KTD1. Introduce a helper along the lines of “given a bash/sh token, return the absolute shell to use”: if absolute → require
isfile, reject System32 via_is_system32_wsl_bash, else return abspath; if bare →_resolve_windows_posix_shell(). (Governs R1–R3) - KTD2. Wire that helper in
cmd_start’s basename-bash branch (so absolute…\bash.exeno longer always resolves), in_popen_argv’s bash/sh head branch, and in_rewrite_windows_env_bash_argvfor the bash token. (Governs R1, R4) - KTD3. Fixture-only tests under existing
windows_platform/ntpathhelpers: absolute portable kept; absolute System32 rewritten/fail path; bare still resolves. No production behavior change for barebash. (Governs R1–R3)
Assumptions
- Codex P1 (Linux path semantics in unit fixture) remains addressed by
97ff131; this plan does not reopen it. - Callers that pass absolute bash intend that binary;
CE_PEER_BASHremains the override for bare-name launches, not a silent override of an explicit argv0.
Patterns to Follow
- Existing
_is_system32_wsl_bashand absolute-path preflight incmd_start. - Byte-copy +
tests/peer-job-runner-parity.test.ts. - Unit fixture
windows_platformfor portable Windows path mocks.
Implementation Units
U1. Keep absolute non-WSL bash; resolve only bare names
Goal: Explicit absolute shells are preserved; bare and System32 paths still go through preference / fail-closed.
Requirements: R1, R2, R3, R4
Dependencies: None
Files:
- Modify:
skills/ce-doc-review/scripts/peer-job-runner.py(canonical), then copy toskills/ce-code-review|ce-pov|ce-work|ce-plan|ce-brainstorm/scripts/peer-job-runner.py - Modify:
tests/fixtures/peer-job-runner-unit.py
Approach:
- Add shared helper per KTD1.
- Replace unconditional resolve in
cmd_startbash basename branch with the helper; setwindows_posix_shellfrom the kept/resolved path. - Same for
_popen_argvbash/sh head and env-token rewrite. - Tests: absolute portable kept; absolute System32 not kept; bare
bashstill rewritten to preferred; env… absolute_bash …kept when non-WSL.
Execution note: Test-first in the unit fixture (absolute-keep must fail on current code), then implement helper + wire sites, then parity copy.
Patterns to follow: #1268 resolver and System32 helper; windows_platform fixture.
Test scenarios:
- Happy:
cmd_start/_popen_argvwith absolute portable bash → argv0 unchanged; metawindows_posix_shellequals that path when recorded. - Happy: bare
bashstill becomes preferred absolute Git Bash. - Edge: absolute System32 bash → not used; resolver preferred or fail-closed with actionable message.
- Edge: env-prefixed argv with absolute non-WSL bash token → token kept.
- Error: absolute path that does not exist → preflight failure, no detach.
- Integration: six skill copies byte-identical after copy.
Verification: Unit fixture green under Windows and under windows_platform on Linux semantics; parity test green; no smoke policy change required.
Verification Contract
python tests/fixtures/peer-job-runner-unit.pyexits 0 / prints OK.bun test tests/peer-job-runner-parity.test.tspasses.- Manual or fixture assertion covering absolute-keep vs bare-rewrite.
Definition of Done
- Codex P2 resolved on PR #1292 head.
- Origin plan absolute-prefix edge case restored without weakening bare-name Git Bash preference.
- Parity intact across six runners.
Sources & Research
- https://github.com/EveryInc/compound-engineering-plugin/pull/1292#discussion_r3690011704
docs/plans/2026-07-31-002-fix-prefer-git-bash-over-wsl-plan.md(U2 edge: absolute non-System32 left as-is)- Prior residual: WindowsApps/Sysnative still out of scope