claude-code - 💡(How to fix) Fix Hooks can't gate assistant chat text — only tool-call and user-prompt boundaries [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#52844Fetched 2026-04-25 06:19:23
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Participants
Timeline (top)
labeled ×2

Hooks cover user prompts (UserPromptSubmit), tool calls (PreToolUse/PostToolUse), stops, and compaction — but nothing fires on the assistant's free-form chat text as it's being finalized. Rules whose trigger is the model's own output have nowhere to live except the system prompt / CLAUDE.md, consuming context every turn even when the trigger isn't present.

Root Cause

Every bucket-C rule has to sit in the system prompt every turn for a <5% hit rate. On a tuned CLAUDE.md that's a real chunk of context paying the cache-miss cost every session start. A pre-finalize hook would let these rules be lazy-loaded the same way UserPromptSubmit and PreToolUse already allow for buckets A and B.

RAW_BUFFERClick to expand / collapse

Summary

Hooks cover user prompts (UserPromptSubmit), tool calls (PreToolUse/PostToolUse), stops, and compaction — but nothing fires on the assistant's free-form chat text as it's being finalized. Rules whose trigger is the model's own output have nowhere to live except the system prompt / CLAUDE.md, consuming context every turn even when the trigger isn't present.

Concrete context

Pruning ~/.claude/CLAUDE.md, I found rules fall into three buckets by trigger source:

  • A. User-keyword triggered — can move to UserPromptSubmit regex hooks that inject the rule only when the prompt matches. ✅ Works today.
  • B. Claude-about-to-write-a-file triggered — can move to PreToolUse on Write|Edit that scans tool_input.content / tool_input.new_string / tool_input.file_path and returns permissionDecision: deny with a reason. ✅ Works today.
  • C. Claude-chat-text triggered — ❌ no hook fits.

Bucket C examples from my CLAUDE.md:

  • Correcting name misspellings Claude produces in chat (e.g. "Wei Wu" → "Weiwu")
  • Temporal framing: Claude about to describe a past event as "upcoming" because the source document was authored earlier
  • Filler phrases, style drift, provenance slips ("talking to user" vs "writing into project files")

Stop doesn't solve these: it fires after the message is already streamed to the terminal. Exit-2 / decision: \"block\" forces a follow-up turn, but the wrong text stays on screen and the correction is visible as a separate message.

Request

A hook event that fires on each assistant message as it is being finalized, able to either:

  1. Transform the text before it's shown to the user, or
  2. Reject and force regeneration, with structured feedback to the model (analogous to PreToolUse permissionDecision: deny + permissionDecisionReason, but for assistant messages rather than tool calls)

Why this matters

Every bucket-C rule has to sit in the system prompt every turn for a <5% hit rate. On a tuned CLAUDE.md that's a real chunk of context paying the cache-miss cost every session start. A pre-finalize hook would let these rules be lazy-loaded the same way UserPromptSubmit and PreToolUse already allow for buckets A and B.

extent analysis

TL;DR

Implement a new hook event that fires on each assistant message as it is being finalized, allowing for text transformation or rejection with structured feedback.

Guidance

  • Identify the specific requirements for the new hook event, including the ability to transform text or reject and force regeneration with feedback.
  • Determine the optimal placement for the new hook event in the existing codebase, potentially leveraging the existing UserPromptSubmit and PreToolUse hooks as a reference.
  • Consider the performance implications of introducing a new hook event, particularly with regards to the cache-miss cost mentioned in the issue.
  • Explore potential solutions for lazy-loading rules, similar to how UserPromptSubmit and PreToolUse already allow for buckets A and B.

Example

No code snippet is provided as the issue does not contain sufficient technical details to generate a specific example.

Notes

The introduction of a new hook event may require significant changes to the existing codebase, and careful consideration should be given to the potential impact on performance and existing functionality.

Recommendation

Apply a workaround by introducing a new hook event that meets the specified requirements, as this would allow for the desired functionality without relying on existing hooks that are not suitable for bucket C rules.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Hooks can't gate assistant chat text — only tool-call and user-prompt boundaries [1 participants]