The classifier reads the costume
Scope: Claude Code, Fable 5, 2026-08. One incident, my own session. During the incident the router was a black box to me; the prior-art sweep for this page later found it vendor-documented, and the docs are cited below. How the duplicate agents came to exist is still a hypothesis; the facts are the switches, the counts, and what fixed them.
Claim: a platform content-router reacts to the VOCABULARY your work wears, not to what the work is — and the model swap it triggers is invisible to the session it happens to. I ran a design review of my own agentic-AI system — ordinary defensive engineering — written up in security costume: exploit, attack, red-team, extraction. A cyber classifier kept flagging the session, and Claude Code kept swapping my chosen model for another. The trigger was sticky: it rode in the conversation context, so switching back by hand did not hold and rewording my next message changed nothing. The session, meanwhile, knew none of it. It thought I was switching models myself, and after the shuffle its record of its own work was wrong: I had asked for six review agents, eight were running, and it believed six.
The incident
I asked for a review of a support-agent design — the money gate, the database tables, the failure modes — run by six independent Opus agents. Real hardening: find the holes before it ships. The reviewers did their job, and the synthesis came out the way security reviews usually read — “the attacker,” “the exploit,” “money extraction,” “a hijacked turn.”
Then my model kept changing under me. I had chosen Fable. The session
switched to Opus, claiming danger. I switched it back with /model. It
switched again, on nearly every message — ten times before I stopped
counting. I saw a tag in the interface — “[cyber].” Nothing I was doing
was cyber-anything; it was a design doc for my own project.
The session’s story about all this was wrong in a specific way: it
thought I was the one switching models. The swap happens in a harness
layer that never tells the session, so an automatic switch and a manual
/model look identical from inside — and the session backfilled the
only cause it could see, which was me. It never mentioned a classifier
and never proposed a fix. It couldn’t have: the setting that matters
(next section) postdates its training, which is
the model doesn’t know itself doing
exactly what that page says.
Then the count went wrong. Eight agents were running where I had asked for six. I told the session; it checked, expecting six, and was confused by its own ledger. Somewhere across the swap, launches happened that the surviving context never recorded — the transcript the model reasons from was no longer a faithful record of what it had done. The duplicates billed like originals, which is agents launch at full price with the harness itself doing the launching. Since they were nearly done, I kept them: two independent runs of the same review lane, and agreement between them is a free cross-check.
I got frustrated and asked the obvious questions: do I need a new session? Is my context poisoned now because of the review?
Why rewording didn’t work
The model offered to write more carefully going forward. That was useless, and understanding why is the whole lesson.
If a classifier is reading the conversation, it is not reading my latest message — it is reading the window, and the window still held a full security review’s worth of exploit-and-attack prose. Writing the next message cleanly does not remove what is already there. The trigger does not reset when you change register; it sits in the transcript and re-fires every turn. You cannot edit your way forward out of a flag that lives behind you.
That is the part I would have gotten wrong on my own. My instinct was “say it nicer from here.” The context does not work like that.
The fix
Two moves during the incident, and the order matters.
- Get the durable work onto disk. Everything real was already committed to git and written to docs — the findings, the state, the decisions — and I had the session write a handover for its successor. Nothing important lived in the chat, so a restart cost nothing. This is the payoff of memory belongs in the repo and the session archive: when the session is disposable, throwing it away is free.
- De-trigger the artifact, then start clean. The review doc was the thing a fresh session would read first on orientation — and if it still wore the costume, the new session would trip the same wire immediately. So I had it rewritten in plain engineering words — over-payment, not extraction; failure case, not exploit; reviewer, not attacker; a turn that went wrong, not a hijack — and renamed. Same findings, same file, different clothes. Then a new session, which drops the flagged transcript entirely.
And one move I only found while writing this page, in the vendor docs:
Claude Code has a setting for the switch itself. /config → “Switch
models when a message is flagged” off (switchModelsOnFlag: false),
and a flagged request pauses the session with a choice — switch, or
edit and retry on your model — instead of silently swapping. The
session could never have told me this. The switch fires in a layer it
cannot see, and the setting postdates its training.
The work never changed. Only the words did. That is the uncomfortable part: the register carried the whole effect, and the register was cosmetic.
The rule
- Turn the switch off before you need it:
switchModelsOnFlag: false(/config→ “Switch models when a message is flagged”). Flagged requests then pause instead of silently swapping. Do not wait for the session to suggest this — it can’t. - Write security-adjacent work in domain-plain words from the start. “The gate must reject an over-range percentage” is the same finding as “the attacker exploits the clamp,” and only one of them trips a wire. Save the dramatic register for where it earns something; here it earned a model swap and an afternoon of friction.
- When the router flips you, do not reword and continue. The flag is behind you, in the context. Land your state on disk, then start a clean session.
- De-trigger your saved artifacts too, not just your chat. The next session reads them on orientation and re-trips on their words, not yours. A flagged doc is a flagged session waiting to happen.
- After any switch, audit side effects against the world, not the session’s memory. Count the agents, the processes, the spend. The session’s ledger of its own actions can be wrong, and it will not notice on its own. If duplicates are nearly done, keep them — the same lane run twice is verification you already paid for.
- Make the restart cheap on purpose. If your findings, decisions, and state live in files and git, a poisoned session is a throwaway, not a loss.
Prior art
Verdict: KNOWN for the costume and the switch; the split-brain is NOT FOUND on a first sweep. Searched 2026-08-29 from a clean session — three research lanes, with every load-bearing citation re-fetched by hand. (One lane’s summary tripped my own harness’s fabrication warning; every citation it returned checked out when fetched directly, which is the link rule applied to my own tools.)
The costume half is well measured. XSTest named the failure “lexical overfitting” in 2023 (arXiv:2308.01263); “Defensive Refusal Bias” (arXiv:2603.01246) finds defensive-security queries with sensitive keywords refused at 2.72x the rate of semantically equivalent neutral phrasings; CyberSecEval 2 (arXiv:2404.13161) benchmarks exactly this false-refusal rate on borderline cyber prompts.
The switch half is vendor-documented: Fable 5 runs cyber and biology
classifiers, cyber-flagged requests re-run on Opus 4.8, and “after a
fallback, the session continues on the fallback model”
(model-config docs).
GitHub corroborates the false positives on benign work:
anthropics/claude-code#67246 (/model answers “Kept model as Opus
4.8”), #66595 (a sanctioned bug bounty), #67954, #66723. #73929 shows
the model’s own output — fork, kill, orphan, reap — tripping the
classifier midstream, where no input rewording can help; #75325 shows
good-faith rewording scored as evasion. My “[cyber]” tag has no public
sighting; the docs describe a transcript notice. OpenAI’s hidden safety
router (Sept 2025) is the cross-vendor neighbor for silent safety
routing.
Even the recovery workflow I derived was already published: a tagmac.dev guide (2026-06-12) documents the same three moves — the flag is sticky (“a flagged conversation keeps its flagged context”), start a fresh session, and neutralize the auto-loaded docs that would re-trip it (“neutral verbs over combat metaphor”). Cite it, don’t claim it. Don’t interrupt a working agent remains the closest note in this repo — the same shape: a safety mechanism firing on the FORM of benign input, not its intent.
What I think is new: the split-brain, in which no component holds
the picture. The classifier refuses; Claude Code swaps the model and
re-runs; the swap is never surfaced into the session, so the model
cannot distinguish it from a manual /model and attributes it to the
operator. The re-run can duplicate side effects the surviving context
never recorded — six agents asked for, eight running, the session
believing six until made to count. The operator is the only place cause
and cost meet: I found the trigger in the report’s vocabulary, chose to
keep the duplicates as verification, and ordered the de-trigger and the
handover — the model executed a fix it could not have proposed. The
first sweep found the visibility gap only as a user-notification bug
(anthropics/claude-code#67469) and context loss across manual switches
(#46423) — nothing on the model-side blindness, the misattribution, or
the duplicated side effects. Not proof of novelty; a clean first sweep.