feat(hookify): add silent flag for assistant-only warn rules#1421
Closed
WingsOfPanda wants to merge 2 commits intoanthropics:mainfrom
Closed
feat(hookify): add silent flag for assistant-only warn rules#1421WingsOfPanda wants to merge 2 commits intoanthropics:mainfrom
WingsOfPanda wants to merge 2 commits intoanthropics:mainfrom
Conversation
Warn rules previously returned only `systemMessage`, which is shown to the user console but never injected into Claude's context. Educational messages (the entire point of warn rules) never reached the model. Block rules similarly returned only a generic deny without `permissionDecisionReason`. Now: - Warn rules on PreToolUse/PostToolUse also emit `additionalContext` inside `hookSpecificOutput`, so Claude sees the message and can self-correct. - Block rules on PreToolUse/PostToolUse also emit `permissionDecisionReason`, so Claude sees why the operation was denied. PreToolUse `additionalContext` support landed in Claude Code v2.1.9 (see anthropics/claude-code#15664, anthropics/claude-code#15345). PostToolUse has supported it since earlier. The capability is now available; this patch makes hookify use it. Refs: - anthropics/claude-code#15203 (warn — closed as duplicate) - anthropics/claude-code#12446 (block — closed) - anthropics/claude-code#15664, anthropics/claude-code#15345 (SDK additionalContext support) - Prior PR attempts: anthropics/claude-code#15218, anthropics/claude-code#15219 (closed unmerged, predate v2.1.9)
Adds a `silent: true` frontmatter field to hookify rules. When set, the warn rule suppresses `systemMessage` (user-facing banner) and delivers only via `additionalContext` (assistant-facing). This enables purely Claude-internal self-correction rules without creating user notification fatigue. Behavior: - `silent: true` → no banner, only additionalContext - `silent: false` (default, backward compat) → banner + additionalContext - Mixed matching: banner shows only non-silent messages; additionalContext always contains all messages (silent + non-silent) Builds on anthropics#1420 (adds additionalContext to warn rules in the first place). Motivation: warn rules fall into two classes — those the user should see (shared decisions like "rm -rf confirm?") and those that are Claude-internal coaching ("use python3 not python"). The new flag lets rule authors distinguish them. Refs: - anthropics#1420 (prereq — adds additionalContext) - anthropics/claude-code#15664, anthropics/claude-code#15345 (SDK PreToolUse additionalContext in v2.1.9)
|
Thanks for your interest! This repo only accepts contributions from Anthropic team members. If you'd like to submit a plugin to the marketplace, please submit your plugin here. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
silent: truefrontmatter flag to hookify rules. When a warn rule is marked silent, itssystemMessage(user-facing banner) is suppressed and the message is delivered only viaadditionalContext(assistant-facing).This enables purely assistant-facing self-correction rules — the agent sees the message in its context and adjusts, but the user isn't shown a banner for behaviors they don't need to be interrupted about.
Stacked on #1420
This PR builds on #1420 (
fix(hookify): pass warn/block messages to Claude). If #1420 lands first, this PR's diff will narrow to just the silent-flag additions. If they land together, the combined change is the warn-path rewrite shown below.Motivation
Warn rules now (as of #1420) reach Claude via
additionalContext. That's a huge win — the AI can self-correct. But every warn rule also emitssystemMessage, which banners the user. Two rule classes have emerged in practice:rm -rf— confirm?")python3, notpython", "cd back to project root before wrapping up")Without this flag, all warn rules look the same to the user. With it, users can build coaching rules that nudge Claude silently.
Design
silent: true(defaultfalse)systemMessageis emitted and contains ONLY the non-silent messages (silent rules don't leak to the banner even when bundled)additionalContextalways contains ALL matching messages (silent + non-silent) — assistant always sees everythingsilentkeep current behaviorExample usage
User runs Claude. Claude tries
cd foo-subrepo. User sees nothing. Claude gets the message in its context, does the task,cds back. Invisible self-correction.Changes
plugins/hookify/core/config_loader.py:silent: bool = Falsefield toRuledataclasssilent=bool(frontmatter.get('silent', False))infrom_dictplugins/hookify/core/rule_engine.py:all_messages(foradditionalContext) andvisible_messages(forsystemMessage)systemMessageonly if there are non-silent messages to showTest plan
silent: truein frontmatter is parsed toRule.silent = Truesilentfield defaults toFalse(backward compat)systemMessagein response;additionalContexthas the messagesystemMessageandadditionalContext(same as current behavior)systemMessagehas only non-silent messages,additionalContexthas allStopevent unaffectedadditionalContextarrivedRationale for the partition design
Four options were considered for mixed matching (some silent, some visible):
additionalContexthas allOption 4 is the most predictable: silent means silent, non-silent means visible, mixed works as expected from each rule's own perspective.
Refs
additionalContextandpermissionDecisionReason(prerequisite)additionalContextsupport to PreToolUse hooks claude-code#15664, [FEATURE] Support additionalContext in PreToolUse hooks claude-code#15345 — SDKadditionalContextsupport forPreToolUse