Contents

M10 Show memory

A show keeps a notebook of everything it has written, so that the fortieth episode still sounds like the first: the story so far, how each character talks, the running gags and when each last played, what kind of funny the show is, what it has established about its world, and the setups still waiting for a payoff. It is written for the show as episodes are made, edited by the person like any canon, and read by every writer within a token budget.

Read with docs/design/m10-continuity.md (the continuity log, which memory reads), docs/design/m5-writers-room.md (the writers' room, which reads memory) and schemas/v1/memory.schema.json.

One notebook beside the bible: the choice

Memory is a document kind of its own, ShowMemory, one per show at bible/memory.json, rather than more sections of the bible or of each episode's continuity log.

  • The bible is intent; memory is history. The bible holds what the creator means the show to be (its gags' rules, its tone rules, its arcs and the answers to its threads). It is small, hand-written, and sits whole in the showrunner's cached prompt. Memory grows with every episode and is read through a budget. Folding it into the bible would have grown the cached prefix without limit and mixed what the creator decided with what a pass inferred.
  • The continuity log is evidence; memory is the digest. A continuity log is one episode's record, checked against the episode's scenes, cues and shots, and it drives the outline's bible checks. Memory spans episodes (a character's voice across a season, a gag's every payoff) and is prose a writer reads, with sources rather than proof.
  • One entry shape for everything. Every memory entry has an id, a kind, its words, what it is about (the show's ids), its sources (episode, scene, screenplay line, the words), who wrote it (the person, the deterministic pass, or the model), when, and three flags: pinned (always in a writer's context), locked (no pass changes it), retired (kept for history, never read). The bible's sections each have their own shape; giving every one of them these fields would have changed every bible reader.

Nothing is copied from the rules into memory. The theme's never list and the bible's tone rules are read live by the retrieval function; a memory gag that is a bible gag links to it (about: ["gag.kettle_gravity"]), and the bible's own frequency and usage notes are read from the bible when a writer is told about it. Memory's own tone, never and style entries are the house style the scripts show and the person adds, beside the rules.

Migrating: a show from before memory has no bible/memory.json and works as before: the retrieval function falls back to the bible's gags and threads and to the continuity logs' facts, which is what the writers' room read until now, and Studio's Memory section offers to build memory from the episodes the show already has. Continuity logs stay; the remember pass reads each episode's log into memory (its facts and lasting changes), and an episode memory has not remembered still reaches the writers through its log.

The document

ShowMemory  bible/memory.json  id memory.<show>
  settings    apply review|auto|manual, kinds [story, characters, gags, tone, world, threads],
              budgetTokens (1500), detailedEpisodes (6), restAfter (2), model auto|off
  episodes    the remembered episodes in story order: season, number, title, screenplay,
              its hash when remembered (another means the script changed since), who spoke how much
  entries     id mem.*, kind, title, text, about, sources, uses, status, flags, by, dates

Kinds, by group: story (episode synopsis with what changed for whom, season summary), characters (voice, catchphrase, relationship, knowledge), gags (gag: a running gag or callback, with uses, each time it played), tone (tone, never, style), world (fact), threads (thread, open or resolved).

A gag rests when the person rests it, or when it played in each of the latest restAfter episodes. (implementation) Checks (core/src/validate/memory.ts): an episode synopsis names its episode, a season summary its season, each remembered episode has its own place; entries about ids the show no longer has, and sources in episodes memory has not remembered, are warnings, so cutting a character never blocks the show.

Remembering an episode

Two passes, the second optional. Both say what they found as drafts, one per entry, and the same merge applies them:

  • The deterministic pass (core/src/memory/remember.ts) always runs and costs nothing. It reads the episode's screenplay (with the directed episode's scene ids and summaries, and the outline's logline and scene summaries, when there are), and the same show always gives the same memory:
    • a synopsis skeleton, scene by scene: where, who speaks, the scene's summary (else its first line of action), opened by the outline's logline, with what changed (the continuity log's lasting changes, the threads and arc beats the outline moved);
    • each speaker's voice in numbers over every remembered episode (lines, words a line, questions, exclamations, the parentheticals they keep getting), and their catchphrases: the persona's own, wherever said, and any run of three or more words they say again in another episode;
    • each bible gag's uses: the outline serves it, the continuity log records it, its payoff's quoted words are said ('...I'm getting back down.'), or one line holds every word of its name ("another asteroid shaped like a duck" for Asteroids shaped like ducks);
    • callbacks: words that come back across an episode's scenes or three lines, grouped when said together (tape and optimism: set up on the bridge, paid off three times), and words another episode says again in another mouth, which join the callback already remembered;
    • the house style over every script (action paragraph length, the sounds written in capitals, line length, how often a parenthetical comes and which);
    • the bible threads it opened, moved or resolved, and its continuity log's facts and lasting changes (what someone learned is knowledge, a relationship changed is a relationship).
  • The model pass (core/src/memory/pass.ts) runs after it when a model is configured and memory's model setting is auto. Through the LlmProvider seam, Claude reads the episode's numbered screenplay beside what code found and what memory holds, and calls submit_memory once: a real synopsis, what changed for whom, and entries for voices, catchphrases, relationships, knowledge, gags, tone, facts and threads, each with the lines it comes from. Code checks it against PassDraft (one repair round), ties each line to the script (a cue's line to its speech), keeps only ids the show has, and says in the proposal what it dropped. Its calls are the director's ModelCaller: priced against the show's budget first, billed to the CostMeter and <show>/.reelwright/spend/ under the session memory.<episode>, with show.json's stage writers_room choosing model and effort. A pass that fails leaves code's memory as it is, and the proposal says why.

Merging (core/src/memory/merge.ts): a draft replaces what its entry said of the episodes the pass read and keeps the rest. A pass rewrites an entry's words only when it ranks with whoever wrote them (deterministic below model, and no pass rewrites the person); otherwise it keeps its books (sources, uses). Pinned, locked and retired entries are never changed: what the pass wanted of one becomes a note in its proposal ("The Chief retreats is locked, so 1 use in ep.kettle not recorded"). What the deterministic pass said before of an episode and no longer finds there (a rewrite cut the callback) goes.

Automated, configurable

The hook is the decision that makes an episode: a change applied that directs one (direct_episode, from chat or Studio's Direct) or the showrunner's screenplay approved (write_screenplay). The person's own saves in the script editor do not run it: a script is saved many times before it is done. After it, the studio (core/src/studio/studio.ts) runs a remember pass, one at a time, and, by memory's apply setting:

  • review (the default): proposes memory's updates as a change set for the person;
  • auto: applies them as made (undo takes them back);
  • manual: does nothing until the person asks ("Update memory from episode…").

A show's first memory remembers every episode the show has, so the story starts at its start; the model reads only the episode just made. The other settings choose what a pass remembers (kinds), how many tokens a writer's prompt gives memory (budgetTokens), how many of the latest episodes the story tells in detail before older ones are summed up by season (detailedEpisodes), when a gag rests (restAfter), and whether the model pass runs.

Reading memory

One function every writer calls, memoryContext(show, {characters?, scene?, episode?, budgetTokens?, rules?}) (core/src/memory/context.ts; showMemoryContext(root, …) reads the show first). It picks within the budget, counting the text exactly as it prints, in this order:

  1. Always, whatever the budget: the tone and humor rules (the theme's never list and the bible's tone rules, unless the prompt has them already, then memory's own tone, never and style entries) and every pinned entry.
  2. The characters in play (given, else those the scene names, else everyone by how much they talk): the persona's designed voice, then the voice memory heard, catchphrases with when they last played, relationships and what they know.
  3. Running gags and callbacks, relevant first (the scene's words, its characters, the bible's frequency), fresher before worn, resting ones last and marked RESTING … Rest it (used in each of the last 2 episodes).
  4. The story so far: the latest detailedEpisodes in detail (newest first for the budget, printed in order), earlier seasons by their summary entry, else their episodes' first lines.
  5. Open threads, with where each opened and last moved. 6. World facts, those about the characters in play first.

Retired entries are never read. What did not fit is listed (omitted), and resting gags (resting). The same show and options give the same text.

Who reads it:

  • the showrunner's show context (loadShowContext): a <memory> section at memory's budget, without the rules the context holds already;
  • the writers' room: write_outline's answer gives memory for the outline's cast (700 tokens at most), in place of the twelve continuity facts it gave before;
  • show_memory (read), for any writer that asks with a scene or its characters;
  • the MCP server: the reelwright://memory resource, and its instructions say to read it before writing;
  • the script editor's writing assistant: its "what the show remembers" input (remembers in core/src/studio/assist.ts) is memoryContext for the scene at the caret (the characters it names, the gags it touches), without the episode being written and without the rules its context has already.

Tools and protocol

  • show_memory (read), remember_episode (propose; model: false for the free pass alone) and edit_memory (propose: add, edit, pin, unpin, lock, unlock, rest, unrest, retire, restore, forget, place an episode in the story, and the settings). The showrunner neither changes a locked entry nor locks one: locking is the person's.
  • Session methods for Studio: memory.list {query?, kinds?, retired?} (entries with their sources resolved to a script and line, each gag's last use and rest state, the story in order, counts by group, the theme's and bible's rules read-only, the episodes not remembered, proposals waiting with what each adds, changes and forgets, and the context's size against the budget); memory.edit and memory.configure (the person's own change, applied as made, undone like any other); memory.remember {episodes?, model?} (now; a proposal, or applied when the settings say auto). memory.event says when a pass starts (remembering) or fails, when a change to memory is proposed or decided, and when the file changed outside Reelwright.

Studio: Memory

A section of the rail (Ctrl+7), the same on the desktop and the web edition: entries grouped by kind with counts, search, the story so far by season, gags with their last use and rest state, characters, tone (with the theme's and bible's rules shown read-only), world and threads. Each entry edits in place and can be pinned, locked, rested, retired or forgotten; its sources open the episode's script at the line. Proposals waiting to change memory show inline with Approve and Reject; Settings holds the choices above; "Update from episode…" runs a pass now. A show with no memory says what memory is and offers to build it from its episodes.

The Memory section on the demo show, built from its two episodes

Its running gags and callbacks, each with where it played

A show with no memory yet

(implementation) The screenshots come from engine/tests/support/rw_memory_shots.gd against the real daemon on a copy of the demo. The first pass at them showed the model pass tried (and noted at length) with no key set, filters over an empty memory, groups with nothing in them before memory existed, every card padded twice, a kind badge on every gag, and the threads filter called "Open"; each is fixed.