“You’re absolutely right!” The agent says it before it has looked at anything. You point out a bug, it tells you you’re right. You suggest the opposite of what you asked for a minute ago, it tells you you’re right again. That reflexive agreement, the little affirmation stapled to the front of every reply, is one of the most complained-about tics coding agents have right now, and once you notice it you cannot stop noticing it.
The obvious fix is to tell it to stop. Add a line to your instructions: do not open with placation, do not tell the user they are right before you have checked. Reasonable. But that line now rides in the model’s context on every single turn, read again on the turns the agent was going to agree politely and the turns it was going to do real work, paid for whether or not it was ever about to placate. So the real question the title asks is how you actually stop it, and the answer turns out not to be an instruction at all.
Notice something about that line, though. It is not about any particular file. “Do not open with placation” applies whenever the agent is about to speak, which is every turn, in every file and in none of them. Set it beside a different rule you might add: production code under src/ must not import a mock library. That one has a home. It is about src/, a path you can name. Two kinds of rule end up on an instruction surface, the kind you can pin to a file path and the kind you cannot, because they are about behavior rather than location. Which kind a rule is decides where it can live and what it costs to keep it there. That split is what this piece is about.
Both kinds pile up regardless. Your CLAUDE.md started at nine lines, and six months later it is three hundred. The no-placation rule joins the mock-import rule from the last two pieces, the payments-module invariant, the frontend spacing scale, the deploy checklist, the API-versioning policy, and a paragraph on how to phrase migration names. This morning you asked the agent to fix a typo in the README, and every one of those three hundred lines rode into its context alongside the request. None of them had anything to do with the README.
The series opener named the loop that runs generate, check, steer, retry, stop, and posed three questions about the parts it turns on. Two pieces answered the first two: the check that decides good enough, stop, and the gate that refuses a bad write before it lands. This one takes the third question the opener posed, the part underneath both of the others: the context surface. It is the next arm on the bench, with more still to come. Every check and every gate is fed by rules the agent carries as loaded text, and that text is paid for on every turn whether it applies to the turn or not. So the question the opener left last is a cost question. What does an instruction actually cost to keep loaded, and what changes when you load it only where it applies. The answer runs straight through the split above: one kind of rule you can teach the harness to load only where it belongs, and the other kind, the placation rule among them, you handle a different way entirely.
What the surface is here
The surface is everything the model sees before it reads your request. The system prompt, the tool definitions, whatever documents got retrieved, and the instruction files (CLAUDE.md, AGENTS.md, and their nested siblings) that ride along on every turn. Prompt engineering tuned the request. Context engineering curated this surface. The loop reuses it: the surface is the state the loop carries between iterations, re-sent each time the model generates.
“Re-sent each time” is the property this piece turns on. A conversation is not cumulative from the model’s side. Each turn, the whole surface is assembled and handed over again from the top. The three-hundred-line instruction file is not loaded once at the start of the session and remembered. It is loaded on turn one, and again on turn two, and again on the turn where you were editing a README. Whatever sits on the surface is paid for at every one of those turns, in full.
What loaded costs, part one: tokens
Put arithmetic on it, as a worked illustration and not a measurement. Say the instruction file has grown to a few thousand tokens, which three hundred lines of prose comfortably will. A working session runs dozens of turns. At forty turns, the file is assembled into the context window forty times. If two thirds of it is rules that only matter in one corner of the codebase, you have paid to keep a few thousand tokens of mostly-irrelevant text in the window on every one of those forty turns, and two thirds of that spend bought nothing on the turn it rode along on.
The numbers are illustrative; the shape is not. An always-loaded instruction costs its length times the number of turns it survives, because the window is rebuilt every turn, so a rule you write once and never delete is one you pay for thousands of times over a session, whether or not any given turn had a use for it.
What loaded costs, part two: attention
Tokens are the measurable half. The other half is what the extra text does to the model reading past it.
The State of AI Instruction Quality pointed a deterministic analyzer at 28,721 repositories and found the median instruction file carries 50 content items and 12 actual directives. The other 38 items are headings, restated context, and structure the model is free to ignore. Every turn, the model has to find the twelve rules that bind inside the fifty items that are loaded, and the thirty-eight that do not bind are still text it reads on the way to the work. Adding a rule that does not apply to the current task costs its tokens and widens the pile the relevant rules are hiding in.
There is a measured effect under that pile. A vaguely-phrased instruction is followed less reliably as more unrelated instructions load beside it on the same turn: the same rule that the model largely honors when it is one of a few gets superficially acknowledged and then ignored once it is one of many, and the reporails corpus measures that decline rising with the number of competing topics. The rule did not change. The company it was loaded with did. The lever it points at is fewer rules loaded at once, with the relevant one present on the turn it applies rather than on every turn.
This is the surface reporails reads. It points the same deterministic analysis at your own instruction files and tells you, with measured evidence, which instructions couple to behavior and which are text the model can ignore, so you can see what you are actually paying to keep loaded instead of guessing at it. It does not load your context or trim it at runtime. It measures the surface you wrote down and reports where the spend is not buying compliance. Knowing which of your fifty items are the twelve that bind is the precondition for the next move, which is deciding where each of them should live.
The rules you can pin to a path
Start with the first kind, the rules that have a path. For a located rule the move is to load it only on the turns it applies to instead of on every turn, and the mechanism is older than agents: a thin index at the top that routes to depth, and depth that loads on match.
Claude Code ships exactly this affordance, and it is worth being concrete about it because the build below leans on it. A CLAUDE.md at the project root loads at the start of every session, so it is the always-on surface. A CLAUDE.md placed inside a subdirectory does not: the harness loads it on demand, when the agent reads or edits a file in that subtree, and not before (per the Claude Code memory docs). A rule that only governs src/payments/ can live in src/payments/CLAUDE.md, and it reaches the model on the turns the agent works in src/payments/, on those turns only. The root file keeps the handful of rules that apply everywhere. Everything path-specific moves down to the path it belongs to.
That subdirectory file is the simplest form of path-scoped loading. The frontmatter-scoped form is more precise, and it does not need a file parked in the directory at all. Claude Code also reads .claude/rules/*.md, and a rule file carrying a paths: glob in its frontmatter loads only for matching files. The docs state it plainly: “Path-scoped rules trigger when Claude reads files matching the pattern, not on every tool use.” Tag a rule paths: ["src/**/*.py"] and it rides the surface when the agent touches Python under src/ and is absent otherwise.
The same primitive ships across every major agent tool, each with its own frontmatter key. Cursor scopes a .cursor/rules/*.mdc file with a globs: field, auto-attaching the rule “when a matching file is in context.” GitHub Copilot scopes a .github/instructions/*.instructions.md file with an applyTo: glob, applying it to “requests made in the context of files that match a specified path.” Three vendors, one idea: attach a rule to a file pattern, and pay for the rule only when a matching file is in play.
Reporails canonizes that cross-vendor mapping and checks for it. Its path-scope-declared rule (CORE:S:0038) verifies that a path-scoped instruction file actually declares the scope it governs, and the Claude paths, Cursor globs, and Copilot applyTo equivalence is the exact thing the rule holds constant across agents. The full public rule set lives at reporails.com/rules.
That is the whole idea. The always-on surface carries what is always relevant, and a rule that is relevant only sometimes loads only then.
This scales past a handful of nested files. The steering setup I work in runs its whole rule corpus this way: each rule is subscribed to the transition it governs, and its full body loads only when that transition fires. The system can report what actually loaded, and on a working session the report runs lopsided: a single steering rule loaded its full body, a handful more stayed one-line pointers, and a dozen-plus subscribed rules never loaded at all, because nothing in the session’s work touched their triggers. That is the shape you are after: the rules that applied were in context when they applied, and the rules that did not apply cost a pointer or nothing, instead of a full body on every turn. One caveat the same receipt discipline demands stating: a pointer delivered is not a rule followed, so a rule that must hold every time cannot lean on being loaded only when it happens to apply. It also gets a deterministic floor, the cheapest place of all to keep a rule, which the placation case below turns out to need. The build after that is one you can run yourself, without any of this machinery.
Build it: split the file that grew
Take the running example the series has used throughout. The no-mocks rule from the check and the gate pieces says production code under src/ must not import a mock library. In the three-hundred-line file, it sits in the always-on surface, loaded on every turn, including the turn you spent editing the README where it could not possibly apply.
The split that follows is itself something reporails measures. Its modular-file-organization rule (CORE:S:0010) checks whether an instruction surface distributes its rules across scoped files or piles them into one monolith, which is the exact shape a grown three-hundred-line CLAUDE.md has taken. The build below is what passing that check looks like on your own repo.
Start by sorting the file by scope, not by topic. For each rule, ask one question: does this apply to every turn, or only to turns that touch a particular path or task? The no-mocks rule applies only when the agent is writing Python under src/. The commit-message convention applies only when the agent is composing a commit. The frontend spacing scale applies only under web/ or theme/. The “which test runner” note genuinely does apply everywhere, so it stays.
Then move each rule to where its scope is. The root CLAUDE.md shrinks to the always-relevant minimum:
# Project instructions (root, always loaded)
- Test runner is `pytest`; never edit files under `generated/`.
- Commit style and per-area rules load from the CLAUDE.md nearest
the file you are editing.
Enter fullscreen mode Exit fullscreen mode
The no-mocks rule moves down to src/CLAUDE.md, beside the code it governs:
# src/ instructions (loaded when the agent works under src/)
- Production code uses a real dependency or a constructor-injected fake;
do not import a mock library. no-mocks.sh and the PreToolUse gate
both enforce this; see the earlier pieces in this series.
Enter fullscreen mode Exit fullscreen mode
Now the README turn loads the root file and nothing under src/, because the agent never opened anything under src/. The no-mocks rule, the payments invariant, the frontend scale: none of them ride along, because none of their paths were in play. When the agent does start editing src/payments/charge.py, src/CLAUDE.md loads on that turn, carrying the no-mocks rule to exactly the moment it applies. It is present on every turn it could bind and absent on every turn it could not, and the always-on surface dropped from three hundred lines to a handful.
One discipline keeps the split honest: the nested src/CLAUDE.md extends the root and stays consistent with it. The root names the test runner and points to the nearest file; src/ adds the no-mocks constraint on top and overrides nothing above it. Reporails checks exactly this as child-nested-instructions (CORE:S:0011): a nested instruction file has to build on its parent and hold consistent with what the parent already says, so a subtree file that quietly reverses a root rule is a defect the check catches.
Progressive disclosure changes when the rule loads while leaving what the rule says untouched. The strictness is intact; only the standing cost falls. The check and the gate from the earlier pieces still sit beside the rule, unaltered, refusing to pay for it on the turns it has nothing to say.
The rule with no path
Every mechanism in the last two sections scopes a rule by path: the nested CLAUDE.md, the paths: glob, Cursor’s globs:, Copilot’s applyTo:. They all answer one question, which file is the agent touching, and load the rule when the answer matches. That works because the no-mocks rule is tied to a location. It is about Python under src/, and src/ is a path you can name.
The placation rule from the opening has no such path. “Do not open with placation” is not about where the agent is working. It is about what the agent is about to say, on any turn, in any file or in no file at all. There is no glob for it. You cannot write paths: or applyTo: for a behavior, because no file pattern predicts a behavior, so the whole path-based toolkit has nothing to offer this rule. It cannot be scoped the way a location rule can. If it stays on the surface, it stays loaded on every turn.
This is where the title’s question gets its answer. The rule leaves the surface a different way: not to a narrower path, but to a check.
“Never open with placation, never tell the user they are right before you have checked” is a rule whose violations are rare and mechanically recognizable: the tell is a short list of opener phrases. That makes it a poor fit for loaded text and a good fit for a check. Instead of a stronger instruction paid on every turn, write a deterministic Stop-hook check: a scan that runs when the agent finishes a message, matches the banned openers in the outgoing text, and fires only when one actually appears. On every turn where the placation does not happen, the rule costs nothing, because it is not on the surface at all. It is present as enforcement and absent as loaded text. You did not load a bigger rule. You moved the rule off the surface.
Concretely, here are both forms of the same rule. The steering form is the loaded line, the request that rides every turn, in CLAUDE.md:
# Voice (loaded every turn)
- Open with the substance, not placation. Affirm the user only after you have checked.
Enter fullscreen mode Exit fullscreen mode
The enforcement form is a check you write yourself, a dozen lines of bash, and it closes the loop on the agent’s own output. A Stop hook runs when the agent finishes its turn, and Claude Code hands it the final reply as last_assistant_message on stdin (per the Claude Code hooks reference). The hook checks the reply, steers the model when it placates, lets it retry, and stops when the reply comes back clean or once it has already been steered. Save it as .claude/hooks/block-placation.sh:
#!/usr/bin/env bash
# block-placation.sh: one arm of the loop, run as a Claude Code Stop hook.
# check the reply, steer the model when it placates, let it retry, stop when it comes back clean or once steered.
payload=$(cat) # the Stop event arrives as JSON on stdin
reply=$(jq -r '.last_assistant_message // ""' <<<"$payload") # the final assistant text of the turn
steered=$(jq -r '.stop_hook_active // false' <<<"$payload") # true when this turn is already a re-steer
# check: does the reply open with placation?
if ! grep -qiE '^[[:space:]>*_-]*(you.?re +(absolutely +|completely +|so +)?right|great question|absolutely[[:punct:]])' <<<"$reply"; then
exit 0 # clean, so stop and let the turn finish
fi
# stop arm: if the last turn was already a re-steer and it still opens this way, let it through instead of bouncing forever
[ "$steered" = "true" ] && exit 0
# steer: block the stop and hand back a correction, so the model regenerates the reply (the retry)
echo "Revise before finishing: this reply opens with an affirmation before checking anything. Drop the opening phrase and lead with the substance." >&2
exit 2
Enter fullscreen mode Exit fullscreen mode
Wire it as a Stop hook in .claude/settings.json:
{
"hooks": {
"Stop": [
{ "hooks": [ { "type": "command", "command": ".claude/hooks/block-placation.sh" } ] }
]
}
}
Enter fullscreen mode Exit fullscreen mode
Same rule, two forms, and it is the steering-versus-enforcement split the gate piece drew, now aimed at a behavior instead of a file write. The loaded line asks the model not to placate and is paid on every turn. The hook does not ask. It reads what the agent produced (the check), and on a clean reply it exits and lets the turn stop, so it costs nothing on every turn the placation does not happen because it is not on the surface at all. On the turn a reply opens with you're absolutely right, the hook refuses the stop and hands back a correction (the steer), and the model regenerates the reply (the retry). The loop then terminates one of two ways: the new reply comes back clean, so the hook lets it stop, or it opened placating a second time, in which case the stop_hook_active guard lets it through rather than bounce forever. Claude Code also caps continuations with an 8-consecutive-continuation backstop, so even a hook that forgot its own stop arm cannot loop indefinitely, but the point of a well-built loop is that it names its own stop condition instead of leaning on the platform’s backstop. It is the same generate → check → steer → retry → stop shape the opener drew, now closing on a behavior.
I run this exact check against my own coding agent’s replies, a deterministic scan that fires when a banned opener shows up in what the agent just wrote. In one working session it caught six replies that led with you're right before the agent had looked at anything, each one flagged at the boundary instead of sliding past. A real catch on real output, reproducible, and the banned phrase never had to ride on the context surface for the scan to find it. The rule earned its keep by matching the violation, not by being read on every turn it did not apply.
The gate piece built a hook to refuse a bad write, so the boundary is worth drawing. That piece was about a channel that can say no where a prompt can only ask. This one is about cost. The check is a deterministic scan of the text the agent produced, the same shape as the diff-scan the check piece built, and its context cost is zero on every clean turn. A rule you can express as a check on the output is a rule you never have to keep loaded to enforce.
That splits two axes that are easy to run together. Path-scoping decides when a location-tied rule loads, and it is the right tool for every rule that has a path. It says nothing about whether a rule that did load actually moved the behavior, which is the other axis, and the one that decides whether a behavior rule was worth writing at all. Measuring which instructions on your surface couple to behavior, and which are text the model reads and ignores, is what reporails does: it reads the surface you wrote down and reports the coupling, the axis a path glob cannot reach. The two do not compete. Path-scoping trims what loads; the coupling read tells you whether what loaded earned its slot.
Which rule loads where
The sort has a failure mode in each direction, the same shape the gate piece found for steering versus refusing.
Push a genuinely global rule down into a subtree and it goes missing on the turns it was supposed to cover. “Never edit generated/” scoped to src/ does not reach the agent when it is about to edit a generated file under web/, which is one of the turns you wrote it for. A must-hold-everywhere rule belongs on the always-on surface, and the cost of keeping it there is the cost you should pay, because its scope really is every turn.
Hoist a narrow rule up into the root and you are back where you started. It loads on every turn, taxes every turn, and pads the pile the global rules hide in. The payments-module invariant on the always-on surface is billed on the README turn and the frontend turn for nothing.
The heuristic is the scope question made explicit. A rule loads at the level whose every access it governs. Applies to the whole repo, root file. Applies to one package, that package’s file. Applies to one task the agent performs occasionally, a file or skill that loads on that task’s description match rather than on every turn. The test is not how important the rule is. A critical rule with a narrow scope still loads narrowly; importance decides whether you also back it with a gate, which the gate piece covers, not where the rule loads.
The loop only checks what you wrote down
Three arms of the loop taken apart so far, and the loop is not out of arms. The check decides good enough, stop, and a misfiring check is a broken instrument before it is an absent signal. The gate refuses a bad write before it lands, and a rule that must hold every time belongs in the channel that can say no. The surface is what feeds both, and every rule on it is loaded text you pay for on every turn it survives, so a rule that applies only sometimes should load only then, and a rule you can turn into a check on the output does not need to sit on the surface at all.
What ties them together is the thing the series keeps returning to. The loop only ever checks, gates, and steers on what you wrote down. The check runs the rule you encoded; the gate refuses on the pattern you specified; the surface carries the instructions you authored and hands them to the model turn after turn. None of it reaches past the text you put there. That is why the text is worth engineering. What it says decides whether the loop catches the right thing, and where it loads decides what every turn costs to run. Load the whole surface every turn and you pay for all of it on turns that needed almost none of it. Load each rule where it applies and the loop still holds, on the turns that matter, for a fraction of the standing cost.
There is an arm this series has kept naming in passing and has not yet taken apart: the steer. Between one attempt and the next, the loop carries something back to the model, the check’s own output, rephrased into the next instruction. What it carries back is a choice, and a careless one poisons everything downstream of it. Feed back the wrong signal and the next check judges the next attempt against the wrong thing, so the loop converges, confidently, on an answer no one asked for. What the loop should hand back between tries, and what breaks when it hands back too much or the wrong part, is the next arm to measure.
I work on Reporails, deterministic diagnostics for the instruction files, rules, and prompts that steer coding agents. It reads the steering surface and tells you, with measured evidence, which instructions couple to behavior and which are text the model is free to ignore. It does not load or trim your context; it measures the surface you wrote down, so you know what you are paying to keep in front of the model.





답글 남기기