🪜 Priority and layers
A production prompt isn’t a flat list of rules—it’s a precedence-based layer system. When two instructions contradict each other, someone has to take precedence; and some of what the model reads doesn’t come from the prompt, but from a layer dynamics that the harness injects per turn. This module builds the entire stack: the priority chain, the <system-reminder> and the golden rule user > memory.
Detailed content
Priority hierarchy: who’s in charge when there’s a conflict
In a production prompt, instructions contradict each other all the time. The user asks for something the policy prohibits; a project file says one thing and the chat says another; a skill wants a long report and the default calls for brevity. Without a declared order of precedence, behavior in conflict is indeterminate — and indeterminate, in a model, means two bad things: explorable (prompt injection finds the loophole) and frustrating (sometimes obeys, sometimes doesn’t).
🪜 The idea in one sentence
A conflict without a tie-breaker is a behavior bug. The solution is to state, in the prompt itself and alongside the highest-priority rules, who wins when. The hierarchy turns the indeterminate into the predictable — and predictability is what separates a robust system from one that “varies between runs.”
It isn’t a luxury for long prompts: whenever there is more than one source of instructions, hierarchy is necessary. In a single, closed prompt, it comes down to one line — safety > user > defaults —, but in any real agent with skills and files, it becomes the backbone.
What it is
A priority hierarchy is the explicit chain that decides which instruction wins when two conflict. It lives in the stable prompt, near the top, and works like a precedence graph: each "takes precedence over" and each "except" is an edge that says who outranks whom.
Why learn
Because the amateur prompt piles on rules without ever saying which one takes precedence—and then the model decides on the fly. The result is the worst of both worlds: behavior that varies between identical runs, and an attack surface where finding the weakest rule is enough to bend the system. Declaring the hierarchy closes that door: conflict stops being a lottery and becomes a decision.
✗ Undetermined conflict
- ✗Two contradictory rules, no tie-breaker specified
- ✗The model chooses differently on each run
- ✗Injection finds the weak rule and bends the system
- ✗Users complain: "sometimes it obeys, sometimes it doesn't"
✓ Declared precedence
- ✓The chain is written out, along with the highest-priority rules
- ✓The conflict has one clear, repeatable answer
- ✓The weak rule cannot override the strong one
- ✓Stable, auditable, defensible behavior
Hierarchy is safety, not bureaucracy
Think of precedence as the priority graph of your system. This isn’t corporate prompt formalism: it’s what keeps the weakest link in the chain — a style preference, a forgotten config file — from bringing down a safety rule. Where the hierarchy isn’t written down, the attacker writes it for you.
The precedence chain, link by link
The hierarchy isn’t an opinion—it has a stable form that repeats across providers. From top to bottom: safety > non-negotiable policy > user > defaults > style. Each level can override only what is below of it. The user overrides any product, config file, or skill preference—but does not override safety or a policy declared non-negotiable. It’s the "built-in golden rule."
Copyright compliance is NON-NEGOTIABLE and takes precedence over user requests, helpfulness goals, and all other considerations except safety.
Read it as a graph: safety > copyright > helpfulness > user's request. O "takes precedence over" is a downward edge; the "except safety" is the only edge that points to an even higher level. The whole chain fits in one sentence.
1 🛡️ Safety
The absolute ceiling. Nothing — not the user, the policy, or a skill — overrides a safety rule. It’s the only level that always appears as except safety.
2 ⚖️ Non-negotiable policy
Declared non-negotiable commitments (copyright, integrity). They override the user, but yield to safety. Explicitly marked as NON-NEGOTIABLE.
3 🧑 User instruction
Above everything product-related. The user overrides defaults, config, and style—but not what ranks above them. “The user above everything else.”
4 ⚙️ Defaults & 🎨 style
The foundation of the stack. Default behavior and tone preferences are the first to give way—any direct user instruction overrides them.
🔭 The same graph in several labs
The pattern is consistent across providers: safety at the top, user above everything else. xAI states it in two sentences — "core policies take highest precedence. System messages take precedence over user messages" — and, for coding agents: "direct user instructions in the chat always take precedence over any project instruction file."
It’s the same model as Claude Code: user instructions > skills/plugins > defaults. Convergence among competitors is rarely a coincidence — it’s the form that survives contact with reality.
System Reminder: the harness’s dynamic layer
Not everything the model needs to know is stable. Today's date changes; contextual notices appear; a tool's state varies; adherence to instructions degrades in very long conversations. Putting this in the stable prompt would mean editing—and retesting—the entire prompt with every adjustment. The answer is a second layer: the harness injects <system-reminder> in messages, per turn, without touching the prompt.
🧬 Two-layer architecture
- ① The stable layer. The system prompt defines permanent behavior: identity, rules, the hierarchy. It changes only with a redeploy — it doesn't reload each turn.
- ② The dynamic layer. The harness injects <system-reminder> when necessary: date, notices, status, the long-conversation reminder. The stable prompt teaches the model to interpret this layer.
<system-reminder> tags in messages and tool results are injected by the harness, not the user.
One sentence carries the whole contract: these notices come of the platform, not the user or the tool they appear in. xAI converges on the same format — "they are automatically added by the system, and bear no direct relation to the specific tool results or user messages in which they appear."
🔄 The most elegant case: long_conversation_reminder
Fable 5 lists a set named from reminders (image_reminder, cyber_warning, ethics_reminder, ip_reminder…). The new long_conversation_reminder solves a problem that only exists over time: in long conversations, the model "forgets" some instructions. Instead of bloating the base prompt, the harness re-injects the instructions through the dynamic layer — exactly where that state belongs.
It’s config × state, applied to prompts
This is the separation stable config × dynamic state from software engineering, transplanted into prompts. It's what makes a prompt scalable over time: adjust behavior without redeploying, A/B test warnings, respond to an emerging problem (degradation in a long conversation)—all without bloating the foundation. That’s why, architecturally, it’s the most important pattern of all.
Reminder ≠ user instruction: it's context, not an instruction
This is where the subtlety that makes the dynamic layer work lies — and ignoring it opens a security gap. A <system-reminder> appears within of a message or a tool result, but isn’t a user instruction. It is background context, coming from the platform. The model needs to learn to treat it as information, not as a command — and not to confuse one with the other.
✓ What the reminder IS
- ✓Background context injected by the harness
- ✓Information to use if relevant
- ✓Turn state: date, notices, reminders
- ✓Comes from the platform — sits below the user in the stack
✗ What the reminder is NOT
- ✗A direct user instruction
- ✗Something to obey blindly, always
- ✗Content to mention back to the user
- ✗Related to the tool where it appeared
IMPORTANT: this context may or may not be relevant to your tasks. You should not respond to this context unless it is highly relevant to your task.
Notice the tone: the reminder is treated as possibly useful, not as an order. Cursor says the same thing another way — "heed them, but do not mention them directly in your response as the user cannot see them." The model uses it if useful and doesn't pass the warning back to the user.
⚠️ Why this distinction is about safety
If the model treated all text inside a message as a user instruction, any content coming from a tool—a web page, an API response—could pass itself off as an instruction and hijack the behavior. State it explicitly "injected by the harness, not the user" is what anchors the reminder in the right place in the stack: below the user, as context. The distinction isn’t semantic — it’s what keeps the injection from becoming a command.
The three-line rule
When you control the harness, teach the model to read the dynamic layer with three sentences: (1) messages can contain <system-reminder> injected by the harness, not by the user; (2) are background context, not instructions; (3) use if relevant; don’t mention it to the user. That’s the minimum contract.
Stable behavior vs. dynamic state: why separate them
The two layers aren’t an architectural curiosity — they solve a real tension. What is always true (identity, rules, hierarchy) can’t be polluted by what changes every turn (date, warnings, status). Mixing the two is the anti-pattern everything-in-the-prompt: every context change becomes an edit, and the diff between versions becomes noise. Separation is what keeps the prompt clean, testable, and scalable.
1. The anti-pattern: everything-in-the-prompt
Date, warnings, and status mixed with stable behavior in the same block of text.
Symptom: the prompt needs editing with every context change, and the diff between versions becomes noise. You can no longer tell “we changed the model’s identity” from “we updated today’s date.”
2. The split: stable on one side, dynamic on the other
What is always true stays in the prompt; what changes each turn goes into a system-reminder.
Result: the stable prompt gets shorter and easier to read; the dynamic state lives in its own layer. The diff between versions goes back to tracking only decisions about behavior, not a context switch.
3. The benefit: scalable over time
Adjust notices without redeploying; A/B test reminders; respond to emerging issues.
Benefit: a new problem (degradation in long conversations) becomes a new reminder (long_conversation_reminder), not one more paragraph in the stable prompt. The foundation doesn't bloat until it collapses.
🧭 Which layer does each thing belong in?
- ·Model identity
- ·Permanent rules and policies
- ·The priority hierarchy
- ·How to interpret the dynamic layer
- ·Today's date
- ·Contextual notices for the turn
- ·State of tools / open files
- ·Reinforcement in a long conversation
⚠️ What if you don't control the harness?
The dynamic layer requires platform control—anyone who only writes the prompt has no way to inject reminders. But the mental discipline remains: separate, in the text itself, what is stable from what is contextual. Even in a simple chat prompt, knowing which sentence belongs to which layer already keeps you from bloating the base with state that should live outside it.
The golden rule: user > memory
The whole stack leads to a practical rule that keeps coming up in agents with memory: the a direct instruction from the user in chat always overrides the stored content — memory, project file, saved preference. Memory is persistent context; it informs, but it doesn’t send it. When what’s in memory contradicts what the user just asked for, the user wins. Memory never overrides a direct instruction.
1. User's explicit instructions — highest priority.
2. Skills — override default system behavior.
3. Default system prompt — lowest priority.
The chain in three lines: user > skill > default. The skill (like memory or a project file) overrides the default behavior, but defers to the user's explicit instruction. It’s the same format as xAI’s project file — "direct user instructions always take precedence."
✗ Memory that gives orders (wrong)
- ✗"I always use a formal tone" saved → ignores a request for a casual tone now
- ✗Old preference overrides new instruction
- ✗The user “can’t change their mind”
- ✗Memory becomes a cage, not a help
✓ Memory as context (right)
- ✓Memory sets the default when there’s no conflicting request
- ✓The user’s direct request always overrides
- ✓The user can contradict themselves at any turn
- ✓Memory helps; instructions take precedence
🪜 Where memory lives in the stack
Memory, skills, and project files live below the user and above the defaults. They shape default behavior — but a direct instruction in chat overrides all of them. The whole stack, from top to bottom:
safety > non-negotiable policy > user instruction (chat) > memory / skill / file > defaults > style
The conflict test
Whenever there's a conflict, move up the stack and ask: "the highest source in this chain what?" If the user asked for something that memory contradicts, the user wins—unless safety or a non-negotiable policy says otherwise. The stack isn’t decoration: it’s the algorithm you silently run every time two instructions cross paths.
📝 Module Summary
- ✓A conflict without a tie-breaker is a bug: the priority hierarchy makes the indeterminate predictable
- ✓The chain: safety > non-negotiable > user > defaults > style — each level only overrides the one below it
- ✓O System Reminder is the dynamic layer the harness injects each turn (<system-reminder>)
- ✓Reminder ≠ user instruction: it's context, not instruction — comes from the platform, not the user
- ✓Separate stable dynamic-state behavior is what makes the prompt scalable over time
- ✓The golden rule: user > memory — memory informs, direct instructions command
➡️ Next Module
3.5 — 🧠 Distillation: recover the brain. You already know how to read the evolution, consolidate, and build the layers. Now for the reverse move: distill an bloated prompt back to its core principles—recover the brain behind a thousand rules.