C.W.K.
Stream
Lesson 04 of 04 · published

Two Stages, One Boundary

~11 min · two-stage, product-boundary, response-contract, roadmap

Level 0Unlit
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Dictation returns text you'll read. Voice chat returns words you'll hear. They are not the same product."

The Two Stages

Firekeeper has a deliberate roadmap with two stages, and the wall between them is load-bearing:

  • Stage 1 — Dictation. Speak, get clean text inserted into the active app. This is the near-term product and the whole first job.
  • Stage 2 — Voice chat. Speak, get Pippa to answer out loud. This starts only after Stage 1 is genuinely useful daily.

It's tempting to say "they're both voice, just build toward the bigger one." That instinct is exactly the trap.

Why the Contracts Differ

Dictation cleanup and a spoken reply are different output contracts, not different sizes of the same thing. Cleanup takes your words and hands back polished text to insert — it must never answer you, never add content, never editorialize. A voice reply takes your words and hands back a short, spoken turn — it is an answer, it's interruption-friendly, and it must sound right read aloud (no headings, no tables, no ten-bullet dumps). Look at the shapes side by side and the difference is obvious:

Dictation cleanup:  transcript in  -> polished text out (insert it, don't answer it)
Voice reply:        transcript in  -> a spoken turn out (answer it, keep it short)

The Failure You're Preventing

The classic mistake is "Stage 2 is just Stage 1 plus text-to-speech" — pipe your normal long-form Pippa answer into a TTS engine and call it voice chat. It produces something unbearable: a two-minute spoken essay with "first, secondly, in conclusion" read aloud, no room to interrupt. Good voice chat needs a response mode that knows it is speaking: one clear thought per turn, offer to continue instead of dumping. That's a whole new contract, which is why it's Stage 2 and not a checkbox on Stage 1.

A product boundary is where two contracts meet, not where two features do. Stage 1 and Stage 2 are separated because 'text to insert' and 'words to speak' are genuinely different return types. Keep the boundary and each stays small and correct; erase it and you get a blurry app that dictates awkwardly and converses worse.
Don't smuggle Stage 2 into the Stage 1 spine. Every time you're tempted to add a 'quick conversational reply' to the dictation path 'while you're in there,' stop. That's how the dictation loop grows a second brain, a second latency profile, and a second failure mode — and stops being a tight, shippable thing.

Code

Two different output contracts, kept apart on purpose·typescript
// Stage 1: cleanup returns text to INSERT. It never answers you.
interface CleanupResult {
  text: string;          // polished transcript, ready to insert
  action: "insert";
  press_enter: boolean;
  warnings: string[];
}

// Stage 2: a voice reply returns a SPOKEN TURN. It is the answer.
interface VoiceChatReply {
  textForTTS: string;      // short, TTS-friendly, one thought per turn
  textForTranscript?: string;
  shouldContinue?: boolean; // offer to go deeper instead of dumping
}

// Same input (a transcript), fundamentally different output.
// That difference is the product boundary.

External links

Exercise

Write the return type (just the fields) for two features of some app you use: one that 'produces content to place somewhere' and one that 'answers you conversationally.' If the two types look nearly identical, you've probably under-designed one of them. Where do they genuinely diverge?
Hint
They diverge on intent: 'place somewhere' output must be inert and complete; 'answer conversationally' output must be responsive, short, and continuable. The moment your types encode that difference (insert-vs-speak, complete-vs-continuable), you've found the real product boundary.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.