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 arelationship).
- The model pass (
core/src/memory/pass.ts) runs after it when a model is configured and memory'smodelsetting isauto. Through theLlmProviderseam, Claude reads the episode's numbered screenplay beside what code found and what memory holds, and callssubmit_memoryonce: 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 againstPassDraft(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'sModelCaller: priced against the show's budget first, billed to the CostMeter and<show>/.reelwright/spend/under the sessionmemory.<episode>, with show.json's stagewriters_roomchoosing 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:
- 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.
- 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.
- 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). - The story so far: the latest
detailedEpisodesin detail (newest first for the budget, printed in order), earlier seasons by their summary entry, else their episodes' first lines. - 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://memoryresource, and its instructions say to read it before writing; - the script editor's writing assistant: its "what the show remembers" input
(
remembersincore/src/studio/assist.ts) ismemoryContextfor 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: falsefor the free pass alone) andedit_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.editandmemory.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.eventsays 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.



(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.