Feature request: pre-text-emission hook to enforce content policies on assistant prose
Problem
The current hook surface (SessionStart, UserPromptSubmit, PreToolUse,
PostToolUse, Stop, FileChanged, etc.) cannot intercept the assistant's
text output before it is rendered to the user.
PreToolUse can block tool calls and Stop can block "natural stop" to
force continued generation, but neither can gate, modify, or rewrite
the assistant's prose. PostToolUse / UserPromptSubmit inject context
as advisory text only.
This breaks user-built enforcement of content policies such as
"never claim a fact without a verified: tag" or "must restate only
verified context after a discard event." The assistant can comply with
a tool-call block by simply emitting prose that re-engages the
prohibited pattern — no hook sees it.
Proposal
Add a PreResponse (or equivalent) hook event that fires before
assistant text is shown to the user, with:
- Input: the about-to-be-emitted text (and ideally the prior turn's
context for matching).
- Block semantics: exit 2 prevents the emission and returns an
error / forces re-generation.
- Optional rewrite path: stdout replaces the emitted text (similar
to UserPromptSubmit's additionalContext model, but on output).
Use cases
- Verify-before-claim enforcement: scan the about-to-emit message
for unverified hedge words (likely, probably, may, seems, etc.)
and block emission until tagged correctly.
- Discard-poisoned-context enforcement: after a sentinel is set
(e.g., a violation log was just written), require the next message
to be "verified-only + question to user" before allowing it
through.
- Output redaction for sensitive identifiers.
What I tried
Built three coordinated hooks:
- UserPromptSubmit injects rule + clears a sentinel.
- PostToolUse sets a sentinel + injects "discard" reminder when a
violation log is edited.
- PreToolUse blocks all tool calls while the sentinel exists.
This works for tool-call-bearing turns, but a text-only response
slips through entirely. The assistant can ride a poisoned chain in
pure prose with no enforcement point.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