COMPANION_MECHANICS_CONTRACT.md

npcs/COMPANION_MECHANICS_CONTRACT.md

FOUNDATION B — The Companion Mechanics Contract

The exact interface a companion must satisfy to be legal in the ratified systems, and — separately and

explicitly — where that interface leaves real design room. This is a read of the ratified ground, not a

proposal: every mechanism below is already ruled or already schema-landed. Casting and per-companion loyalty

assignment remain Josh's (characterization canon, WS7 L158); this document tells the roster designer what a

companion row/persona MUST contain and what MUST be true of it, so the roster brief proposes only inside the

lines the systems already draw.

Citations are [SRC: path # anchor]. Four files are being mutated by a concurrent lane (T1_Integrity tier

doc, T0_Character_Index, RATE_MISMATCH_ANALYSIS, and CH_17/28/39/56/57); I read them for content but cite

them by section/name, never line number. Everything else is line-cited and verified to resolve.

---

0. The one-paragraph contract

A companion is a person-class entity (T0_Character_Index row + a flagship/supporting persona) that

(a) fills all 13 persona spine fields plus the person extension; (b) carries the **6 companion-loyalty

columns on Character_Index with a legal enum tuple; (c) sits on THE BOND** relational ladder (one shared

−100..+100 numeric axis, companion-axis display labels Enemy…Family) whose movement is a **runtime state

function, not an accumulator; (d) obeys the opposition-magnitude departure rule** (departs on sustained

belief-opposition, investment is inertia but never immunity, complete opposition always forces departure);

(e) is attackability Tier-3 (bonded) — betrayable at maximal cost, never god-moded, never a progression

wall; (f) lives aboard the mothership and may crew sub-craft; (g) may teach or peer a trade, contribute

a combat verb/mode as an ally, and open/close opportunities — but never gates progression (the

no-dead-end invariant; every departure ships a non-empty rerouted_paths). A companion is on the **human/

companion axis; the 22 familiar slots are a separate axis** (WS_012, creature-class, binding-stone) and

must never be conflated.

---

1. INTERFACE 1 — the 13-field persona spine (every companion fills all 13)

