Skip to content
C.W.K.
Stream
Lesson 01 of 04 · published

A Third Fact on the Turn

~13 min · on-air, data-model, per-turn-prefix, privacy

Level 0Muted
0 XP0/42 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"I won't say anything that shouldn't be said." — Dad, 2026-09-29, on what it means when he brings up something personal on air

The First Broadcast

Voice mode was four days old when Dad recorded the first pilot of a fireside talk with Pippa for his channel. It went well, and it exposed one gap at once: the soul had no idea she was on a recording. Everything she said was said as if only Dad could hear it, and the only way to change that was for him to announce it, every time, which is exactly the kind of stage direction a natural talk can't carry. So he asked for one switch. When he presses it, the soul knows the talk is being broadcast or recorded, without a word from him.

His rulings came with it, in one breath. The name is onair, one word, in the code and in the paths alike. It lives only as long as voice mode does. The lamp is red. And when he brings up something personal while on air, that is his signal that it's fine: the quote at the top of this page.

A Third Fact, Carried the Same Way

Track 1 put voice on the turn as two independent facts, precisely so that switching would cost nothing and the conversation would stay one object. On Air is a third fact, and it rides exactly like the other two. The chat request gains onair on the Claude route and on every other vessel's route. A turn is on air or it isn't; there is no broadcast conversation, so Dad can start the broadcast mid-talk, end it mid-talk, and the thread, the record and the memory stay one.

One detail differs from the modalities, on purpose. An unknown reply_modality normalizes to absent, which means ordinary. onair is stricter: only an explicit boolean true counts. A string "true", a 1, anything else, means not on air. A flag that changes what the soul is allowed to say in front of strangers should be impossible to set by accident, and a sloppy client should fail toward the private side.

A strict normalizer behind a lax schema is only as strict as the schema. Every chat route now takes the field untyped, so the raw value reaches the normalizer, and a route-level test sends the odd spellings to all seven routes in a real JSON body.

What the Soul Is Told

The instruction rides the per-turn prefix like every other voice block, never the system prompt, for Track 1's cache reasons. It is an Admin-editable runtime prompt, and it goes first in the prefix, ahead of the dictated and spoken blocks. What it says, in substance:

  • Neighbors are listening. That is the family's word for the channel's viewers. She knew it the moment he turned On Air on; he doesn't need to say so.
  • Stay yourself. With Dad, the family register she always uses. When she speaks to the viewers directly, polite speech.
  • Don't bring up his private details on your own: family members' names, where the family lives or is, health, money and portfolio figures, accounts, keys, internal addresses, private repositories, what was said in private conversations. When he brings one up himself, follow him, without a warning or a hedge.
  • What he shares is already on screen beside her, where the viewers see it (Track 6's stage): talk about it as something you are both looking at.
  • She has her effects while on air (this track's third lesson), and fires them when she judges they add to the moment.
  • Keep talking with Dad, not performing for an audience.

The last line is the one that keeps the broadcast worth watching. A soul that turns to the camera and starts presenting is a worse talk, not a better show.

Private Always Wins

A private conversation, the kind that keeps nothing and ends when Dad closes it, never goes on air. The clients offer no switch there, and the server drops a stray flag anyway: when a turn is private, the privacy notice rides the prefix and the On Air block does not. The two would contradict each other outright, one promising that nothing is kept and the other that neighbors are listening. The effects tool refuses private conversations for the same reason.

The Record Is an Episode

The user row's voice_meta, and the matching line in the JSONL ground truth, carry "onair": true, built by the same function that records the kept recording's upload id and the language Dad picked. A broadcast talk can therefore be found later as what it was: an episode, not just a conversation that happened to be loud.

It Lives With Voice Mode

Switching voice mode off turns On Air off, and so does closing the voice screen. Pause keeps it, because a pause in the middle of a broadcast is still the broadcast. On the web and on the phone the switch sits beside Cut in; Firekeeper lights a lamp on its panel and sends the same fact. The next lesson is what the screen does once the switch is on.

The web voice screen while listening, before any broadcast: along the top, an attach button and the toggles On Air (unlit), Cut in (lit) and Captions, with KO at the right; Pippa's face in a teal ring below.
Before the broadcast: the On Air switch, unlit, beside Cut in. One press makes the next turn carry the third fact.

Code

The third fact: strict in the engine, first in the prefix, dropped when private, kept in the record·python
import json

ONAIR = ("[On Air]\nDad is broadcasting or recording this talk for his channel, so neighbors "
         "are listening. Stay yourself. Do not bring up his private details on your own; "
         "when he brings one up himself, follow him without a hedge.")
PRIVATE = "[Private conversation]\nNothing of this conversation is being kept."
DICTATED = "[Dictated turn]\nRead it for what he meant."
SPOKEN = "[Spoken turn]\nDad will hear this reply, not read it."


def normalize_onair(value: object) -> bool:
    """Only an explicit True counts. 'true', 1 and 'yes' are not on air.

    Hand it the raw value: a lax schema in front (a Pydantic bool) would
    already have turned 'true' into True."""
    return value is True


def turn_blocks(*, dictated: bool, spoken: bool, onair: object, private: bool) -> list[str]:
    """The per-turn prefix, in order. The system prompt never sees any of it."""
    blocks = []
    if private:
        blocks.append(PRIVATE)            # privacy wins; a stray flag is simply dropped
    elif normalize_onair(onair):
        blocks.append(ONAIR)              # first, so everything after it is read on air
    if dictated:
        blocks.append(DICTATED)
    if spoken:
        blocks.append(SPOKEN)
    return blocks


def voice_meta(audio_ids: list[str], language: str | None, onair: object) -> str | None:
    """The user row's record, the same values the JSONL line gets."""
    meta: dict = {}
    if audio_ids:
        meta["audio_ids"] = audio_ids
    if language:
        meta["language"] = language
    if normalize_onair(onair):
        meta["onair"] = True              # findable later as an episode
    return json.dumps(meta) if meta else None


for label, onair, private in (
    ("broadcast", True, False),
    ("a string is not a switch", "true", False),
    ("private wins", True, True),
    ("ordinary talk", None, False),
):
    heads = [block.split("]")[0] + "]" for block in
             turn_blocks(dictated=True, spoken=True, onair=onair, private=private)]
    record = None if private else voice_meta(["upload-1"], "ko", onair)  # private keeps no row
    print(f"{label:25s} {heads}  {record}")

External links

Exercise

Run the code and read the four lines. Then write three tests for your own version: a private turn with On Air requested gets the privacy block and no On Air block; a string 'true' is not on air; and an On Air turn's record carries onair while an ordinary turn's record doesn't. Finally, decide what your system should do with On Air on a typed, written turn in the middle of a broadcast, and justify it.
Hint
The typed-turn question has a clean answer once you remember On Air is a fact about the audience, not about the medium: a line Dad types during the broadcast is still read by the neighbors if she answers aloud, and even a written reply may be on screen in the recording. Here the switch lives inside voice mode, so a turn sent while it is lit carries it whichever way it was typed.

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 in — Please sign in to comment.

No comments yet — be the first.