Skip to content

feat(daily): open on a fourth-wall line instead of the host's name - #231

Merged
schmug merged 1 commit into
mainfrom
claude/cortech-daily-opening-script-uw7exi
Sep 14, 2026
Merged

schmug merged 1 commit into
mainfrom
claude/cortech-daily-opening-script-uw7exi

Conversation

@schmug

@schmug schmug commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Summary

The cold open credited a person — "I'm <host_name>" — and nobody is there: a scheduled job pulls the feeds, ranks them and writes the script, and a model speaks it. #223 retired that claim from the sign-off and replaced it with the button, but left the same fiction standing at the top of the episode, where it started.

Every cold open now carries one sentence saying the show is machine-made, built exactly like the button so there is one pattern rather than two:

  • FOURTH_WALL_ANGLES names the ANGLE, never a phrase to say (the TRANSITION_MOVES posture) and the wording is written fresh each run — a stock disclosure read every morning stops being information and becomes a jingle.
  • Four angles against INTRO_MODES' five, so the open's mode and its disclosure cycle together over twenty days instead of pairing off forever (classic would otherwise carry the same disclosure in every episode ever made).
  • FALLBACK_FOURTH_WALLS — the three literals the no-model path needs — are the same three SKILL.md holds up as the register and burns, so a line is never both the example every writer sees and the day's opening.
  • The line is dry and explicitly not a joke. The button already carries the machine gag at the other end of the episode; the same joke told twice is a bit. The open states the fact and moves on.

host_name stays in config.json as the written credit only — it still matches the public show's <itunes:author> — and no part of the daily script speaks it now. The old "if the COLD OPEN names the host, take the name from host_name" rule is gone rather than narrowed, since narrowing it is what left the name in the open last time. Frontier Commits' cold open never named a host, so it is untouched.

SKILL.md is the production path (the scheduled run follows it, not orchestrate.py), so the bank, the placement rule and the burned examples live there too, pinned by drift tests.

The angles:

# Angle Do
0 machine-byline State it as flatly as a wire service states its byline: this episode was assembled by a machine.
1 pipeline Point at the mechanism that produced the episode — feeds pulled, items ranked, the script written overnight.
2 synthetic-voice Acknowledge that the voice itself is generated, in one clause, then keep moving.
3 no-one-here Say plainly that there is no host in the room: the show exists because a scheduled job ran.

Related issue

Refs #223 (this finishes at the top of the episode what that change did at the bottom).

Acceptance criteria

  • The cold open no longer names the host; "I'm <name>" is retired at both ends of the episode
  • The replacement is model-written prose from an assigned fourth-wall angle, not a fixed line
  • The fallback (no-model) path still says what is speaking, seeded by the date
  • The angle bank does not lock to the cold-open mode bank
  • SKILL.md — the production path — documents the bank, the register and the burned examples
  • host_name is documented as a written credit that no line of script reads aloud

Testing

  • ruff check . is green (and ruff format --check ., with the CI-pinned ruff 0.14.10)
  • pytest is green — 1536 passed, 10 skipped. One pre-existing failure is excluded: test_the_sandbox_exercises_the_music_layer_against_the_bundled_asset needs ffprobe, which this container has no ffmpeg for; it fails identically on a stashed (unmodified) tree, and CI installs ffmpeg.
  • Dry-run exercised — N/A: no renderer or manifest-path change. This touches script text only (the intro prompt, the fallback intro string, and the prose contract); render.py is untouched.
  • Manual notes: sampled the date rotation and the degraded path directly — day 5 is classic + pipeline, day 1 theme-first + pipeline, day 2 lead-first + synthetic-voice; the fallback intro reads Today's digest for September 14, 2026. 9 stories today. <line> Here's the rundown. with the disclosure as a beat of the open rather than its end.

New tests: test_fourth_wall_angle_is_not_locked_to_the_intro_mode, test_intro_prompt_carries_the_days_angle_and_hands_over_no_line_to_copy, test_intro_prompt_retires_the_hosts_name_at_the_TOP_of_the_episode_too, test_fallback_fourth_wall_lines_fit_the_cap, test_fallback_intro_still_says_what_is_speaking, test_skill_md_burns_the_fallback_fourth_wall_lines_it_shows_as_examples. Rewritten: test_skill_md_keeps_the_hosts_name_out_of_the_whole_script (was ..._out_of_the_sign_off) and test_skill_md_keeps_the_host_name_out_of_the_narration (was ..._routes_the_spoken_host_name_through_config, which asserted the opposite of what is now true). test_skill_md_documents_every_shape_and_mode now covers the new bank, and the button's burned-example test is scoped to its own section — two sections now carry a burned bank, and an unscoped search would let one pass on the other's rule.

Risk / blast radius

Small, and confined to script text. No renderer invariant is touched — no change to the 1:1 segment ↔ source mapping, chapter math, covered.json write ordering, last-chapter silence, or mono 44.1k. The cold open stays one segment with role: "intro" and source_url: null; only its wording changes.

Two things worth knowing: the cold open's ~350-400 char band now has to carry one more sentence (capped at 90 chars, and the rule says it sits inside the band rather than extending it), and host_name becomes a config key nothing speaks — it is deliberately kept, not removed, because it is still the written credit the public feed carries.

Docs kept in sync

  • Updated skills/daily-podcast/SKILL.md — new The fourth-wall line section, the host-credit rule replaced, the config-block comment and the Unattended daily run seed step updated. The procedure is not re-inlined anywhere; prompts/daily.md stays a stub.
  • Updated CLAUDE.md — new bullet under Script variety is assigned, not requested, and the button bullet's now-false claim that host_name still reaches the cold open is corrected.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RmUbYqCEQjMsi4jgWo2GQg


Generated by Claude Code

The cold open credited a person - "I'm <host_name>" - and nobody is there:
a scheduled job pulls the feeds, ranks them and writes the script, and a
model speaks it. #223 retired that claim from the sign-off and left it
standing at the top of the episode, where it started.

Every cold open now carries one sentence saying the show is machine-made,
built exactly like the sign-off's button: FOURTH_WALL_ANGLES names the
ANGLE and never a phrase to say, the wording is written fresh each run, and
FALLBACK_FOURTH_WALLS - the literals the no-model path needs - are the same
three SKILL.md holds up as the register and burns, so a line is never both
the example every writer sees and the day's opening.

Four angles against INTRO_MODES' five, so the open's mode and its
disclosure cycle together over twenty days instead of pairing off forever.
The line is dry and explicitly NOT a joke: the button already carries the
machine gag at the other end, and the same joke twice is a bit.

host_name stays in config.json as the written credit only - it still
matches the public show's <itunes:author> - and no part of the daily script
speaks it now. SKILL.md is the production path, so its cold-open section
carries the bank and the rules; the old "if the COLD OPEN names the host"
rule is gone rather than narrowed. Frontier Commits' open never named a
host and is untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RmUbYqCEQjMsi4jgWo2GQg
@schmug
schmug merged commit 4cd36dc into main Sep 14, 2026
3 checks passed
@schmug
schmug deleted the claude/cortech-daily-opening-script-uw7exi branch September 14, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants