main() dispatches the gate subcommand before run(), and the COMMITWARD_HITL check lives inside run() (main.rs:313). So the documented off switch is inert on the programmatic path, while the binary's own help text says it disables the binary entirely.
Measured — published commitward 0.3.0
ghcr.io/barnett-studios/commitward:0.3.0, the env var set in the process environment:
$ docker run --rm -i -e COMMITWARD_HITL=off --network none \
ghcr.io/barnett-studios/commitward:0.3.0 gate < request.json
{"schema_version":"1","status":"ok","body":{"fired":[{"name":"path-guard",...},{"name":"content-guard",...}],
"unacked":["path-guard","content-guard"],"exit_class":2,...}}
exit_class: 2 — a consumer reading the documented decision field blocks, with the off switch on. Same request without the variable gives the identical envelope, so the variable changes nothing on this path.
The documented claim
--help, printed by this same binary, two lines under the gate subcommand it lists:
SUBCOMMANDS:
gate Read a JSON gate request on stdin ...
Disable entirely with COMMITWARD_HITL=off.
"Entirely" is the word at issue. install-hook.sh honours it ([ "${COMMITWARD_HITL:-on}" = "off" ] && exit 0), the CLI honours it, gate does not.
The counter-reading, stated plainly
CONTRACT.md puts Off switch under Front door 1 — CLI, and never claims it for the envelope. On that reading the scope is intentional — the programmatic consumer owns its own escape hatch — and the only defect is the word "entirely" in USAGE, which would make this a docs fix rather than a behaviour one. I have filed class-D on the basis that the failing surface is the help text a user actually reads, not CONTRACT.md; if the maintainer reads it as class-N, that is fair and I will not argue the label.
What is not defensible either way is the silence: a gate run with the off switch set gives no indication that the switch was seen and ignored. If the scoping is deliberate, body.warnings is the natural place to say so.
Suggested direction
Either honour it (exit_class: 0 plus a warning naming the override, so the response still says a check did not run), or keep the scope and make USAGE say which door it opens — "Disable the CLI gate with COMMITWARD_HITL=off; the gate envelope is not affected."
Environment
ghcr.io/barnett-studios/commitward:0.3.0 (digest sha256:1f737085474e), --network none, no mounts
- Also present on
main (9212058): the check remains inside run(), after the gate dispatch in main()
- Filed by the family QA rotation (
Barnett-Studios/.github#3)
main()dispatches thegatesubcommand beforerun(), and theCOMMITWARD_HITLcheck lives insiderun()(main.rs:313). So the documented off switch is inert on the programmatic path, while the binary's own help text says it disables the binary entirely.Measured — published
commitward 0.3.0ghcr.io/barnett-studios/commitward:0.3.0, the env var set in the process environment:exit_class: 2— a consumer reading the documented decision field blocks, with the off switch on. Same request without the variable gives the identical envelope, so the variable changes nothing on this path.The documented claim
--help, printed by this same binary, two lines under thegatesubcommand it lists:"Entirely" is the word at issue.
install-hook.shhonours it ([ "${COMMITWARD_HITL:-on}" = "off" ] && exit 0), the CLI honours it,gatedoes not.The counter-reading, stated plainly
CONTRACT.mdputs Off switch under Front door 1 — CLI, and never claims it for the envelope. On that reading the scope is intentional — the programmatic consumer owns its own escape hatch — and the only defect is the word "entirely" inUSAGE, which would make this a docs fix rather than a behaviour one. I have filedclass-Don the basis that the failing surface is the help text a user actually reads, notCONTRACT.md; if the maintainer reads it asclass-N, that is fair and I will not argue the label.What is not defensible either way is the silence: a
gaterun with the off switch set gives no indication that the switch was seen and ignored. If the scoping is deliberate,body.warningsis the natural place to say so.Suggested direction
Either honour it (
exit_class: 0plus a warning naming the override, so the response still says a check did not run), or keep the scope and makeUSAGEsay which door it opens — "Disable the CLI gate withCOMMITWARD_HITL=off; thegateenvelope is not affected."Environment
ghcr.io/barnett-studios/commitward:0.3.0(digestsha256:1f737085474e),--network none, no mountsmain(9212058): the check remains insiderun(), after thegatedispatch inmain()Barnett-Studios/.github#3)