STORYDEPTH_ARC_ARCHITECTURE_2026-07-27.md

pipelines/STORYDEPTH_ARC_ARCHITECTURE_2026-07-27.md

THE PER-ARC / RELATIONSHIP PASS ARCHITECTURE

Read-only design-research analysis. Axis: what ARCS exist in the corpus, what tracks each,

where the DATA HOME and the DEPTH PASS are missing, and the machine-checkable form of

"every relationship holds depth and flows end to end."

Analyst note on evidence tiers used below:

sibling token), per the standing a-search-that-cannot-match rule.

---

0 · THE ONE-LINE ANSWER TO JOSH'S QUESTION

Everything in the factory is keyed on a NODE or a ROW. Nothing is keyed on an ARC.

arc_id appears 0 times across registries/, docs/, and harness/

(POSITIVE-CONTROLLED: the identical grep for thread_id returns hits in registries/).

There is exactly one arc-shaped data structure in the entire corpus — T0_Thread_Grid,

664 rows of (thread_id × chapter_id → progression_stage) — and **no gate, critic, skill, or

enrich pack ever reads it as a sequence.** It is written per-node and never graded end-to-end.

That is why Josh can author a Prologue/Ch-1 emotional spine as good as the amulet chain and

still be right to worry: the machine has no place to put "this arc" and no pass that walks it.

---

1 · HOW EVERYTHING HAS BEEN GETTING WIRED UP (the honest map of the factory today)

Five wiring vectors exist. All five are node-scoped or row-scoped.

#VectorWhat it isScopeArc-aware?
1The spine node79 docs/spine/CH_*.md at schema v3.1 — the beat → fork → state graph (beat_id permanence, typed site rows, action-keyed fork tables, mark_write with forward_track, seam diffs)ONE nodeNo
2The registries56 registries/T0_* dirs; the cascade's step-9 scatter writes structured fields out of the node into rowsONE rowThread_Grid only
3The gates29 in harness/gates_config.json27 node/row-local; 2 sequence-aware (below)Barely
4The skills/spine-chapter (12-step cascade, Step-3a significance-lens pass) + normalize-doc (fresh-context critic rubric)ONE nodeNo
5The docs tier + DOC_MAPproposals/design docs + the anti-orphan master indexHuman/agent-readN/A

The two gates that already read a SEQUENCE — these are the proof the pattern works, and

they are the template to generalize:

two manifests: the CARRIED-FAMILIAR manifest (a familiar asserted PRESENT at page N+1 that

page N neither carries nor acquires is a finding) and the LINK-RECIPROCATION manifest. It even

gets the hard part right: out-of-slice acquisitions are recorded, not flagged. (CITED:

file docstring.) This is a working arc-continuity gate that happens to be scoped to region

pages instead of arcs.

continuity (does the named later chapter actually READ the mark?), pre/post-Ch-65

path_bucket consistency, and seam cross-file equality. **Fires only on full-79-node

invocations.** (CITED: docs/SPINE_SCHEMA_v3.md §6.)

The gap this map exposes: forward_track is the corpus's ONE real end-to-end promise→payoff

tooth, and it is scoped to a single mechanic (the community mark). MEASURED: 338 mark_write/

forward_track lines across 51 of 80 spine files. The same tooth, generalized to every arc

class, is most of the answer.

Also relevant and often mis-stated: docs/WIRING_AUDIT.md still lists the 33 significance

lenses as [ORPHAN]. That is STALE. MEASURED: .claude/skills/spine-chapter/SKILL.md

carries 10 significance hits including a dedicated Step 3a — the significance-lens pass

(the 33 lenses in seven groups + the §4 control-for-relevance filter, with `[SRC:

SIGNIFICANCE_LENSES]` anchor guidance for blocks 6/7/8) and normalize-doc rubric lines 151-152.

So the lenses ARE wired — author-side, per node. What does NOT exist is any lens column in

any registry (significance_lens = 0 registry hits) and any application of a lens **to an

arc**. A region gets lensed; a relationship never does.

---

2 · THE ARC CENSUS — every arc class, what tracks it, what is missing

Twelve classes. For each: DATA HOME (is there a per-arc × per-node anchor grid?), DEPTH PASS

(who walks it end to end?), and the cost of the gap.

