Execute Windows batch hooks through the system command processor - #4206
Execute Windows batch hooks through the system command processor#4206lox wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
I found no concrete issues. The shared Windows process-launch and cmd.exe quoting path is subtle enough that it still warrants a human sanity-check. CI exercised the new Windows batch regression coverage successfully; the overall build remains red on the separately documented lifecycle-hook flake.
Want to dig deeper?
Paste this into your agent to explore the findings from this review's Buildkite build:
Download the buildsworth logs from build 13128, then answer my questions about the findings.
Install the reading-buildsworth-logs skill to run this.
About buildsworth
Model: gpt-5.6-sol with xhigh thinking.
How to request a review: Comment @buildsworth-bk review on the PR, or request buildsworth-bk as a reviewer.
Risk labels (how buildsworth classifies risk) — buildsworth classifies risk itself from the diff. To let it approve, grant L2 approval by mentioning @buildsworth-bk (see L2 approval grant):
- L1 — Low risk (dep bumps, docs/copy, lockfiles, small presentational fixes). buildsworth may approve by default.
- L2 — Standard risk (new UI, additive API fields, refactors). Approved only with an L2 grant; otherwise comment-only.
- L3 — High risk (auth, migrations, payments, secrets, perf-critical paths). Human review always required.
There was a problem hiding this comment.
No concrete issues in the implementation or the follow-up metacharacter and exit-status coverage. Targeted and race tests passed locally, as did Windows cross-compilation. The raw cmd.exe launch path affects Windows hook execution broadly enough that it still needs a human sanity-check. The branch Buildkite check is red, but its job logs were unavailable to this session.
Want to dig deeper?
Paste this into your agent to explore the findings from this review's Buildkite build:
Download the buildsworth logs from build 13135, then answer my questions about the findings.
Install the reading-buildsworth-logs skill to run this.
Amp-Thread-ID: https://ampcode.com/threads/T-019fdff3-2ce6-7502-83c0-400bec313cd3 Co-authored-by: Lachlan Donald <lachlan@buildkite.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019fdff3-2ce6-7502-83c0-400bec313cd3 Co-authored-by: Lachlan Donald <lachlan@buildkite.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019fdff3-2ce6-7502-83c0-400bec313cd3 Co-authored-by: Lachlan Donald <lachlan@buildkite.com>
e4d35fb to
e338d7e
Compare
There was a problem hiding this comment.
No concrete issues in this revision. The raw cmd.exe launch and quoting path affects all default Windows batch hooks, so the execution approach still warrants a human sanity-check. go test and go test -race passed locally for internal/shell and internal/process, and both packages' Windows test binaries cross-compiled; branch CI is still running.
Want to dig deeper?
Paste this into your agent to explore the findings from this review's Buildkite build:
Download the buildsworth logs from build 13182, then answer my questions about the findings.
Install the reading-buildsworth-logs skill to run this.
Summary
.batand.cmdhooks through the Windows command processorcmd.exefrom the Windows system directory rather thanPATHcmd.exequoting for script paths containing spaces and shell metacharacters%rather than allowing environment-variable expansion to select a different pathWhy
The agent currently passes default Windows batch hooks to
CreateProcessWas if they were executable images. This usually works because Windows has an undocumented compatibility behavior that converts a.bator.cmdapplication into acmd.exe /cinvocation. Rust documents the same behavior, warns that it may be removed, and handles batch files explicitly.That implicit behavior is not the supported Windows contract. Microsoft's
CreateProcessWdocumentation says that callers must start the command interpreter to run a batch file. Go'sos/exec.Commanddocumentation also calls outcmd.exeand batch files as exceptions to its normal Windows argument quoting and directs callers to provide the appropriate raw command line.This change makes that contract explicit at the shared
internal/shellboundary. Default lifecycle, bootstrap, repository, and plugin batch hooks run through the trusted system command processor with cmd-specific quoting, while explicitHooksShelloverrides remain unchanged.Literal
%is legal in a Windows path but is expanded bycmd.exeeven inside quotes. Until there is a verified literal encoding for script paths, the agent rejects these paths with an actionable error rather than potentially executing a different path.Validation
go test ./internal/shell ./internal/process ./clicommandgo test -race ./internal/shell ./internal/process ./clicommandgolangci-lint run ./internal/shell ./internal/process ./clicommandinternal/shellandinternal/processtest binaries.batand.cmd, piped stdout/stderr, non-zero exit propagation, environment expansion, paths containing spaces,&, parentheses,!, and^, and deterministic rejection of%in paths