Development record
The person still sees the question guard's refusals as errors while a session rewrites a question. On 2026-10-15 one question to the product thinker was refused three times before it reached them: the header, three sentences per option, the row limit, a missing Change later line and a named command. Each refusal showed on their screen as a hook error, because the session drafted the question itself instead of through the drafting agent
The person still sees the question guard's refusals as errors while a session rewrites a question. On 2026-10-15 one question to the product thinker was refused three times before it reached them: the header, three sentences per option, the row limit, a missing Change later line and a named command. Each refusal showed on their screen as a hook error, because the session drafted the question itself instead of through the drafting agent
The error framing of a guard refusal on the host is its own open finding, iss-2610070637562567; this record is about the session skipping the drafting step that would have avoided the refusals.
Frontmatter
| id | iss-2610150558540639 |
|---|---|
| type | issue |
| lifecycle | open |
| severity | minor |
.abcd/work/issues/open/iss-2610150558540639-the-person-still-sees-the-question-guard.md
open on GitHub ↗ · commit history ↗
mentions1
- iss-2610070637562567After the hook commands became one-line wrappers, a guard refusal still reaches the person as 'PreToolUse:<tool> hook error: [sh "${CLAUDE_PLUGIN_ROOT}/hooks/pre-tool-use.sh"]: <message>', framed as an error, because the guard blocks by exiting 2 with its message on stderr. Claude Code's hooks reference documents a structured alternative for PreToolUse: exit 0 with hookSpecificOutput.permissionDecision "deny" and permissionDecisionReason on stdout, which blocks the call (a question included) and hands the model only the reason; the command echo in front of an exit-2 message is not documented at all. Unverified here: the guide that reported it worked from summarised documentation.