Development record
guard warn tier is silent on the live PreToolUse hook: internal/surface/cli/guard.go maps VerdictWarn to Fprintln(stderr, message) + return nil = exit 0, but the failOpen path's own comment (same function) documents that a pre-tool-use hook exiting 0 has its stderr DISCARDED — which is exactly why failOpen uses exit 1 to be loud. So every warn-tier entry (e.g. git-reset-hard) writes a message nobody ever sees and the command runs as if allowed. The warn tier is effectively invisible. Fix direction: map VerdictWarn to exit 1 (the same non-blocking-but-loud status failOpen already relies on), so a warn both runs and surfaces its message. Load-bearing for iss-200's Option-D design, whose 'warn the middle with context' model is impossible while warn is silent; also a standalone correctness bug independent of iss-200.
guard warn tier is silent on the live PreToolUse hook: internal/surface/cli/guard.go maps VerdictWarn to Fprintln(stderr, message) + return nil = exit 0, but the failOpen path's own comment (same function) documents that a pre-tool-use hook exiting 0 has its stderr DISCARDED — which is exactly why failOpen uses exit 1 to be loud. So every warn-tier entry (e.g. git-reset-hard) writes a message nobody ever sees and the command runs as if allowed. The warn tier is effectively invisible. Fix direction: map VerdictWarn to exit 1 (the same non-blocking-but-loud status failOpen already relies on), so a warn both runs and surfaces its message. Load-bearing for iss-200's Option-D design, whose 'warn the middle with context' model is impossible while warn is silent; also a standalone correctness bug independent of iss-200.
Frontmatter
| id | iss-231 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | major |
.abcd/work/issues/resolved/iss-231-guard-warn-tier-silent-on-hook.md
open on GitHub ↗ · commit history ↗
mentions2
- iss-200guard's env wrapper table listed -S/--split-string as a value-owning flag for the SEPARATE-TOKEN spelling only ('env -S git push --force origin main'), but GNU env -S/--split-string also accepts the value glued to the flag ('env -Sgit push --force origin main', 'env --split-string=git push --force origin main'), which re-splits identically and executes identically; a fix attempted in bug-hunt loop round 9 (bugfix/env-split-string-guard-bypass) closed only the separate-token form and was BLOCKed at pre-PR review by both an independent correctness reviewer and an independent security reviewer, who each independently reproduced that the glued forms remain a complete, silent bypass of every guard blocker on the live PreToolUse path; suggested remediation (from both reviewers, converging independently): in commandOf/skipWrapperArgs, treat -S/--split-string as a value-owning env flag in all three spellings — the exact separate-token form (-S as its own token, value in the following token), the glued form (-S<value>, len>2), and the --split-string=<value> form (value non-empty) — and in every case read the first word of <value> as command position, rather than either treating the whole glued token as a consumed wrapper flag or skipping the following token outright in the separate-token case — no nested re-tokenizing required, contained to the same two functions
- iss-232itd-111 latent coupling: the ahoy install staleness refusal keys on the binary's vcs.revision (via vintage current-from-BuildInfo). Release binaries are VCS-stamped today (release.yml runs make build VERSION=<tag> from a git checkout, -buildvcs=auto default), so pinned users have a determinable vintage and proceed. But if a future release build ever sets -buildvcs=false or builds from a .git-less source archive, Known flips false for every pinned user and ahoy install begins REFUSING until they pass --allow-stale-binary. Add a guard/test on the release build config asserting the shipped binary carries vcs.revision, so this coupling cannot silently break. Non-blocking; surfaced by the independent ruthless review of feat/itd-111-staleness. NOTE: captured in the iss-200 design worktree to avoid an allocator collision (iss-231 taken there); it is an itd-111/release-build follow-up, not iss-200 work.