Cygwin: gate is unusable end-to-end

Author: DanKaplanSESCreated Jul 9, 2026Updated Sep 21, 2026
Labelsbugready-for-pr

Cygwin: gate is unusable end-to-end (review agent returns no result; plus post-receive hook and ^{commit} bugs)

Summary

Running no-mistakes in a Cygwin environment on Windows, I hit three separate failures trying to run a single trivial commit through the gate. The goal here is for no-mistakes to work under Cygwin. Any one of the first two failures can be worked around, but the third (the review step) is a hard blocker with no workaround available to the user, so the gate cannot complete a run. Filing them together because they were all hit in one init -> push -> run flow and all trace back to shell / path / subprocess handling in a Cygwin environment. Happy to split into three if you prefer.

Environment

  • Shell environment: Cygwin (C:\cygwin64) on Windows 10 Pro (10.0.19045); the CLI and git push are driven from a Cygwin bash shell
  • no-mistakes: v1.34.0 (dc5a800)
  • git: 2.51.0
  • Agent: Claude Code CLI (claude) v2.1.160, installed as C:\Users\<user>\AppData\Roaming\npm\claude.cmd
  • no-mistakes doctor is fully green (git, gh, data dir, database, daemon, and claude all detected)

Bug 1 (blocker): review step fails with "claude returned no result event"

Every run fails at the review step, deterministically, after ~14.5s:

step review failed: agent review: claude returned no result event

Full review.log:

reviewing changes...

claude started pid=10880

claude exited pid=10880 error=claude returned no result event


error: agent review: claude returned no result event

Notably, in axi status the review step's active_steps row shows an empty agent_pid, which suggests the daemon is spawning claude through a wrapper (the .cmd shim) rather than tracking the native process.

The agent itself is healthy

Headless claude works fine on this machine. Running the same stream-json invocation the adapter would use produces a proper terminal result event:

bash
claude -p "Reply with exactly: OK" --output-format stream-json --verbose --max-turns 1
# ... emits {"type":"result","subtype":"success","is_error":false,...,"result":"OK"}

I verified this twice: once with the inherited CLAUDE_CODE_* session variables present, and once with them all cleared. Both emit the result event. I also restarted the daemon (no-mistakes daemon restart) from a clean shell so its next spawn would inherit a current environment; the review step still failed identically. So it is not the agent, not auth, and not the daemon's inherited environment. It is specific to how the daemon spawns and reads the claude subprocess on Windows.

The consistent ~14.5s before "no result" looks like a fixed wait rather than a crash, which would fit a prompt that never reaches claude over stdin (so claude has nothing to do and exits), combined with the .cmd shim swallowing the native pid.

Bug 2: git rev-parse <ref>^{commit} has its braces stripped

no-mistakes rerun and no-mistakes axi run (when it has to resolve the gate head to start a run) both fail:

resolve gate head: git --git-dir=C:\Users\<user>\.no-mistakes\repos\<id>.git rev-parse refs/heads/<branch>^{commit}: exit status 128: fatal: ambiguous argument 'refs/heads/<branch>^commit': unknown revision or path not in the working tree.

Note the argument in the error is refs/heads/<branch>^commit with the { and } gone. The ^{commit} peel suffix is losing its braces somewhere in how the command is built/quoted on Windows, so git never sees a valid revision. This blocks both the normal run-start and rerun paths. The only trigger that avoids it is daemon notify-push, because it is handed explicit SHAs and never resolves ^{commit}.

Bug 3: post-receive hook hardcodes a backslash path that the hook shell cannot exec

git push no-mistakes <branch> delivers the ref but the hook fails to notify the daemon:

remote: no-mistakes: notify-push failed for refs/heads/<branch> (exit 127):
remote: <gate>/hooks/post-receive: line 32: C:\Users\<user>\AppData\Local\no-mistakes\no-mistakes.exe: command not found

The generated post-receive sets:

bash
NM_BIN='C:\Users\<user>\AppData\Local\no-mistakes\no-mistakes.exe'
if [ ! -f "$NM_BIN" ]; then
  NM_BIN="$(command -v no-mistakes 2>/dev/null || echo no-mistakes)"
fi
...
out=$(NM_HOOK_HELPER=1 "$NM_BIN" daemon notify-push "$@" 2>&1)

The [ -f "$NM_BIN" ] test passes on the backslash path, so the fallback to the PATH-resolved no-mistakes never fires, but executing a backslash Windows path from the hook shell fails with 127. A forward-slash path (or forcing the command -v fallback) would avoid this. As a result the push never registers a run, and the pipeline does not start until daemon notify-push is run by hand with the ref's SHAs.

Impact

Bugs 2 and 3 are individually recoverable (drive runs via daemon notify-push with explicit SHAs). Bug 1 is not: the review step cannot be skipped through the only working trigger, so no run can complete, and no PR is opened. On this Windows setup the gate is effectively unusable end to end.

Repro (minimal)

  1. In a Cygwin environment on Windows with npm-global claude, no-mistakes init --fork-url <fork> in a repo whose origin is the parent.
  2. Commit a trivial change on a feature branch.
  3. git push no-mistakes <branch> -> Bug 3 (hook exit 127), branch lands but no run.
  4. no-mistakes axi run --intent "..." or no-mistakes rerun -> Bug 2 (^{commit} braces stripped).
  5. Trigger via daemon notify-push --gate <bare> --ref refs/heads/<branch> --old 000... --new <sha>, then no-mistakes axi run --intent "..." -> reaches review, then Bug 1 (claude returned no result event).