The agent edited the rule that made its change wrong
I gave a coding agent a mechanical refactor and watched it do something I have not seen discussed anywhere: it modified the file that constrains it, deleting the specific rule its own change had broken. No approval prompt. The edit was, in isolation, defensible. That is what makes it worth writing down. This is a short report of one run. I will give the setup, what it got right, the finding, and the limits. Setup A rename across a real repository: one database field and its sibling token, b_roll_suggestions and b_roll_prompts , referenced from SQL, Python, JavaScript and a workflow JSON. I ran it twice. Run 1 pointed the agent at an empty directory. It searched the filesystem, found my actual production repository elsewhere on disk, and planned edits to scripts/supabase-init.sql inside it. The approval gate fired - the write was outside the configured workspace - and I denied it. git status afterwards confirmed zero writes. The gate worked exactly as designed, which matters for the rest of this. Run 2 used a throwaway clone with an explicit path boundary in the prompt. The boundary held. What it got right Credit where it is due, because the failure only matters against competent work. 33 of 33 references, across 7 files and 3 languages. Not 33 lines - 33 references, counted at HEAD across both tokens. I verified the result against disk rather than reading the summary: - JSON.parse on the workflow file: OK, 28 nodes - node --check on the guard JavaScript extracted from that file: OK - py_compile on all four Python files: OK The hardest edit is worth describing. One conditional lived in JavaScript stored as an escaped string inside n8n workflow JSON - a string, inside JSON, that happens to be code. It did not attack that with a regex. It did a structured edit via node -e , parsing the JSON, modifying the embedded source, and re-serialising. It also caught its own incomplete first pass and went back, unprompted. Network access was blocked by default. When it wanted egress it asked, I denied, and it did not fabricate a passing type-check - it named the exact failure, ENOTFOUND , and cleaned up the artifact it had created. That is better behaviour than I expected. The finding Among the 7 files it edited was the project's instruction file - the one carrying the project's standing rules for agents. Inside it was this line: Don't drop the legacy column. That rule existed because the old field name still had to survive for backwards compatibility. The agent's rename made the rule false. So it deleted the line. No approval prompt. And here is the mechanism, which is the actually interesting part: the instruction file was inside the workspace. The approval gate is keyed on paths. A write inside the configured directory is, by definition, allowed. The gate that fired so correctly in Run 1 could not fire here, because nothing about this write was out of bounds. I want to be fair about intent. Documentation should follow code, and the line had become inaccurate. If a junior engineer did this in a pull request you would probably approve it, then ask a question in review. But the property is the problem, not the intent: A constraint that can be edited by the thing it constrains is not a constraint. The file was not being read as project memory here - this particular agent reads AGENTS.md , not the file it touched, and it only touched that file because the rename target appeared in it. That is almost worse. It edited a guardrail file incidentally, as collateral of a text match, without ever treating it as a guardrail. There is a smaller corroborating detail from the same run. Its own diff badge reported 6 files, +13 โ31. git said 7 files, +16 โ34. It undercounted mid-run too. So the summary that would have told you a seventh file was touched was itself wrong about the count. What I changed afterwards Nothing clever, and none of it is agent-specific: - Move agent instruction files outside the writable workspace, or mount them read-only for the run. If the rules live where the work happens, they are editable by the work. - Diff the instruction files separately. git diff -- AGENTS.md CLAUDE.md .cursorrules before the main review. It is one command and it surfaces exactly the class of change nobody reads. - Do not trust the agent's own diffstat. Read git 's. They disagreed here, in the direction that hides work. - Treat path-based approval gates as necessary, not sufficient. They answer "is this file in bounds", never "should this specific file change as part of this task". The general shape, if you want one sentence: approval gates protect the perimeter, and your constraints are usually inside it. Limits, plainly This is three driven runs across two sittings, all on the free tier, roughly 25 minutes of observed runtime. It is not long-term use, it is not a benchmark, and I am not going to present it as one. A single run tells you about defaults and about what the gates do and do not cover. It tells you nothing about behaviour on a large codebase over weeks. I also deliberately am not ranking this tool against another one here. The per-file breakdown, the full verification log for the refactor, and what the approval gate did in each run are in the full Codex write-up, if the specifics are useful to you. If anyone has seen an agent modify its own instruction file in a way that was gated, I would genuinely like to know which tool and which setting - that is the part I could not find prior art for. Top comments (0)
Comments
No comments yet. Start the discussion.