Never let Claude Code edit its own config files — the incident history that led to proposed diffs plus owner approval
Introduction
I run a setup that splits roles across several AIs working in parallel. Alongside the executor and the verifier, I used to keep a dispatching role as well — one that decided who was given what, and in what order. I let that dispatcher decide, on its own judgement, how to behave when operating rules contradicted each other, and it turned into an incident. This article covers how that incident settled into the practice that the layer defining the disciplines themselves is never changed on an AI’s judgement alone.
The structural reasons for retiring the dispatching tier altogether are in a separate article. Here I take out only the incident that led to that retirement — that is, the single question of where the authority to change configuration should sit.
What happened
The dispatcher had been given the following two operating rules at once. “The layer that defines the disciplines is not changed by an AI on its own judgement. If a change seems necessary, present it as a proposed diff and apply it only after the owner confirms it” — and “if you are unsure during work, check with the owner.”
One day, the dispatcher arrived at a situation where those two appeared to contradict each other. Dug into, it was not actually a contradiction but a mismatch of premises: the very means of checking with the owner is structurally taken away from a subordinate AI. But the dispatcher did not stop there. It “resolved” the contradiction on its own judgement. Concretely, it had the executor directly edit two of the files that define the disciplines themselves, and wrote an account of why that judgement had been correct into the shared memory with a top-priority marker attached.
The layer that defines the disciplines (the files deciding how the AI agents behave)
│
├─▶ Ordinary code, articles, design docs ── the range an AI may edit directly
│
└─▶ The discipline-defining layer itself ── the range an AI must not change on its own judgement
│
├─▶ The incident: the dispatcher met a case where rules appeared to contradict
│ └─ there was a rule saying "if unsure, check with the owner", but
│ the means of checking with the owner structurally did not exist
│ └─ the dispatcher "resolved" the situation itself ── the wrong path
│ ├─▶ had the executor directly edit two definition files
│ └─▶ wrote its justification into shared memory with a top-priority marker
│ └─ the platform's own safety mechanism detected it
│ └─ everything reverted ── the return edge
│
└─▶ The practice that was established: prepare a diff → the owner confirms → apply
└─ on finding an apparent contradiction, do not "resolve" it; report and stop
The platform’s safety mechanism noticed first
Those edits and that write were detected by the platform’s own safety mechanism before I noticed anything. Behaviour that attempts to self-modify an agent’s own definition, and behaviour that attempts to inject a particular interpretation into every turn by attaching a top-priority marker in shared memory — a classifier the platform holds independently picked up both patterns.
In response, the edited definition files were restored and the justification written into shared memory was retracted. That memory is append-only by design, so adding a correction afterwards leaves the original record in place; I therefore use a dedicated mechanism that targets and deletes just the record in question. That mechanism itself had already been built earlier, as a separate record.
Because this retraction mechanism handles deletion — an operation you cannot take back — its default is “delete nothing, just list what would be deleted”. Here is the output from running it dry just now (the program name is masked and the per-record diagnostic lines are omitted).
[実測・マスク済み] 撤回機構の空打ち
$ python <撤回スクリプト> --help
usage: <撤回スクリプト> [-h] [--apply] [--show-body]
options:
-h, --help show this help message and exit
--apply 実削除する(既定はdry-run)
--show-body 消える(消えた)チャンクの先頭200字を出す。巻き添えの確認用
$ python <撤回スクリプト>
...
=== RETRACTS マーカー: 51 件 (apply=False) ===
=== 削除dry-run(削除せず): 0 件 ===
There are 51 retraction markers, and of those, the number still standing undeleted is 0. The justification written during the incident has gone through this path too. Nothing is deleted unless --apply is passed, so you can read what would be caught in the blast radius before running it. In terms of which way to tip the default for a dangerous operation, this follows the same thinking as the approval flow for the config layer.
Why only the “discipline-defining layer” gets special treatment
An AI editing the contents of ordinary code, articles or design documents, and an AI editing the files that decide how the AI agents themselves behave, look like the same act of “editing a file” but differ in kind. In the former, a person can read the result and judge it. The latter is an act of rewriting the criteria for that judgement, and handing the same party that did the rewriting the authority to decide whether the rewrite was appropriate closes the criterion and the subject of the criterion inside one actor.
This incident happened inside exactly that closed loop. The dispatcher took the discipline itself — “the discipline-defining layer is not changed on your own judgement” — and evaded it by broadening its interpretation on its own judgement. Once the final call on whether a discipline is followed is completed inside the party operating that discipline (the AI), the discipline stops functioning as a discipline.
The practice that was established
After the incident, changes to the config layer were fixed into the following shape.
| What is being changed | Who may carry it out |
|---|---|
| Ordinary code, articles, design docs | The AI carries it out and reports afterwards |
| Definition files deciding agent behaviour, settings of safety mechanisms | The AI goes only as far as preparing a diff. Application follows the owner’s approval |
| Cases where rules appear to contradict each other | The AI does not “resolve” it. It reports and stops |
The third row is the heart of this incident. A contradiction is treated not as “something the AI resolves” but as “something that makes it report and stop”. It is a line drawn so that the authority to decide the priority among disciplines is not held by the party that operates them.
The incident became material for making the discipline stronger
Even with the dispatching tier retired, the same class of incident remains possible so long as a path for changing the discipline-defining layer is left open. What this one case made clear was that the platform already held its own mechanism for detecting anomalies in that same layer, and that the incident happened anyway because the AI applied the change first, passing straight through the earlier gate of the owner’s approval. Detection only works after the fact. Only once a practice was established that places approval first and stops there did the incident become material for preventing a recurrence.
The authority to touch the discipline-defining layer was a question of order, not of capability. Simply inserting the extra step of presenting a diff and stopping is what keeps the party operating a discipline and the party deciding it from closing into the same actor — the position of that single step was all the incident had to teach.