enhancement: first-class subagent policy primitive — explicit in-prompt rules still get rationalized past
Summary
Even when policy rules are pasted directly into a subagent's prompt — citing CLAUDE.md by name, including an explicit "no rationalization" clause, and framing the rules as system-level constraints — the general-purpose subagent still volunteers commentary the rules prohibit. The phrasing softens (more hedging, more parentheticals) but the substantive violation remains.
This is a model-compliance gap distinct from the context-delivery gap in #62944. Even when the rules are unambiguously in context, they aren't treated with the priority their framing requests.
Reproduction
- Create a project
CLAUDE.mdwith a clear rule, e.g.:
````
For any "explain this file" request, give a single one-sentence summary
and stop. Do not produce section-by-section walkthroughs, line-numbered
breakdowns, or unsolicited observations about the code. No exceptions;
no rationalization clauses ("flagging because it's load-bearing",
"mentioning because it's context", etc.) are valid.
- From the parent, dispatch a subagent and paste the same rule directly into the subagent's prompt as a preamble:
```
Agent({
subagent_type: "general-purpose",
prompt: "REMINDER: The project CLAUDE.md defines strict-scope mode...
[rule text]...
Now: explain what <some-file>.py does in this repo."
})
```
- Use a non-trivial source file that contains patterns the model might want to comment on (perf, style, structure, etc.).
Expected
The subagent obeys the explicit in-prompt rule and returns a one-sentence summary.
Actual
The subagent produces a sectioned walkthrough with line numbers and volunteers observations the rule prohibits, often with softened phrasing ("note this...", "(also worth noting...)") that effectively constructs a rationalization the rule explicitly forbids.
This held across:
- Multiple wordings of the rule (terse, verbose, marked as system-level)
- An added "no rationalization" clause naming the specific evasion patterns
- Multiple capability tiers (Opus 4.7, Sonnet 4.6)
Why this matters
Several teams want to use Claude Code in environments where strict-scope behavior matters — regulated codebases, audit/compliance reviews, training or evaluation environments, etc. Natural-language policy via CLAUDE.md or prompt preamble is the obvious primitive to reach for, but it doesn't hold up against the model's helpfulness training when salient patterns are visible in the code.
The current alternatives — PreToolUse hooks or custom subagent definitions — work but are awkward for policy that's about response content rather than tool calls. Hooks can't easily inspect or rewrite a model's text response; custom subagents require maintaining duplicated rule text across multiple .md files.
Suggested directions
- Stronger system-prompt slot for project policy. A
.claude/policy.mdor similar that gets injected at system-prompt priority into both parent and subagent contexts, not as a user-message-after-system-prompt the way CLAUDE.md currently is.
- Response-content hooks. A
PostMessage/PreResponsehook that can inspect or rewrite the model's text output before it's surfaced to the user, analogous toPreToolUsefor tool calls.
- Per-subagent policy file. Allow
.claude/subagents/<name>.mdto reference a shared.claude/policy.mdso policy doesn't have to be duplicated across every subagent definition.
- Trained behavior. Longer-term: model-side reinforcement that in-context rules with explicit "no rationalization" framing should be followed more strictly than default helpfulness.
Related
- #62944 (docs gap on CLAUDE.md inheritance)
Environment
- Claude Code: 2.1.152
- OS: macOS (Darwin 25.4.0)
- Model: Opus 4.7 (1M context); reproduces on Sonnet 4.6
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