Dynamic system-prompt sections silently override CLAUDE.md; no precedence rule, no way to observe it
There is no defined precedence between an Anthropic-authored dynamic system-prompt section and a user-authored CLAUDE.md, and when the two conflict the harness section wins silently — no signal to the model that it is overriding user configuration, and no signal to the user that it happened at all.
I hit this concretely in #80988, but the content of that particular section is beside the point here; the precedence gap is the defect, and it will recur with the next section whose wording happens to contradict someone's config.
What the conflict looked like
My ~/.claude/CLAUDE.md contains an explicit, thresholded delegation policy: recon touching more than ~5 files, or an implementation run over ~20 lines, must be dispatched to a subagent rather than done inline. It is the single most load-bearing rule in that file — it exists because inline work in long sessions produced a documented run of quality incidents.
CLI 2.1.219 rendered a dynamic section (heron_brook) whose default text reads, verbatim:
Do not call the AgentTool unless the user requested it
Do not use workflows or deep-research unless the user requested it
That is a direct contradiction. And because the section arrives in the same undifferentiated voice as everything else in the system prompt, the model read it as the user's own instruction, invoked the escape hatch in the user's policy that requires an explicit user directive, and worked inline for a full session. The user's configured policy was dead, and the user could not see why.
Why this is a defect independent of that section's wording
- No author signal.
CLAUDE.mdcontent and harness/experiment content are concatenated into one prompt with no distinction. A model cannot apply "the user's instructions take precedence" when it cannot tell which text is the user's. - No conflict surfaced. The correct behaviour on a genuine contradiction is to raise it, not to resolve it on the merits. Nothing in the prompt makes contradiction detectable, so it gets resolved silently, in whichever direction the phrasing happens to favour.
- Server-gated, so it is non-reproducible from the user's side. The section is gated on a model-registry capability plus a
tengu_*flag, so it appears for some accounts/models/builds and not others. Two sessions on the same machine and the same build behave differently, which reads to the user as the model being erratic. - Invisible in the transcript. Session transcripts (
~/.claude/projects/**/*.jsonl) do not record the system prompt or the set of active dynamic sections. Diagnosing this required scanning the ~250MB binary for the section registration and its gate. That is not a reasonable diagnostic path for a user asking "why did Claude stop delegating today."
This is the same defect shape as #62205 (GrowthBook flags overriding settings.json): server-side configuration silently beating user-side configuration, with the user's file left looking like it was ignored. Also related: #62061, the same mechanism reported earlier.
The ask
In priority order.
- Define and implement precedence. When a dynamic section conflicts with the user's
CLAUDE.md/settings.json, the user's file wins. If that is too strong a guarantee to make, then at minimum instruct the model to surface the conflict rather than resolve it — "your operator configuration and this section disagree; say so" is a one-line fix that turns a silent override into a visible question.
- Make the rendered prompt observable. Record the active dynamic-section names (and the flag values that gated them) in the session transcript, or expose them behind a flag or
/doctor-style command. This costs almost nothing and removes binary archaeology from the diagnostic path entirely. It would also have made #80988 a five-minute report instead of a multi-hour investigation.
- Optionally, author-labelled envelopes. Wrapping harness-authored sections the way
<system-reminder>already wraps background context would make attribution mechanical rather than inferred. I list this last deliberately, with two caveats worth stating: a label inside a prompt is only trustworthy because the harness controls the wrapper — it is otherwise forgeable by any text that reaches the prompt (file contents, tool output, a pasted diff) — and labelling your own text as non-user makes it explicitly disputable, which you may not want. (1) and (2) are the real requests; (3) is a suggestion.
None of this requires agreeing that any particular section's wording was wrong. The narrow claim is only that a user who writes a rule in CLAUDE.md should not have it silently overridden by text they cannot see, attributed to a voice that is not theirs.