"Forgetful by default was a rule with a reason. When the reason changed for one surface, the rule changed there — and only there."
From Never Kept to Always Kept
When voice chat shipped on 2026-09-26 it inherited dictation's rule: the audio is discarded. Eight days later cwkPippa ran a record check across its conversations and found that 0 of 55 dictated Firekeeper turns had a recording — by Firekeeper's own design. That mattered because of a new goal: any conversation should be able to become a video later, with no live recording session, which means its ground truth — Dad's actual voice — has to survive. Dad ruled the same day, for Firekeeper and the navigation app alike: keep both voices. Asked why the copy should be 16 kHz, he answered with a question: why keep it at 16 when 48 kHz costs nothing extra?
What a Turn Now Keeps
When an utterance ends, Firekeeper takes two files: the 16 kHz recording the transcriber heard, and the same stretch at the microphone's own rate from the voice kit's tape. Both go to cwkPippa's /api/upload, and the turn names them in input_audio_ids — a record attached to the turn, never something the model reads. cwkPippa tells the two apart by sample rate. If the server is briefly away, the upload is asked again under the same rule the listening grant uses; any other failure leaves the note "The recording was not kept." and the words still go out. Nothing is kept on the Mac. And dictation did not change at all: its audio never leaves as a file and is discarded once transcribed, apart from the bounded failure rescue track 8 describes (at most ten files, and only while history is on).
utterance ends
-> voice-<stamp>.wav 16 kHz: what the transcriber heard (replay timing, loudness)
-> voice-hq-<stamp>.wav mic rate, through voice processing (MacBook mic, AirPods)
voice-raw-<stamp>.wav mic rate, the microphone's own sound (office)
-> POST /api/upload (a private talk names its own folder)
-> turn.input_audio_ids = [ids]
On this Mac: nothing. Dictation: unchanged (discarded; failure rescue aside).
On Office, the Microphone's Own Sound
The first video made from a talk sounded like a phone call, and Dad asked for better — on one condition: if fixing it would disturb cut-in, don't. The WebUI needed a second, unprocessed opening of the device to get a clean copy, because its talk stream runs through the browser's echo cancellation. Firekeeper needed nothing new: office's 32-input interface never runs voice processing, so the talk's own channel already is the raw microphone at 48 kHz. Measured inside the app's own path, the tape was flat to 24 kHz with the room at about −54.5 dBFS. So the capture did not change, cut-in could not be touched, and the only change was the name: a copy taken without voice processing is voice-raw-…, a processed one stays voice-hq-….
The Copy Starts When the Listening Began
A raw copy keeps everything the room heard — including Pippa's own voice from the monitors. The first version cut the copy as "the utterance's length plus half a second" from the end of the tape, and that half second reached back before the listen began: a web raw copy that evening opened with 0.4 s of her voice at speech level. Now, whenever the listen's start time is known, the copy is bounded by the time since that recording began, so it cannot reach back into her reply; when the start time is missing, the function falls back to the old length plus half a second. In a speaker test that night, every copy lined up with its 16 kHz twin at 0.99–1.00 correlation within 45 ms of the start.
The Retention Rule Still Holds
Track 8 said retention is the exception with a reason, bounded. This is exactly that: a stated reason (a talk must be able to become a video), a bounded scope (talks yes, dictation no beyond its bounded failure rescue, nothing of a talk on the Mac), and one store (cwkPippa, the same seam the WebUI and the phone use, so its record check reads a Firekeeper talk with no new code). A private talk's recordings land in that talk's own folder and end with it.