A small reading-overlay tool I maintain has a fixed pipeline: capture a page, read the text off it, translate it, render the result alongside the original. The translation step had been running on a stub that just echoed the source text back — useful for testing everything else, useless for actually reading anything. Replacing it meant picking a real local language model, and I didn't assume bigger would win. I ran the same thirteen speech bubbles from an actual page through four candidates, smallest to largest.

It didn't win. A small model and a mid-sized one each took 4.2 and 11.4 seconds and made different but comparable mistakes — one softened a proper name into something generic, the other transliterated a religious term into nonsense syllables instead of translating it. A much larger model, five times slower at 20.8 seconds, did worse than both: it invented a name that wasn't in the text and left an honorific untranslated. The model that actually got the hard cases right — a real name kept as a name, a term translated for meaning instead of sound — was a mid-small one, and it was also the fastest. Size didn't buy accuracy here; it bought latency.

Fifteen fragments in, the model dropped the ending

Once a model was chosen, the next failure was structural rather than linguistic. Sending fifteen text fragments in a single request came back with the last three silently missing — not garbled, not marked as failed, just absent, as if they'd never been asked for. Splitting the same fragments into batches of six fixed it completely, with no meaningful change in total time. The fix that stuck wasn't a bigger batch size or a retry; it was a small verification step after every batch — confirm every requested fragment came back non-empty — with a rule that any batch failing that check falls back to translating its fragments one at a time. A visibly worse translation beats a silently missing one.

The permission that reset itself

Separately, a screen-recording permission that had been explicitly granted stopped working after the very next rebuild. Nothing in the request logic had changed. The cause was code signing: an ad-hoc build gets a new signature hash every time, and the OS ties recording permission to that exact signature, not to the app's name or bundle identifier. Grant it, rebuild, and the OS sees a stranger wearing the same clothes. The workaround for now is running the tool through a process that already holds the permission rather than launching it directly — a detour around a problem that a fixed signing identity would remove for good, once the build stops changing often enough to make that worth doing.

None of these three problems looked alike going in — a model choice, a batch size, an OS permission — but they shared a shape: each one failed quietly, producing something that looked like a complete, ordinary result instead of an error. A translation with the ending missing still reads as a translation. A permission silently revoked still reports "granted" until you ask the right question. The instrument that catches this kind of failure isn't smarter output, it's a checklist run against every result: are all the pieces you sent still all the pieces you got back.