LEITMOTIF_ARCHITECTURE.md

music/LEITMOTIF_ARCHITECTURE.md

THE LEITMOTIF ARCHITECTURE — the roster completed, and what each motif has to do

CANON SUBORDINATION — this document is PROPOSAL-TIER: it serves canon and never outranks it.
The canon: the CVD · the T1 foundation docs · the T0 registries (registries/) · the spine
(docs/spine/CH_*.md) · the region pages (_source/02_Tier_2_Region_Pages/). Authority order: docs/DOC_MAP.md § 0.
Canon served (scanned from this document's own citations — widen it by hand where it is thin):
CVD §17 · T0_SFX_Registry · T0_Theme_Registry · T0_Thread_Grid · T0_Thread_Registry · docs/spine/CH_PROLOGUE.md
READ THAT CANON FIRST — open it and derive from it before you build anything from this document.
If this document disagrees with canon, CANON WINS and this document is the defect — fix the
document, never the canon. Nothing here is applied until it is ratified into canon.

Tier: PROPOSAL. The machine form of everything below is

docs/proposals/music/theme_architecture_rows.json, applied by

harness/apply_theme_architecture.py. The reasoning is here; the cells are there; the registry is

the authority once it lands.

0. What was missing, stated plainly

T0_Theme_Registry carries fourteen rows. Twelve are the cardinal roster Josh pinned at the

twenty-second sitting; two are the Cassius cue variants. That roster is good and it is not an

architecture, because five things it needs were reserved and never minted, and each absence has a

consequence you can name:

outright that a row with motif_class unset cannot be scored and cannot be rendered. Two of the

twelve are deliberately not tunes — the wonder identity is a harmonic-transformation identity and

the voice colour is a timbre — so a single hummability checklist run over the roster would have

failed them for not being what they were never meant to be.

inside a hard_line_relevance cell. Music is a named surface of HL_0043 and HL_0044, and the one

thing the antagonist material must do — recur, unnamed, for thirty-six chapters — had no row to

live on.

empty deny list has not been reviewed. Twelve rows, twelve empty deny lists.

triad-outlining *or* purely stepwise, deliberately, never both — that nobody had made for any

motif.

familiar bond across twenty-two species slots, and eleven realms, all with nowhere to go. The

doctrine's own allocation says twenty-two independent themes exceeds any listener's recognition

budget and produces mush; the fix is families, and there were none.

This pass mints all five, adds twenty-four rows, and moves the cardinal count by zero.

1. The allocation, and where the new rows sit

The cardinal roster is untouched: twelve rows, row_class = cardinal_theme, and the applier

refuses to write if that count moves in either direction. Everything below is Tier B or Tier C.

classcountwhat it is
cardinal_theme12unchanged; now carrying all thirteen new columns
family_head8seven thread families over the 22 threads, plus the realm family
companion_theme1the healer's child
cue_variant4the two landed Cassius stages, plus the childhood-constancy cue and the pre-gate pattern
timbral_signature1the voice colour, judged on the atmosphere bar
region_cell12the slice's Tier-C region cells, one per region page

2. The seven families, and why inheritance is the default

A thread earns its own Tier-B motif only if it recurs across five or more nodes, has an on-screen

agent, and has an arc that changes state. Every one of the twenty-two clears the first test — the

smallest, Thread 15, still carries seven anchors — so the first test discriminates nothing here and

the allocation is decided by the other two plus the recognition budget. Seven families, each a

shared head cell and a shared harmonic signature; every inheriting thread takes that cell with

exactly one interval substituted and a distinct carrier voice.

Thread 22 Sacred Stones and Thread 9 The Great Work inherit.

of Life inherit; all three are one idea at three scales — a built thing, a raised thing, an axis.

7, 12 and 20 inherit.

family alone is reveal-gated at Ch 38, and its head is stated unnamed before then.

shared idea and contour inversion is the shared operation.

Thread 21 heads it because this is the one thread where music is the mechanic rather than the

scoring — Flores canonizes the gong-waning as the region's vril-active instrument and the arc's

first audible vril resonance, and Bali reaches confrontation on it with sorcery music theory as

the chapter's lead questline.

Which number the anchor counts above are, and the divergence they sit on top of. Every count in

this section is T0_Thread_Registry.anchor_count (T01 24 · T02 37 · T03 36 · T15 7 · T17 39 — each

verified against the registry cell). That column diverges from T0_Thread_Grid's live population by

two to three times: counting Thread_Grid rows whose progression_stage is anything other than

NOT_PRESENT gives T01 65 · T02 63 · T03 69 · T15 8 · T17 44, and counting raw rows regardless of

stage gives 70 · 78 · 78 · 8 · 44. The allocation above is unaffected either way — the ≥5-node

test discriminates nothing under any of the three readings, which is exactly what this section

already says, and the family heads were chosen on the other two tests. But the two columns should be

reconciled before any Tier-B promotion decision is made to rest on a count, and the reconciliation

is a registry question rather than a music one: the divergence is pre-existing and was not minted by

this pass. Recorded here rather than boarded because this is the document that consumes the number,

and the consumer is where a stale number does its damage.

The two threads that came closest to earning independence and still inherit are Thread 17, which has

the anchor count for it but whose on-screen agent is the same agent as Thread 20's for most of the

arc, and Thread 13, whose arc changes state mostly through places rather than through itself. Both

are recorded here rather than argued, so a later pass can promote either on evidence.

3. The motifs this pass was asked for

3.1 The protagonist — already cardinal, now specified

The head is four notes and purely stepwise, chosen deliberately against the alternative: this

arc leans on fragile solo statements far more than on statements that have to cut through a loud

orchestra, and the head-cell law forces the choice rather than allowing both. One deviant only, a

borrowed degree on the third note.

The shape is the single-theme arc: the Prologue statement and the Ch-77 statement are the same tune

and the player must feel the distance. Eight transformations budgeted out of the allowed six to ten

— augmentation at the losses, diminution in pursuit, fragmentation as the combat-layer form,

reharmonisation at each vril escalation, one mode shift per integrity-band crossing, carrier

migration per region, and the closure change reserved for Ch 77. The three ending rows are not three

new tunes; they are that withheld cadence spent three ways, and the deny list forbids them any

shared arrival gesture, because CVD §17.5 requires three-ending differentiation with no convergence

cue.

The row's own notes already record the risk: its thematic kinship to the Grand Sage reveal makes a

pre-reveal leak high-risk. That is now a deny-list clause with a named check rather than a comment.

3.2 The main companion — a new Tier-B row, and one thing it may not do

The healer's child, CHAR_0002, has walked the route as the unsigned watcher since Ch 3 and steps

into companion at CH13_B01, where she signs her first note *Ntala* and opens the evidence journal

— the one canonical Ch-13 join-and-journal beat, bound by HL_0070. The motif is built for that

shape: the head cell alone for every unsigned-watcher appearance from Ch 3 to Ch 12, and the

full phrase first stated when she signs her name.

Fragmentation is normally the foreshadow operation, and using it for ten chapters would ordinarily

be a reveal problem. It is not one here, and the reason is worth stating: there is nothing held. She

is really there, the player really can see her, and the fragment is doing presence rather than

prophecy. What the fragments buy is that CH13_B01 lands as recognition instead of introduction.

And the thing it may not do. The spine records a designer-only resonance: the healer's child's

gender inherits from the player's Ch-1 best-friend selection, so the companion who joins at Ch 13

carries the same gender as the fairy-realm friend left behind — *invisible on first play and never

surfaced*, carrying zero forward reveal-valence. A shared motif between the two would surface it,

which is the one thing it may not do. So COMPANION_HEALERS_CHILD is declared independent of the

childhood-constancy cue, on the same grounds and by the same precedent as HOME_AND_LOSS's declared

independence from the protagonist head cell.

*The strongest objection:* that forfeits the best recombination payoff available anywhere in the

slice — two childhood motifs fusing at the Ch-13 departure would be the most affecting thirty

seconds in the first fourteen hours. *The answer:* the payoff that is actually earned there is the

object's, not the friend's. MOT_0001, the mother's ward, already recurs Prologue → Ch 1 → Ch 2 →

Ch 13 and resolves at Ch 13 in the live motif registry, and HOME_AND_LOSS already names those

exact beats. The departure has its cadence; it does not need a second one built out of material a

hard line says must stay silent.

3.3 The familiar bond — cardinal, and the trap in it

Head of three notes, triad-outlining because it has to read under twenty-two different species

carriers, with one unusual leap — an ascending sixth into the third note — that every per-species

variant keeps. Per-species carrier migration is the whole mechanism: the tune does not change, the

voice does. Twenty-two slots in the base game, thirty-three at the post-game Epilogue.

The deny list carries the trap. The player believes the Child Familiar dead from Ch 2; the truth

gates to the Truly Good path at Ch 58. No grief colour may touch that material before Ch 58 — a

mourning register applied early tells the player the score knows something they do not. The one

combination the motif is allowed, with the protagonist carrier, is reserved for the Ch-58 reunion

and states the relation with no dialogue.

3.4 The antagonist pattern — the row that did not exist

PATTERN_UNNAMED_PREGATE, row_class = cue_variant, parent HOUSE_OF_VELHEIM_THEME,

reveal_gate = CH_38. It is modelled exactly on the ruled Cassius collapse: one motif with logged

transformations, not a second identity, so no foreign key moves.

Thread 3 is live from Ch 2 at its pre-family scales — an individual bargain at Ch 2, then the

institutional forms at Ch 11, Ch 12 and Ch 13, each a real local antagonist and none of them named

as anything larger. The motif is the parent's three-note head, fragmented, and fragmentation is

the *only* operation permitted before Ch 38: augmentation, combination or a mode shift would each

announce that the score has an opinion. A different local carrier every time, so the listener

remembers the shape and never the sound. One statement per node, never the phrase, never a swell,

never on a face.

An unnamed recurring motif is the leitmotif's entire power. The player is meant to have heard this

many times before anyone tells them it means anything, so that Ch 38 is a recognition. **The count,

read off T0_Thread_Grid rather than estimated: Thread 3 is present in thirty-five chapters before

Ch 38, so one statement per node is thirty-five pre-gate fragments, of which eleven fall inside

the Prologue→Ch 13 slice** (Ch 2–9, Ch 11, Ch 12, Ch 13; Ch 10 carries no Thread-3 presence).

Eleven is the slice commission; thirty-five is the transformation budget.

The firewall is mechanical, not a promise. The row is named *The Recurrence* — a name that says

what the cue does and never what it means. harness/emit_music_cues.py refuses to emit any cue

whose reveal_gate is later than its own chapter if the cue **name, its site or its trigger

context** carries a held token — those are the three fields that exist at construction time and all

three are scanned there. The cue_id is assigned inside the writer, so its value cannot be scanned

at construction; its shape is MC_dddd, which carries no token by construction, and verify()'s V4

scans the assigned value along with the name and the trigger. Must-fire fixtures prove both

refusals fire. **The gate source is the theme row's own reveal_gate, taken as the stricter of that

column and a frozen crosscheck dict, and it fails closed**: an unparseable gate raises rather than

defaulting to ungated, a theme the dict has never heard of is still held if its row declares a gate,

and a column-versus-dict contradiction raises rather than being averaged. The earlier shape read the

dict alone with a default of zero, which is a fail-open whitelist coupling. The recurrence anchors are

deliberately left unpopulated: each statement has to be placed against its own node's staging by

a lane that has read that node, and a hand-typed anchor list here would be exactly the invented-canon

failure this repo gates against. The firewall arms itself the moment the first anchor lands.

3.5 The childhood constancy — a variant, not an identity

The Ch-1 best friend is *the one who stayed while others turned*. That is the chapter's warmth and

the thing the argument puts at risk. It lands as a cue_variant of HOME_AND_LOSS rather than a new

row, because giving the best friend an independent identity would make the childhood readable as

setup, and HL_0116 forbids exactly that: the rift-fall has no author, no aim, no omen and no curse,

and the score is a player-facing surface of that hard line.

The transformation plan has a deliberate hole in it. Nothing happens at the argument. The

correct cue for CH01_B12 is the abundance register continuing, unbothered — which is what actually

happens to a childhood afternoon after a fight, and is also the only setting that refuses to

editorialise.

3.6 The region families — Tier C, and the one rule that keeps them honest

Twelve region cells for the slice, one per region page, each parented to JOURNEY_WORLD, each

one-to-two bars, none of them required to be hummable — only coherent with the parent.

Every cell's instrumentation is copied from that page's own Section 10 rather than composed

here, so a composer reading the row is reading the page. That is what stops the generic

world-music wash the doctrine names as a care failure rather than a taste note. It also means the

cells are honestly uneven, and the unevenness is the point: Bali's cell has a full ensemble

architecture to build on and Swahili Coast's has three attested sentences, because the page says so

first and the page is right to. Where a page states its lane is thin, the cell is built from what is

attested and the gap is left.

The Tier-C rule that matters: where a region also carries a Tier-A payoff, its cell **must quote the

parent head at least once**, or the payoff has no soil to grow in — and that quotation is a

composer-authored stem laid over generated material, or fed as lego conditioning, never a prompt,

because the generator has no melodic conditioning that could honour one.

**The one licence constraint that binds the moment generated material enters, stated here because

this is where generated material and lego conditioning are specified.** The Sonniss bundle licence

prohibits use as training data, so **no Sonniss file is ever a fine-tune corpus, a LoRA corpus, or an

audio conditioning input for any generator** — direct use only. The landed Sonniss beds ride in the

bed worklist's landed_beds_excluded list as the material a generated bed must not be derived from,

and the constraint travels on the row rather than in a note: every cue row carries licence_class

alongside bed_source, the per-page §10 projection block carries both columns and restates the rule

in its header, and every produced bed writes its generating model and licence into

T0_SFX_Registry.generation_licence_ref — a dispatch field the worklist hands the operator, not an

assertion nobody was instructed to satisfy. The generator itself (ACE-Step-1.5-XL-SFT) is MIT with

no output-use clause; that read is recorded as DL_0008/DL_0009 in the tooling download manifest

with the licence body pinned by hash, and it is the *other* side of the constraint, not a

substitute for it.

4. The deny lists, and the one clause on every row

Every new row carries a real deny list. One clause is universal, because CVD §17.1's collective

protection expressed in music has exactly one failure mode and it is easy to commit by accident:

No region's own register is used as the threat signal, systematically darkened, inverted or
menace-coded. The darkening operations belong to the antagonist material and travel with it,
never with the place.

The corollary is equally binding and points the other way: an individual antagonist may be scored

fully inside his own culture's register, with the same craft as that region's protagonist cues. A

blanket register ban is the named failure, not the safe option. Care-tier inflation is a defect;

care-tier evasion is also one.

JOURNEY_WORLD carries the clause hardest, because it is the motif that visits every region, and it

may never become the recurring cue for threat in any region it enters.

5. What this pass deliberately did not do

SUPERSEDED IN PART, 2026-08-05. The first bullet below was true when this pass ran and is no
longer true of the roster. Josh's ruling that day — *"Humans aren't composing the music… what the
fuck. The entire music pipeline is yours"* — retired composer-in-loop, and the melody A/B then
measured that authored composition delivers the brief's contour where text conditioning does not
(dossier §8). The melodies now exist: thirteen served head cells plus one held parent, in
notes, at build/audio/authored/**, composed by harness/music_gen/theme_compositions.py and
checked by author_head_cell.py's battery. Two of this document's own named transformations are
composed as well — the companion's head-cell-alone form (§3.2) and a family's minor-mode
recurrence, built on the realm family because §4's care clause forbids darkening a real region's
register and that is the one family whose register is invented. **Everything else in this section
still stands**, in particular the unpopulated recurrence anchors of §3.4: each statement is still
placed against its own node by a lane that has read that node, and none of them were placed here.

flag stays True on every row.~~ What is specified here is the *shape a melody must satisfy* — head

length, contour class, the single deviant, the transformation budget, the payoff node — which is

what a brief is for, and it is exactly what made the composed cells checkable rather than merely

present: every constraint in this document became a control the battery runs against the notes.

meaningless without a deny list and its region-as-threat check; those rows now have both, and the

substrate column fills when a register card is signed off per node.

lanes held the shared baselines open — re-emitting the fidelity baseline in that tree would have

swallowed their work, which is the reason recorded at the head of

harness/apply_theme_architecture.py. The director ran it in a clean tree:

T0_Theme_Registry went 14 rows x 30 columns to 38 x 45, the cardinal roster asserted at twelve on

both sides, the fifteen columns declared under owner leitmotif-architecture in

docs/registry_extensions.json, the parent_theme_id self-edge declared in docs/fk_spec.json

(16 tokens, 0 dangling) alongside floors on theme_id, row_class, tier, motif_class and

reveal_gate, and the fidelity baseline refreshed through the SCOPED vector on the theme keys

alone. The edge and the four enums are mutation-proved rather than asserted: a dangling parent, a

cardinal row spelled under a new row_class token, an off-axis tier and an off-grammar

reveal_gate each fail the gate, and the untouched registry passes.

The consequence named the same day is therefore DISCHARGED. Eleven of the fifteen composed

artifacts had no live registry row, so their records were not permitted to claim one; each licence

and generation record DERIVES its registry pointer from whether the row actually exists and

carries registry_row_present beside it. Twenty-four records were re-derived by

author_head_cell.py --refresh-docs in the landing commit and now name the live registry — the

derivation is what made that a one-command repair instead of a hand sweep. A record asserting a

canon home that does not exist is the same defect class as a proof number that no longer

re-derives, and so is a record still denying a home it now has.

stale.** Found by the apply lane, 2026-08-05. harness/apply_theme_architecture.py held a

hardcoded thirteen-name NEW_COLUMNS list beside a docstring stating the count came from the data

and "never written down here". When plant_node and diegetic_surface were minted into

theme_architecture_rows.json the constant did not move, so an apply would have landed thirteen

columns while the bullet below claimed the two new ones were minted "which makes the gate

representable" — they would have existed in a proposal file and nowhere a gate can read, which is

the half-unrepresentable defect restated one level up. The constant is deleted, the set is read

from the data, and self-test fixture 5 reads the WRITTEN header rather than the constant. It is

mutation-proved: restore the thirteen-name list and the fixture names plant_node and

diegetic_surface as never minted.

diegetic surface, payoff node and closure policy all assigned before first render." Two of the four

had columns and two had none, anywhere — so the gate could not be failed on them, and a first render

landed and is publicly served on fourteen pages with half its gate unrepresented. plant_node and

diegetic_surface are now minted as columns in theme_architecture_rows.json and, since the

2026-08-05 apply, as real columns on the live T0_Theme_Registry — which is what actually makes the

gate representable, since a column that exists only in a proposal is a column no gate can read.

They are deliberately unpopulated, on the same reasoning as the recurrence anchors

above: a diegetic surface exists in a NODE — an instrument a character plays, a performance the

player can walk up to, a surface the player physically inputs — and it is assigned by a lane that has

read that node. Filling it from here would invent it. **Outstanding, and owed before the next render

of any Tier-A row:** a plant node and a diegetic surface for each Tier-A theme, assigned from the

spine entry it plants in; PROTAGONIST_THEME is first, because brief §1 makes its diegetic plant a

named requirement inside the first three nodes it appears in, and docs/spine/CH_PROLOGUE.md

# music_mood currently describes a register with no diegetic performance surface in it at all.

6. How to check this pass rather than trust it

python harness/apply_theme_architecture.py --self-test # 6 fixtures, isolated copies

python harness/apply_theme_architecture.py # the dry-run diff

python harness/emit_music_cues.py --self-test # the fixture suite; exit 2 on any failure

python harness/emit_music_cues.py --check # the cue table re-derives identical

python harness/emit_music_cues.py --verify-s10-flip # the blocker proof, re-run

The emitter's fixture count is deliberately not written down here or printed by the script. It was

written down as eleven, then as thirty-five, and both numbers were stale the moment the next fixture

landed — a rotted proof number reads as evidence, which is worse than no number. The suite runs on

every invocation of the emitter rather than only under --self-test, so the exit code is the

claim.

The self-test mutation-proves the refusals against temporary copies rather than asserting them: a

thirteenth cardinal row is refused, a live roster that has already drifted off the pin is refused, a

column fill naming a theme that does not exist is refused, and a second apply is recognised as

already applied instead of duplicating twenty-four rows. The live registry is never touched by any

of it.

Generated by harness/site/structure_site.py — the URL path is the repo path. review root