"The phone already had the design. The Mac needed the same picker, the same private talks, and one more gate."
Which Soul You Are Talking To
Pippa is not the only soul in cwkPippa, and a talk can be held with any of them. The talk's soul is its own setting, voiceChatSoulId, kept apart from the pippaSoulId that dictation cleanup and command mode use — a talk with another soul must never turn Dad's dictation into that soul's voice. The roster comes from cwkPippa's /api/souls. Switching into a super soul asks for the master passphrase in a sheet every time, and cwkPippa checks it — sent once, outside the door's usual re-authentication, because a wrong passphrase also answers 401 and must not trigger a silent retry. Touch ID can type the passphrase: saved in the login keychain behind a Touch ID check, through the security framework so no other process can read it. Leaving a super soul never asks.
Choosing New or Continue
The talk hotkeys used to always start fresh, and the voice door had no way back into an earlier conversation. Now both hotkeys — ⌃⌥⌘V for a talk, ⌃⌥⌘P for a private one — open a small chooser at the top right, a new conversation first. For a talk it lists the active soul's recent chats from the WebUI's own list (at most 12, newest first), each with where it came from and how long ago; for a private talk, that soul's private talks still open. Arrow keys, Return and Escape work; a click elsewhere cancels; focus goes back to the app Dad was in. With nothing to continue, a new talk starts at once. The behavior is a setting: always ask, always new, or always the last one.
A Conversation Is Born With Its First Words
Opening the panel used to create the conversation. Fifteen talks that ended in silence were left behind as empty "New Chat" rows in the sidebar. Now a talk's conversation is created when Dad first says something, and the chooser leaves the old empty shells out of its list.
Private Talks: Kept Nowhere
A private talk is a cwkPippa private conversation, and cwkPippa enforces its privacy. Firekeeper's part is to keep its own hands clean. The private conversation's id lives in this process's memory only — never in the settings file, which refuses one, and never in the voice-chat log. Its turns carry private: true; its replies use the one-shot speech ticket that keeps nothing; its recordings go to its own folder and end with it; it sends no echo samples and no cut-in diagnostic record (with voice cut-in on, a voice trip still sends its last 2.3 s to cwkPippa's speaker check, which keeps no record of it); it is never on air. The panel wears the phone's teal banner with a lock, the word PRIVATE and the idle countdown, and a status check every 3 seconds catches an end from anywhere: "Private conversation ended — nothing of it was kept."
Stop Means End, Leaving Means Leave
Two rulings shaped the lifecycle. Because the voice door once had no conversation picker, a stopped private talk would have been unreachable, so on Firekeeper Stop is End: the panel's Stop reads End and ends the private conversation on cwkPippa too. But closing the panel window is leaving, not ending — Dad once closed it, pressed the hotkey again, and got a new conversation he did not want. Leaving closes the microphone and keeps the private talk open for its idle window, and the chooser lists it.
Keep: From Private to Kept, Up to Her Last Reply
Sometimes a private talk turns out to be worth keeping. The banner's Keep button copies it into an ordinary conversation, up to the soul's last reply that has words — a question still waiting for her stays out — by walking the conversation from that reply back through its parents. cwkPippa's own branch does the copy, bound to the private talk's soul and owner, so a copy with another soul lands in that soul's list only. The copy is then titled from what was said, and the private talk goes on, still private.