The script pipeline

The eleven stages from a topic to a finished script, with the command, the output and the exit test for each.

TL;DR

A script goes from a topic to a hand-off in eleven stages, S0 to S11. Research comes first (S1 to S3), then the thesis and the declared structure (S4, S5), then the draft with the hook written last (S6), two passes over it (S7), a gate loop run by one command (S8), a read-aloud pass (S9), optional blind readers (S10), and the hand-off (S11). The command check.js runs every automatable gate, says which stage the files show, and prints what to do next. Stop only at BAR MET or when the user says stop.

  • Start and resume with: node .claude/skills/video-script-production/scripts/check.js --dir research/<slug>/script --version vN
  • Order that matters: research before prose; chain before prose; hook last; add (texture), then subtract (voice), then clarify, then lint.
  • Humans decide: the title, naming a private person, running readers (subagents), and committing.
  • Honest status: reaching the v6 bar on a new topic "in one go" is a design intent. Moser Baer took five rounds of the user's feedback to reach v6 (seven to v7); Cafe Coffee Day v1 was the first test of a new topic and reached the bar on the rules of that morning.

The eleven stages at a glance

#StageYou produceToolLeave when
S0Set upthe folder; lessons readscaffold.jslearnings.md and rules.json read; slug chosen
S1Rival-video briefreport.md, synthesis.jsonsrc/topic-research/cli.jsbrief exists; contested claims and verification queries listed
S2Teardownteardown/SYNTHESIS.mdskill winning-video-teardowntable stakes and differentiators known
S3Fact baseFACTS.mdweb search and fetch5+ sourced rows per beat-worth; causal links sourced; magnitudes cross-checked; people researched
S4Thesis and packagingchain.cdl; script sections 1 and 2opening-protocol.mdfour scored candidates, one chosen; title tension stated; withheld list written
S5Chain and texture planchain-vN.json completechain-schema.md, texture.mdevery section filled
S6Draft the voice-overSCRIPT-vN.md section 3extract-vo.jsevery beat has VO; hook written last
S7Two passes (and a clarity pass)the same fileSKILL.md Steps 4a to 4cthe pass questions all answered
S8Gate looplint/, STATUS-vN.mdcheck.js0 FAIL, 0 WARN, damage test, ledger, timecodes, bar numbers
S9Read-aloud passedits; Read-aloud pass: doneextract-vo.js, checklistchecklist answered; S8 green again
S10Reader pass (needs the user's OK)reader reports; fixes backed by quotesextract-vo.js --mode blindfixes applied and S8 green, or Reader pass: skipped: <reason>
S11Hand-offHANDOFF-vN.md; final message; research recordhandoff-template.md, session-log.jscheck.js says BAR MET

Quick start

# 1. scaffold (once per topic; --from vM writes the next version from the last)
node .claude/skills/video-script-production/scripts/scaffold.js --dir research/<slug>/script --version v1 --beats 13 --title "<working title>"

# 2. after every stage
node .claude/skills/video-script-production/scripts/check.js --dir research/<slug>/script --version v1 [--prev v0] [--fix] [--no-selftest]

scaffold.js writes the script template (every section the ledger check expects), the chain template (every section the linter reads), FACTS.md (once per topic) and HANDOFF-vN.md. It refuses to overwrite. Run check.js once straight away: it will fail, which proves the harness runs.

A fresh session, even one on a small model, can run the whole pipeline from references/launch-prompt.md, a prompt with six fields that change per topic (topic, entity, slug, version, language, subagent and commit permissions). The Cafe Coffee Day copy is in docs/PROMPT-cafe-coffee-day.md.

Ground rules and defaults

  1. Research before prose. The user's repeated instruction. The thesis changed once (v4) and the story changed once (v5) because of a source nobody had opened.
  2. Say plainly what is unproven. Every hand-off states it.
  3. No subagents, commits, pushes or publishing unless the user asks.
  4. Keep the user's direction. Change as little as the lesson needs.
  5. Never edit rules.json to pass. Fix the script.
  6. Ask only for decisions that are the user's: title, naming a private person, running the readers, commit and push. Everything else has a default.
  7. Shell hygiene. Heredocs and sed swallow backslashes. Write code and regexes with the Write or Edit tool. check.js scans for stray control characters.
DecisionDefaultWhy
LanguageEnglishHinglish later; chain, pulls, figures and cast carry over; parables are rewritten in local terms.
"First 60 mins"The first 60 secondsThe user wrote 60 mins; it can only mean seconds. Say so in the hand-off.
Length12 to 20 minutes; name the cut candidatesv4 was 12.9 min, v6 19.6, v7 20.2.
Beats12 to 15 beats of 40 to 105 s; hook last to writebeat_words in rules.json (90 to 260 words).
Hook60 to 110 s; over 75 s it must carry the B8 elementsThe user found a 73 s hook "thin".
VoiceEarnest about facts and people, aloof about verdictstexture.md.
TitleA working title and 2 or 3 alternates; flag any word that outruns the evidence; never silently pickThe user has not chosen for Moser Baer.
Private peopleName only someone on record in a national outlet; flag itMahesh Sharma.
AllegationsState what is alleged and what a court decided; never "villain", "scam", "fraud" without a convictionMoser Baer beat 12.
Commit / pushDo notThe user has not asked since 156897f.

The stages in detail

S0. Set up

  1. Read references/learnings.md and apply its [method] and [measure] points; its [content] points are hypotheses. Read scripts/rules.json: its thresholds are the current definition of the lessons.
  2. Choose the slug (the topic lower-cased with dashes, as topic-research does) and create research/<slug>/script/.
  3. Run scaffold.js, then check.js to prove the harness works.

S1 and S2. Rival videos

See page 05. In short: run topic-research in the background; read search.json selected and swap off-angle videos; mine the report into FACTS.md as [CHECK] rows; then write the teardown synthesis (option A, B or C).

S3. Fact base

See page 05. The output is FACTS.md. If a causal claim has no source, change the thesis, not the evidence.

S4. Thesis and packaging

Follow references/opening-protocol.md steps 1 to 5 (details on page 08):

  1. Write the packaging question Q0: what the title and thumbnail promise, in one sentence.
  2. Write the viewer's priors: what a typical viewer already believes. Curiosity needs a prior to push against.
  3. Write 3 to 5 candidate loops ("You think X. The record shows Y. So what is Z?"), including the generic one every rival asks. Score each 0 or 1 on seven criteria (specific, breaks a prior, lands on the viewer, shape-hintable, unspoiled, deliverable, scalable). Choose the highest; record the rest as rejected with reasons.
  4. Write the destination hint (under 20 words, no route terms) and the withheld list (terms that must not appear in the hook).
  5. Write the one-line thesis, the named idea or governing metaphor, the promise ladder (three rungs and one unannounced bonus), and the title options. State any title and evidence tension to the user.

S5. The chain and the texture plan

Fill chain-vN.json completely before writing prose (field reference on page 08). In this order:

  1. The beats as one-line statements with arc tags (origin, rise, turn, response, fall, people, blame, lesson), and typed junctions (THEREFORE, BUT, BECAUSE) with a reason; for a BUT, name the expectation the previous beat planted. Run the three junction tests (say-it-aloud, swap, shared noun).
  2. For each beat fill Understand, Care, Change, Compel. If Change is empty the beat is information, not progress: merge or cut.
  3. Hero numbers (at most 7), each with a stake line before it and a landing after it. Everything else goes to a graphic or the ledger.
  4. The promise ladder and one unannounced bonus; the peak reveal goes after the midpoint.
  5. Pulls: for every minute of runtime write what the viewer is waiting for. Declare at least four pulls of at least three kinds, one a person at risk, one a motif that returns at the close.
  6. The cast: a protagonist with a want, a counterpart, a witness who pays, viewer stakes. The persona lines and the two-sided calls. The figures: one governing metaphor chosen by four tests, a gloss by analogy for each hard term, one or two parables. The hook elements.
  7. The clarity plan: tags for every person, the witness's cost line, the audience's known terms, spoken counts, named ideas, names that appear once and why, which beats are dense and need a headline.

The quotes can be placeholders until S6; they are verified in S8.

S6. Draft the voice-over

S7. The three passes

4a, the texture pass (adds words). Read once per question: who is in every beat and what do they want; where is "you"; what lands after each number; is there a run of more than two number-heavy 30-second stretches; does the governing metaphor return and state its limit; is there an earnest and an aloof line in each third; is every "I" true; does any "he" or "she" at a hinge have a name in the same or the previous sentence.

4b, the voice pass (removes words). Read the whole script aloud at speaking pace and follow references/voice.md: mark, rewrite by pattern, specificity test, keep the honest hedges, do not over-correct. It changes how the script sounds, never what it claims.

4c, the clarity pass. Read each beat once for the K, L, M questions: who is a stranger here, what has to be decoded, is the turn spoken, where is the cost said, does a dense beat open with a headline, does the hook end as a trailer. Add the headline last, once the details are final.

Order

Add, then subtract, then clarify, then lint. One plan (in the chain), one additive pass, one subtractive pass. Three sequential passes would each rewrite the last (the reasoning is in texture.md).

S8. The gate loop

S/check.js   --dir <scriptDir> --version vN [--prev vM] [--fix] [--no-selftest]
S/lint.js    --script SCRIPT-vN.md --chain chain-vN.json --label vN --out <dir>
S/selftest.js --script SCRIPT-vN.md --chain chain-vN.json
S/ledger-check.js --script SCRIPT-vN.md --chain chain-vN.json [--facts FACTS.md] --strict
S/retime.js  --script SCRIPT-vN.md --write
S/compare.js --a lint-vA.json --b lint-vB.json --sa A.md --sb B.md --out compare.md

(S is .claude/skills/video-script-production/scripts.) Fix every FAIL in the script, never in rules.json. Read every WARN and decide; the heuristic ones can be false alarms, in which case reword instead of raising a budget. references/lint-fixes.md lists what each rule usually means and the fix that worked. Expect 3 to 5 loops with the cheat sheet (v6 took about ten without it). Use --no-selftest while drafting and run the damage test before you stop; use --fix to refresh heading timecodes. Details of every gate: page 09.

S9. The read-aloud pass

S/extract-vo.js --script SCRIPT-vN.md --mode timed, then read the whole thing as spoken text once and go through references/read-aloud-checklist.md (26 items, on page 09). A pass that found nothing is suspicious. Fix, re-run S8 (edits can break a declared quote), and write Read-aloud pass: done (<date>; what was found) in the hand-off.

S10. The reader pass (only if the user has asked for subagents)

Give each of two readers only the blind text (extract-vo.js --mode blind: numbered paragraphs, no headings, no chain, no notes). One is a first-time viewer, one a skeptical editor; prompts are in references/reader-prompts.md. Readers return their report as text. Fix only what a reader backs with a quote; each disagreement with the declared chain is a defect in the script, not in the reader. If not authorised, write Reader pass: skipped: not authorised and put it first under "Decisions for you". Limits: two readers, one run, the same model family as the author, honour-system blindness.

S11. Hand-off and close

  1. Complete HANDOFF-vN.md. check.js reads three lines from it, which must start at the beginning of a line: Read-aloud pass: done (...), Reader pass: done | skipped: <reason> | pending, Unproven: <one sentence>. Below them: Decisions for the user, Open items before filming (every [CHECK] and [V-search] row plus the persona's "I" claims), What changed from the previous version.
  2. Write the final message with references/handoff-template.md: the state in one or two sentences, the script, what the user asked for (with the evidence), pipeline changes, things you should know (corrections, assumptions, unverified sources, tensions with our own data, length and cut candidates), decisions for the user, file paths.
  3. Run session-log.js to write the research record.
  4. Append what the run taught to learnings.md as [method], [measure] or [content]; add a row to tools.md for any tool you made.
  5. Run check.js last. Do not commit or push unless asked.

Before sending: check.js printed BAR MET or you named which gate is open; every number in the message came from a tool output you just read; the research record, learnings, tools registry and memory notes are current.

If you must stop early: the maturity ladder

Each rung is a legitimate intermediate result. Say which you reached.

RungWhat existsLooks like
L0Rival brief and teardownWhat rivals say, and what they get wrong.
L1Fact base and thesis (S3, S4)A verified story and a chosen question; no prose.
L2Chain and texture plan (S5)The whole script declared; lint mostly warns "not found in the text".
L3Draft with 0 FAIL (S6 to S8)Moser Baer v4 and v5: structure sound, voice partly machine-like, story or texture incomplete.
L4The v6 bar: BAR MET except the reader passMoser Baer v6 and v7; Cafe Coffee Day v1.
L5L4 plus a reader pass and fixesWhat v4 had after its two readers; the target for the next script.

What check.js reads from the folder

It infers the stage from files. report.md or synthesis.json in the topic folder (the parent of script/) means S1. teardown/SYNTHESIS.md means S2. Five or more [V], [V-search] or [CHECK] markers in FACTS.md plus the script file means S3. A chosen candidate and a cdl.question in the chain means S4. A named human, a figure with a quote and an earnest persona quote means S5. More than 600 spoken words means S6. The Moser Baer v7 status shows "S1 to S6" next to a green set of gates because the stages after S6 leave no file marker; the judgement gates come from the three lines in HANDOFF-vN.md. The inference is a hint, not proof that the stage was done well.

What this does not guarantee

That a second topic reaches the bar in one go has not been demonstrated beyond the Cafe Coffee Day run, which used the pre-round-7 rules and was done by one session with no subagents and no reader pass. The runbook, gate runner and cheat sheets are built so the later rounds' lessons are in from the start. The first run on each new topic is the test: record the deltas in learnings.md and adjust the runbook.

Written 2026-10-27 from the repository files and the project memory notes. If a page and a file disagree, the file is right: fix the page.