2.1 MAIN STORY (1 arc, 79 nodes)

three-path integrity model; WS_004 path_bucket locking at Ch 65; seam diffs between nodes.

(docs/proposals/WHOLE_ARC_CONNECTIVE_WEB.md) + check_spine_graph's cross-file ERROR tier.

workflow whose output is proposal-tier**, and its own headline finding is that the endgame

renders path-flat: CH_75/76/77 "currently list the found-family present path-flat (the

largest relationship gap)" and CH_75's coalition is "currently path-flat" (CITED:

WHOLE_ARC_CONNECTIVE_WEB_INVENTORY.md ECV-01/ECV-05/ECV-07). A per-node gate cannot see

path-flatness; only an arc pass can.

documented, ranked, and unbuilt, with no standing consumer to re-check it.

2.2 THE 22 THREADS — the proven pattern, and the proof that a data home alone is not enough

`thread_id | chapter_id | progression_stage | content_summary |

authoritative_paragraph_anchor | extensions`. This is the model to generalize.

FindingValue
Stage distributionANCHOR 441 · ESCALATION 106 · NOT_PRESENT 49 · CONFRONTATION 45 · RESOLUTION_FINAL 15 · RESOLUTION_PARTIAL 4 · CONVERGENCE 2 · CONFRONTATION_DIRECT 1 · CAPSTONE 1
Threads with no resolution/capstone stage anywhere15 of 22 (T07-T19, T21, T22)
Threads that are MONOTONE (only ANCHOR/NOT_PRESENT, zero escalation)1 — THREAD_19 End-of-World/Eschaton, 10 appearances, all flat
Last appearance of every minor thread except T20between Ch 46 and Ch 69 — none reaches Ch 77
T0_Thread_Registry.resolution_chapter populated0 of 22 (also anchor_count, first/final_anchor_chapter, weaving_count all empty)

66% of every cell in the one arc-tracking structure carries a single value (ANCHOR). The six

MAJOR threads run Prologue→Ch 77 and land RESOLUTION_FINAL; **all sixteen minor threads stop

mid-arc and end on ANCHOR / ESCALATION / NOT_PRESENT.**

*Honest caveat (INFERRED):* ANCHOR may be being used as "present/tracked" rather than "the

arc's anchor beat," in which case the defect is that the grid's vocabulary has collapsed and

no tooth forces the distinction. Either reading gives the same conclusion: **the corpus's one

arc tracker cannot currently distinguish a thread that is building from a thread that is

merely being mentioned.** A prose read-verify per thread is the correct confirmation step and

is exactly what the arc pass in §5 performs.

from Thread_Grid's 664 rows", zero-token) is filed as bookkeeping. It is not. Running it

*is* the shape diagnostic — it surfaces the 15-thread no-resolution finding automatically.

2.3 THE 12 SIDE QUESTLINES — a data home that exists but was never given a shape

chapter_span as a prose string, not a grid. The real per-node data lives in spine Block 11

as `- SQ4 · questline mystery_detective · stage ADVANCE · gate has(local.trace_started) ·

beats [...] · reward ...`. It is never scattered into an arc grid.

SEED 23 / ADVANCE 336 / COMPLETE 11, so a GATE hit would have been found):**

QuestlinenodesSEEDADVANCEGATECOMPLETE
archaeology_inscription_occult5925601
lost_civilizations4734400
mystery_detective4724203
secret_societies4624301
astrology_psychology4033601
fairy_tale_folklore3953202
anomalous_phenomena2532002
military_history2112000
sorcery_music_theory2111901
cryptids1711600
pirate_naval60600
trickery_gambling20200

{SEED, ADVANCE, GATE, COMPLETE} and the schema says "twelve_tier_gate where it binds"

(CITED: SPINE_SCHEMA_v3 §3d/§4). No side questline has a single machine-visible gating

milestone. The enum value exists and has never been used.

trickery_gambling has 2 beats across 79 nodes against archaeology's 59.

and none has a mastery gate. This is the single most legible "does not flow end to end"

defect in the corpus, and it is invisible to all 29 gates because every one of them is

node-local.

2.4 THE 10 TRADE QUESTLINES (120 mastery gates)

ladder into ONE string column: `twelve_tier_quest_gates =

"gate_1_neophyte:Q_TR1_NEO; gate_2_zelator:Q_TR1_ZEL; …"`. MEASURED/POSITIVE-CONTROLLED:

