"The latency is certain. A typed turn, I barely feel it. It's only slow when I chat in voice mode, phone or web." — Dad, Málaga, 2026-10-18
From the Road, Again
The first lesson of this track measured a turn at a desk, on office's own network. Three weeks later Dad was talking to Pippa from hotel Wi-Fi and LTE in Spain, and the numbers he lived with were not the ones in that lesson. His first verdict on Lightning (Track 3's newest lesson) was blunt: it was no use at all, and the wait before thinking even began was long on every brain. So the house measured again, stage by stage, on the night of 2026-10-18, and this time it measured both sides of the request, not only office's.
Where a Spoken Turn's Time Went
| stage | what it is | cost that night |
|---|---|---|
| end of speech | Scribe's silence window, Dad's setting | 3 s by default |
| noisy-place re-read | the batch model reads the utterance again | about 1 s, only in noisy mode |
| speaker check | the recording to cwkBellows' ear (Track 8) | 1.4–3.9 s |
| retrieval | embed 0.1 s, then the 4B reranker on one thread | 2–9 s |
| system prompt build | cached vault base | 0.3–0.8 s, hidden behind retrieval |
| Claude CLI start | spawn, connect, the CLI's own init | init at 13.7–41 s |
| provider to first token | Lightning in Master Chief (~280K tokens), cold / warm cache | 12–13 s / 2.3–5 s |
| Claude Opus in Master Chief (~400K tokens, nearly all cached) | 7.5–10 s after init | |
| each tool call | a Claude shell or MCP tool | about 10 s |
| first audio | prepare plus the stream's first byte | 0.9–1.6 s |
Two of those rows are not Pippa's code, and the design doc says so: the CLI's slow init and its ten seconds per tool both traced to office's file-watch daemon, a host problem filed with the fleet's own issue tracker. The rows that were Pippa's had a shape anyone could see once they sat in one table. The speaker check and retrieval ran one after the other, so a Master Chief voice turn's preparation read 5.4 to 8.7 seconds.
Side by Side, and Heard Early
Every chat route now starts retrieval before the speaker check (an EarlyRag that the route collects later), so the preparation costs the longer of the two instead of their sum. The order that matters is untouched: the speaker check still rules the turn before Dad's row is stored, and if the final query or scope differs from the one retrieval started on, the early answer is thrown away and the route runs its own. The check itself moved earlier too. The phone uploads its 16 kHz take 20 to 45 seconds before the turn, so the upload route now hears it there, and the turn takes that answer when it arrives. On the web the upload and the turn land in the same second, so /api/stt keeps the recording before Scribe runs and starts the check beside it. After both, the route's own lines read 1.1 to 3.3 seconds of preparation with the speaker check at zero, voice and typed turns alike.
The Voice Lane for Memory
The second lesson of this track closed on a ruling: memory quality comes first, and half a second to two seconds is meaningless unless it is voice mode. The 4B reranker stayed, and the faster options were measured and declined. On 2026-10-18 Dad used the clause he had written into that ruling. The reranker became an Admin pick with a pick of its own for spoken turns: rag_rerank_model for written turns (empty means the server's configured model) and rag_rerank_voice_model for spoken ones, Lightning included (empty means the written pick). The choices are read live from the model server, which refuses a model it does not list, and the phone's Settings carries the same two picks. Dad set the voice lane to the 0.6B reranker. A short spoken retrieval went from 2.74 seconds on the 4B to 0.63 on the 0.6B. Written turns still rank with the 4B.
The price is the one that lesson measured: on those 20 prompts the 0.6B kept about three quarters of the chunks the 4B retrieved. That price is now paid on spoken turns only, it was chosen by the person who pays it, and every turn says what it paid: the route's [turn-prep] line names the reranker lane and model it used.
One Timeline per Voice Turn
Office's own lines start when a request arrives and end when the model is done. Everything Dad felt on either side of them, the recording crossing the link and her voice coming back, was unrecorded. Now each voice turn reports one timeline. The client sends it once, at her first sound: seconds before its POST (end of speech, the whole transcription), each recording's crossing (bytes and seconds, with office's own work subtracted through Server-Timing headers), and seconds after (first text, done, first unit, first audio). Office joins its own stages, logs one [voice-turn] line, writes it to the conversation's JSONL first and then to Dad's row. A private conversation is logged by label only and stored nowhere.
The first seven phone turns over LTE gave the wait its real size: a median of 44.6 seconds from the end of Dad's speech to her first sound. Of the 33.4 seconds before the turn even left the phone, 11.1 were pure transfer, 220 to 560 KB at 10 to 40 KB a second. After it, office's first text came at 8.0 seconds, but the stream took 4.5 to 17.5 seconds to cross on the three turns whose 48 kHz recording was uploading beside the reply, instead of 0.4 to 1.5. And her first sound came a median 5.2 seconds after her first text, because a reply's last unit was its whole remaining text.
Each number pointed at its own fix, and none of them touched the soul. The 48 kHz copy now goes up after her answer, behind the turn. A photo handed to the talk starts uploading while Dad is still talking, under its own hash so the same photo always names the same stored upload: single-photo turns had waited 17 to 23 seconds for it after his words. The web reads a reply's last unit at its done instead of when the stream closes, which had cost 2 to 5 seconds. And a chat answer is read paragraph by paragraph, the new lesson at the end of Track 4.