0.44.0
The commit approval gate now actually stops a commit
The bug
The gate returned permissionDecision: "ask". A hook's ask is classifier-approvable, so under permissions.defaultMode: "auto" the auto-mode classifier answered it and no human was ever prompted. The gate has never stopped a commit.
Verified against the Claude Code 2.1.268 binary: only deny binds from a hook, and the hook output schema exposes no way to mark a decision unapprovable. The harness's own safety checks use an internal field that hooks cannot set.
The fix
The gate denies, and the denial is an instruction. It tells the agent to show the human the staged diff and the proposed message, then run a specific approval command. That command is covered by two permissions.ask rules, and rules are evaluated before the classifier in every mode, so running it forces a real prompt. The human's answer is the approval.
One approval covers one commit. The request id hashes the session id, the agent id, and the exact command text, so two agents in one session can never share an approval. The commit that uses a record deletes it. An unused record expires in 15 minutes.
Every failure of the machinery refuses the commit: missing rules, an unwritable or undeletable record, no session id, or a copy of the script the rules do not name.
The scheduled pipeline is unchanged
The WORKBENCH_DEV_TEAM_PIPELINE=1 carve-out still runs first, before the payload is read, and is still per-process. A test proves the scheduled lane commits with no session id and no writable state directory.
Upgrade note, required
Run /workbench-dev-team:setup immediately after updating. Until it runs, the approval script is not at its stable path and its permission rules are absent, so the gate denies every interactive commit with no way to clear it. That is fail-closed by design, and it is loud rather than silent: both the denial and the script name setup as the remedy.
Honest limits
- This is a protocol gate, not a barrier against a hostile agent. Anything holding Bash can write an approval record. The guarantee is narrower and worth stating plainly: an unapproved commit cannot happen silently.
- An invocation spelled differently from the two rules, such as
sh <path>or the path withoutbash, matches no rule and prompts nobody. The denial prints the exact command for that reason. A process-inspection check was rejected as keying the gate to an undocumented harness detail.
Tests
48 gate cases, up from 26. 27 new approval-script cases. 19 new setup cases. 19 mutants, all of which redden.