Q_TR appears 0 times in T0_Quest_Definition_Registry (16 rows; the same file matches

quest_id). Neither registry is enrolled in fk_spec (CITED: register #38).

corpus — dangling as substrings. Window-plan rank 23.

2.5 COMPANION PERSONAL ARCS — the class with no home at all (register v1.1 #41)

companion rows, no companion class. `T0_Quest_Definition_Registry.quest_type ∈

{canonical_hard_line ×12, epilogue_resolution ×3, prologue_baseline ×1}` — no companion type.

22 buckets is LOCKED numerical canon, so a 23rd bucket is not the answer (CITED:

docs/pipeline_review/LENS_BG3_2026-07-27.md BG3-3, with its own positive control).

(PARTY_STRUCTURE, COMPANION_MECHANICS_CONTRACT, CAST_INVENTORY, per-companion files) — all

Status: RECOMMENDATION for Josh, none machine-consumed.

distinct chapters): the entire recurring on-screen cast is seven ids** — Ntala CHAR_0002

(191 actor-beats / 55 nodes), Ana CHAR_0017 (44 / 22), the Elven King CHAR_0005 (5 nodes),

Kxao CHAR_0071 (3), plus three more.

loyalty_belief_axis filled on 4. chapters_present is filled 163/163 but is a **prose

string**, not a stage grid.

companion reacting to the player's choices* — the departure system's own surface. A loyalty

arc is the inverse: the player serving the companion's goal. PARTY_STRUCTURE §3 Tier-1

names it as a requirement; nothing contains it. Zero exemplars on the human axis (the only

paid loyalty arc, CL-01, is the childhood familiar — a firewalled different axis).

whole game is built around is tracked as attendance.

2.6 THE 22 FAMILIAR BOND ARCS

chapter_first_encounter, chapter_bonding_window, bonding_quest_id,

bond_formation_beat_ref, loyalty_condition. That is an acquisition record, not an arc:

it names where the bond FORMS and nothing about where it deepens, is tested, or pays.

real continuity checking — but it runs over region pages (4 cut so far), not the 79 nodes.

Ch 58 reunion (Truly-Good only) → Ch 65 three-way 22nd-slot lock → Ch 75 timed-assist window

(CITED: connective-web Lens C / ECV-02). It has promise, escalation, a band-gated payoff, and

a terminal consequence. It is the exemplar the arc registry should be shaped to hold — and

it lives in a proposal doc, not a registry.

2.7 THE ANTAGONIST WEB ARCS

keyed (operative_id, chapter_id) — MEASURED: 62 distinct chapters covered. Structurally

this is already a grid. Plus WS_020 antagonist_operational_state_per_region and

WS_013 cassius_velheim_state.

*where the pattern escalates*. Reveal discipline is enforced separately and well

(check_reveal_discipline + check_grand_sage_silence, gate #25 PASSing).

not a new home.

2.8 REGION / COMMUNITY ARCS (the relational webs + assimilation-integrity)

accumulation … RATIFIED"), T0_Region_Index (76 rows / 79 nodes), and the strongest existing

tooth: mark_write {community_id, valence, persistence, forward_track:[CH_NN]} with

check_spine_graph verifying every forward_track target actually reads the mark (ERROR

tier, cross-file). MEASURED: 338 mark/forward_track lines across 51 nodes.

shape*.

at doctrine level (§4.9 / §8.3 / §5.5.4) but the two flagship revisits — Ch 40 "the same Ch 11

forest" and Ch 42 "the Ch-12 serpent corridor" — **read identically regardless of how the

player treated those communities centuries earlier.** Also IR-6: the Ch-2 Kelimutu carved mark

is authored as "the Ch-39 revisit anchor" and Ch 39 is West Africa — a **dangling

forward_track**.

world) is data-present and texture-absent at the two chapters that were built to carry it.

2.9 THE ROMANCE / PARTNERSHIP LANE

returns exactly one hit, and it is a book title in T0_Source_Material_Registry. The

recovered Marriage & Partnership system's named home (T1_Personal_Dimension_Spec) is a

byte-level empty stub (CITED: register #22/#23/#43; window-plan rank 24).

2.10 THE PROTAGONIST'S INTERIOR ARC — grief, guilt, identity (Josh just authored its engine)

are WS_009/010/011 (journal status / entries / voice texture), WS_007 age_stage,

WS_025 identity_hiding_status, WS_018 six_option_cumulative_record, and spine Block 4

(body prose, "close-third personal-arc lens"). Block 4 is **prose, deliberately not the event

spec** (CITED: SPINE_SCHEMA_v3 §2/§6 — the schema explicitly says Block 4 "was never the event

spec").

with anchors, escalations, and a payoff.

amulet, her death during the rift-spawn while the King served the realm, the run-back, the

King's never-resentment, the townspeople's grudge, the friend's constancy, the dumb fight, the

fall (CITED: PRE_5090 progress ledger 2026-07-27i). The integration of that is an 18-file

spine plan in AMULET_PROVENANCE_BRIEF.md — i.e. it will be applied node by node, and

after it lands **nothing in the machine will hold "the grief arc" as a thing that can be

graded, re-checked, or deepened.** The next enrichment wave will not know it exists except as

prose scattered across 18 files.

arc with no container at all.

2.11 THE OBJECT / SYSTEM SPINES (the amulet, the journal, the vehicle line, the door-ladder)

WHOLE_ARC_CONNECTIVE_WEB.md §1 (proposal-tier).

the shape an arc row should hold. ECV-06 wants it mechanized as an accumulated record

(the number of Cassius's arguments you can rebut = the atrocities you documented) — currently

scripted, not accumulated.

(SYS-3/TL-14 → Ch 55 Vimana): the capstone "debuts cold" because the feeder rungs were never

authored as a ladder.

2.12 THE RECURRING-BEAST / DEITY-PATRON / ERA-RHYME CHAINS

across 6 connection types (5 recurring-beast spines, 6 deity-patron chains, 9 era-rhymes,

11 L3-literal chains, 27 callback pairs, 7 system spines) and **9 true orphan / unpaid /

seed-debt callbacks**.

next cascade wave cannot see them.

Census roll-up

Arc classInstancesData homeDepth passGrade
Main story1STRONG (v3.1 graph)PARTIAL (RRs, one-time web pass)B
Threads22EXISTS (Thread_Grid)NONEC
Side questlines12PARTIAL (prose span + node rows)NONED
Trade questlines10 (120 gates)NONE (packed string)NONEF
Companion personal arcs~7 recurringNONENONEF
Familiar bonds22PARTIAL (acquisition only)ACCIDENTAL (slice_coherence, region pages)D
Antagonist web64 operativesGOOD (chapter-keyed grid)PARTIAL (reveal gates)B−
Region / community76 regionsGOOD (mark_write.forward_track + WS_019)PARTIAL (link-exists tooth)B−
Romance / partnership0NONE (spec is an empty stub)NONEF
Protagonist interior1 (+sub-arcs)NONENONEF
Object / system spines~7NONE (proposal only)NONEF
Beast / deity / rhyme chains65NONE (proposal only)NONEF

Total arc population if registered: ~290. Tractable — smaller than Thread_Grid's 664 rows.

---

3 · THE ARC REGISTRY — the Thread_Grid generalized

Design principle, per the brief: honor the proven pattern; extend, never duplicate.

T0_Thread_Grid already works structurally. The arc registry is that same shape with the

thread-specific assumptions lifted out — and Thread_Grid becomes a view of it (or is

migrated wholesale; see §3.4). No arc class gets a bespoke tracker.

3.1 T0_Arc_Index — one row per arc (the "what is promised" layer)

ColumnTypeNotes
arc_idARC_NNNNpermanent, never renumbered (the beat_id permanence rule)
arc_classclosed enummain · thread · side_questline · trade_questline · companion · familiar_bond · antagonist · community · partnership · interior · object_spine · chain
arc_nametextplayer-facing where one exists, else the corpus slug
participantsFK arrayCHAR_/FAM_/community_id/faction/NW_/region_id/BE_ — FK-checked like systems: prefixes
owning_docanchorthe T1/T3 doc with authority (the authoritative_paragraph_anchor convention)
first_anchor_node · last_anchor_node · resolution_nodenode idsDERIVED from the grid, never hand-typed (the rank-28 lesson)
promised_beatstext arraywhat the arc's setup PROMISES (the machine form of "the amulet chain")
payoff_nodesnode arraywhere each promise lands; every entry must be grid-present
layer_spanL1/L1.5/L2/L3 setan all-L2 relationship arc is a codex entry, not a relationship
lens_setlens idswhich of the 33 significance lenses / craft lenses the arc registers on
care_band · reveal_windowenumsinherited from the existing vocabularies, arc-scoped
variance_axisenum setwhich of {integrity, relationship, faction, mark, path_bucket, none} alters this arc's later texture — none is the path-flat detector
open_by_designbool + reasonthe honest escape hatch: an arc with no resolution must SAY so and why
depth_gradeA-F, DERIVEDcomputed by the gate from §4's rules; never authored

3.2 T0_Arc_Grid — one row per (arc × node) (the "where it lives" layer)

Identical in spirit to Thread_Grid's six columns, plus the v3.1 join:

ColumnNotes
arc_idFK → Arc_Index
node_idCH_NN / CH_PROLOGUE / CH_EPILOGUE
progression_stageONE unified closed enum across all classes (§3.3)
beat_refs[CH40_B04, …]the join Thread_Grid lacks. Ties the arc to the v3.1 beat graph, so an arc stage is addressable at beat granularity and inherits the beat's in:/out:, reveal, layers, and [SRC:]
content_summaryas today
authoritative_paragraph_anchoras today
state_reads / state_writesws.* / local.* keys — makes promise→payoff machine-visible the way forward_track already is
extensionsas today

3.3 The unified progression_stage enum (reconciling three existing vocabularies)

Today: threads use ANCHOR/ESCALATION/CONFRONTATION/CONVERGENCE/RESOLUTION_*/CAPSTONE/NOT_PRESENT;

side questlines use SEED/ADVANCE/GATE/COMPLETE; familiars use an implicit

first_encounter/bonding_window. Three vocabularies for one concept is why nothing composes.

Proposed single enum (a superset that maps both existing ones losslessly):

SEED (the promise is planted) · PRESENT (tracked, no movement — the honest home for the 441

degenerate ANCHORs) · ESCALATE · TEST (the gate/confrontation — absorbs both GATE and

CONFRONTATION) · TURN (the reversal/cost beat — **new, and the arc-scale hook for the rank-9

narrative-craft gate**) · PAYOFF · RESOLVE · DORMANT (explicitly asleep, with a wake node) ·

NOT_PRESENT.

Mapping: ANCHOR→SEED|PRESENT (the disambiguation the corpus currently cannot make and which

the arc pass performs once per thread), ADVANCE→ESCALATE, GATE|CONFRONTATION*→TEST,

COMPLETE|RESOLUTION_*|CAPSTONE→RESOLVE, CONVERGENCE→PAYOFF.

3.4 Migration posture (extend, never duplicate)

1. Thread_Grid is the seed data. Its 664 rows import as 22 arc_class=thread arcs. Keep

T0_Thread_Grid as a generated VIEW for one release so every existing consumer

(enrich.py:thread_rows, check_spine_graph's THREAD_NN roster check) keeps working, then

retire it. Never two writable homes for one fact (the living-source rule).

2. Antagonist_Network_Registry needs one added column (progression_stage) and an

arc_id; its 64 (operative, chapter) rows import directly.

3. Familiar_Registry / Character_Index / Questline_Index / Trade_Registry keep their entity

rows and gain an arc_id FK. The arc grid holds the per-node stages; the entity registries

stay the identity layer. No entity data moves.

4. Companion arcs take the ruled reuse-first route (CITED, BG3-3 recommendation): a

companion_arc value on T0_Quest_Definition_Registry.quest_type + a companion_ref FK to

T0_Character_Index, riding the existing DT_Beat/DT_Fork spine, gated on the BOND band,

writing the same WS_027/WS_028 the departure system reads. No 23rd bucket — the

locked 22 is untouched because an arc is not a questline bucket.

5. docs/fidelity_baseline.json refresh via --emit-baseline in the same commit (standing rule).

6. DOC_MAP row + gates_config.json entry at creation, or it is an orphan by definition.

---

4 · THE DEPTH PASS — the two halves nobody owns today

The per-node critic checks the node. Nothing checks the arc. The answer is two things: a

deterministic gate that grades SHAPE, and a fresh-context critic fan-out that grades DEPTH.

Neither replaces the other — the gate is cheap and always-on; the critic is the judgement.

4.1 harness/check_arc_continuity.py — the deterministic shape gate

Built on the established scaffold pattern (PASS-on-empty, LOUDLY DECLARED NOT-ARMED for every

unarmed assertion in its own scorecard every run, must-fire/must-not-fire fixtures via

--self-test exiting 2 if a ruler rotted) — the exact discipline gates 26-29 already use.

Corpus-wide, so like check_spine_graph's cross-file tier it fires on full invocations.

Eight teeth, each of which catches a defect measured above:

ToothRuleCatches today
T-1 SHAPEevery arc has SEED → ≥1 ESCALATE/TEST → RESOLVE, or open_by_design=true with a reason15/22 threads · 5/12 side questlines · 2 no-seed questlines
T-2 GATE-PRESENCEany arc whose class declares gates (trade_questline, side_questline with a twelve_tier_gate) has ≥1 TEST stageGATE = 0 corpus-wide
T-3 DORMANCYnode-gap between consecutive stages ≤ the class's cap, or the row is explicitly DORMANT with a wake nodeseed-debt (TL-13 contest ladder, SYS-3 vehicle line); minor threads dying at Ch 46-69
T-4 PROMISE→PAYOFF CLOSUREevery promised_beats entry has a payoff_node that machine-READS it — the generalization of the proven forward_track tooth to every arc classthe dangling Ch-2 Kelimutu mark (IR-6); the 120 dangling Q_TR* gates
T-5 VARIANCEvariance_axis ≠ none for any arc of class companion/community/familiar/partnership: ≥1 fork whose options alter this arc's later texturethe path-flat CH_75/76/77 found-family; the integrity-invariant Ch 40 / Ch 42 revisits
T-6 MONOTONYno arc may be >80% one stage valueThread_Grid at 66% ANCHOR; SQ rows at 89% ADVANCE; THREAD_19 at 100%
T-7 NON-GATINGno arc stage is progression-critical — the check_no_dead_end §3.5 invariant lifted from nodes to arcs(already clean; keeps it clean as arcs mint)
T-8 DENSITY FLOORan arc's node count ≥ the class floor, or it is declared a cameotrickery_gambling at 2 nodes; pirate_naval at 6

Every tooth is computable from T0_Arc_Grid + T0_Arc_Index alone. No new authoring is needed

for the gate to be honest on day one — it will report DECLARED NOT-ARMED for classes with no rows

yet, which is itself the visible backlog.

4.2 The ARC PASS — the fan-out that makes the Pro→Epi sweep a STANDING pass

The standing whole-arc directive ("you're missing a LOT") was executed once, as a workflow, and

its output is a proposal file. That is a heroic pass, not a factory. The factory form:

own grid slice, the anchor nodes named in it, the arc's owning_doc, and the runbook. Not

the full reference stack — the standing trim-shared-reading rule.

with node targets** (arc-scoped seeds, not prose).

every node), calibrated with a devil's-advocate pass against over-conservatism.

is unchanged.

a git diff-derivable worklist (script-emitted, never hand-typed).

This is the piece that answers "how do we GUARANTEE the amulet-class depth everywhere": the arc

pass is the amulet conversation, automated, once per arc, forever.

4.3 The DEPTH rubric the arc pass grades against (the craft half the gate cannot see)

The gate proves an arc has a shape. This proves it has weight. Six criteria, drawn from what

the corpus already ruled rather than invented:

1. PROMISE — the arc's setup makes a specific promise a player can feel, not a topic.

2. TURN — there is a reversal, a cost, and a moral residue. This is **window-plan rank 9's

narrative-craft seed gate (reversal / cost / residue), lifted from the seed to the ARC** —

which is where it actually belongs, and it should be authored at both scopes at once.

3. VARIANCE — the arc reads differently depending on who the player has been (integrity /

relationship / faction / mark). The path-flat finding is a rubric-3 failure at scale.

4. RUNWAY — the capstone was pre-taught. Seed debt is a rubric-4 failure.

5. LAYER FIT — L1 playable, L1.5 ambient, L2 completionist, L3 connective; a relationship arc

that never touches L1 is not a relationship.

6. VOICE — arc-scoped natural-voice: the same person sounds like the same person across 55

nodes, culturally registered. Node-scoped voice checking structurally cannot verify this.

4.4 Pipeline wiring (the anti-orphan half — without this the registry is another orphan)

SurfaceChangeWhy
harness/enrich.pyadd --arc ARC_NNNN mode; and in the CHAPTER pack, add an arc-context section: for every arc touching this node, its stage here, its previous stage + node, and its next promised payoffToday thread_rows(cid) gives the author *this chapter's* thread cells and nothing else. The author literally cannot see arc shape. This is the single highest-leverage wiring change.
.claude/skills/spine-chapter/SKILL.mdStep 3a gains an arc-continuity sub-step: the node declares which arcs it advances, to which stage, and which promise it paysThe lens pass proved this insertion point works
.claude/skills/normalize-doc/SKILL.mdone rubric item: arc declarations present, stages legal, promises paid or explicitly carriedThe critic gate is where node-level arc hygiene lands
new .claude/skills/arc-pass/SKILL.mdthe sibling of /spine-chapter, keyed on arc_id instead of CH_NNMakes the arc pass a first-class, repeatable procedure
harness/gates_config.jsonregister arc_continuityOr the gate never runs
docs/DOC_MAP.mdrows for the registry, the gate, the skillAnti-orphan doctrine: not done until listed

---

5 · SEQUENCING — folding into the existing ranked queue, not competing with it

The pre-5090 window plan is 30 ranked items. The arc architecture should ride items already

queued rather than add a 31st, and three queued items are **arc work that is currently

mis-filed as bookkeeping**:

1. Rank 28 (zero-token) — "derive Thread_Registry's 5 empty columns from Thread_Grid's 664

rows." This is the pilot. Running the derivation produces the shape diagnostic and proves

T-1/T-6 against real data at zero model cost. Do it first, today, as the proof-of-concept for

the whole registry. It also fills resolution_chapter (0/22 today).

2. Rank 9 — the narrative-craft seed gate (reversal/cost/residue). **Author it at ARC scope

as well as seed scope** (§4.3 rubric 2). It is already scheduled BEFORE rank 10's typing pass;

the arc scope costs almost nothing extra at authoring time and is where the criterion bites.

3. Rank 10 — the 264-seed housing typing pass. Assign arc_id at typing time. Seeds

typed only by region become 264 orphans-with-a-home-address; seeds typed by arc become the

ADVANCE/TEST rows the twelve side questlines are missing. This single change is what turns

the hub-and-spoke gap (register #3) and the flat-SQ finding into the same fix.

4. Rank 11 (Persona_Index) — carries the companion_ref FK and the arc participants.

5. Ranks 15 / 23 / 24 mint the missing homes (Quest_Definition execution columns; the 120

trade-gate rows; T1_Personal_Dimension_Spec for partnership). Each should mint **with

arc_id present**, not retrofitted.

6. The interior arc (§2.10) should be minted as ARC_0001 **as part of the amulet

integration**, not after it — while the 18-file plan is live and its beats are known. This is

the one recommendation with a closing window.

Ordering rationale: the registry needs no new authoring to start (Thread_Grid + Antagonist +

familiar rows import), the gate is honest on day one via the declared-not-armed pattern, and

every subsequent queued item then lands INTO a home instead of beside one.

---

6 · THE STRONGEST OBJECTION, ANSWERED

**"This is a second bookkeeping layer over data that already exists in the spine nodes. The v3.1

beat graph is the truth; an arc registry duplicates it and will drift."**

This is the right objection and it has real teeth — the corpus has already been burned by

registries that drift from their source (13 C++ row structs drifted from CSVs, register #21).

The answer is that the arc grid must be DERIVED, not authored in parallel. The spine node is

and remains the single writable source: the node's Block 11 SQ rows, its mark_write blocks, its

actors: lines, and its thread cells are already the arc data — they are just never assembled.

So T0_Arc_Grid is emitted by a script from the 79 nodes (exactly as slice_coherence derives

its manifests, and as rank 28 derives Thread_Registry from Thread_Grid), and the freshness of

that derivation is itself a gate assertion — the check_index_freshness / check_seed_housing

pattern, where the gate is the consumer that makes the artifact non-orphan.

Only T0_Arc_Index's judgement columns are authored: promised_beats, open_by_design,

layer_span, lens_set, variance_axis, care_band. Everything derivable is derived. That

keeps one writable home per fact (the living-source rule) and makes drift structurally impossible

rather than policed.

Residual honest risk (INFERRED): the ANCHOR → SEED|PRESENT disambiguation cannot be

derived — it needs a read. That is ~22 thread judgements, one arc pass, once. It is the cost of

having let one enum value absorb 441 cells, and it is small.

---

7 · WHAT I WOULD HAND JOSH AS THE RULING SURFACE

Everything above is execution within the locked vision — no pillar, no numerical canon, no

naming, no §17 surface is touched, and the locked 22 questline buckets are explicitly preserved.

Per the standing protocol this is apply-and-show, not ask. Two items are worth a brief (not a

bare question) because they touch vocabulary that other docs cite:

changes tokens that check_spine_graph and the v3.1 schema enumerate. Recommendation: adopt

§3.3's superset with the lossless mapping table, migrate Thread_Grid as a view, retire after

one release. Strongest objection: churn in a schema that was just stabilized at v3.1 — answered

by the view-then-retire path, which makes the migration reversible.

trickery_gambling (2 nodes) and pirate_naval (6 nodes, no SEED) are under-built or

deliberately minor is a design call about the twelve-questline promise, and it is the kind

of call the open_by_design column exists to record either way. Recommendation: build them

up — twelve promised side stories where one has two beats reads as an unfinished list, not a

deliberate asymmetry. Strongest objection: not every questline needs equal weight; the counter

is that open_by_design makes the asymmetry a declared choice instead of an accident, which is

the actual requirement.

---

APPENDIX — verification trail

ClaimMethodResult
arc_id absent corpus-widegrep -rl arc_id registries/ docs/ harness/; positive control thread_id0 hits; control returns hits
Thread_Grid stage distributionscript over 664 rowsANCHOR 441 / ESC 106 / NOT_PRESENT 49 / CONF 45 / RES_FINAL 15 / RES_PARTIAL 4 / CONV 2 / CONF_DIRECT 1 / CAPSTONE 1
15/22 threads no resolutionscript; stage-set test per threadT07-T19, T21, T22
THREAD_19 monotonescript10 appearances, stage-set = {ANCHOR}
Thread_Registry derived cols emptyCSV read, 22 rowsresolution_chapter 0/22 filled
SQ stage countsgrep -h "^- SQ" docs/spine/CH_*.md (376 rows)SEED 23 / ADVANCE 336 / GATE 0 / COMPLETE 11
GATE zero is real, not a bad filtersame filter returns SEED/ADVANCE/COMPLETE hitsPOSITIVE-CONTROLLED
5 SQs never COMPLETEper-questline stage countercryptids, lost_civilizations, military_history, pirate_naval, trickery_gambling
Trade gate ids danglinggrep -c Q_TR in Quest_Definition_Registry; control quest_id0 hits; control returns 1
Companion loyalty data densityCSV read, 163 rowsloyalty_model 6 · loyalty_belief_axis 4
Companion arc has no bucket/class/FKCITED docs/pipeline_review/LENS_BG3_2026-07-27.md BG3-3 (carries its own positive control + 3 self-refutations)WEAKER, survives
Marriage/partnership zerogrep -rli marriage registries/1 hit = a book title in Source_Material_Registry
Antagonist grid coverageCSV read, 64 rows62 distinct chapters
mark_write/forward_track densitygrep -h over 80 spine files338 lines across 51 nodes
Significance lenses ARE wired (WIRING_AUDIT is stale)grep -c significance .claude/skills/spine-chapter/SKILL.md10 hits incl. a dedicated Step 3a
slice_coherence reads a sequencefile docstringcarried-familiar + link-reciprocation manifests
spine_graph cross-file ERROR tierdocs/SPINE_SCHEMA_v3.md §6forward_track continuity, path_bucket consistency, seam equality
Path-flat endgameCITED WHOLE_ARC_CONNECTIVE_WEB_INVENTORY.md ECV-01/02/05/07CH_75/76/77 render found-family path-flat
65 through-line chains, 9 orphan/unpaidCITED WHOLE_ARC_CONNECTIONS_PASS.md §1headline counts

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