◂ writeups // michaelz.dev

The Word That Broke My Assistant

I have a single question box for my house. You type anything into it and something sensible comes back. It works by first deciding what kind of question you asked, then sending it to whichever system actually knows. One evening I asked it about a script, and it answered me confidently, with correct sources, about a completely different subject. The entire cause was one very ordinary English word.

One front door, four back rooms

The design is deliberately boring. There are four kinds of question my house can answer, and four different systems that own the truth for each:

  • Is it up right now? → ask the service directly.
  • What changed recently? → ask the change ledger.
  • Has this happened before? → ask the incident history.
  • Anything else → search my notes and code, and have a model summarise.

That last one is the default, on purpose. Anything the three specific rooms don't claim goes to the notes, because searching notes is the only one of the four that can usefully say "I don't know".

Routing is done by looking for words. "Has this happened before?" is obviously a history question. So before lives on the history list.

The question that went wrong

I asked:

In the seed reaper script, what conditions must be met before a torrent is removed?

And got back:

No incidents recorded for that service in the last 30 days. Last known state: healthy.

Read that exchange again, because the shape of it is the whole point. The answer is true. It is correctly sourced — it really did come from the incident history, which really does have no incidents. It is fluent. It carries no error, no warning, no low-confidence marker. Every quality signal you might use to sniff out a bad answer is present and positive.

It's just an answer to a question I didn't ask.

My question contained the word "before" — not in the sense of has this occurred previously, but in the ordinary sequencing sense of this happens before that. The router saw the word, filed it as history, and the history system did its job perfectly on a question that was never meant for it.

A fluent wrong answer is worse than an error, because nothing marks it as wrong. An error interrupts you. This just gets believed.

The fix is grammar, not vocabulary

The tempting fix is to remove before from the list. That breaks the real history questions, which are common and useful.

The actual answer turned out to be positional. Say these out loud:

  • "Has the network card failed before?" — temporal. The word ends the sentence.
  • "…what must be true before a file is deleted?" — sequencing. A clause always follows it.

That's a reliable discriminator, and it's not a hack: it reflects something genuinely true about how the word works in English. Anchor it to the end of the sentence and both readings coexist happily.

So I went looking for its friends

Having found one ambiguous word, I had no reason to think it was the only one. I wrote out nineteen realistic phrasings — things I'd actually type — and ran them all through the router. Nine went to the wrong room.

again was much worse than before, and worse in a way I hadn't anticipated: its bad case is the common one. There's a completely different meaning of "again" that has nothing to do with recurrence — the conversational one that means remind me:

  • "What port is that service on again?"
  • "How does the reaper work again?"
  • "Where does the certificate authority live again?"

Every single one of those went to the incident history. And I type sentences like that constantly — it's how you talk to something you expect to know your house.

Here the positional trick doesn't work, because both meanings can end the sentence: "has it crashed again?" and "how does it work again?". What separates them is the shape of the question. The history sense is a yes/no question — has, did, is — asking whether something occurred. The remind-me sense opens with how, what, where — asking to be told something. Different words, different discriminators.

One important asymmetry: that yes/no rule can only apply to the ambiguous words. "What happened to the media server?" opens with a question word and is unmistakably a history question. Apply the rule too broadly and you break the clear cases while fixing the murky ones.

And then the good one

The audit turned up a third word I hadn't suspected, and it isn't a vocabulary problem at all.

alive is on the "is it up right now?" list, for obvious reasons. Which means this question:

What is the keep-alive setting on that box?

…triggered a live status probe. Because alive appears inside keep-alive, and a hyphen counts as a word boundary. The router saw a word it recognised, sitting inside a completely unrelated compound word.

My favourite detail in this entire investigation: the same setting written as KEEP_ALIVE — with an underscore — routed correctly the whole time. An underscore is a word character. A hyphen isn't. Same concept, same sentence, opposite outcome, decided entirely by punctuation.

This one had been broken since the beginning. It had just never surfaced, because sentences about keep-alive settings tended to also contain a history word, which claimed them first. Fixing one bug uncovered an older one that had been hiding behind it.

Proving a fix by breaking it

All nineteen phrasings are now a test that runs with the rest of the suite. Before trusting it, I ran it against the old code — the version with the bugs still in — to watch it fail. It did, naming the exact sentences.

This sounds pedantic and it isn't. A test that passes both before and after your change has proved nothing whatsoever; it's decoration that looks like diligence. The only way to know a test is load-bearing is to see it go red against the broken thing it's meant to catch.

The last twist

With everything fixed, I asked a fresh question to confirm — a "remind me" phrasing, about a setting I'd changed hours earlier. It routed correctly, cited exactly the right pages, and gave me the wrong number.

Brief moment of despair. Then I checked the pages it cited, and they said the wrong number too. The setting had moved twice; the documentation had followed neither time. The retrieval was flawless. It faithfully repeated what my own notes said, and my notes were out of date.

A retrieval system is a mirror. Before you debug the search, check whether the corpus simply says the wrong thing.

So the evening produced three routing bugs and two stale documents, and the documents were arguably the more embarrassing find — because unlike the router, they were wrong in a way no amount of clever engineering was ever going to fix.

What I'd take from this

Keyword routing is a perfectly reasonable technique, and I'm not replacing it with something bigger. What I'd do differently is add a habit: every time a word goes on a list, ask what that word does in a sentence that isn't about this category. "Before" means two things. "Again" means two things, and the second one is how people actually talk. "Alive" hides inside other words.

And the broader one, which applies to anything that answers questions in sentences: plausibility is not a quality signal. The failure mode of these systems isn't gibberish. It's a fluent, well-sourced, confidently delivered answer to a question you didn't ask — and the more polished the surface, the longer it takes anyone to notice.

Comments

◂ all writeups michaelz.dev ▸