The narrowest question
Anyone at the table may talk into the card: Dad, the person serving him, a friend leaning in. Before Pippa writes a word, the engine has to decide which way this sentence goes. That sounds like language identification, a hard problem with a long tail. It is much smaller than that, because Dad speaks Korean. The rule only needs to know one thing: is this Korean or not?
- Korean in is Dad speaking. It goes out in the other person's language, as a card for them.
- Anything else in is theirs. It comes back in Korean, for Dad.
Two signals answer the question, in a fixed order. First, the language Scribe named when it committed the transcript. When Scribe named none, the script decides: Hangul anywhere in the words means Korean. The returned direction records which one decided, in by: scribe, script, or dad when Dad flipped it.
Reading the function
The first excerpt below is the whole rule. A few details deserve a slow read.
_primary lowercases a tag, keeps only its first subtag, and folds three-letter codes to two. That folding exists because Scribe speaks two dialects. Its realtime model and every card use ISO 639-1 (es), while its batch model, used when the engine transcribes a kept recording itself, names languages in ISO 639-3 (spa). The sitting keeps the short form, so spa, es and es-ES all compare equal.
The Hangul pattern covers three Unicode ranges: the precomposed syllables, the conjoining jamo, and the compatibility jamo. A word typed on a phone and a transcript that came out as loose jamo both count.
When the speaker is Dad, the target is the counterpart's language, taken from the sitting's scene language. When the speaker is the other person, the source is whatever was detected, and the target is always Korean. One odd case is handled on purpose: a flip that turns Korean words into "theirs" would leave the source as Korean, so the function substitutes the counterpart's language instead.
And when nothing names a language and there is no Hangul, the answer is "other, source unknown, into Korean". The engine does not guess the name. Pippa's refined result carries its own BCP-47 language tag, and that names it.
The counterpart's language moves
The sitting's scene language is a live value. It starts as the card's language, or a blank card's best guess. When the other person speaks a language Scribe names, and it differs from the scene language, the engine writes it to the moment before anything else happens, so Dad's next card is in it. Ask for the bill in Spanish, get an answer in English, and the next thing Dad says comes out in English.
A blank sitting where Dad speaks first works the other way round: Pippa picks "the language of the place" for his first card, and the language she wrote it in becomes the sitting's.
One tap to flip
Any rule this small will sometimes be wrong. A Korean speaker answering Dad in Korean, or Dad trying out a phrase in the other language. So every exchange shows its direction as a chip, and a tap posts a new utterance with flip_of set to the earlier exchange. That new turn reads the same words and language from the turn it flips, and inverts the speaker. The original stays in the record. The test for it asserts that the sitting now holds two heard results with the same words, which is the honest history: it was heard once, read once each way.
Note what is not in the rule. The design first named two tie-breakers: Pippa's own reading of the words, and the speaker ear, cwkPippa's local check of whether a voice is Dad's. Neither was needed for a yes-or-no question about Korean, and leaving the ear out keeps a stranger's voice away from the one service that embeds voices.
The design also measured whether to hint Scribe. With no fixed language and detection on, six utterances spoken by macOS voices (three Spanish, two Korean, one English), each run twice, were labeled right 12 times out of 12. Adding Korean and Spanish as secondary languages made the English one come back labeled Korean: one wrong out of six. So the socket opens with no hint at all.
Dad practicing
The next-to-last assertion in the test reads Quiero agua, tagged Spanish, and expects Korean as the target. Dad practicing his Spanish is read back to him in Korean, which is the useful direction: he hears what he actually said. If he meant it as a card for the waiter, the chip is right there.