fix(tui): preserve Windows verbatim-path operands through POSIX word split - #5610
Conversation
…split shell_words splits with POSIX backslash-escaping, which silently eats the separators of Windows absolute paths (C:\Users\... becomes C:Users...) and mangles the \\?\ verbatim prefix before the readonly operand classifier can see it. The 4285710 strip only handled key=value operands after the split; bare-token operands (cat <path>, git -C <path>) never reach it. Protect Windows-absolute-path-like words by doubling their backslashes before both shell_words::split sites (enforce_readonly_workspace_operands and hardened_readonly_argv); the splitter round-trips the real path and the existing verbatim strip then classifies it correctly. POSIX escapes and unix hosts are untouched. Unblocks the Windows CI failures on FEAT-019 (PR Hmbown#5609): - tools::shell::tests::readonly_operands_are_workspace_bounded_and_symlink_aware - tools::subagent::tests::read_only_inspection_roles_execute_pwd_and_absolute_git_log
…ility The v0.9.10..HEAD release-note receipt gate requires the exact PR number referenced by a feature commit. Upstream 6110159 cites Hmbown#5604 in its subject but its changelog entry only carries Hmbown#5589; add the Hmbown#5604 reference so the Version drift gate passes on any PR based on current main.
3ba4003 to
064c7e1
Compare
…rs too The subagent posture gate judges commands through is_agent_readonly_shell_command / is_parallel_readonly_command in command_safety.rs, which split with shlex (POSIX backslash escaping) and reject '?' as a glob char. The \\?\ verbatim prefix produced by Path::canonicalize trips the ? gate and shlex eats the backslashes, so 'git -C \\?\C:\... log' was refused at the posture gate even with the shell.rs split fix. Move the normalization to a shared command_safety helper: strip the \\?\ prefix (the only spelling with the ? glob problem; \\.\ device paths are preserved verbatim) and double the backslashes of Windows-absolute-path-like words so shlex/shell_words round-trip the real path. Apply it at both classifiers and both shell.rs split sites; POSIX escapes and unix hosts are untouched.
|
Thank you for this — I verified it and it is doing more work than the title suggests: this PR unblocks the whole open-PR queue.
Your run is green on both One non-blocking observation for the record, not a change request: Nice, well-tested fix — the |
|
Follow-up: every check is now green — For the record on why this one matters more than its diff size suggests — the two gates it fixes are currently red on five other open PRs (#5592, #5593, #5594, #5611, and #5609's Windows lane), all inheriting the breakage from |
|
CI is fully green, including the previously failing
Once merged, FEAT-019 (PR #5609) will be rebased and its Windows job should go green as well. Ready for review/merge. Paulo Aboim Pinto |
#5610) Windows canonicalizes operands to \\?\-prefixed verbatim paths; that prefix is Win32 syntax, not a glob, but its '?' tripped both readonly classifiers' metacharacter gates and the POSIX tokenizer ate the backslashes. normalize_windows_command_paths strips the prefix for CLASSIFICATION ONLY (drive-letter and UNC forms both handled, quoting preserved, mid-token '?' left alone so wildcards still reject); the executed argv is never rewritten — real splitting stays in split_command_windows_style (#5595). Adapted from PR #5610, whose tools/shell.rs hunks are superseded on this branch. Co-Authored-By: Grok 4.6 <noreply@anthropic.com>
…ntities Twenty external contributions landed after the v0.9.11 band closed and none were credited: the newest band in docs/CONTRIBUTORS.md was still v0.9.11 while main shipped 0.9.12 work. Adds the v0.9.12 band covering all twenty (#5591, #5599, #5604, #5610, #5613, #5621-#5624, #5629, #5650, #5657, #5669, #5682, #5683, #5685, #5687, #5688, #5689, #5692) and demotes v0.9.11 so only the newest band stays expanded. AUTHOR_MAP gains numeric-noreply entries for musichen, M-Maciej, and serephus so future harvested credit is graph-mappable, plus a comment recording that wangfengcsu@qq.com (21 commits on main via #704) has no resolved login yet. AUTHOR_MAP is a project convention consumed by scripts/check-coauthor-trailers.py for new commits; GitHub does not read it, so it grants no retroactive contribution-graph credit for history already on main. No-Issue: contributor credit hygiene; no issue tracks it Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Summary
Fixes the two Windows CI failures that block FEAT-019 (PR #5609):
tools::shell::tests::readonly_operands_are_workspace_bounded_and_symlink_awaretools::subagent::tests::read_only_inspection_roles_execute_pwd_and_absolute_git_logRoot cause
enforce_readonly_workspace_operands(andhardened_readonly_argv) tokenize the read-only command withshell_words::split, which follows POSIX backslash-escaping. On Windows,Path::canonicalizereturns verbatim device paths (\\?\C:\...); the POSIX splitter silently eats the separators of any backslash path (C:\Users\...→C:Users...,\\?\C:\...→\?C:...).The previous fix (4285710) stripped the
\\?\prefix after the split and only forkey=valueoperands (token.split_once('=')). The failing tests pass the canonical path as a bare space-separated token (cat <path>,git -C <path> log), so the splitter already mangled it before the strip could run — the refusal then happened on the mangled spelling.Fix
Normalize Windows absolute path spellings before any POSIX-style splitter or glob-charset gate via a shared
normalize_windows_command_pathsincrates/tui/src/command_safety.rs:\\?\verbatim prefix (Path::canonicalizeartifact) whose?trips the classifiers' glob-charset gate;\\.\device paths are preserved verbatim;:, verbatim, or UNC prefix) soshlex/shell_wordsround-trip the real path instead ofC:\Users\...collapsing toC:Users....Applied at all judging sites:
is_agent_readonly_shell_commandandis_parallel_readonly_command(command_safety.rs) — the subagent posture gate;shell_words::splitsites in shell.rs (enforce_readonly_workspace_operandsandhardened_readonly_argv).Only Windows-absolute-path-like words are touched — POSIX escapes (
echo a\ b) and unix hosts are unaffected.Testing
cargo fmt --all -- --checkgit -Ccommands; POSIX escapes and drive-relative spellings untouchedtools::shellmodule — 139 passedtools::subagentmodule — 555 passed-D warningsoncodewhale-tui— 0 warningsThe definitive validation is the Windows CI job (Linux cannot reproduce verbatim-path canonicalization); a green
Test (windows-latest)on this PR unblocks FEAT-019.Paulo Aboim Pinto
No-Issue: this fix unblocks FEAT-019 (PR #5609); umbrella #5316 must remain open for the remaining decomposition FEATs.
Paulo Aboim Pinto