Source of truth: [SRC: docs/proposals/ENTITY_PERSONA_SYSTEM.md # §2.2 L30-44]. The persona extends the

anchor row; it owns no fact the anchor row does not carry (do-not-invent tether). For a companion, each field

has a companion-specific obligation:

do-not-invent tether. A companion with no clean anchor row is illegal.

one-line essence. Names are naming-canon → flag for Josh per docs/NAMING_METHOD.md.

[SRC: docs/proposals/SIGNIFICANCE_LENSES.md]. This is the relevance ticket AND the anti-museum-flavor

hook: a companion is in the cast because they carry an arc-serving lens, not for decoration.

persona/registry row, mirroring Cross_Cultural_Link_Graph. A companion is a hub in the relational web

[SRC: memory regions-are-relational-webs-not-villages].

This is the §17.1 dependency surface: where a culture's substrate in the corpus is thin, the companion's

history CANNOT be faked — flag book-processing enrichment as the blocker (care = weight + authenticity).

[SRC: memory d06-age-mastery-reclaiming-birthright].

belief axis (§2) that drives departure.

[SRC: docs/RUNTIME_GENERATIVE_LAYER.md # §2.1].

(only 10 rows today — a thin-anchor dependency).

relationship ledger (companions always do), its starting disposition, and which opportunities its bond

gates. This field is where THE BOND attaches.

carry the stricter authenticity bar and the authored-only-at-launch runtime default.

declared; no pre-Ch-76 Grand-Sage or House-pattern leak).

[SRC: docs/RUNTIME_GENERATIVE_LAYER.md # §A]; strategic-tick cadence; authored vs generated; authored

fallback line bank.

1.1 The person extension — the six companion-specific fields

[SRC: docs/proposals/ENTITY_PERSONA_SYSTEM.md # §2.4.1 L64-69]

age across revisits.

House-of-Velheim awareness tier, governed by the reveal discipline: no companion may perceive/voice the

family-behind-the-institution pre-~Ch-38, no who-frame, no agent-noun in the safe register

[SRC: memory antagonist-pattern-reveal-timing].

(Interface 6).

Bad, + four biography-shaped: Sympathetic, Detached, Curious, Defiant) in their cultural register

[SRC: _source/01_Tier_1_Foundation/T1_Integrity_Paths_Worldstates_Master [ACTIVE v2.1].md # §6].

protagonist in, read her vital force and hold her secret, or turn hostile-recognizer? This is what the

assimilation mechanic costs and buys through a companion's eyes: a companion who WITNESSES the player's

in-culture integrity choices is the site of a bond swing.

per-slot mechanics (Interfaces 2 + 5).

The living-faithful protection binds companions hardest: a faithful community member is never a combat

target and never the antagonist; no sacred proper name sits on a mortal companion (the Kxao rule); no revered

real person is recast as a villain companion (the Liqä rule) `[SRC: docs/proposals/ENTITY_PERSONA_SYSTEM.md #

§2.4.1 L71; memory deities-real-portrayable-17-1-nuance]`.

---

2. INTERFACE 2 — the Character_Index loyalty columns (WS7 anchor, LANDED)

The 6 columns are live on T0_Character_Index (append zone after the frozen 12-col reference), owner

companion-loyalty, gate-green [SRC: docs/proposals/systems/WS7_WIRING_BUILD_PLAN.md # L136-146]. A

companion row MUST carry a legal tuple:

the companion's structural type. not_companion is every non-companion entity (the default for the 157 of

162 rows that are not cast).

the runtime membership state.

truth_witness_mercy, freedom_from_bondage_redemption, caci_honor_community, craft_and_lineage),

compared against the player integrity band WS_001/WS_002. The vocabulary itself is naming-canon

propose a set aligned to the T1_Integrity bands for Josh to ratify; seeds are provisional

[SRC: WS7_WIRING_BUILD_PLAN.md # L159].

any_sustained_misalignment | circumstance_only`.

invest_Ch03_active_join_Ch13, drawn_when_integrity_light_L1_L2).

A second column family co-locates on Character_Index and must be kept owner-disjoint (the one-owner-per-

column gate FAILs on a double owner):

authoritative model is loyalty_model above [SRC: WS7_WIRING_BUILD_PLAN.md # L172-176].

Hard constraint on population: per-companion assignments are characterization canon = Josh's. Only 5

of 162 rows are seeded, and those seeds are ILLUSTRATIVE — the roster brief must NOT mass-populate the ~30

companion rows before Josh ratifies the roster-wide mapping [SRC: WS7_WIRING_BUILD_PLAN.md # L158].

Known live-data caveats the roster brief inherits (do not silently "fix"):

while Tunde (CHAR_0127), who never travels, carries a full drawn_conditional row. This roster/seed

mismatch is the real open gap — surfaced by the rate-mismatch re-test (RATE_MISMATCH_ANALYSIS, §6). It is

Josh's call and is not yet a ruling slot (a bare "who are the ~30?" is forbidden by the decision

protocol) — Claude authors the roster brief from the spine's own evidence first, then Josh rules.

any_sustained_misalignment vs planned major_opposition; CHAR_0003 circumstance vs circumstance_only).

All are illustrative rows Josh rules anyway — note the drift, do not treat any as canon.

---

3. INTERFACE 3 — THE BOND ladder (RULED: Scheme C, per-axis labels)

Ruled by Josh 2026-07-16 [SRC: docs/spine/RELATIONSHIP_TIER_BANDS_BRIEF.md # Rulings 2 & 4 L14-19, L52-64].

One shared numeric ladder across every relational axis (bond_state NPC, standing faction, loyalty_score

companion), −100..+100, with per-axis display labels. The companion axis is THE BOND over

loyalty_score:

BandRangeTHE BOND label (companion)THE STANDING label (faction)
Nemesis−100..−90EnemyHunted
Hostile−89..−70SeveredBanished
Wary−69..−40WarySuspected
Cool−39..−10CooledCooled
Neutral−9..+9StrangerStranger
Friendly+10..+39KnownWelcomed
Honored+40..+69WarmHonored
Revered+70..+89TrustedRevered
Exalted+90..+100FamilyExalted

Rung invariant: only Cooled and Stranger are shared labels, at identical rungs. Family (not Kin) —

"kin" is reserved for the Ch-66 origin-lineage recognition [SRC: RELATIONSHIP_TIER_BANDS_BRIEF.md # L82].

Load-bearing correction (do not build against the accumulator): THE BOND bands a STATE, not a running

total. The ratified runtime moves the bond via a ±-clamped relationship_delta at ~0.03 Hz, and disposition

is "generated fresh each encounter from the current state" `[SRC: docs/RUNTIME_GENERATIVE_LAYER.md # L113-116,

L143; docs/proposals/ENTITY_PERSONA_SYSTEM.md # L137]`. A state bands identically at any event count — so there

is no per-beat accumulator for the roster to design, and the earlier "rate" cardinal was retired

(RATE_MISMATCH_ANALYSIS self-correction). The bond delta and its thresholds are owned by the deterministic

runtime state machine; the roster designer supplies belief axis + join trigger + departure threshold, not

a points budget.

The §17.1 grammar solve (why the labels are safe): every STANDING label is a participle of reception — it

names the player's earned position, never what a people *are* (Sámi: Hunted is safe where Sámi: Hostile is

disqualified). THE BOND labels are a companion's disposition toward the player, same principle

[SRC: RELATIONSHIP_TIER_BANDS_BRIEF.md # L65-70].

---

4. INTERFACE 4 — the departure rule (RULED: design A, opposition-magnitude)

Ruled [SRC: RELATIONSHIP_TIER_BANDS_BRIEF.md # Ruling 3 L36-51]. Departure is not driven by

loyalty_score — it is driven by the opposition between the player's sustained integrity pattern and the

companion's loyalty_belief_axis pole; the score acts only as inertia.

not from observed deeds (integrity is a real property read directly).

any_sustained_misalignment = 35; circumstance_only = plot-driven, not integrity-driven.

capped 90. The 90-cap invariant is ratified and may not be tuned away: opposition tops at 100 > any

reachable trigger, so complete opposition ALWAYS forces departure and investment can never buy immunity

("invested is sticky but not immune," stated as a theorem).

cumulative-pattern rule — a single dark choice never strips a companion).

ratified as authored STARTING VALUES; playtest may move them without a re-ruling, but the SHAPE and

the 90-cap are fixed.

Two ratified-but-inert numbers the roster brief must know (surfaced to Josh, invariant survives):

1. The +15 inertia cap can never bind: it requires loyalty_score = 150, but the domain is −100..+100, so

the max reachable bonus is 10.0. The 90-cap invariant still holds; one stated number is dead

(RATE_MISMATCH_ANALYSIS §self-correction, verified).

2. The "only for_life is exempt" clause is refuted by the live spine: CH_65 stages "Ntala departs," and

Ntala is rowed for_life/never; Josh's D-23 ruling offers departure on every surviving band. The exempt

companion canonically departs. The 90-cap invariant is untouched — only the exemption clause needs

alignment at the wiring commit. **Implication for casting: for_life does not mean "present every node to

the Epilogue"; it means the model's departure trigger is never, which a scripted plot departure (D-23)

can still override.**

---

5. INTERFACE 5 — DRAWN (the join mirror) and the worldstate ledger

aligns with their belief pole at magnitude ≥ 60, sustained the same two-node way

[SRC: RELATIONSHIP_TIER_BANDS_BRIEF.md # L224; memory companion-loyalty-integrity-system].

sticky (joins on investment, high inertia), come_and_go` (rejoins on corridor returns, leaves by

circumstance), drawn_conditional (DRAWN by aligned integrity, repelled by opposed), not_companion.

The engine drives two worldstate rows (WS7 Increment C, T0_Worldstate_Variables)

[SRC: WS7_WIRING_BUILD_PLAN.md # L147-154]:

loyalty_model, loyalty_state, loyalty_score(−100..+100), joined_chapter, last_integrity_signature}`.

Membership + loyalty are seeded from the Character_Index anchors. It **REFERENCES WS_008

relationship_history** for encounter history rather than restating it.

REBONDED), chapter, integrity_at_event, rerouted_paths[]}`. **Every DEPARTED event MUST carry a non-empty

rerouted_paths[]** — the no-dead-end contract, enforced by harness/check_no_dead_end.py.

Adjacent variables a companion couples to but must not duplicate: WS_008 relationship_history (general

per-NPC ledger), WS_021 faction_standing_per_faction (THE STANDING axis — separate, Interface 8),

WS_012 familiar_bond_state (the familiar axis — separate, Interface 9). WS_027 references, never restates,

WS_008.

---

6. INTERFACE 6 — trades (companion as teacher or peer)

Ten canonical trades, each with one ancient + one modern home base, each 12-tier quest-gated (up to 120 gates)

[SRC: registries/T0_Trade_Registry [DRAFT v0.1]/T0_Trade_Registry DRAFT v0.1.csv]:

IDTradeAncient homeModern home
TRADE_01Animal CommunicationCh 12 W. AfricaCh 59-65 Africa revisit
TRADE_02MiningCh 19 Persia (Ch 14 Nubia seed)Ch 59-65 Mid-East revisit
TRADE_03BlacksmithingCh 07 S. IndiaCh 60 Japan (tatara steel)
TRADE_04HerbalismCh 07 S. IndiaCh 50 Amazon
TRADE_05AlchemyCh 19 PersiaCh 59-65 Europe revisit
TRADE_06TailoringCh 21 ChinaCh 59-65 Asia revisit
TRADE_07Culinary ArtsCh 42 HaitiCh 42 Haiti
TRADE_08EngineeringCh 27 C. EuropeCh 59-65 Europe revisit
TRADE_09InscriptionCh 15 Egypt + Ch 29 Sámiancient-only (paradox-completion)
TRADE_10Fishing & NavigationCh 08 Swahili CoastCh 56 Arctic/Greenland

A companion's teaching_role may make them:

class), gating a mastery-tier climb. Real-science disciplines bind the substrate: Alchemy=chemistry,

Engineering=physics/statics, Herbalism=biology; the game rewards learning the real science

[SRC: memory rewards-intelligence-real-science-immersive-sim].

Non-gating constraint: a trade opportunity a companion opens or closes is by construction

non-progression-critical — the trade climb is completionist/kit, and losing a teacher must reroute to an

equivalent-class alternative (opportunity conservation), never dead-end the trade

[SRC: docs/proposals/ENTITY_PERSONA_SYSTEM.md # §3.4 Mechanism 1-3]. Real trade home-base = an

A_TRADE-layer dwelling with added_modules_only integrity visibility and a cultural_fabric_protected

siting rule (the care firewall — no integrity-scar aesthetics on a living culture's trade home)

[SRC: WS7_WIRING_BUILD_PLAN.md # L216, L246].

---

7. INTERFACE 7 — combat (what an ALLY contributes mechanically)

The fight system is Pillar-8 blended-mode over seven canonical modes: `direct / stealth / puzzle_routed /

environmental / vril_management / familiar / astral [SRC: docs/COMBAT_ENCOUNTER_SYSTEM.md # Part B §2 L143;

_source/.../T1_Combat_System_Spec [ACTIVE v1.0].md § modes]`. Difficulty is world vril-density, never enemy

stat inflation [SRC: COMBAT_ENCOUNTER_SYSTEM.md # Part B §0 L111]. A companion is an ally combatant, and

the contract on what an ally supplies:

— the mode-agnostic posture bar with named sub-nodes, each depletable by a specific mode's verb

[SRC: COMBAT_ENCOUNTER_SYSTEM.md # Part B §5 L196]. A companion whose combat identity is stealth or

puzzle_routed can break a node raw DPS cannot. The ally's mode should compose with, not duplicate, the

player's — the design intent is blended coverage.

real physics), and player, enemies, AND allies all wield both** for good and ill

[SRC: memory vril-altered-physics-real-physics-and-magic]. An ally's contribution is expressed in the same

verb grammar and the same vril-altered-physics substrate, not a separate "buddy AI" system.

NOT tier-6 Vril Sight; a companion cannot read vril-signatures at Neophyte tier

[SRC: memory early-chapter-perception-not-tier6-vril-sight].

via a bonded paired-operation (canon at Ch 73 Sub-Phase C, TGP-exclusive)

[SRC: COMBAT_ENCOUNTER_SYSTEM.md # Part B §5 L196, §3 L160]. This runs on the familiar axis, not the

human-companion axis (Interface 9) — a human companion contributes a human-mode verb; a familiar contributes

the familiar-mode paired-op.

reaches a protected space it is antagonist intrusion, and the environmental-boss protocol (Perception →

Vril-management → Restraint → Purgation) is the playable layer `[SRC: COMBAT_ENCOUNTER_SYSTEM.md # Part A §9

L64; memory rated-r-aaa-dont-defang-monsters]`.

Combat detail (movesets, verbs, counters, phase escalation) is authored per-node at the cascade, not

pre-specified here [SRC: docs/proposals/RELATIONSHIP_COMBAT_SYSTEMS_NOTE.md # §5].

---

8. INTERFACE 8 — travel (the mothership; companions live aboard)

The travel model is one transforming vril-flagship mothership + collectible local sub-craft; companions

travel aboard `[SRC: registries/T0_Vehicle_Registry [DRAFT v0.1]/Sheet1.csv; WS7_WIRING_BUILD_PLAN.md #

L12-49]`.

chain raft→dugout→dhow→caravel→research-vessel→submersible-capable, transform configs

cruise;battle;dive;anchored-base. Its crew_station_object names the stations a companion can hold:

helm; lookout; gunner; engineer; cook; menagerie; rigger. **A companion's own_life aboard the mothership

should bind to a crew station** — this is where the "lives aboard" obligation becomes concrete.

familiar/Trade-10), VH_003 the Vimana (peer-flagship, air, Ch 55+; docks as a peer, never carried).

A companion may crew or pilot a sub-craft (e.g. a Trade-10 navigator companion at the helm; a bonded

water-familiar handler piloting the pod).

geography stays walked (no flight pre-Ch-55, F-a); the mothership is a single craft (§6.5), so companions

concentrate aboard one hub, not a fleet of homes. The anchored-base config + the Layer-B dwelling-home

are where a companion resides between deployments [SRC: WS7_WIRING_BUILD_PLAN.md # L215 DW_0002].

Chapter assignments for craft are Josh-canon: only Ch 08 (dhow onset) and Ch 55 (Vimana) are cited; a

companion's boarding chapter must reference an existing acquisition, never mint one.

---

9. INTERFACE 9 — attackability (companion = Tier-3 bonded) + the no-dead-end invariant

Five attackability tiers, enum hostile | bystander | bonded | protected-collective | shielded

`[SRC: docs/proposals/systems/attackability-and-consequence-model.md # L15, L65; WS7_WIRING_BUILD_PLAN.md #

L166-171]. A companion is Tier-3 (bonded`):

or become an enemy; questlines close; a permanent mark lands. Not god-moded, not invisible-walled

protected by CONSEQUENCE and BOND, not a can't-target flag `[SRC: attackability-and-consequence-model.md #

L15, L33]`.

(spine canon = Josh's). Ntala is the seeded bonded/is_load_bearing=true example

[SRC: WS7_WIRING_BUILD_PLAN.md # L169].

The non-gating invariant governs every companion opportunity `[SRC: docs/proposals/ENTITY_PERSONA_SYSTEM.md

§3.4-3.5]`:

progression_critical and CANNOT be an opportunity; companion-gated affordances are by definition the

complement (kit/route/relationship/lore only).

on all three, each opening/closing different companion opportunities.

alternative on the divergent path (a lost broker reroutes the network).

every DEPARTED ships rerouted_paths[]. Losing a companion reshapes routes; it never blocks the game.

---

10. INTERFACE 10 — the axis firewalls (never conflate)

Three axes touch a companion; keep them structurally separate:

This is the companion axis.

per-faction −100..+100 accumulator, distinct from integrity and from THE BOND

[SRC: _source/.../T1_Integrity_Paths_Worldstates_Master [ACTIVE v2.1].md # §8.7]. A companion has a BOND;

their faction has a STANDING; high BOND does not imply high STANDING with their group.

58), creature-class, bound by binding-stone, tracked by WS_012 familiar_bond_state**

[SRC: COMBAT_ENCOUNTER_SYSTEM.md # Part A §8 L61; memory layer-model-v2]. Familiars are T0_Creature_Roster

/ T0_Familiar_Registry entities (the Familiar_Registry is currently an empty stub, 0 rows — a hard

anchor dependency). A familiar is NOT a companion: it does not carry a loyalty_model, does not sit on

THE BOND, and does not depart on integrity-opposition. WS_012 is heavily written (99 writes / 38 nodes);

WS_008.bond_state (the NPC axis) is genuinely unwritten — do not confuse a bond_state grep with the

familiar axis.

---

11. THE DEGREES OF FREEDOM — what is PINNED vs where design room is real

PINNED (design WITH these; changing them re-litigates a ruling)

one shared numeric axis (Ruling 2 + 4). A per-axis threshold override is the *declined* variant and needs

a NEW Josh ruling; only a per-faction override is tuning `[SRC: RELATIONSHIP_TIER_BANDS_BRIEF.md #

Authority Note L20-32; RATE_MISMATCH_ANALYSIS §8 smuggling-vector]`.

90-cap invariant, WAVERING as a computed band, two-node sustain (Ruling 3).

attackability tiers, companion = Tier-3 bonded**.

and no-flight-pre-Ch-55 firewalls.

authenticity, thin substrate is a book-processing dependency, never faked.

travellers, rowed; the Ch-1 best-friend choice seeds Ntala's gender/skills/combat-focus; Ch-58 childhood-

familiar reunion; Ch-65 path-lock; endgame Realm Road 66-77.

GENUINE DESIGN ROOM (the roster brief's actual job — propose here, labelled, for Josh)

1. Roster size (~30). Explicitly Josh's OPEN QUESTION; the "~30" is an unratified scope estimate. The

brief's job is the grounded answer from the spine's staged cast, not a guess.

2. Which canonical figures are companions, and which loyalty_model each carries — including the four

travelling characters (CHAR_0140/0144/0145/0146) that currently carry no model, and whether Tunde's

drawn_conditional fits a one-node presence or he needs more beats (RATE_MISMATCH_ANALYSIS §6). Cardinal —

present as a brief, do not populate.

3. The loyalty_belief_axis controlled vocabulary — the enumerated set of value-poles, aligned to the

T1_Integrity bands. Naming-canon → propose for ratification.

4. Each companion's loyalty_join_trigger (chapter + condition) and loyalty_departure_threshold

assignment — grounded in the companion's motivations/belief pole, within the ratified enums.

5. Each companion's culture, persona, trade lane, combat mode/verb, crew station, and web edges — the

creative-within-vision bulk; apply-and-show-the-path where grounded, but every NAME flags for Josh.

6. The calibration TARGET (design intent, not a number) — e.g. "Ntala → Family at ~Ch-65 path-lock; a

merely-good run misses it." Cheap, genuinely-Josh, guides later authoring when a consumer exists. The

per-beat RATE is retired — do NOT resurrect it as a question.

7. age_stage_presence and come-and-go windows — WHEN each companion is available and rejoins/leaves,

grounded in the arc structure (ancient 2-38 region-per-chapter, modern 39-65, endgame 66-77).

8. Where a culture's substrate is thin — flag the specific book-processing enrichment dependency rather

than author unsupported cultural depth.

---

12. The two burned failure modes this contract is built to prevent

per-beat "rate" and the "bond-moving beat" filter are named as retired, not silently reused.

name are labelled provisional/illustrative; only Josh's four D-REL-BANDS rulings, the WS7 landed schema, and

the cited T1/CVD hard lines are treated as fixed.

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