"1, 2초 늦게 시작하더라도 안 끊기는 게 더 중요해." ("Even if she starts a second or two later, not breaking up matters more.") — Dad, Málaga, the night of 2026-10-19 (2026-10-20 in Korea), on build 157
A Reply That Spoke One Sentence
The lesson before this one closed the gaps between paragraphs by warming the next take while the current one played, and on 2026-10-19 the stronger version of that idea measured true: with every unit's take opened the moment the unit was queued, twenty boundaries between units on build 155 fell silent for only 0.09 to 0.17 seconds each. That same evening in Málaga, on build 156 over hotel Wi-Fi with AirPods, a reply was whole on the server (done at 40.4 seconds, no error) and whole on the screen, and Dad heard "원칙은 하나야." ("There is one principle.") and nothing more. The phone said "Reconnecting — The engine did not answer in time."
The access log on the Mac that was then the Pippa machine had the cause. When the reply's tool finished, the phone fired four take prepares, four take streams and the 1.96 MB microphone-rate copy of his recording in the same second. The unit just starting starved for 8.7 seconds, and every other call timed out on the same link. Both bursts were ours. Opening every take at once was the gapless fix itself, and the copy that went up "behind" the turn at its done landed, under paragraph reading, in the middle of her reply. Fourteen minutes earlier Bellows' own rows had shown the same shape: five takes of one reply created within 0.75 seconds, and the units playing ran dry three times, 8.51 seconds in all, while their siblings were being made. The gap measurement had measured the silence between units. Nothing had measured the starvation inside one.
The Buffer That Held Her Voice Back
Earlier that day, in the crowded Picasso Museum on LTE, Dad had already named the other half: "이제 이어지긴 하는데 특히 첫 응답이 뚝뚝 끊기는 현상이 잦아." ("It flows on now, but the first answer in particular keeps breaking up.") The gaps between units were gone; this was choppiness inside a unit, mostly the first, the only one played while its bytes arrive. The cause sat in the kit's StreamingSpeechPlayer, the player of every reading outside a hands-free talk. Parsed packets waited in a 32 KB buffer, about two seconds of 128 kbit/s audio, before the audio queue saw them. A stream arriving only a little faster than it plays left the speaker dry while the audio sat in that buffer, and a dry queue then played each scrap the moment it came: a word, silence, half a word. The queue started after 0.35 seconds of audio, whatever the link.
cwkSiblingKit a89401e (2026-10-19) took the buffer out: packets reach the queue as each piece of the body is parsed. The first sound waits for a cushion of audio on hand, and a queue about to run dry while the body still arrives holds once and refills, then plays on: one pause, never a stutter. A unit is never split or restarted. On the kit's bench, a congested cell (1.6x real time, held 0.3 to 0.9 seconds every second) went from two stalls and 1.48 silent seconds to none.
Two Rulings, Both by Ear
At 20:14 that evening Dad gave the first: "처음에 그냥 통째로 읽기를 했을 때가 훨씬 기능이 나았던 것 같은데" ("I think it worked much better at first, when it just read the whole thing"). Build 157 (cbe99bd0) made whole-answer reading the default on the phone again. The line before a tool is still read as it comes; the rest of a finished answer is one take, read through. Prefetch is bounded too: only the playing unit and the next have their take open (PippaSpeechPlayback.prefetchDepth = 1), which keeps the reading gapless and leaves the playing unit at most one competitor. Later that night, in the MacBook's WebUI, Dad heard the web do what the phone no longer did: "끊기는 데다 아예 건너 뛰어" ("it breaks up, and it skips whole parts"). Build 157's switch had reached the phone only.
The second ruling came on build 157 itself. A whole answer over hotel Wi-Fi still ran dry three times in its opening seconds, because the cushion on a good link was still 0.35 seconds. Dad's answer is this page's epigraph: between a fast start and a reading that never breaks, he chose the reading.
So the paragraph lesson's exception came back out. Invariant 19, one synthesis per speakable unit, never stopped being the rule; the one exception Dad granted on 2026-10-18 lasted a day, and the same ear that granted it withdrew it. The paragraph cutter is not deleted. It waits behind a switch, and it comes back only if a day of measured turns shows it beating whole-answer reading on first audio, zero breaks and zero false "Reconnecting".
One Switch, Every Cutter Tested Against It
A switch on one surface turned out to be worse than none. A take's identity in Bellows is its unit's text, so every cutter has to agree to the character: the screen's takeSpokenUnits, the server's spoken_units (which GET /api/onair/record and the On Air replay use to find takes that already exist) and the phone's SpokenUnits. While the phone read whole and the server still cut stored replies into paragraphs, the record check could name takes that were never made. So the switch lives in one place, the shared fixture's reads_by_paragraph (frontend/src/__tests__/fixtures/spoken-units.json, set to false), and each surface's constant is tested against it: the screen's READS_BY_PARAGRAPH, the server's voice_turn.READS_BY_PARAGRAPH and the phone's AppModel.readsByParagraph. Two lists of cases pin both settings: whole_answer_cases pins the default cut on screen and server, and cases keeps the paragraph cut honest behind the switch. Flip the fixture alone, and every cutter that did not follow fails its test.
A Cushion Sized for No Break First
The second ruling became numbers in CwkKitCore.SpeechCushion (cwkSiblingKit 21507b4, build 158). Before the first sound a reading holds 1.5 seconds of audio on a good link and 2.0 seconds on a costly one (cellular, expensive or constrained). A reading that ran dry adds 0.5 seconds for the readings after it, remembered for ten minutes, because a congested cell stays congested for minutes, not for one reply, and nothing is ever held longer than 3.0 seconds. A refill after a stall is never less than the costly start, since a stall proves the link is costly. And a link the phone cannot name yet counts as costly: build 157's first turn after launch read link=unknown on Wi-Fi and started at the smallest cushion, so the link monitor now starts at launch. At the three to four times real-time synthesis measured then, the deeper cushion cost roughly 0.4 to 0.8 seconds before her first word. There is one cushion per process, so what one reading learned holds for the next, and the talk's own engine (VoiceLoopSpeechPlayer) keeps the same rule.
The server measures the other side. Each [tts-take] line on the Pippa machine carries need=: the cushion that take alone would have needed from its first byte never to run dry. A break whose take needed more than the phone's cushion was the synthesis; one whose take needed less was the network. The sketch below runs the cushion against a link that sags for two seconds.
Her Voice Has Deadlines
A cushion answers a slow link. It does nothing for a dead one, and under whole-answer reading one unit can be the whole answer. The voice-mode review of 2026-10-22 gave her voice deadlines. A take with no first byte in 15 seconds answers 504 and its synthesis is abandoned, so the retry starts a fresh one instead of joining the stall. Bellows' stream is read with a 30-second limit between chunks instead of one 320-second number. A take Bellows cuts off midway ends as a broken transfer (TakeCutShort, logged as [tts-take] … failed short_at=), never as a whole short answer, because a player cannot tell a truncated take from her finishing. And a hold that gains no audio for 20 seconds (SpeechCushion.holdDeadline) ends the reading as .stalled: in a hands-free talk the phone first asks for the same take again and reads on from where she was heard, and only a second failure is said ("Her voice stopped early") and reported. Track 6's "The Exception Paths" follows the rest of that review.
What It Bought, and What It Costs
The first full measurement came after the Pippa machine moved: 103 phone voice turns on 2026-10-21 and 22, 90 of them over cellular, every one with underruns=0, and a single gap above 0.3 seconds. The breaks were gone. The price is written down beside them. From the end of Dad's speech to her first sound, dictated turns took a median 31.0 seconds (p90 47.5). About 13 seconds of that was the model's first text with thinking on, a median 5.7 seconds was waiting for done, which is whole-answer reading itself, and 3.4 seconds ran from the unit to her first sound. The review called the two big pieces posture choices, not defects, and the 5.7 seconds is Dad's trade for zero breaks, made with the numbers in front of him.
So this quest's v5 is superseded, not erased, the way fast-by-default was before it: a quality default the listener re-chose by ear, an exception that came back out, and one switch with every cutter tested against it. Track 10's "A False Alarm, and One Measurement per Cause" follows the other thread of that Málaga night, the "Reconnecting" line that was never true.