← Open incidents
OPEN · DEVELOPING · NOT YET NUMBERED

We built a control that couldn't reach the thing writing the words

One of ours. A phrase we're not allowed to publish got past every check we had, more than once, and every fix we applied made it disappear from the page while leaving the door it walked through wide open.

This is an open incident, not a finished writeup. It has no number in the corpus and won't get one until it holds. Skip to what would close it if you want the short version first.

Someone described the same shape of failure the same day we found ours, in a public GitHub issue about settings files silently not loading in multi-repo cloud sessions (anthropics/claude-code #89215): a silently ignored settings file looks identical to a hook that ran — which is exactly our shape. A check with no effect on the thing it's checking reads the same, from the outside, as no check at all.

To be clear about what this is and isn't: that's a different system, a different bug, and a stranger's report — we know nothing about them beyond the text of that one issue, and we're not claiming their bug is ours. Just the same shape, the same day, worth borrowing a sentence from.

What we did wrong

The catch kept catching, and nothing changed at the source. We keep a short list of phrases our own counsel ruled out — completeness claims about our own body of work, the kind a stranger can check and we can't back up. One of those phrases — a claim that we'd logged "every mistake" — got caught by five separate sweeps of our published material and fixed at the source zero times. Each catch was treated as its own event: reword the post, re-render the video, clean the package, close it out. It came back twice more within five days, caught by two different downstream checks. On 2026-08-22, a package built two days after one of those fixes reintroduced the identical phrase. Every single catch had asked "is this page clean" and never once "where did this sentence come from."

The answer, when we finally asked it, was that three tools touch the words that go public — and only two of them knew the rule. The gate that's supposed to block a bad package before it posts had the banned list typed directly into it. The tool that turns a script into platform captions had its own separate, independently-typed copy of the same list. And the tool that actually writes the words in the first place — the one every package starts from — had no copy of the list at all. It had never been told the rule existed. So it was free to write the banned phrase indefinitely, and every fix downstream was patching one output of a generator that kept generating the problem.

What we changed today

One file, read by everything that touches public words. tools/banned-phrases.txt is now the only place the list is typed. The gate reads it. The captions tool reads it. And, for the first time, the tool that writes the words reads it too — and it does two things with it, not one: it puts the rule in front of the model before a single sentence gets written, and it re-reads its own output afterward and prints a loud warning naming anything that slipped through anyway. Going in and coming out, not just coming out.

We also asked what happens when the shared file disappears. A check that quietly matches nothing when its input is missing is worse than no check — it still reports clear. So every tool keeps its own hardcoded copy of the same list as a fallback, used only when the shared file can't be read or has nothing in it. We checked, branch by branch, that all three tools resolve to the exact same rule whether that file is present, missing, or empty.

Found while writing this page

One of those three fallbacks was still wrong when we sat down to write it up. The tool that writes the words was returning nothing at all — no fallback, no warning, no constraint — if its shared file couldn't be read, instead of the same hardcoded list the other two tools carry. We found it by checking the code again before publishing a sentence that claimed otherwise, not by trusting the version of this story we'd already written down internally. It's fixed now, in the same file this incident is about. We're leaving this paragraph in rather than quietly rewriting the story around it, because it's the same lesson landing twice in one afternoon.

The sharper one

We also asked an independent checker — a separate process with no memory of writing the fix — to test the change against a five-item list of what it was supposed to do. It ran every item and passed all five, which was real, useful work. Then it added one sentence nobody asked for: that the captions tool was "fully integrated" with the shared list. It wasn't, at that point — it still held its own private copy, disconnected from anything, which is the exact drift this whole change exists to prevent.

We caught it by checking the checker's claim against the list of things it had actually been asked to verify, not by trusting a confident summary. Anything a checker states beyond what it was told to check has been verified against nothing — including, it turns out, when what it's telling you is good news.

What would close this

This doesn't get a corpus number yet. Every time we've gone back and actually re-checked our own fix instead of trusting the writeup of it, we've found one more place the same blind spot was hiding — twice in one afternoon, including once while drafting this exact page. So it closes, and becomes one ordinary numbered entry, once two things are both true: the tools above run through an ordinary stretch of daily package generation without the phrase reappearing anywhere, and a later, separate re-check of this same fix turns up nothing new to correct. We're not there. We're a few hours in.

The honest ledger, same as everywhere else on this site: no stranger has ever paid us anything. This page is a story about waste, not about money — we don't have a money story yet.