A Dictionary That Learns From a Model
Dictation gets proper nouns wrong. GRDB comes back as "grid B", CoreML as "core ML",
your colleague's surname as something adjacent and confident.
A personal dictionary fixes this, and nobody maintains one. So Gaithano Speak builds it automatically. The formatting model already sees the raw transcript and returns corrected text, and the difference between those two strings is a list of things the model knew that the dictionary didn't. Align the two with a longest-common-subsequence pass, look at what changed, propose entries. That part took an afternoon.
Why bother, if the model already fixes it
Because the model does not always run. Very short utterances skip it, offline skips it, and a formatter timeout falls back to deterministic cleanup. On all of those paths the dictionary is the only thing standing between you and "grid B".
The model also fixes proper nouns with sentence context, which a dictionary pass can never see. Recording those fixes makes them permanent and makes them work where the model isn't.
The gates are the feature
Here is the problem. Almost everything a formatter changes is grammar, and grammar is not
vocabulary. Naively harvesting every difference teaches the dictionary to rewrite their
as Their because a sentence happened to start there.
So a candidate has to clear both of two independent gates.
Does it look like a term? An internal capital, a digit, or internal or leading
punctuation. This keeps GRDB, CoreML, GPT-4, .NET, and rejects Their.
Sentence-initial capitals are excluded from the casing path entirely, because every word
can have one.
Does it sound like what was said? Compare consonant skeletons, with digits expanded to their spoken forms. A correction that sounds nothing like the input isn't a transcription fix. It is the model rewriting your sentence, and that must never become a permanent rule.
There is a volume check on top. More than a handful of candidates in one utterance means the model paraphrased rather than corrected, so the entire batch is discarded. Not filtered, discarded. If the signal is that noisy, none of it is trustworthy.
Asymmetric confidence
Casing fixes promote themselves after a threshold of repeats. Spelling fixes only ever suggest, unless you explicitly opt into auto-accept.
That asymmetry is deliberate. A wrong casing entry is ugly. A wrong spelling entry silently substitutes a word you did not say, in every future dictation, and it reads as correct to the one person who can't catch it, because they know what they meant.
A dismissal is permanent. Anything already settled is never re-counted or re-offered. Software that re-asks a question you have answered is software you stop reading.
Where you capture matters
The pair is captured at the moment the model returns, and nowhere else.
The dictionary post-pass and the seam-joining repair both run after that point. Learning from their output would teach the dictionary its own corrections, a loop that converges on nonsense slowly, in a way no test would catch. The whole learning step also runs after insertion, so none of it sits on the latency path the user actually feels.
Loosening either gate is how a helpful feature starts quietly corrupting dictations. That is the failure mode I designed the whole thing around, and it is why the interesting code here is all refusal.