fix(tools): Block MSYS coreutils under Windows sandbox#476
Conversation
Git for Windows usr\bin coreutils (head, grep, cat, ...) are MSYS PE binaries that fail with ACCESS_DENIED and cygheap/signal-pipe errors when Zero runs them in the write-restricted Windows sandbox. Detect and block these commands before execution, surface MSYS runtime failures from stderr, steer agents toward native Zero tools or require_escalated, and exclude MSYS-prone names from known-safe command tails. Refs Gitlawb#458
WalkthroughThis PR adds Windows MSYS/Cygwin sandbox detection, threads the new ChangesMSYS/Cygwin Sandbox Detection
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/tools/shell_runtime.go (1)
57-96: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
expris MSYS-prone but never actually detected.
MsysProneCommandName(Line 61) listsexpras an MSYS-prone command name, but neitherwindowsMsysPosixExecutablePattern(Line 31) norwindowsPosixUtilityPattern(Line 35) includeexprin their alternations. SodetectShellCommandIssuewill never flag a bareexpr ...invocation on Windows, even thoughknownSafeCommandSegment(incommand_prefix.go) will reject it as unsafe. The model gets no proactive guidance for this specific command even though the rest of the system treats it as MSYS-prone.🔧 Proposed fix
- windowsMsysPosixExecutablePattern = regexp.MustCompile(`(?i)(?:^|[&|;\s"])(?:[\w .:\\-]+\\)?(head|tail|grep|cat|cut|wc|nl|paste|tr|uniq|rev|seq|stat|uname|which|id|awk|sed|xargs)\.exe(?:\s+|$|")`) + windowsMsysPosixExecutablePattern = regexp.MustCompile(`(?i)(?:^|[&|;\s"])(?:[\w .:\\-]+\\)?(head|tail|grep|cat|cut|wc|nl|paste|tr|uniq|rev|seq|stat|uname|which|id|expr|awk|sed|xargs)\.exe(?:\s+|$|")`) windowsPosixUtilityPattern = regexp.MustCompile(`(?i)(^|[&|;]\s*)(head|tail|grep|cat|cut|wc|nl|paste|tr|uniq|rev|seq|stat|uname|which|id|awk|sed|xargs)(?:\s+|$)`) + windowsPosixUtilityPattern = regexp.MustCompile(`(?i)(^|[&|;]\s*)(head|tail|grep|cat|cut|wc|nl|paste|tr|uniq|rev|seq|stat|uname|which|id|expr|awk|sed|xargs)(?:\s+|$)`)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/tools/shell_runtime.go` around lines 57 - 96, The Windows shell detection is missing bare expr even though MsysProneCommandName already treats it as MSYS-prone. Update the Windows command-issue detection in detectShellCommandIssue by adding expr to the same matching path used for other POSIX utilities, likely via the windowsPosixUtilityPattern or the MSYS-prone executable handling alongside windowsMsysPosixExecutablePattern. Keep the existing behavior and make sure a bare expr invocation now returns a windows_msys_sandbox issue with the same kind of guidance as the other MSYS-prone commands.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/tools/shell_runtime.go`:
- Around line 119-134: The final fallback in msysRuntimeFailedInOutput is too
broad and can misclassify non-MSYS failures as windows_msys_sandbox. Tighten the
last return condition in msysRuntimeFailedInOutput by adding a stronger
MSYS-specific anchor, such as requiring usr\\bin, cygheap, or an MSYS-style log
prefix like [main], alongside the existing win32 error 5 and terminating checks.
Keep the earlier more-specific branches unchanged and make the fallback only
match genuine MSYS runtime failures.
---
Outside diff comments:
In `@internal/tools/shell_runtime.go`:
- Around line 57-96: The Windows shell detection is missing bare expr even
though MsysProneCommandName already treats it as MSYS-prone. Update the Windows
command-issue detection in detectShellCommandIssue by adding expr to the same
matching path used for other POSIX utilities, likely via the
windowsPosixUtilityPattern or the MSYS-prone executable handling alongside
windowsMsysPosixExecutablePattern. Keep the existing behavior and make sure a
bare expr invocation now returns a windows_msys_sandbox issue with the same kind
of guidance as the other MSYS-prone commands.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e6d23b5c-35e6-428c-a314-98b418ed13a3
📒 Files selected for processing (8)
internal/agent/command_prefix.gointernal/agent/command_prefix_test.gointernal/agent/loop_test.gointernal/agent/system_prompt.gointernal/tools/bash_tool_test.gointernal/tools/exec_command.gointernal/tools/shell_runtime.gointernal/tools/shell_runtime_test.go
Vasanthdev2004
left a comment
There was a problem hiding this comment.
Approve — genuine Windows-sandbox hardening; two edge-case false-positives worth a fast-follow
Worth merging: yes. This fixes a real, documented failure (#458): Git-for-Windows MSYS coreutils fail under Zero's write-restricted sandbox token and strand the agent in retry loops. The layered approach — pre-exec block + reactive stderr detection + allowlist tightening + prompt guidance — is well-tested and correct. Thanks @euxaristia.
Reviewed as part of the 6-PR Windows-sandbox cluster, with the detection logic ground-truthed against the actual code and independently re-verified. Note the CHANGES_REQUESTED here is the CodeRabbit bot, not a human — not a merge gate.
Two real but minor edge cases I'd fold in as a fast-follow (non-blocking):
- The
require_escalatedescape hatch it advertises is self-blocked.detectShellCommandIssuefires unconditionally (bash.go:87/exec_command.go:520) beforesandboxPermissionsis consulted, so re-running the same command withrequire_escalated— exactly what the new message suggests — gets hard-blocked identically and never reaches the escalated path that would actually succeed. The advertised recovery isn't actionable through the same tool. - The
.exeregex over-matches.windowsMsysPosixExecutablePattern's leading class[&|;\s"]matches a coreutil.exetoken appearing anywhere as an argument or inside a quoted string — sogit commit -m "fix head.exe crash"is hard-blocked as a false MSYS invocation. Uncommon, but plausible in a repo that literally discusseshead.exe/grep.exe. Anchor it to the invoked-program position the way the barewindowsPosixUtilityPatternalready is. (Also:expris missing from the util set.)
Neither blocks — both are recoverable via native tools and the core fix is correct. Merge as-is and file one polish issue, or fold them in.
Sequencing: land after #465 — both touch bash_tool_test.go with different test functions, so keep a single copy of the echo-arg helper on rebase.
CodeRabbit review feedback: the win32-error-5 plus terminating check had no MSYS-specific anchor, so unrelated access-denied failures could be mislabeled as windows_msys_sandbox. Require an MSYS marker like the neighboring checks do. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Vasanthdev2004 asked for this PR to be split since it bundled several independent static-analysis fixes. Remove the specialist depth cap, bash output OOM cap, and persistence error logging: each now has its own PR (Gitlawb#491, Gitlawb#492, Gitlawb#493). Also drop the "cat" addition to the Windows POSIX-utility detection in shell_runtime.go. PR Gitlawb#476 already covers cat detection comprehensively under the MSYS/sandbox angle, so keeping it here would duplicate that work. What remains: the Windows cmd.exe quoting-guidance rewrite, the Windows-specific interactive-command suggestions (steering away from Unix head/tail/ps toward native or PowerShell alternatives), the clipboard PowerShell -Command fix, and the CI test-slack change in exec_command_test.go. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
jatmn
left a comment
There was a problem hiding this comment.
I found a few issues that need to be addressed before this is ready.
Findings
-
[P2] Make the advertised escalation path actually bypass the MSYS block
internal/tools/bash.go:83
The new MSYS hint tells the model to rerun withsandbox_permissions: "require_escalated"when host-level execution is truly required, but bothbashandexec_commandcalldetectShellCommandIssuebefore the parsedsandboxPermissionsis used to choose the unsandboxed command engine. That means rerunning the exact blocked command withrequire_escalatedis still hard-blocked by the same preflight result and never reaches the escalation path. Please either let approvedrequire_escalatedcalls bypass this MSYS preflight check or remove the escalation suggestion so the recovery guidance matches the actual behavior. -
[P2] Use one MSYS-prone command set for every detection path
internal/tools/shell_runtime.go:31
CodeRabbit's outside-diff request is still valid, and it points at a broader drift problem: this PR now has a centralMsysProneCommandNamelist, butdetectShellCommandIssuestill maintains separate regex alternations.expris listed as MSYS-prone andknownSafeCommandSegmentrejects it on Windows, yet bareexpr ...andexpr.exemiss the proactivewindows_msys_sandboxguidance because the regexes omit it.lshas the opposite inconsistency: it is listed as MSYS-prone, but it hits the oldwindows_shell_syntaxbranch before the MSYS branch, so it gets different metadata and recovery guidance from the rest of the shared set. Please make the preflight detection derive from the same MSYS-prone command set, or otherwise keep the lists and result kinds explicitly synchronized, and add regression coverage forexprandls. -
[P2] Make the MSYS command detection quote-aware
internal/tools/shell_runtime.go:31
The new MSYS preflight regexes do not understand shell quoting, so they can treat harmless argument text as an executable command.windowsMsysPosixExecutablePatternmatcheshead.exe/grep.exeafter any whitespace or quote, which hard-blocks commands likegit commit -m "fix head.exe crash"orgh pr comment --body "grep.exe fails under MSYS". The bare utility regex has the same boundary problem around quoted operators, soecho "try git log | head"can be blocked as ifheadwere actually being invoked. This repo now explicitly discusses those command names, so the false positive is likely during follow-up commits, PR comments, or docs edits. Please anchor detection to parsed command positions or explicit MSYS paths, and add regression tests for quoted argument text.
…uote-aware Addresses jatmn's review on PR Gitlawb#476: - bash and exec_command called detectShellCommandIssue before resolving sandbox_permissions into a command engine, so a require_escalated retry of a blocked command was still hard-blocked by the same preflight check. Resolve the command engine first and only bypass the windows_msys_sandbox issue kind when that resolves to true unsandboxed execution; other issue kinds (real cmd.exe syntax problems) still block regardless of escalation. - Unify all MSYS-prone command name checks (MsysProneCommandName, the preflight scan, and transitively command_prefix.go's known-safe guard) behind one windowsMsysProneNames set. This fixes expr (in the name set but missing from the old regex alternations, so never proactively flagged) and ls (hit the older windows_shell_syntax branch first, so it got different metadata than every other MSYS-prone name). - Make the preflight scan quote-aware: split the command into cmd.exe- operator-separated segments respecting double-quote grouping, and only check the first word of each segment instead of scanning raw text anywhere. Fixes false positives on quoted text like commit messages or PR comment bodies that merely mention a coreutil name.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/tools/exec_command_test.go`:
- Around line 164-176: The Windows-only exec command test is using a
PATH-dependent command in the RunWithOptions call, so the result can be polluted
by a shell_issue even when the sandbox bypass works. Update the test in
exec_command_test.go to use a guaranteed native command instead of the current
cat invocation, or assert the require_escalated bypass directly from
RunWithOptions/ExecCommandToolName behavior so the check does not depend on
shell availability.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 88ad9884-a6d4-4623-9219-de8285ddd2ba
📒 Files selected for processing (6)
internal/tools/bash.gointernal/tools/bash_tool_test.gointernal/tools/exec_command.gointernal/tools/exec_command_test.gointernal/tools/shell_runtime.gointernal/tools/shell_runtime_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- internal/tools/shell_runtime_test.go
TestBashToolRequireEscalatedMsysGuard and TestExecCommandRequireEscalatedBypassesMsysGuardAfterApproval asserted shell_issue == "" to prove the require_escalated bypass worked. Once bypassed, "cat somefile.txt" actually runs unsandboxed, and its real, PATH-dependent output could trip the unrelated post-execution detectShellOutputIssue heuristic, failing the assertion for reasons unrelated to the preflight guard under test. Assert on the exit_code "-1" sentinel (set only by shellIssueBlockResult) instead, which directly reflects whether the preflight guard blocked the command.
|
Status update on the open findings: Already fixed on this branch before this push:
Fixed in 304a5a5 (this push): CodeRabbit's last finding, that TestExecCommandRequireEscalatedBypassesMsysGuardAfterApproval asserted shell_issue == "" after running the real go build/vet clean on both linux and windows targets, go test ./internal/tools/... ./internal/agent/... green. @jatmn ready for re-review. |
jatmn
left a comment
There was a problem hiding this comment.
Thanks for the update. I rechecked the changed paths and found a couple of issues that still need to be addressed.
Findings
-
[P2] Apply cmd.exe command-position parsing to every MSYS preflight path
internal/tools/shell_runtime.go:151
The quote-aware fix only covers the bare-name scan, but the explicit MSYS path detector still runs against the entire raw command beforewindowsCommandSegments/firstCommandWordis used. That means commands such asgit commit -m "C:\Program Files\Git\usr\bin\head.exe fails"orgh pr comment --body "C:\Git\usr\bin\grep.exe is blocked"are still hard-blocked even though the MSYS path is just quoted argument text, which is the same class of false positive the latest parser was meant to avoid. The segment splitter also does not match cmd.exe tokenization: it treats caret-escaped operators and;as command separators, soecho ^| headandecho foo; headare classified as actualheadinvocations even though cmd.exe prints those as argument text. Please route the explicit path check through a real command-position parser, or otherwise make the parser handle quoted/escaped argument text consistently, and add regressions for quoted MSYS paths, caret-escaped operators, and semicolon text. -
[P2] Do not offer a prefix approval that leaves an MSYS-prone tail uncovered
internal/agent/command_prefix.go:31
This PR removes MSYS-prone commands fromknownSafeCommandSegmenton Windows, butproposedCommandPrefixstill returns the first non-safe valid segment before proving the remaining segments are safe. For a command likeps aux | head -5, the prompt can still offer onlyps auxas the reusable prefix; if the user chooses that option,shellExecutionArgsForApprovaladdssandbox_permissions: "require_escalated"to the entire command and the first execution runs the uncoveredheadsegment unsandboxed. That undercuts the new guard because the current command can still bypass the sandbox through a prefix that does not cover the MSYS-prone segment. Please only offer prefix approval when every other segment is genuinely known-safe for the current OS, or include the unsafe segment in the approval flow instead of escalating the whole command under the earlier prefix.
…x approval gap Address jatmn's latest review on PR Gitlawb#476: - shell_runtime.go: the explicit MSYS binary-path check (usr\bin\, mingw64\bin\, msys-2.0.dll, cygwin1.dll) ran against the raw command string, so a quoted mention (e.g. a commit message describing a usr\bin\head.exe failure) was still hard-blocked. It now runs against the first word of each operator-separated segment, same as the coreutil-name check. windowsCommandSegments also stopped treating ; as a command separator (cmd.exe does not split on ;, unlike bash) and now respects cmd.exe's ^ escape character, so escaped operators like echo ^| head are no longer misread as a real head invocation. - command_prefix.go: proposedCommandPrefix could offer to approve a single segment (e.g. "ps aux" in "ps aux | head -5") without checking that every other segment was independently safe. Since approving a prefix escalates the whole command to bypass the sandbox, an MSYS-prone or otherwise unsafe segment could ride along uncovered. It now only proposes a segment as the prefix when every other segment in the command is known-safe on its own. Added regression tests for quoted MSYS path mentions, caret-escaped operators, semicolon text, and the prefix-approval gap. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
jatmn
left a comment
There was a problem hiding this comment.
Thanks for the update. I rechecked the changed paths and found a couple of issues that still need to be addressed.
Findings
-
[P2] Treat cmd redirection as a command-name boundary
internal/tools/shell_runtime.go:177
The new command-position scan only checks the first whitespace-delimited word of each cmd.exe segment. That still misses real MSYS-prone invocations when cmd redirection is attached directly to the command name, which cmd.exe accepts. For example,some-command | head>out.txt,cat<in.txt, andgrep>matches.txtall invoke the same MSYS-prone utilities, butfirstCommandWordreturnshead>out.txt/cat<in.txt/grep>matches.txt, somsysProneCommandWordnever matches the bare command name. Please strip or split cmd redirection operators when extracting the invoked command word, and add regressions for attached</>redirection. -
[P2] Keep post-execution MSYS detection from matching quoted command text
internal/tools/shell_runtime.go:193
The preflight path now avoids quoted MSYS-path mentions, but the output heuristic still lowercases and scanscommand + "\n" + output. That means a failed command whose arguments merely contain an MSYS failure string, such as agh pr comment --bodyor commit command quotingC:\Git\usr\bin\head.exe: *** fatal error ..., can be mislabeled aswindows_msys_sandboxeven when the actual failure output is unrelated. This reintroduces the same false-positive class the command-position parser just fixed, only after execution. Please base the MSYS runtime heuristic on the command's actual output/stderr, or otherwise apply the same command-position/quote-aware treatment before using command text as evidence.
Process note: the linked issue #458 still does not have the issue-approved label, while CONTRIBUTING.md says community PRs require an approved parent issue. Please wait for maintainer confirmation on whether this PR can proceed under that policy.
…nd text as output evidence Addresses jatmn's latest review on PR Gitlawb#476: - firstCommandWord only split on whitespace, so cmd.exe redirection attached directly to a command name (head>out.txt, cat<in.txt, grep>matches.txt) was read as one word and never matched against the MSYS-prone name set. It now also stops at < and >. - detectShellOutputIssue scanned command+output together, so a command whose own argument text merely quoted an MSYS failure string (e.g. a gh pr comment --body describing the bug) could be mislabeled after running even though the real stdout/stderr was unrelated. Removed the command parameter entirely from detectShellOutputIssue and both call sites (bash.go, exec_command.go), so the command line can never be used as post-execution evidence again.
Vasanthdev2004
left a comment
There was a problem hiding this comment.
Re-approving. My earlier approval predates the hardening you and jatmn worked through, so I read the delta since then rather than let a stale approval ride on a sandbox PR.
The part that matters most is the escalation hole in proposedCommandPrefix, and it's closed correctly: since approving a prefix escalates the whole command past the sandbox, it now refuses to propose one unless every other segment is independently known-safe, and knownSafeCommandSegment no longer treats MSYS-prone coreutils as safe on Windows. That's the actual security boundary and it holds.
The rest is advisory-hint quality, and it's careful too — detection is anchored to the first word of each cmd.exe segment (so head.exe quoted in a commit message or PR body doesn't false-trigger), the output scan reads output only instead of the command line, the win32-error-5 fallback is anchored to MSYS markers so an unrelated ACCESS_DENIED isn't mislabeled, and the prone-name set is one source of truth shared by every path so they can't drift. Test coverage across all of it is good.
Solid. Over to kevin.
|
please rebase from main and fix conflicts @euxaristia |
Fixes #458
Summary
Git for Windows ships POSIX coreutils (head, grep, cat, and similar) as MSYS PE binaries on PATH. Under Zero's write-restricted Windows sandbox they fail at startup with ACCESS_DENIED, CreateFileMapping, signal-pipe, and cygheap errors instead of running the command. This leaves agents retrying broken shell pipelines.
Detect MSYS-prone commands before execution, surface MSYS runtime failures from command output, steer the agent toward native Zero tools or cmd/PowerShell alternatives, and exclude MSYS-prone command names from known-safe segmented-command tails on Windows.
Note: #458 may still need the
issue-approvedlabel per CONTRIBUTING.md before merge.Changes
internal/tools/shell_runtime.go.exe, or directory-prefixed).MsysProneCommandName()for shared guard logic, now backed by a single canonical name set shared by every detection path.windows_msys_sandboxissues fromdetectShellCommandIssue()with guidance toward native tools orrequire_escalated.detectShellOutputIssue()(CreateFileMapping, signal pipe, cygheap).internal/tools/bash.go,internal/tools/exec_command.gointernal/agent/command_prefix.gointernal/agent/system_prompt.gointernal/tools/shell_runtime_test.goexpr/lsconsistency.internal/tools/bash_tool_test.go,internal/tools/exec_command_test.go,internal/agent/command_prefix_test.go,internal/agent/loop_test.goUpdates addressing jatmn's review
bashandexec_commandwere callingdetectShellCommandIssue()before resolvingsandboxPermissionsinto a command engine, so rerunning a blocked command withsandbox_permissions: "require_escalated"was still hard-blocked by the same preflight check it was supposed to escalate past. Both tools now resolve the command engine first and only bypass thewindows_msys_sandboxissue kind when that resolves to true unsandboxed execution (an approved escalation). Any other issue kind (a real cmd.exe syntax problem) still blocks regardless of escalation, since running outside the sandbox does not fix a syntax error. Covered byTestBashToolRequireEscalatedMsysGuardandTestExecCommandRequireEscalatedBypassesMsysGuardAfterApproval.windowsMsysProneNamesis now the single source of truth:MsysProneCommandName(), the preflight command scan, and (transitively) the known-safe-segment guard incommand_prefix.goall derive from it. This fixes two drift bugs:exprwas in the name set but missing from the old regex alternations (so it was never proactively flagged), andlshit the olderwindows_shell_syntaxbranch before ever reaching the MSYS check (so it got different metadata/guidance than every other MSYS-prone name). Covered byTestDetectShellCommandIssueFlagsExprAndLsConsistently.echo "log | head is broken") could be misdetected as an actual invocation. Detection now splits the command into cmd.exe-operator-separated segments (respecting double-quote grouping) and only checks the first word of each segment, the actual command position, not the raw text anywhere. Covered byTestDetectShellCommandIssueIgnoresQuotedMsysMentions.usr\bin\,mingw64\bin\, ...) still scanned raw command text, so a quoted path mention had the same false-positive risk item 3 fixed for coreutil names; it now runs against the same per-segment first word. The segment splitter also stopped treating;as a separator (cmd.exe does not split on it, unlike bash) and now respects the^escape character, soecho ^| headis no longer misread as invokinghead. Separately,command_prefix.go'sproposedCommandPrefixcould offer to approve a prefix (e.g.ps auxinps aux | head -5) without checking that the remaining segments were independently safe, letting an MSYS-prone tail ride along uncovered once the whole command was escalated. It now only proposes a prefix when every other segment is known-safe on its own.firstCommandWordsplit only on whitespace, sohead>out.txtorcat<in.txt(cmd.exe accepts redirection with no separating space) were read as one word and missed entirely; it now also stops at</>. Separately,detectShellOutputIssue()scannedcommand + outputtogether, so a command whose own argument text merely quoted an MSYS failure string (e.g. agh pr comment --bodydescribing the bug) could be mislabeled after running, even when the real stdout/stderr was unrelated. It now takes onlyoutput(thecommandparameter is removed from its signature and both call sites), so the command line can never be used as evidence again. Covered byTestDetectShellCommandIssueFlagsRedirectionAttachedToCommandandTestBashToolIgnoresMsysMarkersInCommandArgumentsAfterFailure.Test plan
go build ./...go test ./internal/tools/...(pass)go test ./internal/agent/...(pass)go vet ./internal/tools/... ./internal/agent/...(clean)head.exe/git log | headblocked or surfaced with MSYS sandbox guidance on WindowsSummary by CodeRabbit
require_escalatedflows bypass the MSYS sandbox guard when execution becomes host-level.