{"slug": "loaded-obeyed-why-your-agent-quotes-rules-it-doesn-t-follow", "title": "Loaded Obeyed: Why Your Agent Quotes Rules It Doesn't Follow", "summary": "A developer migrating from Claude Code to OpenCode found that agent rules were loaded but not followed, a state they call 'loaded but not load-bearing.' They propose a two-lane diagnostic model distinguishing rules that never loaded from those that loaded but lost influence, and recommend re-declaring rules into the harness's primary file and verifying with a three-part query.", "body_md": "*The file was loaded. The rules just weren't followed. Here's the two-failure diagnostic that tells you which one you have — and what to do for each.*\n\nMy agent used to follow my rules. The output-format rules, written once into a `CLAUDE.md`\n\n, were obeyed like law — for months, in Claude Code.\n\nThen I migrated to OpenCode, and the rules quietly stopped meaning anything. The agent quoted them back flawlessly. It recited them every time I asked. And it ignored them, day after day, rule after rule. The file was loaded. The rules just weren't obeyed.\n\nThe fix wasn't stronger wording, and it wasn't a better prompt. It was re-declaring every rule, one by one, into a fresh `AGENTS.md`\n\n— and it held.\n\nThat's the lesson this post is built on: a rule that isn't followed is one of two failures. Either it never loaded, or it loaded and lost. Here's how to tell which, and what to do for each.\n\nI didn't run that test once. I ran it in fresh sessions, multiple times, for days. Every time, the same answer: a perfect recital. Every time, the same next output: the format rules broken.\n\nIn the middle of it, the token usage climbed — noticeably higher than expected. Not because the work was harder. Because the rules were being re-derived and re-explained instead of followed, every session, on top of a `MEMORY.md`\n\nthat was already bloated. Token waste and trust damage from the same root cause.\n\nThis is the exact state readers end up in with their own agents, and the reason most of them are on GitHub filing issues that never get answered.\n\nSo let's name what that means.\n\nHere's the model that ended my guesswork. A rule that isn't followed is one of two failures:\n\n| Lane A — never loaded | Lane B — loaded and lost | |\n|---|---|---|\nWhat it is |\nA file/loading problem: wrong file, nested or path-scoped rule, compacted away, not read at all | A model-behavior problem: the rule reached the context window and still didn't steer |\nThe truth about it |\nThe harness never applied weight to this rule | Rules are context, not enforced configuration |\nThe fix |\nRe-declare it into the file the harness actually reads, then verify | Redesign the rule's shape, or move it to a mechanism that can't lose |\nCost of guessing wrong |\nYou reword a rule that never mattered | You reword a rule forever, because wording was never the lever |\n\nThe whole point of the model is that these are two different problems with two different fixes. Most advice treats them as one problem — \"write better rules\" — which is why so much of that advice doesn't change anything.\n\nMy migration had both lanes in play. But the one that broke me was neither, exactly. It was the state in between.\n\nHere's what my migration actually looked like. OpenCode reads `AGENTS.md`\n\nas its first-class rules file, and it falls back to `CLAUDE.md`\n\nif there's no `AGENTS.md`\n\n— which is why the agent could quote my old rules at all. The fallback file was present enough to recite.\n\nPresent enough to quote. Not enough to act on.\n\nThe telling detail was what the agent *couldn't* do. It could recite the general rules. It couldn't tie them to a file or a plan — it couldn't tell me where they lived or what it would do to follow them. That's the gray zone's fingerprint: quoting without any load-bearing behind it.\n\nI call that state **loaded but not load-bearing** — and it quietly breaks the most common piece of advice in this space: *\"ask your agent what your rules are.\"* I asked, every single day. The answer was always a perfect recital. The recital proved a file existed. It proved nothing about whether the rule carried any weight.\n\nThat's the trap the two-lane model has to catch before it can help you: the gray zone — a rule that is loaded, quotable, and useless.\n\nThe reason \"what are my rules?\" failed me is that it's the bottom rung of a three-rung ladder:\n\nThe one line you can run today:\n\n\"Quote the exact rule, show me where it lives, and tell me what you'll do with it.\"\n\nAnd what a passing answer looks like — this is the test I ran after the re-declaration:\n\n\"The output-format rule is the first block under\n\nOutput formatin`AGENTS.md`\n\n. It requires a per-file summary (path, what changed, why) and a fenced, language-tagged code block for every diff. I'll apply it: every change in this session gets that summary and a tagged diff block.\"\n\nThat's quoted + located + plan statement — level 2 proven. Then you watch the next output for level 3.\n\nThe asymmetry matters here: Claude Code can show you loading proof directly — `/context`\n\nlists what actually loaded. OpenCode doesn't have an equivalent shipped (there's an open issue asking for loading verification). Which means on OpenCode, this test isn't optional. It's the whole test.\n\nThis is the part that ended the blame-game for me, because the mechanism is documented.\n\nAnthropic's own memory docs describe `CLAUDE.md`\n\nas providing \"context, not enforced configuration.\" And they're explicit about what that means: there's \"no guarantee of strict compliance\" — the wording is right there in the docs for anyone to read.\n\nYour agent ignoring a rule you wrote is not a personal prompt failure. It's the documented behavior of a system where instructions are context rather than commands. That reframes the whole problem: the question isn't \"why is my agent broken,\" it's \"which lane is this rule in, and what does the fix look like when instructions aren't commands?\"\n\nAnd it's not just me saying it. The issue trackers are full of this exact failure — users reporting \"my agent quoted my rules back and ignored them,\" and the admissions go further. In one thread, a user counted 14+ corrections on a single rule before anything stuck. The demand set is real, current, and cross-harness: it's the \"I Told You\" Developer's situation, at scale.\n\nWhat finally fixed my migration wasn't a better prompt or stronger wording. It was re-declaring every rule, one by one, into a fresh `AGENTS.md`\n\n— the file OpenCode actually applies weight to.\n\nCopying files across hadn't worked. The old `CLAUDE.md`\n\ncame along, was read as a fallback, and was quotable without being load-bearing. The re-declaration was different because it moved the rules into the first-class file — and then I verified each one at level 2, and watched the output for level 3.\n\nHere's the shape the rule needed to take. This is a faithful reconstruction of the kind of rule that lived in the fallback `CLAUDE.md`\n\n— a paragraph buried in a file that held rules, context, and everything else:\n\nAlways present your output in a clear and professional format. Use code blocks where appropriate and make sure diffs are easy to read. Pay attention to formatting quality in all responses.\n\nVague, not checkable, one paragraph competing with every other paragraph in the file.\n\nAnd this is how the same rule reads re-declared in the fresh `AGENTS.md`\n\n:\n\nOutput format (required, no exceptions):\n\n- Every change is summarized as: file path, what changed, why.\n- Every diff is a fenced code block tagged with the language.\n- Never inline a diff without a code block.\n- When in doubt about the format, ask before outputting — do not improvise.\n\nEvery line is checkable — the summary either has the three parts or it doesn't; the diff either is fenced or isn't. Self-verifying by observation.\n\nIt was a one-time fix. The rules went into a fresh `AGENTS.md`\n\nonce, and the loaded-but-not-load-bearing state never came back. Since that day I've been fully settled on OpenCode — the fixes since have been minor.\n\nHere's the part I had to learn the hard way: **re-declaration fixes loading, not obedience.** If a rule is in Lane A, re-declaring it into the right file is the fix. If a rule is already in Lane B — loaded into the right file and still ignored — re-declaring it does nothing. Which brings us to the second fix.\n\nOnce you've confirmed a rule is genuinely loaded and still losing, the choice comes down to a single question:\n\n**Can I afford for this rule to lose?**\n\nIf the answer is yes — and the output-format rule from the previous section is exactly this kind — keep it in prose, but make sure it's shaped well: short, specific, prohibition-framed, impossible to misread. You can see the output either follows it or doesn't, so it's the right fit for the load-bearing file.\n\nIf the answer is no, prose is the wrong home for it. The rule can't afford a single loss, so it moves to the mechanical floor: hooks, deny rules, permission configs. Mechanisms can't be ignored because they're not asking the model to comply; they're intercepting the action. (Reporails' line captures it: *prompts steer, hooks enforce.*)\n\nYour own secrets rule is the perfect example — \"don't push secrets to git repos.\" (GitHub's analysis of 2,500+ repos found it the single most common rule in `AGENTS.md`\n\nfiles.) As prose, it's the weakest kind of rule:\n\nNever push secrets to the repository. Check for API keys and credentials before every commit.\n\nIt's not self-verifying by observation — a leaked secret looks like a normal commit. It's catastrophic when lost even once. And the docs' \"no guarantee of strict compliance\" means the model is never forced to check. It's a rule that begs to be ignored in a rushed session — which is exactly when secrets leak.\n\nSo the mechanical version:\n\n- A pre-push secret scan (a git-secrets / gitleaks style hook) that\nblocks the pushif a secret pattern matches.- A deny rule on the harness side (e.g., deny reading\n`.env`\n\n, deny the push action until the scan passes).`.env`\n\nin`.gitignore`\n\nas defense-in-depth.\n\nThe mechanism intercepts the action — the model isn't being asked to comply, so there's no \"strict compliance\" gap to exploit. The choice stops being abstract: one rule earns shaped prose, the other earns the floor.\n\nI'll be straight with you: I don't run a mechanical enforcement layer. My safety net is the memory loop — `AGENTS.md`\n\ntells the agent to read `MEMORY.md`\n\nat the start of every session and update it at the end ([the exact three-file system I built](https://dev.to/buildloops/i-built-a-session-log-that-survived-my-migration-heres-the-three-file-system-4bj6)), and that log is how I'd notice a rule starting to get ignored (the entries would begin to diverge from what the rules require). The escalation above is for rules you can't afford to lose, not the setup I run.\n\nAnd the takeaway that ties the series together: **rules are another thing you have to re-declare, not carry.** When your agent keeps making the same mistakes, the fix is the file that tells it how to work — and knowing what that file can and can't enforce is the difference between a rule that steers and a rule that decorates.\n\nOne more thing, because it's the case that misleads everyone.\n\nCompaction — when the context window gets rebuilt mid-session — re-injects the root `CLAUDE.md`\n\n. What it does not re-inject is nested or path-scoped rules, or rules that lived in files outside the root. The same goes for nested files in general: if a rule lives in a subdirectory that only loads in certain paths, and you switch harnesses, it can quietly drop out of the bundle.\n\nThe result looks exactly like Lane B. \"The agent just ignored my rule,\" you'll think, and start rewording a rule that never actually loaded — a Lane A costume on a Lane A failure. This is where the two-lane test matters most: diagnose before you reword. Quote-and-locate first. Only then decide whether the fix is re-declaration, redesign, or the mechanical floor.\n\nThe mystery at the top of this post — rules that worked, then quoted-and-ignored — resolved into something much simpler than I expected. Loaded ≠ obeyed. The file was loaded; the rules just weren't load-bearing. And once you see the failure as two lanes instead of one, the fix stops being a guessing game: re-declare if it never loaded; redesign or enforce if it loaded and lost.\n\nThe migration made both lanes visible at once. That's the only reason I can hand you the diagnostic instead of a longer list of things that didn't work. If your agent quotes your rules and ignores them, run the test — quote, locate, watch the output — and you'll know which lane you're in before you change a single word.\n\nRules are another thing you have to re-declare, not carry. If your agent keeps making the same mistakes, the fix is the file that tells it how to work — I wrote the playbook here: [Why Your Coding Agent Keeps Making the Same Mistakes — AGENTS.md Fixes It](https://dev.to/buildloops/agentsmd-is-programming-for-your-ai-agent-not-documentation-for-humans-1g4o).\n\nThis closes Break 1 of the migration diary ([what broke when I switched from Claude Code to OpenCode](https://dev.to/buildloops/i-migrated-my-claude-code-workflow-to-opencode-heres-what-broke-5ajc)). Next up: why skills silently degrade — the same failure class, different file.\n\nWhich of the two lanes are you stuck in? Quote the rule that still isn't obeyed in the comments and I'll tell you which one it is.", "url": "https://wpnews.pro/news/loaded-obeyed-why-your-agent-quotes-rules-it-doesn-t-follow", "canonical_source": "https://dev.to/buildloops/loaded-obeyed-why-your-agent-quotes-rules-it-doesnt-follow-2256", "published_at": "2026-08-09 13:00:00+00:00", "updated_at": "2026-08-09 13:10:36.137213+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "large-language-models"], "entities": ["Claude Code", "OpenCode"], "alternates": {"html": "https://wpnews.pro/news/loaded-obeyed-why-your-agent-quotes-rules-it-doesn-t-follow", "markdown": "https://wpnews.pro/news/loaded-obeyed-why-your-agent-quotes-rules-it-doesn-t-follow.md", "text": "https://wpnews.pro/news/loaded-obeyed-why-your-agent-quotes-rules-it-doesn-t-follow.txt", "jsonld": "https://wpnews.pro/news/loaded-obeyed-why-your-agent-quotes-rules-it-doesn-t-follow.jsonld"}}