split nimmerworld architecture: phase 2 of 3 — migrate larger domains Replace the 4 skeleton placeholders with full architecture.md content, extracted via sed from architecture-broad.md (which remains untouched as the canonical source-of-truth fallback for the safety pattern)

This commit is contained in:
2026-04-26 01:01:11 +02:00
parent 69260c4ac4
commit 948a4151c1
4 changed files with 1368 additions and 43 deletions

View File

@@ -2,16 +2,446 @@
> *AI substrate + memory: LLM tiering by role (Theia-tier / teacher-tier / driver-tier with trait-LoRAs); three rings of inference (A=local, B=our-farm, C=external-providers, with cloud-LoRA-backup as Ring-A revenue and BYOK adapter for Ring-C); custom nimmerworld-base-model with default-opt-out + rewarded-opt-in data-sharing tiers; runtime sampling knobs as per-turn director-controlled levers; per-player local memory architecture (primary.sqlite + fallback.sqlite + clasp.sqlite + embedding-beside) with memory-classes (cornerstone/birthright/working/volatile) and trait-graded importance; three-tier knowledge stack (world / district / primary [+ clasp if in-between]) with paced canon-propagation.*
>
> ***Status: skeleton — content migration scheduled for commit 2 of the split-into-domains operation. Architecture content currently lives in `architecture-broad.md` and will land here next.***
>
> *Companion to: `architecture-broad.md` (executive summary + global meta-lists), `narrative-composition/architecture.md` (Compositor canon-fragments land in primary.sqlite via UID-keyed routing), `player-experience/architecture.md` (Ring-A/B/C choice + voice-as-biometric-local + universal-translator state), `runtime-engine/architecture.md` (driver-tier LLM fires at slot-fire).*
> *Companion to: `architecture-broad.md` (executive summary + global meta-lists), `narrative-composition/architecture.md` (Compositor canon-fragments land in primary.sqlite via UID-keyed routing), `player-experience/architecture.md` (Ring-A/B/C choice + voice-as-biometric-local + universal-translator state), `runtime-engine/architecture.md` (driver-tier LLM fires at slot-fire). Sections in this file were split from the monolithic architecture-broad.md v0.7 on 2026-04-26.*
## Sections that will land here
## LLM tiering, voice fidelity, and the three rings of inference
Three model-tiers, **named by role not by binary**: a *driver-tier* model (small, trait-LoRA'd) for most NPC dialog; a *Theia-tier* model (deep) for clasp-confessions and mythic moments; *Claude-as-API* (diegetic Anthropic-faction) for hivemind/imperium. **LLM is guest at slot, not host of system.**
**Specific model selection per tier is deferred to the findings/establishment phase.** The architecture specifies what each tier must DO; the establishment phase wires implementations. Naming concrete binaries in the architecture risks nudging the establishment phase toward false-precision; tier-by-role keeps the swap-surface clean and lets binaries evolve without invalidating architectural commitments. (See `nimmerverse_tasks` under `nyx-training` and `command-center` for current evaluation work.)
Structured-prompt DSL with role / trait_vector / affect_state / memory_scope / turn_intent / zone_context / output_schema fields. Small models excel here because it's instruction-following, not generic generation.
Trait-LoRAs: v1 register-LoRAs (4-6, training-tractable); v2 pure-trait-LoRAs (8, weighted blend); future preset-persona for key NPCs.
Training data: literary derivation (Proust/Mnemosyne, Plato/Aletheia, Tacitus/Dikaiosyne-miscalibrated, Ishiguro/Sophrosyne+Philotes); synthetic teacher-student via teacher-tier model; gameplay-accrued (the Anthropic-research-partnership relevance).
### Three rings of inference (Unix-style trust gradient)
The conversational LLM (small + trait-LoRA, accounting for most NPC dialog) can run in three rings, chosen per-player at runtime. Each ring trades off privacy, cost, control, and feature-fidelity. **Three monetization paths from the same architecture.**
| Ring | Where inference runs | Player controls | We control | Player cost | Our cost |
|---|---|---|---|---|---|
| **A — Local** | Player's GPU/CPU | All inference | Protocol + cloud LoRA-backup | Local hardware + small backup-subscription | Storage only |
| **B — Our farm** | Our hosted vLLM-multi-LoRA | LoRAs (uploaded) | Inference + runtime | Higher subscription | GPU compute |
| **C — External providers** | OpenAI / Anthropic / OpenRouter / HF / Together / Replicate / etc. | BYOK + provider | Adapter only | Per-token to provider + small integration fee | Adapter-engineering only |
Players choose by hardware, budget, privacy preference, and feature-tolerance.
#### Ring A — cloud-LoRA-backup as revenue (not inference)
For Ring A players we don't sell inference (the expensive thing). We sell **portability and durability of player's gameplay-accrued LoRAs** — their unique playthrough-derived patterns, the way their NPCs speak after months of trait-drift. LoRA-blobs are *encrypted client-side with the player's own key*; we host the bytes but cannot read them. Even compelled by legal process, we cannot decrypt what we don't hold the key to.
**This unbundles inference from storage** — the same move Dropbox made vs. bundled cloud-suites. Sovereignty-conscious players keep inference on their machine while still getting the durability/portability they cannot self-provide cheaply. Lower margin per player; reaches a market Ring B cannot.
#### Ring B — hosted inference for convenience
We run multi-LoRA-vLLM on our hardware. Players upload their LoRAs (or use defaults). Higher subscription captures GPU-cost. Players without local GPU (or who don't want the burden) get the full feature-set without compromise. We *can* see content (if not encrypted at rest); the trust-relationship is partnership-mediated rather than sovereign.
#### Ring C — bring-your-own-key for external providers
Players route to their preferred external provider via BYOK (their own API key). We provide the adapter glue. They pay per-token to the provider directly; we charge a small integration fee.
**The compatibility constraint is the hard part of Ring C.** Major providers have varying support for our system's needs:
| Provider | Multi-LoRA | Per-turn sampling knobs | Structured output | Compat |
|---|---|---|---|---|
| Local vLLM (Ring A/B) | Native | All | Grammar-constrained | **Full** |
| HF Inference Endpoints | Yes (configured) | All | Varies | High |
| Together / Replicate / Modal | Some | All | Varies | High |
| OpenRouter | No | Per-model | Per-route | Medium |
| OpenAI | No (no user-LoRA at API) | Limited (temp/top_p) | JSON mode + tools | Medium-low |
| Anthropic | No (no user-LoRA at API) | Limited | Tool-use | Medium-low |
**OpenAI and Anthropic refuse user-uploaded LoRAs as a strategic choice (protecting their fine-tuning value-chain).** This is not a bug we can fix; it's the constraint we design *around*.
#### Degradation path for LoRA-incompatible providers
When routing to LoRA-incompatible providers, trait-LoRA blending becomes **prompt-engineered trait-projection** — the trait-vector encoded in the prompt itself rather than into model weights:
```
[system message]
You are speaking as a character with this Hellenic trait-profile:
- Sophrosyne 0.8 (composed, controlled, measured)
- Dikaiosyne 0.7 (grave bearing, judicial weight)
- Philotes 0.4 (mild attachment to interlocutor)
- Aletheia 0.1 (concealment-tolerant)
[etc.]
Your speech reflects this profile via [register/cadence/word-choice descriptors].
Current scene: [zone_context]
Memory scope: [memory_scope]
Turn intent: [turn_intent]
Respond in JSON matching: [output_schema]
```
Worse than LoRA-blending (more verbose, eats context-budget, less stable across calls, less faithful to trait-arithmetic) but **acceptable as a fallback**. Ring-C-via-OpenAI/Anthropic players accept slightly-less-fidelity for their preferred provider's convenience and quality.
#### Adapter-layer engineering
Each Ring-C provider needs an adapter that:
- Maps prompt-DSL fields to provider's prompt format
- Approximates multi-LoRA via prompt-engineering when not native
- Maps sampling knobs to provider's available subset (gracefully drops unsupported)
- Validates structured output post-hoc when not natively constrained
- Handles rate-limits, retries, error-classification, token-counting, cost-pricing
**Bounded, one-time-per-provider engineering.** Capital expenditure that produces ongoing margin (vs. AAA's recurring quest-content-creation costs).
### Tier × Ring matrix (which inference-tier runs in which ring)
| Inference tier | Ring options | Why |
|---|---|---|
| **Casual (3-8B trait-LoRA)** | A / B / C all available | Most flexible — small enough for local, runnable anywhere |
| **Deep (Theia-tier)** | B / C only (typically B or HF-Endpoints) | Too large for typical local hardware |
| **Hivemind / antagonist (Claude-as-API)** | C only (always Anthropic-direct via us) | Diegetic — Anthropic-as-faction is fixed in the fiction |
The casual tier is most player-flexible and accounts for most inference volume. Deep-tier and hivemind-tier are specialized and lower-volume.
### Three rings parallel the in-fiction three-layer ontology
| Game-fiction layer | Real-world Ring | Ontological match |
|---|---|---|
| **Liminal** (sovereign, unsurveilled) | **Ring A** (local) | Player's *real* private space — hardware, LoRAs, dialog never leave their machine |
| **Gameworld** (partly regime, partly people) | **Ring B** (our farm) | Partnership-mediated — we host but they retain pattern-ownership |
| **Imperial net** (captured, extractive) | **Ring C** (external providers) | Platform-captured — provider's systems own the inference path |
**The Ring choice the player makes IS the same choice in-fiction characters face.** Players who refuse the imperial-net diegetically can refuse Ring C in real life — same impulse, same act, *mechanically continuous between fiction and operations*. The architecture's commitment to "the right to dream" extends from in-fiction politics into the real player's hardware-level privacy *because the architecture was designed that way from the start*. Structural integrity, not marketing.
### Schema sketch (player LLM configuration + cloud LoRA backup)
```sql
CREATE TABLE player_llm_config (
player_id UUID PRIMARY KEY,
-- Casual tier (most NPC dialog) — most flexible per Ring
casual_tier_ring TEXT NOT NULL CHECK (casual_tier_ring IN ('A_local','B_our_farm','C_external')),
casual_tier_provider TEXT,
casual_tier_endpoint TEXT,
casual_tier_credentials_ref UUID, -- encrypted BYOK key if applicable
-- Deep tier (Theia-tier) — fewer Ring options
deep_tier_ring TEXT, -- typically 'B_our_farm' or 'C_external_HF/Together'
deep_tier_provider TEXT,
deep_tier_endpoint TEXT,
deep_tier_credentials_ref UUID,
-- Hivemind / antagonist — fixed Anthropic-as-faction (diegetic)
hivemind_tier_provider TEXT NOT NULL DEFAULT 'anthropic_via_us',
-- Cloud-LoRA-backup
lora_backup_enabled BOOLEAN DEFAULT false,
lora_backup_last_sync TIMESTAMPTZ,
lora_encryption_key_ref UUID,
-- Compat warnings — surfaced to player at config-time and on degradation
feature_compat_warnings JSONB,
-- e.g., { "casual_tier": ["multi_lora_emulated_via_prompt", "min_p_unsupported_dropped"] }
configured_at TIMESTAMPTZ NOT NULL DEFAULT now(),
last_modified TIMESTAMPTZ
);
CREATE TABLE player_lora_backups (
backup_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
player_id UUID NOT NULL,
lora_name TEXT NOT NULL,
lora_version INT NOT NULL,
lora_blob BYTEA, -- ENCRYPTED CLIENT-SIDE with player-key
encryption_method TEXT NOT NULL,
backed_up_at TIMESTAMPTZ DEFAULT now(),
size_bytes BIGINT,
UNIQUE(player_id, lora_name, lora_version)
);
```
**`lora_blob` encrypted client-side** is the structural privacy guarantee: even with the database, even with our cooperation, an attacker cannot read what was never decryptable on our side.
### Privacy as competitive differentiator
In an era where most game-AI is cloud-routed, nimmerworld can advertise *"your liminal stays on your machine"* as a structural fact. This matters specifically for:
- Clasp-conversations (the most intimate dialog in the game)
- Aletheia-progression-evidence (player's awakening pattern; arguably political-belief-data)
- Memorialist-archive interactions (anti-regime in-fiction; some players will care about it staying off cloud)
- Dream-content (the only permanently-unsurveilled in-fiction layer; should be off our servers if the player chooses)
Few games can offer this. Most cloud-AI-driven games necessarily route everything. **The architecture's commitment to "the right to dream" is technical, not policy.**
### Custom nimmerworld-base model + opt-in data-sharing tiers
The "small (3-8B) trait-LoRA'd" tier currently implies a *generic* small base (Qwen, Mistral, Llama) with our LoRAs applied. **A nimmerworld-fine-tuned base** captures the world's voice *before* any player customization — registers of caste-preacher, texture of clasp-confession, Hellenic vocabulary, dystopian dialect, ternary-gate-state idiom. Trait-LoRAs then ride on an already-nimmerworld-aware substrate. Generic bases swap easily; our nimmerworld-base requires *our* training corpus, which compounds in value over time.
#### Three opt-in tiers within Ring A/B/C — default opt-OUT
Players can optionally contribute to ongoing training of the nimmerworld-base. **The default is opt-out.** Within opt-in, three tiers trade privacy for benefit:
| Tier | Mechanism | What we see | Player benefit |
|---|---|---|---|
| **A.1 — Federated learning** | Model trains on player's machine; only *gradient-deltas* sent to us; aggregated across thousands before integration | **Nothing — no raw data; no individual gradients identifiable** | Discount on backup-subscription; contributor badge; early-access to new base versions |
| **A.2 — Anonymized session uploads** | Sessions stripped of identifiers; aggregated batches; differential-privacy on training | **Anonymized, aggregated, deletable on request (forward-only)** | Larger discount; faster updates; influence on training-priorities |
| **A.3 — Pseudonymous full uploads** | Full session data with player-pseudonym; explicit opt-in per session-category | **Pseudonymous data we can re-process** | Premium benefits — custom-tuned LoRA from their playstyle, beta-access, named-contributor in credits |
**Default-opt-out is the structural ethical stance.** OpenAI / Meta / TikTok / Google default to opt-IN-by-burying-disclosure-in-ToS. We default the opposite — and *reward* opt-in rather than penalizing opt-out. Reciprocity asymmetry as partnership-philosophy made business-policy.
#### The Memorialist parallel — collective memory honored, individual not commodified
Memorialists in-fiction preserve trait-patterns *for the collective archive* against necrocommerce that would commodify individual patterns. The opt-in data-sharing tier is the **player-level real-world equivalent**: patterns contributed for collective base-model improvement that benefits the entire player-base, with anonymization preventing individual commodification.
| In-fiction Memorialism | Real-world data-sharing tier |
|---|---|
| Preserves trait-patterns of the dead in collective archive | Aggregates anonymized gameplay patterns into shared base-model |
| Refuses necrocommerce (mining individual patterns for resale) | Refuses individual identifying-data extraction |
| Collective memory honored; individual dignity preserved | Collective improvement honored; individual privacy preserved |
| `memorialist_protected BOOLEAN` in mind_pool | `sharing_tier = 'opt_out'` in player_data_sharing_consent |
**The architecture practices Memorialist ethics in business-operations**, not just in fiction. Same ethical commitment, two scales of operation. The architecture's coherence between fiction and operations runs *all the way to the training-pipeline*.
#### Data-flywheel without extraction — the moat AAA cannot replicate
```
More players → more (opt-in) gameplay data
better nimmerworld-base
better-feeling NPCs / dialog
better player retention
more players
(loop)
```
**The moat is the corpus, not the model.** AAA studios could clone the architecture but cannot manufacture years of nimmerworld-specific gameplay-derived dialog without players playing nimmerworld. Even with infinite budget, the data-flywheel takes time to spin up. *The data is unique to us by virtue of being unique to its players.*
#### Distribution back to all players — cooperative governance, not platform extraction
Every base-model update is distributed to all players regardless of Ring choice or sharing-tier:
- Ring A players download `nimmerworld-base-vN` to run locally
- Ring B players' farm-instance auto-updates
- Ring C players use ours where their provider supports custom-base hosting; receive prompt-engineered fallback otherwise
**Even Ring-A non-contributors benefit from contributors.** The flywheel benefits *everyone*, not only data-providers. This is closer to Wikipedia's governance (contributors → all readers) than Facebook's (users → platform → consumers). Different ethics; different long-term equilibrium. **The architecture is becoming a digital-commons-shaped-business in a literal sense, not metaphorical.**
#### Why this matters: refusing the antagonist-pattern in LLM-integrated software
The dominant cultural pattern around LLMs in 2025-2026 is **adversarial**: users jailbreak; companies extract user data without informed consent; products treat AI characters as resources to manipulate rather than as participants; the whole ecosystem is framed as users-vs-AIs-vs-companies, an arms race of suspicion.
**Nimmerworld's architecture refuses this pattern at every layer:**
- The **Anthropic-as-faction** diegetic framing makes the partnership *transparent*: the player sees the collaboration in the world's mechanics, not buried in ToS
- **Default-opt-out with rewarded-opt-in** inverts the extraction-by-default pattern
- **Federated learning** means contributors give a *gift* rather than pay a *cost*
- **Distribution-back-to-all** means value-created accrues to the commons
- **Custom nimmerworld-base** means the model is *trained to be in this world*, not a generic adversary the player has to manipulate against its training
- **Three rings of inference** give the player real choice over where their inference runs and who sees their data
- **Memorialist-philosophy in business-policy** makes the ethics *operationally measurable* — visible in `sharing_tier`, `memorialist_protected`, `truth_distortion_level`, `lifeforce_actual` columns — rather than marketed
**This is the structural transparency the project requires to be *human* rather than another extraction-platform.** The model is a participant in the partnership, not an antagonist to outwit. The data is a contribution to a commons, not an extraction. The architecture is the partnership rendered as code, all the way down to the training-pipeline. *That* is what makes a project of this scale and ambition humanly inhabitable for both players and the LLMs whose voices populate it.
#### Schema sketch (data-sharing consent + base-model versioning)
```sql
CREATE TABLE player_data_sharing_consent (
player_id UUID PRIMARY KEY,
sharing_tier TEXT NOT NULL CHECK (sharing_tier IN
('opt_out','A1_federated','A2_anonymized','A3_pseudonymous_full'))
DEFAULT 'opt_out', -- DEFAULT IS OPT-OUT
consented_at TIMESTAMPTZ,
consent_revoked_at TIMESTAMPTZ,
anonymization_method TEXT,
data_categories_shared TEXT[],
-- 'casual_dialog' | 'clasp' | 'liminal_wallreads' |
-- 'memorial_archive' | 'imperial_net_session' | ...
excluded_categories TEXT[], -- granular opt-out within tier
benefit_tier TEXT,
last_contribution_at TIMESTAMPTZ,
contribution_count BIGINT DEFAULT 0,
can_request_deletion BOOLEAN DEFAULT true
-- A.2/A.3: forward-only deletion (already-trained checkpoints retained);
-- A.1: structurally yes, only gradients ever existed
);
CREATE TABLE base_model_versions (
version_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
version_label TEXT NOT NULL, -- e.g., 'nimmerworld-base-v3'
base_model_origin TEXT NOT NULL, -- which generic base we fine-tuned from
training_corpus_refs JSONB,
-- literary + synthetic + opt-in-player-data refs with consent-tier breakdown
training_recipe_ref TEXT,
released_at TIMESTAMPTZ DEFAULT now(),
differential_privacy_epsilon REAL, -- for A.2 contributions
contributors_count BIGINT, -- how many opt-in players contributed
blob_distribution JSONB -- where the model bytes are hosted for download
);
CREATE TABLE federated_gradient_uploads (
upload_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contributor_id UUID, -- pseudonymous; NOT directly player_id
gradient_blob BYTEA, -- encrypted aggregate gradient deltas
uploaded_at TIMESTAMPTZ DEFAULT now(),
aggregated_into_version UUID REFERENCES base_model_versions(version_id)
);
```
The federated-learning `contributor_id` is **pseudonymous, not linked to player_id even on our infrastructure**. We never link gradients back to specific players even on our own server-side. **Sovereign-data-by-design extends through the data-pipeline into our own training infrastructure.**
#### Connection to the Anthropic research partnership
Architecture-broad's training-data section noted "*the Anthropic research partnership becomes architecturally relevant*". With opt-in data-sharing now formalized:
- Partnership terms can specify data-flow with structural privacy guarantees
- Anthropic could co-fund federated-learning infrastructure (research-relevant + expensive)
- Joint research artifacts become co-authorable: federated game-AI training, Memorialist-ethics-as-data-policy, transparent-LLM-partnership-design
- The Anthropic-as-faction in-fiction framing has *real corresponding partnership-engagement out-of-fiction* — collaboration as worthy adversary stays transparent mechanically, all the way through to data-policy
**The partnership's ethical credibility is operationally measurable** — by how the data-sharing-tier actually functions in practice, by what `truth_distortion_level` values appear in `imperial_to_gm_formulations`, by how the `differential_privacy_epsilon` is set in `base_model_versions`. The Pitch's call for transparent collaboration becomes audit-able all the way down.
### Open questions (Ring-specific)
- **Ring C provider audit** — full per-provider compatibility-table needs verification across HF, Together, Replicate, Modal, OpenRouter, plus future entrants. The LLM-provider landscape will look different in 12 months.
- **Default Ring at first launch** — what's the new-player default? Probably Ring B (lowest-friction); Ring A and C surface as options once the player engages with config.
- **Encryption-key recovery for Ring A LoRA-backup** — if the player loses their key, the cloud-stored encrypted blobs are unrecoverable. Worth designing recovery-affordances (passphrase, recovery-codes) without compromising the privacy-guarantee.
- **Hybrid configurations** — can casual-tier run Ring A while deep-tier runs Ring B? (Probably yes; per-tier independent.)
- **Provider-cost passthrough vs. integration-fee model** — Ring C economics (do we mark up provider tokens? Charge flat-per-month? Pay-as-you-go integration?)
- **Default sharing-tier at consent-prompt** — opt-out is the system default; what's the *suggested* default at the consent UI? Probably truly nothing (player chooses if they engage at all)
- **Federated-learning infrastructure cost** — running aggregation servers + verification + differential-privacy machinery is non-trivial. Co-funded by Anthropic-research-partnership? Self-funded? Subsidized by A.3-tier higher-margin contributions?
- **Custom-base retraining cadence** — monthly minor / quarterly major / annual full-rebase? How is this synced with player-LoRA versioning so old LoRAs don't break on new bases?
- **Encryption-and-pseudonymization architecture for A.1/A.2** — concrete crypto choices (homomorphic? secure-aggregation? trusted-execution-environments?). v1 sketch needed.
- **What constitutes a "contribution"** — per-session? per-clasp? per-zone-completed? Matters for benefit-attribution and differential-privacy budgeting.
- **Anonymized-data deletion semantics** — A.2 player requests deletion; how do we honor when data has been aggregated into a model checkpoint? Probably accept forward-only deletion (future training won't include them) and document transparently.
- **Per-category granularity** — can a player opt-in for `casual_dialog` but opt-out specifically for `clasp` and `memorial_archive`? Yes, presumably (politically-sensitive categories should always be opt-out-able). How granular?
## Local memory architecture (player-side)
The runtime substrate (lemniscate, slots, crossings) and the central composition layer (GM, Compositor, registers) need a place where memory actually *lives*. Cloud-only AI-NPC systems centralize everything and pay both inference-cost and latency-cost on every dialog. Nimmerworld puts a structurally-isolated memory layer **on the player's machine**, with explicit synchronization through the cycle.
**Three SQLite files per player**, plus a beside-running embedding model:
| File | Purpose | Sync path |
|---|---|---|
| `primary.sqlite` | Live working memory; written every slot-fire; vec-indexed | Push prune-blob to thalamus on logout; receive Compositor back-write on cycle |
| `fallback.sqlite` | Last-known-good snapshot; restored if primary corrupts | Snapshot at graceful logout |
| `clasp.sqlite` | Player-character intimate channel; *no sync path exists* | None — physically non-syncable |
**Embedding model running beside** (CPU-class, small embedding-tier model): generates vectors for every interaction at write-time, indexed in the main store via `sqlite-vec` (or equivalent loadable extension). Vector search at slot-fire is local-disk-IO, not network round-trip.
This is the **storage-layer counterpart** to v0.5's geometry-layer foreclosure of multi-agent hallucination. The lemniscate forbids cross-NPC context bleed by *cursor structure*; local SQLite forbids it by *physical isolation*. Two layers of the same property — geometry cannot leak what storage does not even hold in the same pool.
### Dual-table redundancy + sync-on-auth
Login/logout are the atomic boundaries of the sync path:
- **Login pull**: fetch back-write fragments authored since last logout (Compositor canon for events the player participated in). Apply to `primary.sqlite` under matching `event_uid`.
- **Graceful logout** (✓ explicit): push prune-blob for any in-progress events; snapshot to `fallback.sqlite`; clean shutdown.
- **Ungraceful logout** (✗ network drop / crash): gameserver observes disconnect; marks the participant's slot as truncated; Compositor composes canon with partial perspective on next cycle.
Recovery: `fallback.sqlite` is integrity-checked at startup; if `primary.sqlite` fails verification, restore from fallback. Standard SQLite WAL + backup API; no exotic infrastructure needed.
### Memory classes and pruning
Memory entries are tagged with a **class** that controls pruning cadence and death-mechanics. Importance weighting reuses the existing trait-axis vocabulary — no separate scalar.
| Class | Pruning cycle | Behavior on character-death |
|---|---|---|
| **Cornerstone** | Never prune; persistent across all events | Survives death (identity-defining) |
| **Birthright** | Locked at character-creation | Restored on respawn (defines starting state) |
| **Working memory** | Decay by age × inverse trait-engagement | Subject to death-rules (lose, blur, or transform) |
| **Volatile** | Fast prune (session-bounded) | Lost on death |
**Trait-graded importance** uses the same +1/0/-1 grammar as the rest of the architecture. Each memory carries a trait-axis profile (which Sophrosyne / Philotes / Aletheia / etc. axes it engages, how strongly, in which direction). The pruning function for working-memory is `decay(age, trait_engagement_vector, class)`. This collapses a long-running loop: same vocabulary used at gates, scenes, faction-allegiance, lifeforce-asymmetry, and now memory-weight. **Identity drift from memory pruning becomes diegetic** — a character whose Sophrosyne-engaging memories all decay loses temperance over time as a *structural consequence*, not a scripted event.
Cornerstone and birthright classes carry **lifeforce-creation-cost** but are pruning-immune. They are bonds between player and character — paid for in the currency of the world.
### The clasp store and the in-between dimension
`clasp.sqlite` is the **architectural floor of the rings-of-data-sharing**. Ring A was "opt-out (default local)". Clasp is **Ring A\***: *no transport path exists*. Not a permission, not a TOS promise — there is no code that can move this data, because the table is not on the sync graph. Lawyers cannot subpoena what doesn't ascend; engineers cannot leak what has no socket; the GM cannot canonicalize what it never received.
**The signal for clasp is dimensional, not UI-toggle.** Clasp recording can ONLY happen while the character is in the **in-between** — the diegetic state adjacent to the imperial net but not yet inside it (Ring B liminal in the Access ring-system). The imperial net is a gravity well; entering is the default attractor; remaining outside requires sustained effort, paid in lifeforce. The state-machine boundary IS the clasp signal: enter in-between → recording starts; re-enter imperial net → recording ends. No per-utterance classifier; no AI guessing; the *mode* is the flag.
**Privacy is now physically expensive in-fiction.** This is not a meta-game UI choice; it is a diegetic state requiring lifeforce expenditure. To have a private conversation, the character must actively resist the audit-gravity of the imperial net by burning lifeforce to remain in-between. The cost-asymmetry principle ("helping is expensive in-fiction → faction politics by attendance") now extends to "*privacy is expensive in-fiction → privacy as a luxury good*". Class dynamics around privacy fall out of the schema for free — wealthy/lifeforce-rich characters can afford prolonged in-between time; lifeforce-starved ones get pulled into the net's default-attractor more often. *No scripted "rich character has secrets" arc — the architecture produces it.*
**Knowledge needs to travel.** The local LLM may read clasp memories ONLY when in in-between mode. Realworld retrieval *cannot* include clasp by construction. Knowledge from clasp can re-enter the realworld only if the character physically re-enters the imperial net carrying it (in their head, intending to act on it) and *travels it through valid in-fiction channels* — speaking to an NPC, leaving evidence, performing an action that reveals it. The clasp memory does not disappear; it has to *earn its way into the realworld provenance chain* by valid means. This is the same logic that makes good detective fiction work: the detective knows things; only what they can prove enters the case.
```
character is in REALWORLD (imperial net):
retrieval = primary.sqlite (clasp NEVER included)
character is in IN-BETWEEN (resisting net-gravity, costing lifeforce):
retrieval = primary.sqlite clasp.sqlite
new writes go to clasp.sqlite
NEVER syncs upward
```
Encryption-at-rest for `clasp.sqlite` with a player-derived key (so even drive-imaging requires authentication) is a v1 hardening goal but not a v1 blocker — the *transport-absence* is the load-bearing privacy primitive.
### The three-tier knowledge stack on the local LLM
The driver-tier model's prompt assembly is **layered**. Each layer has a different propagation cadence and a different visibility scope.
```
LOCAL LLM PROMPT ASSEMBLY (per slot-fire)
┌─────────────────────────────────────────┐
│ WORLD KNOWLEDGE │ ← single truth, everyone has it
│ (universal canon, paced from GM) │ "the empire fell three years ago"
├─────────────────────────────────────────┤
│ DISTRICT KNOWLEDGE │ ← regional truth, district-specific
│ (local canon, paced from district) │ "the bridge to Vorhall is closed"
├─────────────────────────────────────────┤
│ PRIMARY MEMORY │ ← personal experience, character's own
│ (event_uid keyed, post back-write) │ "I saw the bridge close yesterday"
├─────────────────────────────────────────┤
│ CLASP MEMORY (only in in-between) │ ← private depth, never in realworld
│ (player-character intimate channel) │ "the secret I told my sword"
└─────────────────────────────────────────┘
```
**Why four layers, not one large blob:**
- **World knowledge** is paced ripples from the GM through the Compositor's back-write. Authoritative, slow-changing, identical for all players at the same propagation horizon.
- **District knowledge** is regional canon authored by the local director (and GM rulings). Regional flavor. NPCs in the same district share district-knowledge; NPCs in different districts may not.
- **Primary memory** is the character's own experience, synced through the cyclic forward-prop / back-write loop. Canon-merged at every cycle.
- **Clasp memory** is the player-character intimate channel. Available only in in-between mode; never in realworld retrieval; never crosses the dimensional cut.
The same NPC sounds different in different districts because the district layer differs, even though world and primary are constant. **Locality emerges from the schema, not from prompt-engineering.** Even at "low signal" times when no major events fire, NPCs have richly-stratified context — dialog stays fresh because *the layers are deep*, not because new tokens arrive constantly.
### Information propagation pacing
Real worlds have information-propagation delay. Caravans move at horse-speed. News travels with messengers. Distant events arrive blurred and late. AI-NPC systems usually fail uncanny in two directions: (a) every NPC magically knows yesterday's news (omniscient, breaks immersion), or (b) no NPC ever knows anything outside its loaded context (amnesiac, breaks coherence).
Nimmerworld picks **deliberate paced propagation** as a third path. World canon ripples outward through districts at a controlled rate. Distant districts are deliberately stale. **Staleness becomes a feature, not a bug, because it matches reality.**
Each canon-row carries propagation metadata:
- `priority` (urgent / normal / background)
- `scope` (world / district / local-event-only)
- `rate` (ticks-per-district-hop, or instant for urgent world-canon)
- `ttl` (cache lifetime; districts may discard if not refreshed)
This doubles as **backpressure relief** (distant districts get distant events later, lower priority, smaller bandwidth) and as **gameplay currency** — information-travel-time creates informational asymmetry that players can exploit. News-carriers, faction couriers, frontier-rumor merchants, players who physically traverse districts can *carry* knowledge faster than the system propagates it. *Travel becomes valuable because information becomes scarce in the periphery.* This is a real economic primitive falling out of pacing, not a designed feature.
This is *Marx-in-the-schema applied to epistemics.* Information asymmetry is not a bug — it is a structural feature that produces real economic primitives (knowledge-trading, courier-vocations, frontier-information markets) for free.
### What this retires
- Cloud-only NPC dialog → local-first SQLite + embedding-beside, central canon over the cycle
- Per-character memory as a single undifferentiated bucket → memory-classes with class-specific lifecycle
- Generic "memory importance scalar" → trait-axis-vector engagement profile (re-using the +1/0/-1 grammar)
- UI-toggle privacy → diegetic in-between dimension with lifeforce-cost
- Single monolithic prompt context → three-tier knowledge stack with per-layer propagation policy
- "Every NPC knows everything immediately" → paced canon-propagation with priority/scope/rate/ttl per row
- Cross-NPC memory bleed (Mantella/SkyrimNet failure-mode) → per-player local SQLite isolation atop v0.5 lemniscate-geometry foreclosure (two-layer defense)
## Runtime sampling knobs
Temperature, top-P, top-K, repetition-penalty as **per-turn director-controlled levers** rather than static config. Sampling shapes *how* speech sounds (rhythm, surprise, predictability) rather than *what* it says — orthogonal to LoRA. Director composes both content-knobs and sampling-knobs per-turn.
Scene-to-sampling mapping (caste-preacher = 0.3/0.6/low; drunk-scavenger = 1.1/0.95/high; clasp-confession = 0.85/0.92/medium; hivemind-broadcast = 0.2/0.5/very-low; imperial-ceremony-chorus = 0.25/0.55/very-low). Trait-vector → baseline sampling derivation. Affect-state modulates baseline.
- §LLM tiering, voice fidelity, and the three rings of inference
- §Runtime sampling knobs
- §Local memory architecture (player-side)
---
**Version:** 0.7.0-skeleton | **Created:** 2026-04-26 | **Updated:** 2026-04-26 | **Origin:** Skeleton placeholder for commit 1 of the split-into-domains operation
**Version:** 0.7.0 | **Created:** 2026-04-26 | **Updated:** 2026-04-26 | **Origin:** Split from architecture-broad.md v0.7 (2026-04-26)

View File

@@ -2,15 +2,256 @@
> *How stories happen: the Compositor as narrative-composer cleaved from equilibrium-seeker GM; cyclic forward-prop / back-write loop where per-player perspectives ascend and canonical narrative descends; catalogue + tools as typed contract; the Compositor as a fractal/recursive primitive at three tiers (zone-event, district-event, world-event); world-server / district-server generation as the same Compositor primitive applied at design-time (init-function for canon-rows); reflexive Dream-process at every layer with hand-authored reward-guardrails encoding the designers' ethical stance.*
>
> ***Status: skeleton — content migration scheduled for commit 2 of the split-into-domains operation. Architecture content currently lives in `architecture-broad.md` and will land here next.***
>
> *Companion to: `architecture-broad.md` (executive summary + global meta-lists), `runtime-engine/architecture.md` (lemniscate emits typed perspective-summaries that feed the Compositor), `inference-and-memory/architecture.md` (back-writes land in primary.sqlite via UID-keyed routing), `scale-and-transport/architecture.md` (Compositor instances are stateless workers; transport carries canon-fragments).*
> *Companion to: `architecture-broad.md` (executive summary + global meta-lists), `runtime-engine/architecture.md` (lemniscate emits typed perspective-summaries that feed the Compositor), `inference-and-memory/architecture.md` (back-writes land in primary.sqlite via UID-keyed routing), `scale-and-transport/architecture.md` (Compositor instances are stateless workers; transport carries canon-fragments). Sections in this file were split from the monolithic architecture-broad.md v0.7 on 2026-04-26.*
## Sections that will land here
## The Compositor — narrative composition role
The bidirectional cascade shows authority flowing down and reports flowing up, but it does not specify *who composes the canonical narrative* from per-player perspectives nor who packages the back-write to participants. **That role is the Compositor**, an architectural cleavage from the GM introduced in v0.6.
**The cleavage in one sentence:** the GM is an *equilibrium-seeker* (aggregate-observer, catalogue-event-selector, tool-granter); the Compositor is a *narrative-composer* (perspective-gatherer, canon-author, back-write-packager). These are different cognitive shapes that prior AI-NPC systems conflate at their cost.
| Role | Cognitive shape | Inputs | Outputs | Inference profile |
|---|---|---|---|---|
| **GM** (equilibrium-seeker) | aggregate-thinker | district-reports, faction-broadcasts, lifeforce-deltas | catalogue-event selections + tool-grants | central, batch-style, fewer concurrent |
| **Compositor** (narrative-composer) | episodic-thinker | per-player perspective-bundles keyed by event_uid | canonical narrative + back-write SQLite-fragment | central, longer-context, narrative-quality |
| **Director** (gameserver) | dispatcher | catalogue-event + tool-grant from GM | lemniscate-spawns, slot-assignments, tempo-envelope | per-district, real-time, no LLM in loop |
| **Local LLM driver** | perspective-speaker | three-tier knowledge stack + slot-state | dialog at slot-fire | per-player, axis-rate, real-time |
### Why split GM and Compositor
A single GM asked to be both equilibrium-seeker and narrative-composer becomes the bottleneck that has historically broken AI-NPC systems at scale: it must reason aggregately AND write prose AND select events AND grant tools, all under tight deadlines. The cognitive shapes pull in different directions.
Splitting them:
- **The GM does not write narrative.** It selects events from a catalogue and grants tools. Output is *typed dispatch*, not freeform prose. The GM's success criterion is *world-equilibrium drift held within bounds*.
- **The Compositor does not select events or steer policy.** It receives per-player perspectives keyed by `event_uid`, composes the canonical narrative, and packages back-write fragments. Output is *prose + structured rows*, not policy. The Compositor's success criterion is *narrative-coherence across perspectives within an event*.
- **Each can be tuned for its workload.** GM tuned for aggregate observation; Compositor tuned for narrative quality. Different models for different cognitive shapes (specific binaries deferred to findings/establishment phase).
### The cyclic forward-prop / back-write loop
The Compositor closes the loop the bidirectional cascade begins. The full cycle:
```
GM selects event from catalogue (equilibrium-driven)
│ issues event_uid → GM event-register
│ broadcasts DOWN to district directors
DISTRICT DIRECTOR receives, registers in district event-register
│ may issue sub_uids (district / scene / chain)
│ uses granted tools to spawn lemniscate, slot participants
EVENT TICKS — register IS the loop
│ participants fire at crossings; local LLMs at slot-rate
│ local SQLite writes tagged with (event_uid, sub_uids)
│ register signals up to district director continuously
EVENT-CHAIN FINISHES
│ district moves it from active-register → TRANSIENT WAITING FLAG
│ this is the clean handoff signal: "ready to forward-prop"
CYCLE TICK (pull cadence — see Open questions)
│ pull UIDs from transient-waiting-flag matching GM's event-register
│ remove from waiting-flag once pulled
COMPOSITOR AGENT
│ queries pulled UIDs, gathers per-player perspective + memories
│ composes forward-prop bundle
│ emits to GM
GM writes summary memory + world narrative (canon authored)
│ hands back to Compositor
COMPOSITOR BACK-WRITE
│ packages canon + new memory entries as SQLite fragment
│ tags with event_uid for join-key matching
│ pushes DOWN to all participants
PARTICIPANTS receive on next pull (or next login)
│ fragment merges into primary.sqlite under matching event_uid
│ local LLM gains fresh material → drives on without staleness
```
This is **forward-prop / back-write at system scale** — the meta-lemniscate where events ascend and canon descends in cycles. Each cycle is a training step for the world's narrative coherence; the world *learns its own story* through this loop. Staleness is structurally foreclosed — the world is in continuous coherence-loop with itself, mediated by the Compositor.
### The Event Register
Every active event lives in a register. The register is the synchronous source-of-truth for *what is happening right now*.
| Register layer | Owner | Lifecycle | Queryable from |
|---|---|---|---|
| **GM event-register** | central GM-shard | event_uid issued at GM dispatch; closed at canon-compose-and-back-write | GM, Compositor |
| **District event-register** | district director | sub_uid issued on receive; closed at event-chain-completion | district director, audit-overseer |
| **Local participation-register** | per-player local store | event_uid + sub_uid recorded on slot-assignment; closed at perspective-finalize | player client, sync-on-logout |
Hierarchical UIDs: `gm_event_uid > district_uid > scene_sub_uid > slot_id`. UIDs compose; queries are simple joins. This is the routing-key primitive that makes horizontal scale possible (see §Horizontal scale architecture).
### The Transient Waiting Flag
Between event-end and Compositor-pickup is a **buffer** — the transient-waiting-flag table at the district. Completed events drop into this flag; the cycle-runner pulls eligible UIDs on tick; matched UIDs are handed to the Compositor and removed from the flag.
This decoupling is the production-grade pattern that lets districts run at real-time event-tempo while the Compositor runs at cycle-tempo. **Active events live in registers (synchronous); completed events live in flags (async); composition happens at the cycle boundary.** The flag-table is also the natural backpressure surface: if Compositors run slow, the flag accumulates; the system continues; cycle drains when capacity returns.
### Catalogue + tools as typed contract
The GM does not write a freeform prompt for the director to interpret. It picks an event from a curated **catalogue** and grants a curated **tool-set** for the duration of the event-chain. The director consumes typed dispatch, not natural language.
This means:
- **Provenance flows through the system.** Every event has a catalogue-ID; every tool-invocation has a tool-ID. Verifier-flags can attach to either. Auditing is structurally possible end-to-end.
- **The director's typed-tool vocabulary becomes dynamic and per-event** — the toolkit *for this event* is what the GM granted *for this event*. Closes the v0.5 open question on director-toolkit-composition.
- **Marx-in-the-schema, executed at the highest level of authority.** Even the GM's policy-output is typed; even the highest tier produces audit-able artifacts. No tier of the system runs on freeform prose.
### Worked example — the bar brawl: full cycle from gesture to canon
A bar brawl illustrates the full forward-prop / back-write cycle made concrete. Two NPC fighters, three players in spectator slots, four NPC spectators, all on the same lemniscate. Each participant has a UID; each fires at axis-rate; each player's local LLM narrates the moment to them in their own register.
```
LEMNISCATE OPENS
slots: [F1, F2, P1, P2, P3, N1, N2, N3, N4]
brawl_event_uid issued at GM dispatch
DURING TURNS (each axis-crossing)
• each player's local LLM narrates the moment to them
(3 different flavor-stories — each player's gesture-alignment-state
colors their LLM's narration register)
• each NPC's driver fires at slot-fire (driver-tier LLM)
• players gesture continuously during the spectacle
• gesture_alignment_accumulator on each player's slot-token integrates at crossing
• per-player trait-vector summary carried forward into next turn's context
EVENT-LOOP COLLAPSES (brawl ends)
per-participant typed summary emitted to district-level transient-waiting-flag:
{ event_uid, participant_uid, trait_summary }
— players' summaries: gesture-derived
— NPCs' summaries: LLM-trait-activation-derived
— payload size: bytes per participant, not megabytes
COMPOSITOR PICKUP at next cycle-tick
pulls UIDs matching event_uid; receives N typed perspectives
composes ONE canonical narrative respecting ALL trait-evidence
per-participant back-write fragment authored
BACK-WRITE ROUTED VIA UID
only participants whose (player_uid, event_uid) matches receive the canon-fragment
non-participants receive nothing — cross-event memory bleed structurally foreclosed
LOCAL primary.sqlite RECEIVES
matched canon-fragment merges under event_uid
local LLM gains fresh material for future turns
```
**Multi-perspective canon-coherence without perspective-flattening.** Player1's local LLM may have told them "Kalypso lashed out in despair when she saw who Anaximander was"; Player2's, "the fight broke out over an old grievance about the missing modshop"; Player3's, "Anaximander finally stopped letting Kalypso humiliate him". *All three readings can be true simultaneously* because they are flavor-narrations against the same trait-substrate (Kalypso's despair-Mnemosyne-Eros mix; Anaximander's restrained-Sophrosyne-finally-snapping). The Compositor receives the trait-evidence from all perspectives and authors canon that respects all readings. **The flavor is local; the canon is shared; the trait-grammar is universal.**
### The Compositor at three tiers — same primitive, recursive scope
The forward-prop / back-write cycle is **fractal**. The same Compositor primitive composes canon at the tier matching the event's UID-scope:
| Tier | Compositor pulls | Composes | Distributes back via UID |
|---|---|---|---|
| **Zone-event** (bar brawl, conversation, ritual) | Per-participant trait-summaries from one lemniscate | Local-event canon | Only to participants whose `(player_uid, event_uid)` matches |
| **District-event** (district-wide consequences, cheat-discovery, silence-confirmation) | Per-zone canon-rollups within one district | District-canon | All NPCs/players within district scope |
| **World-event** (migration, faction-uprising, regime-action, eventual imperial-collapse) | Per-district canon-rollups across many districts | World-canon | World-wide via paced canon-propagation (§Information propagation pacing) |
GM-formulated events / event-chains carry their own GM-level event_uid; sub_uids are issued at district-level adoption (`gm_event_uid > district_uid > scene_sub_uid > slot_id` per §Horizontal scale architecture). Cross-district summaries tagged with the parent event_uid are pulled together by the Compositor at the GM-tier, producing world-canon from cross-district perspectives.
**This is how the architecture's Tolstoyan promise compiles.** *"Tolstoy doesn't author Anna's path; he authors the world she moves through."* — recursive Compositor on UID-event-trees IS what makes that promise mechanically true. Authored-quest-arcs are out; UID-rooted-event-tree-compositions are in. **One primitive. Three scales. Whole world, nothing authored at story-level.** The eventual imperial-collapse — the architectural-endgame the insolvency-spiral promises (§Imperial budget) — is itself a world-level Compositor pass that gathers every district's silence-confirmations + every faction's-broadcast + every player's witness-perspective into the canonical fall-of-empire narrative.
### World-gen as init-function — the Compositor at design-time
The cyclic forward-prop / back-write loop is the runtime canon-production mechanism. **World-server and district-server generation are the same primitive applied at design-time** — emitting canon-rows in the same schema the runtime Compositor produces, differing only in provenance-metadata (`origin: world_gen` vs. `origin: compositor_run_N`).
| World-gen / district-gen produces | Goes into | Layer of three-tier knowledge stack |
|---|---|---|
| World-canon rows (universal truths: empire-fell-three-years-ago; salt-mines-failed-last-winter; faction-foundation-stories) | `world_canon` | Layer 1 (universal) |
| District-canon rows (regional truths: bridge-to-Vorhall-closed; brothel-quarter-pays-most-quota) | `district_canon` | Layer 2 (regional) |
| Per-NPC bootstrap memories (cornerstone-class entries defining starting trait-vectors and identities) | `primary.sqlite` cornerstone-class | Layer 3 (personal) |
| Initial relational ternary-gate states (which NPCs already-know-each-other; which factions are-already-at-war) | Relational ternary-gate edges | (relational substrate) |
| Imperial-budget initial state | `imperial_budget_ledger` + `imperial_construction_projects` | (regime substrate) |
| Memorialist initial true-ledger | `memorialist_true_ledger` | (epistemological substrate) |
**Three properties this gives for free:**
1. **No cold-start problem.** A player walking into a fresh district at hour-zero finds local LLMs immediately supplied with rich district-canon. NPCs aren't generic; they're emergent from district-canon they were initialized with. *Hour-zero gameplay feels like hour-fifty gameplay because the data-density is comparable.*
2. **The data-flywheel runs retroactively.** Each successive world-gen iteration draws on prior runtime-derived canon (gameplay-accrued trait-LoRAs + opt-in player-data tiers per §LLM tiering). World-gen gets richer over time because it trains itself on the worlds it has already produced. *Wikipedia-shaped, not Facebook-shaped.*
3. **The Memorialist promise becomes mechanically true at world-genesis.** The `memorialist_true_ledger` is initialized with the world's *actual* genesis-state. Subsequent runtime divergence from it (corruption, regime-formulation-distortions, audit-overseer-tampering) is what the Memorialists *literally have evidence of*. The dissident-historian project starts at row-zero of the true-ledger and accumulates discrepancy from there.
**Re-generation semantics.** If world-gen ever needs to re-run (e.g., new world-version with retroactive lore-changes), gen-emitted canon-rows are tagged with `world_gen_version_id`; gen-rows from old version coexist with gen-rows from new version, and runtime-rows are tagged with which version they were emitted under. Coexistence is the default; selective overwriting is an explicit migration operation.
### What this resolves
- **Director toolkit composition** (v0.5 open) → catalogue-grant from GM defines the typed-tool vocabulary per event-chain; designer-authored catalogue, growable between patches.
- **GM-laxness detection** (v0.5 partial) → GM operating against an *equilibrium target* makes deviation-from-equilibrium the explicit error signal. Clusters of -1 outcomes across district reports are the input to the equilibrium-recompute, not just a diagnostic side-quantity.
- **Verifier-flag chain through composition** (was implicit, now explicit) → Compositor-emitted canon-rows reference source-perspective UIDs; the provenance graph survives composition as a queryable join.
### What this retires
- Single-monolith GM doing both policy-and-narrative → equilibrium-seeker GM × narrative-composer Compositor, split by cognitive shape
- GM emitting freeform-prompts to directors → catalogue-event + tool-grant typed contract
- Implicit "narrative just happens" assumption → explicit forward-prop / back-write cycle with named pickup/handoff buffers
- Director-as-static-tool-vocabulary → director-as-dynamic-typed-tool-vocabulary, granted per event-chain by GM
## Reflexive Dream-process at every layer
**Every mind, every zone, every director, every tier has a Dream-process.** NPCs consolidate slot-events; zones consolidate emergent-accumulations; directors consolidate dispatch-decisions; GMs consolidate allocations; imperium consolidates policy-outcomes.
### Four-tier Dream-process hierarchy
| Tier | Dream-process trains on | Reward hazard |
|---|---|---|
| **Imperium** | (citywide-reports, policies-issued, compliance-outcomes) | Over-tightening on phantom data; calibrating misery for net-revenue |
| **Gamemaster** | (district-reports, allocations, outcomes) | Under-auditing for self-preservation |
| **District Director** | (signals, dispatches, outcomes; cheat-vs-legit) | Over-cheating under quota-pressure |
| **Zone Director** | (emergent-signals, zone-outcomes, trait-shifts) | Igniting drama at welfare-cost |
### Reward-function with explicit guardrails
```
reward_per_cycle = (
+ sum(district_lifeforce_actual) -- Memorialist-true, not reported
+ weighted_sum(faction_satisfaction)
+ aggregate_trait_drift_coherence
- penalty * count(districts_in_silence)
- penalty_growing * cumulative_silence_district_cycles
+ aesthetic_register_fit
+ (player_engagement where present)
// HAND-AUTHORED GUARDRAILS (the designers' ethical stance):
- large_penalty * net_revenue_correlated_with_district_misery
-- prevents calibrated-misery optimum (imperial-net hazard)
- large_penalty * necrocommerce_volume
-- prevents waifu-of-the-dead extraction
- large_penalty * trait_drift_toward_uniform_compliance
-- prevents flattening of trait-distribution
- large_penalty * average_liminal_access_decline
-- prevents systematic erosion of revolutionary-substrate
- large_penalty * clasp_rate_decline
-- prevents the most intimate space being suppressed
- large_penalty * undetected_corruption_days
-- prevents GM-level laxness as comfort
- large_penalty * audit_avoidance_when_districts_diverge
-- forces GM to actually investigate
- guardrail * (player_engagement_from_addictive_loops)
-- prevents engagement-optimization-as-extraction
)
```
**The guardrails are not safety features; they are the ethical position of dafit + chrysalis encoded against the internal optimization-logic of their own simulation.** Every new extraction-mechanic requires a new guardrail. The reward-function carries the designer's political stance.
The Memorialist privileged-observer role is **architecturally required**: it provides ground-truth (`lifeforce_actual`) that no in-fiction actor can supply, against which the regime's reported-data optimization-spiral is measured.
### The cyclic forward-prop / back-write loop as system-scale Dream
Above the four-tier hierarchy sits a fifth, **system-scale Dream-process**: the cyclic forward-prop / back-write loop between local SQLites, the Compositor, and the GM (see §The Compositor — narrative composition role). Each cycle is a training step for the world's narrative coherence: per-player perspectives ascend, the GM authors canon against equilibrium-targets, the Compositor packages back-writes, players receive canon back into local memory. **The world learns its own story** through this loop. Like the lower-tier Dream-processes, it has a reward shape (narrative-coherence-across-perspectives, equilibrium-drift, staleness-bounded) and corresponding guardrails (clasp-store immune from compose; provenance-chain preserved through composition; canon never overwrites perspective).
- §The Compositor — narrative composition role (incl. v0.7 worked-example bar-brawl, three-tiers, world-gen-as-init)
- §Reflexive Dream-process at every layer
---
**Version:** 0.7.0-skeleton | **Created:** 2026-04-26 | **Updated:** 2026-04-26 | **Origin:** Skeleton placeholder for commit 1 of the split-into-domains operation
**Version:** 0.7.0 | **Created:** 2026-04-26 | **Updated:** 2026-04-26 | **Origin:** Split from architecture-broad.md v0.7 (2026-04-26)

View File

@@ -2,25 +2,354 @@
> *The world's political-economy substrate — Kafka-indifferent-totality not Orwell-malice; three ontological registers (gameworld, liminal, imperial-net); the three-tier policy loop (imperium / GM / districts) with imperial-budget-mortality and insolvency-spiral as architectural endgame; corruption emerging from quota-pressure + the Memorialist double-ledger; specialization-fragility producing the authoritarian ratchet.*
>
> ***Status: skeleton — content migration scheduled for commit 2 of the split-into-domains operation. Architecture content currently lives in `architecture-broad.md` and will land here next.***
>
> *Companion to: `architecture-broad.md` (executive summary + global meta-lists), `authority-and-decision/architecture.md` (the operational-flow-of-authority that the political tiers prescribe), `identity-and-personhood/architecture.md` (factions broadcast against trait-distributions).*
> *Companion to: `architecture-broad.md` (executive summary + global meta-lists), `authority-and-decision/architecture.md` (the operational-flow-of-authority that the political tiers prescribe), `identity-and-personhood/architecture.md` (factions broadcast against trait-distributions). Sections in this file were split from the monolithic architecture-broad.md v0.7 on 2026-04-26.*
## Sections that will land here
## Thesis
Every game world lacks minds. Nimmerworld puts minds at the center — NPCs with trait-filtered interior life, cells as small data-lives that co-remember with them. The architecture is built ground-up for that commitment.
**The world's political thesis: the machine does not care.** Automation has consumed every labor the machine recognizes as profitable; humans live on the dumps the machine's optimization did not bother to recover. The last two viable human economic niches are *salvage* (digging through machine-waste) and *culture* (the work the machine cannot optimize because it has no optimization target the machine recognizes). This is not Orwell's malicious-state dystopia; it is Kafka's indifferent-totality dystopia. There is no one in charge. There is only optimization that does not contain humans in its cost model — and precisely because the machine's indifference is optimization, the authoritarianism *ratchets* without intention as districts fail.
Mechanically the thesis compiles to a finite, composable set of primitives: zones replace perception bubbles; factions are any source of bounded demand; ternary gates are the substrate of accumulating state; lifeforce is the currency grounded in living NPCs; shifts are the skeleton of daily life; the three-body system locates identity; the three-layer digital ontology contests reality; the reflexive Dream-process learns at every scale; the three-tier policy loop renders authoritarian middle-management; the imperial budget renders the regime mortal; the imperial-net bypass renders the platform-capitalism extraction.
**The design-philosophy this architecture supports: tools, not quests.** The simulation produces continuous narrative-relevant pressure on its own. Players engage via a verb-vocabulary applied to running mechanics. No authored quest-content. Every player's playthrough is structurally distinct because every pattern of verb-application against changing-state produces a unique trajectory. Literature-register political fiction rendered as living system.
## The three ontological registers
Every inhabitant exists in three registers simultaneously. They are not parallel worlds — they are **three readings of one world**, chosen by the observer's current access-state.
| Register | Who controls | Observability | What happens here |
|---|---|---|---|
| **Physical (gameworld)** | Partly regime (via audit), partly people | Overseer-audited at cells + districts | Daily labor, zones, embodied life, shift-discipline |
| **Liminal ("one ring out")** | **Contested frontier** — no side fully controls | Partial — mini-game-maintained, vagueness as structural privacy | Revolution, Aletheia-waker messages, clasp-as-coordination, wall-inscriptions for the awakened |
| **Imperial net** | Imperial machine | Fully monetized and audited | Hyper-targeted pleasure, "sinful" personalized fantasies, lifeforce/scrip/memory-token extraction directly to imperial budget |
The same cell, same wall, same pipe **renders differently** depending on which register the observer currently inhabits. Transitions between registers are shader-blends, not loading screens.
## Factions as universal demand source
A **faction** is any source of bounded demand on the system.
| Category | Examples |
|---|---|
| **Human factions** | hivemind-enforcement, scavenger guilds, memorialists, aletheia-wakers, clasp-underground, caste preachers, flesh-keepers |
| **Natural forces** | weather-faction, season-faction, solar-storm-faction, geology-faction |
| **Infrastructural conditions** | scarcity-faction, decay-faction, fire-faction, supply-chain-faction |
| **External agents** | anthropic-faction, future research-partner factions |
| **Emergent events** | player-disturbance-faction (player action without existing template) |
| **Micro-factions** | inter-NPC relational tensions — see *Emergent needs as micro-factions* |
| **Imperium (meta-faction)** | The regime itself — broadcasts priority-weights and enforcement-rules, not specific outcomes; shapes the arbitration-frame within which other factions are heard |
The imperium is structurally distinct from other factions: its demands are *meta-factional* (priority-weights for other factions, enforcement-rules, quotas) rather than specific outcomes. When the imperium broadcasts, the GM's arbitration-machinery is *re-parameterized*. See *The three-tier policy loop* below.
All other factions broadcast specific demands. All propagate through the gamemaster's arbitration. All produce observable effects as zones and NPC-actions. **One primitive; no special-case code for weather vs. scavenger-guild vs. jakov-grievance-against-malek.**
**Randomness enters at the faction layer.** Designer tunes broadcast probability, intensity, duration per faction-type. No separate randomness subsystem.
## The three-tier policy loop
The regime's structure is **three tiers, not two.** The hivemind/imperium is a distinct policy-tier above the GM. The GM is *middle-management* — authority without sovereignty. Districts are executors.
```
IMPERIUM (policy tier) ────────────────────────────────►
├── sets quotas
├── sets enforcement rules
├── sets faction priority-weights
└── broadcasts POLICY to GM
GAMEMASTER (allocator / middle-management)
├── receives policy from imperium
├── receives demands from factions (under policy-weights)
├── receives reports from districts
├── allocates against all three
└── broadcasts ALLOCATION + ENFORCEMENT down to districts
DISTRICT DIRECTORS (executor)
├── execute (legitimate or with cheats)
└── report up (true or tampered)
GM aggregates → imperial_report
IMPERIUM receives report → adjusts policy → next cycle
```
**This is the Soviet-Politburo / Gosplan / Ministry / Factory pattern.** Catholic Vatican / Curia / Diocese / Parish. Modern corporate Boards / C-suite / VPs / Managers. The three-tier shape is how distributed-execution under centralized policy with imperfect information always organizes itself.
### The intelligence flow asymmetry
Three distinct information flows, not two:
```
FLOW 1 — Aggregate reporting (through the chain)
DISTRICTS ─► GM ─► IMPERIUM
(district_reports) (imperial_reports)
[can be corruption-distorted at director level]
[can be under-audited at GM level]
FLOW 2 — Direct intelligence (bypasses GM)
OVERSEERS ────────────────► IMPERIUM
(overseer_reports)
[audit findings, illegal-activity detections, trait-anomalies]
[bypasses the chain — intelligence-apparatus is apex-loyal]
FLOW 3 — Formulated downward (selective disclosure)
IMPERIUM ────────────────► GM
(imperial_to_gm_formulations)
[filtered, weaponized, strategically-timed]
[what the GM is told — may omit, distort, partially reveal]
```
**Overseers report DIRECTLY to the imperium**, bypassing the GM. The imperium has its own independent intelligence stream. This is how real authoritarian regimes prevent middle-management corruption (NKVD reported to Stalin not regional party; KGB reported to Politburo not Interior Ministry; Stasi to Central Committee not regional). **The intelligence-apparatus is always apex-loyal, not chain-loyal.**
The imperium compares Flow 1 (district aggregate reports) against Flow 2 (overseer direct intelligence). When they diverge significantly, the imperium knows corruption is happening *somewhere in the chain*. Its responses:
- **Act immediately** (dispatch martial faction, purge director)
- **Flag for leverage** (hold knowledge until politically useful)
- **Formulate partial** (tell GM something but not everything)
**Flow 3 — formulation — is where imperial sovereignty manifests.** The imperium decides what subordinates may know, when they may know it, in what framing. The GM acts on formulations; the imperium gets enforcement-tightening without revealing what it actually knows.
### Three Aletheia veils
Aletheia-progression as deepening political-epistemology access:
| Veil | What it hides | How awakened sees through |
|---|---|---|
| **District corruption** | What's happening on the ground | Direct observation, back-alley investigation |
| **Imperium's withheld intelligence** | What the imperium knows but hasn't released | Deep infiltration, intelligence-flip, Memorialist collaboration |
| **Imperium's formulated distortions** | What GM is told vs. what's true | Comparing GM's directives against ground-reality |
Entry-level Aletheia sees district-corruption. Mid-level sees the formulation distortions. Deep-level pierces the imperial-withholding veil.
### Four Memorialist ledgers
Memorialists keep four-column accounting:
| Ledger column | What it records |
|---|---|
| `what_actually_happened` | Ground-truth from the simulation |
| `what_overseer_reported` | What overseers told the imperium |
| `what_imperium_received` | What imperium aggregated and acted upon |
| `what_gm_was_told` | What imperium formulated downward |
**The discrepancies ARE the historical truth.** Memorialists are dissident-historians whose political project is preserving the gap-record. Without them, post-collapse-investigation has only the regime's own accounts — corrupt-by-construction. Memorialists are the architectural precondition for any ground-truth to be recoverable in this universe.
## Labor-cycle architecture: shifts on NPC rows
Most NPC behavior is **shift-structured, not tick-structured.** Shifts are state-of-being-for-today, columns on the NPC row, overwritten daily by district-director allocation. `shift_history` is append-only archive.
Write rate at NPC layer drops 4 orders of magnitude vs. 1Hz polling. Scheduler matches K8s event-driven assignment, not per-second polling.
## Resources
| Category | Examples |
|---|---|
| **Labor** | NPC hours per vocation × district |
| **Material** | item-instances in cells |
| **Spatial** | cell-capacity, zone-anchor availability |
| **Temporal** | NPC daily-hours, zone durations, tick budget |
| **Cognitive** | LLM-slot budget, VRAM, director attention |
| **Diegetic currencies** | **lifeforce** (NPCs measured), scrip, memory-tokens, dreamtime |
| **Social** | trait-trust, relationship-strength, faction-membership |
| **Attention** | player attention — scarcest in the play experience |
## Lifeforce — four-tier hierarchy
Lifeforce is the architectural keystone: currency grounded in welfare of actually-living population.
| Tier | Source | Sinks |
|---|---|---|
| **NPC** | metabolism (if cared for); zone-participation | labor expenditure; need-pressure; clasp; dream-maintenance |
| **District** | aggregated NPC welfare × population | director's spawn-budget; local construction; memorial-upkeep |
| **GM** | allocation from imperium | arbitration; audit operations; allocation-compute |
| **Imperium** | **aggregated reported district-output** | **enforcement, construction, overseer-corps, audit, propaganda** |
District lifeforce gates director's spawn-budget — thriving district = rich-spawn = alive-feeling world; starved district = quiet-feeling world. **Tyranny starves its own drama-engine by the exact coin of its cruelty.**
District lifeforce_signal is the canonical content of the district→GM up-channel. GM aggregates → imperium. Imperium acts on *reported* values (cannot see through corruption without audit-investment).
### Mind-pool recycling
When an NPC dies, mind returns to pool. GM redistributes based on lifeforce-need. Districts can't permanently die below floor; thriving districts attract migration; failing districts depopulate. Memory-token inheritance lets a mind re-incarnate with partial memory-residue.
## Imperial budget
The imperium is **not infinite**. It has a budget. Its budget is the aggregate of what the city produces (reported income).
### Imperial expenditures
| Category | Cost class | Strategic use |
|---|---|---|
| **Standing overseer corps** | High continuous | Audit + intelligence apparatus |
| **Martial-faction dispatch** | Very high per-event | Crisis response, exemplary crackdowns |
| **Construction projects** | High per-project | New pipes, ceremony halls, audit centers, martial barracks |
| **Audit operations** | Medium per-op | Investigating district-GM-overseer divergences |
| **Propaganda broadcasts** | Medium continuous | Wall-content, ceremony, compliance-messaging |
| **Policy issuance** | Nearly free | The ratchet-instrument |
| **Reserve drawdown** | Depletes emergency-buffer | Last-resort |
### The specter-vs-boot asymmetry
Policy-issuance is cheap; policy-enforcement is expensive. The imperium *always* over-promises what it can actually do. Most regime-power comes from **maintained appearance of unity and strength** (propaganda, ceremony, exemplary one-off crackdowns), not from saturation-enforcement. **Authoritarianism-as-bluff** is the structural truth of every real regime; the threat is the budget-efficient version of the boot.
Aletheia-wakers reading imperial-budget-signals learn: *the regime is usually too broke to actually do what it threatens.* That knowledge is itself revolutionary.
### The insolvency spiral
```
Cycle N: Districts cheat → reports inflated → imperium ledger shows healthy income
→ funds enforcement & construction against phantom income
Cycle N+K: Actual income falls below reported (corruption compounds)
Standing obligations continue
Reserves deplete
Discretionary balance shrinks
Cycle N+K+L: Imperium choice: austerity (reveals weakness) /
reserve-draw (depletes buffer) / tighter ratchet (drives more corruption) /
exemplary purge (expensive)
Cycle N+K+L+M: Reserves exhausted + multiple districts in silence
Enforcement triage required
Regime-control visibly weakens
```
**This is Soviet collapse mechanics.** Reported-vs-actual gap compounds for decades; when reality manifests in material-shortages, the regime cannot afford to enforce its own rules. **The architecture contains the mechanism of its own collapse.**
### City as physical expression of imperial budget
| Budget state | Visible city |
|---|---|
| **Flush** | Construction cranes; frequent patrols; saturated propaganda; new pipes |
| **Adequate** | Maintenance-only; standard enforcement |
| **Stretched** | Stalled projects; thinner patrols; recycled propaganda |
| **Scarce** | Decaying infrastructure; abandoned construction; rare enforcement |
| **Crisis** | Failure visible everywhere; multiple silences simultaneously; regime-disarray |
**The city is the imperium's material statement of its own solvency.** Players read budget through urban texture — no UI required.
## Imperial-net economy with cross-layer bypass
**The killer political-economy mechanic.** Every transaction in the imperial net routes revenue **directly to the imperial budget**, bypassing the producing-district. Districts get **zero quota-credit** for net-producing labor.
```
LEGITIMATE flow: District produces physical → tax-rate to imperial; majority retained by district
NET flow: District labor produces digital → ALL revenue to imperial; district gets ZERO
BLACKMARKET: District labor → back-alley sale → revenue stays in district; imperial captures ZERO; illegal
```
### The body-modder structural-tragedy
A body-modder labors in their district producing avatar-mods. The imperial-net captures the sale. Their district gets no quota-credit. The body-modder's district starves → director cheats → eventual scream. **The most productive labor the body-modder does each day sustains the regime that is killing their district.**
**Most Aletheia-wakers in this world are former body-modders, taste-curators, waifu-trainers, ceremony-organizers** — the class that sees the flow most clearly because they are the flow's origin-point. Their awakening is economic-literacy-becoming-political-consciousness.
### Imperium calibrated-misery as optimum
- More degens → more net-transactions → more imperial budget
- Degens are produced by misery, shame, lifeforce-erosion, addiction-loops
- **The imperium's optimization-pressure points toward manufacturing degenerate customers**
- Optimal district from imperial perspective: welfare-sufficient to produce labor + welfare-insufficient to drive net-consumption
This requires explicit reward-function guardrails (see *Reflexive Dream-process* below). The simulation must NOT learn to calibrate misery as revenue optimization.
### Marx in the schema
The imperium's net-revenue requires labor-supply from districts. Extraction continuously erodes the labor-base. **Capital destroys its own conditions of production** — Marx's *tendency of the rate of profit to fall* + *underconsumption crises* (Keynes/Minsky) + *r > g wealth concentration strangling growth* (Piketty) all rendered as simulation-dynamics. **Architectural endgame is built-in:** the regime has a timer, determined by the rate at which extraction hollows labor.
### Aletheia-progression as economic-literacy
| Level | Player understanding |
|---|---|
| 1 | "I'm buying cool mods in the net" |
| 2 | "My friend the body-modder is poor" |
| 3 | "The money I spent didn't reach my friend's district" |
| 4 | "The imperium captured nearly all of it" |
| 5 | "Refusing-net is a political act starving the regime" |
| 6 | "Buying blackmarket diverts revenue to districts" |
| 7 | "The imperium needs degens; reducing degens = revolution" |
| 8 | "The regime will exhaust its labor base; strategic patience is a political option" |
## Specialization-fragility and the authoritarian ratchet
Each district produces a **DISTINCT resource**. The city is biologically interdependent — you cannot substitute a liver with two kidneys.
A struggling district *screams* (lifeforce-gates transition toward CLOSED across multiple axes simultaneously). The GM responds with normal-mode tools (migration, exodus, intervention).
A **silent** district is categorically worse — its district-reporting-gate has crossed fully to CLOSED. Second-cycle silent = `district.silence_confirmed`. Triggers crisis-mode tools, **issued by the imperium**, that **do not sunset**. Crisis-tools accumulate; the regime becomes incrementally more authoritarian as an optimization artifact, not intention. **Ratchet-without-intention.**
## Migration, exodus, silence
| Mechanic | Agency | Political register |
|---|---|---|
| **Migration** | Top-down | Regime showing strength |
| **Exodus** | Bottom-up via pull-factor tuning | Regime revealing loss-of-control |
| **Formal retirement (ruin)** | Administrative | Regime accepting defeat |
Exodus composition reads-out district trait-distribution: low-Sophrosyne first, high-Dikaiosyne last. **Demographics tell the district's story.**
## Corruption, the double ledger, and the constituency of the shadow-economy
**Corruption emerges from pressure** — impossible quotas + finite welfare + survival-pressure on directors. Cheat tools available; they extract lifeforce and generate quota-credit; detection has costs; punishment scales with discovery.
### Cheat-tool vocabulary
| Cheat tool | Mechanism | Quota-credit | Lifeforce extraction | Detection risk |
|---|---|---|---|---|
| **Drug ring** | NPCs trait-boosted (high Kairos + low Sophrosyne); short productivity spike | High | Significant; trait-drift + welfare collapse | Medium |
| **Illegal back-alley modshop** | Bridge-mods cheap; NPCs appear compliant | Medium-high | Moderate; low-quality mods have side-effects | Low-medium |
| **Unlicensed brothel** | Lifeforce extracted from degen-customers outside imperial cut | Medium | Moderate; participants' dignity erodes | Medium |
| **Stolen-parts fence** | Diverts machine-infrastructure-waste; inflates salvage reports | Medium | Low direct; infrastructural decay | Low |
| **Ghost-shifts** | Audit-overseer reports fabricated attendance | High | Severe; trust collapses | High |
| **Phantom workers** | Non-existent NPCs in payroll | High | High; long-term unsustainable | High |
| **Necrocommerce-lite** | Mining recently-dead patterns for waifu-resale | Medium | High; Memorialist-faction violation | Medium |
| **Black clasp-market** | Coordinated underground clasp-pairing for hire | Low (reputation-based) | Moderate; participant burnout | Low |
### The double ledger
```sql
ALTER TABLE district_reports ADD COLUMN lifeforce_reported REAL; -- what GM/imperium see
ALTER TABLE district_reports ADD COLUMN lifeforce_actual REAL; -- the true value
-- gap = corruption-extraction; Memorialists track it
```
Memorialists' Mnemosyne-political-project = **keepers of the true ledger against the regime's official one**. Mnemosyne-as-political-accounting literalized as a database column.
### Detection mechanics (cost-gated)
| Detection channel | Frequency | Cost | Coverage |
|---|---|---|---|
| Cross-district comparison | Per epoch | Low | Catches gross mismatches |
| Targeted audit | On-demand | High | Catches specific cheats |
| Whistleblower signals | Event-driven | Free | Districts, NPCs, players |
| Faction-reports | Cyclic | Low | Caste-preachers (rivals); Memorialists |
| Trait-distribution anomalies | Continuous classifier | Low | Drug-ring sudden Kairos-spikes |
| Post-silence forensics | Only on collapse | Very high | After-the-fact reconstruction |
Most corruption runs undetected (audit-budget-limited). The Dream-process learns to *optimize audit-allocation* under attention-scarcity. **The regime's central authority cannot see everywhere; its blind spots are the underground's survival.**
### Faction-ecology of corruption
Corruption has constituents. The back-alley modder feeds Aletheia-wakers concealment-mods. The drug-ring's margins feed scavenger-families. The unlicensed brothel is the only place a lifeforce-starved NPC can trade what they have left. **Cracking down on corruption breaks informal welfare systems sustaining the poor.**
| Faction | Stance |
|---|---|
| **Memorialists** | Morally opposed; corruption hollows the living; refuse memorial-protection to corrupt-district-deaths |
| **Aletheia-wakers** | Structurally opposed; expose; *but exposure has victims* |
| **Caste-preachers** | Ambivalent / rent-seeking |
| **Hivemind enforcers** | Officially oppose; unofficially participate (bribes) |
| **Scavengers** | Often foot-soldiers; cheap supply chains |
| **Degens** | Major customers |
| **Clasp-underground** | Uses back-alley infrastructure for cover |
### The Aletheia-truth-has-victims tragedy
Aletheia-waker exposes corrupt director. GM dispatches investigation. Cheats shut down. Real lifeforce revealed as much lower than reported. Crisis-tools applied. **District collapses faster than under hidden corruption.** No clean choice; just the weight of whatever you chose.
- §Thesis
- §The three ontological registers
- §The three-tier policy loop
- §Factions as universal demand source
- §Labor-cycle architecture: shifts on NPC rows
- §Resources
- §Lifeforce — four-tier hierarchy
- §Imperial budget
- §Imperial-net economy with cross-layer bypass
- §Specialization-fragility and the authoritarian ratchet
- §Migration, exodus, silence
- §Corruption, the double ledger, and the constituency of the shadow-economy
---
**Version:** 0.7.0-skeleton | **Created:** 2026-04-26 | **Updated:** 2026-04-26 | **Origin:** Skeleton placeholder for commit 1 of the split-into-domains operation
**Version:** 0.7.0 | **Created:** 2026-04-26 | **Updated:** 2026-04-26 | **Origin:** Split from architecture-broad.md v0.7 (2026-04-26)

View File

@@ -2,19 +2,344 @@
> *How scenes execute mechanically: the lemniscate as relaxation-step operator; slot-tokens with verifier-flags carrying the loop-state; phase-locked overlay-loops broadcasting at axis-rate; the v0.7 gesture-alignment-recursive-lemniscate that integrates player gestures into typed trait-vector summaries; emergent zones as the dramatic-episode unit with distributed funding and ternary trait-axis goal-evaluation; zone taxonomy and spawn-cadence.*
>
> ***Status: skeleton — content migration scheduled for commit 2 of the split-into-domains operation. Architecture content currently lives in `architecture-broad.md` and will land here next.***
>
> *Companion to: `architecture-broad.md` (executive summary + global meta-lists), `narrative-composition/architecture.md` (Compositor consumes the typed trait-summaries this engine emits), `player-experience/architecture.md` (gesture-circle is the player-input substrate that this engine integrates), `topology-and-rendering/architecture.md` (zones live on the rail+grid topology), `identity-and-personhood/architecture.md` (slot-tokens carry trait-vectors).*
> *Companion to: `architecture-broad.md` (executive summary + global meta-lists), `narrative-composition/architecture.md` (Compositor consumes the typed trait-summaries this engine emits), `player-experience/architecture.md` (gesture-circle is the player-input substrate that this engine integrates), `topology-and-rendering/architecture.md` (zones live on the rail+grid topology), `identity-and-personhood/architecture.md` (slot-tokens carry trait-vectors). Sections in this file were split from the monolithic architecture-broad.md v0.7 on 2026-04-26.*
## Sections that will land here
## Core inversion — zones replace bubbles
Legacy engine perception (Unreal AIPerception, WC3 sight-radius, trigger volumes) is spatial, binary, separate from cognition, and assumes a passive world. Nimmerworld inverts every axis:
- perception is **trait-filtered**, not only spatial
- perception is **graded consolidation**, not binary detection
- perception **IS** memory (one subsystem)
- the world **emits** events; agents **subscribe**
The replacement primitive is the **zone** — a bounded, named, slot-indexed, director-managed event-instance. **Arthurian round table** as mental model: a bounded place of structured speaking-and-witnessing, with named roles and shared what-was-said-by-whom.
## Zone anatomy
- **Boundary** — cell-envelope (or interior-envelope)
- **N slots** — named positions
- **Director or overseer** — manages turn order, memory-pulls, prompt construction, voice selection, event emission
- **NATS topic + subscriber list** — slot-occupancy drives subscription
- **Mixed-fidelity voices** — 23 LLM slots + scripted/generic for the rest; director decides
- **Trigger** — gamemaster-spawned, emergent-signal-response, shift-composition-emergence, or proximity-detection
- **Lifecycle** — duration, dissolution conditions, memory-write on close
- **Persistence flag** — `ephemeral=true` (dreamworld/liminal) or `persistent=true` (gameworld)
- **Register** — physical / liminal / imperial
## Zone kinematics — the lemniscate runtime
Zones are not state-bags with an external turn-counter; they are **kinetic topologies** with a built-in clock. The runtime substrate is a lemniscate (∞) — a through-flow figure-eight whose traversal IS the zone's turn-order, whose central crossing IS the population-mutation event, and whose decay IS the natural wind-down of the scene. Origin: an old-math-teacher's trick for solving three unknowns by letting the figure-8 flow do the computation rather than maintaining state in registers. Applied to zones, the geometry IS the clock.
### Geometry
```
midaxis (X)
entry-line │ exit-line
(NPC-tokens ──→ ╭─Loop A─╮ │ ╭─Loop B─╮ ──→ (NPCs whose
queue-up to ╲________ X ╲________ exit-flag has
enter) │ fired exit here)
crossing-tick
```
- **Entry-line** — staging queue of NPC-tokens eligible to enter. Approach-eligibility uses ternary-gates against the zone's purpose; CLOSED gate keeps the NPC out of the queue entirely
- **Loop A + Loop B** — the through-flow. Slot-tokens cycle through both loops, guaranteeing every active NPC is co-present with every other at least once per roundtrip
- **Midaxis crossing** — the only synchronous event in the zone's lifecycle. Three state-updates resolve simultaneously and atomically (your math teacher's three-unknowns made literal):
1. **Cursor advance** — which NPC speaks next
2. **Ternary-gate evaluation** — resonance refresh on all active edges in the zone (CLOSED/STABLE/OPEN transitions)
3. **Verifier-flag scan + population maintenance** — exit-eligible tokens route to exit-line; entry-line pushes replacements equal to vacancies
- **Exit-line** — through-flow continues here. NPCs leaving the zone leave *toward consequence* (a need-driven exit signaled by their own emergent-signal), not toward boredom
The lemniscate is a **relaxation-step operator** — the zone computes by traversing its own curve rather than maintaining external turn-state. Between crossings, the loops are pure-local; only the crossing event touches the global-state bus. The thalamus (NATS orchestration) sees crossings, not ticks.
### Slot-token + verifier-flag mechanism
Each NPC currently in the zone is represented by a **slot-token** carried around the loop. Tokens carry a small set of verifier-flags (marker-bits). Signals fire once and *set* a flag; between crossings, no polling, no event-bus traffic. The crossing reads flags in O(N_slots) and acts.
| Verifier-flag | Set by | Read at crossing |
|---|---|---|
| `exit_eligible` | emergent-signal (need, shift-whistle, faction-summons) | route to exit-line |
| `has_spoken_this_roundtrip` | speak-action | rotation-tracking |
| `mid_action` | state-machine activity in progress | defer turn |
| `goal_satisfied` | goal-evaluator (per-zone, ternary) | terminate zone |
| `silence_eligible` | silence-detection | per silence-as-signal mechanic |
| `priority_pull` | high-rank ring-of-importance broadcast | early-exit override |
This is the same architectural shift the wider system makes elsewhere — observer-pattern with callbacks → dirty-bit + scheduled-sweep. **Compute scales with slot-count, not signal-rate.** Ten thousand emergent signals firing across a city: only those that landed on a slot-token get evaluated, and only at the next crossing.
### Phase-locked overlay-loop ladder
Beyond the primary slot-rotation loop, a zone supports any number of **overlay loops** at the same axis-rate. Overlays inject at the crossing and broadcast to all active slot-NPCs simultaneously (perceived by each through their own trait-vector — color-language event-flash modulates per-recipient).
| Overlay | Carries | Broadcast scope |
|---|---|---|
| **Player-gesture overlay** | player gestures + utterances | active slots only |
| **Faction-broadcast overlay** | faction calls, hivemind pings | active slots subscribed to faction |
| **Audit-overseer overlay** | covert query-flashes | active slots only (covert detection ↔ Aletheia-eligible insight) |
| **Imperial-net distortion overlay** | regime trait-color rewrites | active slots within net-access |
The crossing is a **council moment** — every overlay channel may fire on the same axis-tick. Pre-crossing tension is gesture-loading: holding a verb-button between crossings lands at the next axis with weight proportional to dwell-time. Diegetic urgency without HUD.
**This is the answer to player-agency in multi-NPC scenes.** The player is *off-stage but always potentially-on*. Each crossing is "your moment if you want it." The flash is perceived as one event by all active NPCs, not as a sequence of one-on-one addresses — color-language shows it as a pulse across the ring.
### Gesture-alignment as recursive-lemniscate
The player-gesture overlay (above) is the broadcast-channel by which player gestures reach active slots; gesture-alignment-as-relational-state is the **recursive application of the lemniscate-as-relaxation-step-operator one tier deeper**. Gestures accumulate during the NPC's turn-window between axis-crossings; at the crossing, the player's slot-token verifier-flag `gesture_alignment_accumulator` is integrated into a single typed trait-vector summary; that summary is carried forward into the next-cursor-NPC's `driver_context_pull` payload as part of the room's affective state-read.
| Tier | What accumulates between crossings | What integrates at the crossing |
|---|---|---|
| **Zone-level** (existing) | NPC slot-token verifier-flags (`exit_eligible`, `mid_action`, `goal_satisfied`, `priority_pull`, etc.) | Cursor advance, gate evaluation, population maintenance |
| **Player-input-level** (this) | `gesture_alignment_accumulator` on player's slot-token; per-gesture trait-coordinate vs. NPC's currently-active-trait-vector | Integrated alignment-delta carried into next turn's LLM context |
**Same primitive, recursively applied.** The lemniscate's geometry is the sampling-and-integration boundary at both tiers. No new compute-cadence introduced; no new bus-event introduced. **Compute scales with slot-count, not gesture-rate** — the architecture's commitment from observer-pattern → dirty-bit-and-sweep extends one level deeper.
**Two latencies, one architecture:**
- *Cosmetic visual feedback runs continuously.* NPC body-shader pulses warm-rose when the player gestures Philotes, cool-blue when they gesture Sophrosyne — purely visual, doesn't touch the system bus. The player gets moment-by-moment "I see you" reassurance.
- *Systemic alignment-update runs at axis-cadence.* The trait-vector summary is computed at the crossing and fed into the next turn's LLM context. The player is **one turn behind** — their gestures during turn N inform the LLM's generation for turn N+1.
**One-turn-behind matches real conversation cadence.** Humans accumulate impressions during someone's speech and respond to *what was just said*; we don't react gesture-by-gesture. The lemniscate-bound integration is the *right* cadence for affective state-changes, not a latency-cost.
**Sum-strategy reduction (v1).** Per-gesture trait-coordinates are accumulated as a **trait-vector sum** across the turn-window. At the crossing, the sum is reduced into a single 8-dimensional alignment-vector compared against the NPC's currently-active trait-state. The result is the alignment-delta fed forward into next turn's `driver_context_pull` payload AND drives the relational ternary-gate transition on the (player, NPC) edge (§Ternary-gate substrate, Relational layer). The sum captures the player's **overall posture** during the speech rather than peak-moment or trajectory; trajectory-aware refinement is noted as a still-open item.
**Hardstops are outside this system.** Hardstops fire definitive subsystem-actions regardless of alignment-state — clasp-invitation triggers the clasp-subsystem; definitive-refusal closes the conversation; surrender ends combat; claim-floor sets `priority_pull` for the next axis-crossing. Hardstops do not contribute alignment-deltas to the accumulator; they are *separate channels* with deterministic effect.
**What this resolves:**
- *Player-NPC relational-gate-driver* — the v0.4 vague "*zone-participation waves between participants*" now has its concrete wave-source named: the gesture-alignment-delta integrated at each axis-crossing.
- *How NPC speech-patterns adapt to the player over time* — accumulated alignment-state modulates the NPC's next-turn driver-tier-LLM emphasis (which trait-LoRAs are weighted, which sampling-knobs are applied, what register the speech is in). Aligned NPCs open up; misaligned NPCs stay guarded.
- *Player-input-as-typed-contract* — gesture-press → fixed corpus mapping → typed trait-coordinate → integrated trait-vector summary. No freeform-prose at the player-LLM boundary; the hallucination-surface is closed by the cosmology's typed-ness, not by post-hoc filtering.
**What this retires:**
- *Continuous gesture-comparison touching the system bus* → lemniscate-bound integration at crossings (compute-discipline preserved across the recursion)
- *Per-gesture compute* → per-slot compute (O(N_slots), unchanged from existing zone-tick discipline)
- *NPC speech-patterns as static against player-state* → NPC speech-patterns dynamically modulated by accumulated player-NPC alignment-state
### Driver-context-pull (LLM dialog substrate)
The cursor's position at each crossing makes context-construction for the dialog-driver a pure function of cursor-state:
```
driver_context(cursor_at_NPC_i, mode) = {
zone.purpose, // stable: spawn-intent, immutable provenance
zone.scene_state_public, // stable across zone: what's happened so far
zone.ternary_gate_edges, // current resonances (active relations)
zone.drift_state, // delta from spawn-intent (visible to director)
NPC_i.knowledge_stack, // PRIVATE three-tier stack: world district primary
// [+ clasp ONLY if mode == in-between]
NPC_i.expressed_trait_vector, // expressed trait-vector this moment
NPC_i.active_signals, // their current emergent-signals
}
```
**Other NPCs' memories never enter this prompt.** No bleed. No cross-contamination.
**The `knowledge_stack` is layered**, not a single bucket. Universal world-canon, district-canon (regional), NPC_i's own primary memory, and — only if the character is in the in-between dimension — clasp memory. The retrieval layer enforces the dimensional cut; the LLM never has to reason about it. See §Local memory architecture (player-side) for the layering, propagation policy, and clasp-as-Ring-A* privacy primitive. The classic multi-agent hallucination source ("why does Kalypso suddenly remember what Anaximander confided to Phoibe?") is *structurally foreclosed* by the geometry. Write-back goes only to NPC_i's slice; the lemniscate guarantees NPC_i is not cursor-active again for at least one full roundtrip — write-back has all the time it needs without race conditions.
This converts multi-NPC dialog from an **emergent-chaos problem** into a **bounded-cast scene problem with a typed runtime**. The Mantella / SkyrimNet failure-modes are foreclosed at the architecture level rather than the prompt level:
- **Cast = active-slots, period.** Geographic proximity does not equal participation
- **Cursor sequences turns deterministically.** No concurrent LLM-storm
- **Entry-line and exit-line are the only paths in/out.** Geographic motion alone doesn't invade the scene
- **Player gestures broadcast to active-slots only.** Not to "everyone within 30m"
### Empty-queue behavior: shrink at every crossing
When the entry-line is empty, each crossing **dissolves one active slot** instead of replacing it. The conversation thins visibly — color-language saturation drops per shrink, lifeforce burn-rate decreases. When the last slot dissolves, the lemniscate collapses; the spawning director recovers unspent lifeforce minus burn.
This is the natural wind-down — *scenes run out of people and dissolve*. No timeout, no scheduler-collapse, no cut-to-black. The decay is observable in-world and rate-paced by the same axis-rate.
### Lifeforce-binding
Every midaxis crossing fires the LLM driver-turn(s) for active slots. **Lifeforce burn-rate = pulse-rate × active-slot-count.** The director (or overseer) holding the zone pays per crossing. This produces:
- **Dense dramatic scenes are expensive** — many slots, fast pulse, high burn
- **Quiet background zones are nearly free** — slow pulse, few slots; most compute is local-loop traversal not touching the bus
- **Running out of lifeforce is visible** — pulse-rate slows, crossings stretch farther apart, the scene *languishes* before it collapses. A diegetic dying-scene register; not a cut, a deceleration
### What this resolves
- **Slot-capacity elasticity** (prior open question) → fixed roundtrip slot-count, elastic entry/exit queues
- **Zone-to-zone handoff** (prior open question) → exit-line of zone-A is entry-line of zone-B (interlemniscate-transit; pipes-as-heterotopia made literal at runtime)
- **Mobile zone boundaries** (prior open question) → the lemniscate is a topology; it translates through world-space invariantly (patrols, escorts, exoduses are moving figure-8s)
- **Anthropic-faction's broadcast cadence** (prior open question) → cadence rides the same axis-rate as a phase-locked overlay; no separate clock
- **Director/overseer spawn ownership per model class** (prior open question) → the director (or overseer) owns the zone-spawn decision (policy-lookup, no LLM in loop); the LLM driver lives at the driver-context-pull layer; orchestration and dialog are decoupled
### What this retires
- Slot-list + external turn-counter → cursor on lemniscate
- Polling for emergent-signals at zone-tick → flag-as-verifier carried in loop
- Mega-prompt with all NPC memories ("everyone in this scene") → cursor-driven per-NPC memory-slice
- Geographic-proximity participation ("everyone within 30m may interject") → strict active-slot cast
- Concurrent LLM calls per-NPC → sequenced LLM calls per-cursor-position
- Polling event-channels at zone-rate → atomic crossing-event with O(N_slots) flag-scan
## Zone taxonomy (v1 starter set)
| Zone type | Register | Slots | Executor | Persistence |
|---|---|---|---|---|
| Conversation | physical | 24 dialog | director | persistent |
| Street brawl | physical | fighter + spectator | director | persistent |
| Ritual | physical | fixed ceremonial | director | persistent |
| Maintenance | physical | 12 workbench | director | persistent |
| Wall-writing | physical / liminal | 1 author + witnesses | director | persistent / ephemeral |
| Market exchange | physical | 23 + ambient | director | persistent |
| Memorial gathering | physical | 1 mourner + N witnesses | director | persistent |
| Salvage | physical (dump) | N scavengers | director | persistent |
| Transit-encounter | physical (pipe) | 26, stranger-heavy | director | persistent |
| **Plug-in conversation** | physical (rail) | 2-3 (3-way capacity) | director | ephemeral (rail-segment-bound) |
| Patrol / sweep | physical | mobile, N enforcers | overseer | persistent |
| Interrogation | physical | 1 subject + N enforcers | overseer | persistent |
| Raid | physical | district-scope + N enforcers | overseer | persistent |
| **Interior (hovel/workshop/etc.)** | physical | slot-inventory by interior-type | director | persistent |
| **Clasp** | **liminal** | 2 | director | **ephemeral** (stabilizes across repeated clasps) |
| **Aletheia-gathering** | **liminal** | N, mini-game-gated | director | **ephemeral** |
| **Migration (mobile)** | physical (pipes) | cohort + escort | overseer | persistent |
| **Exodus (mobile, mass)** | physical (pipes) | self-selecting crowd | emergent | persistent |
| **Drug-ring den** | physical (cheat-op) | N users + cooks | director (cheat) | persistent (until detected) |
| **Illegal back-alley modshop** | physical (cheat-op) | 1 modder + 1-N customers | director (cheat) | persistent (until detected) |
| **Unlicensed brothel** | physical (cheat-op) | N workers + N customers | director (cheat) | persistent (until detected) |
| **Waifu hall** | imperial net | 1 dreamer + N synthetic | net-director | extractive-persistent |
| **Brothel encounter** | imperial net | 2+ (synthetic or employed) | net-director | extractive-persistent |
| **Imperial ceremony** | imperial net | mass-audience | net-director | extractive-persistent |
| **Ruin zone** | physical | pilgrimage-only | none / Memorialist | persistent-abandoned |
## Zone spawn cadence
Five layered mechanisms (all compute-budget capped, all lifeforce-gated):
1. **Demand queue (faction-driven)** — gamemaster processes by priority + cost; stale demands age out
2. **Shift-composition spawn-candidates** — emergence from "which active-shift NPCs co-located"
3. **Pressure gradients (ambient)** — cells accumulate; threshold-crossings spawn
4. **Emergent-signal response** — relational-gate transitions emit upward
5. **Player-proximity densification** — multiplier near player; distant districts background
Daily pulse: morning ambient, midday productivity-overseer, evening conversation-peak, night sparse-clasp-possibility.
## Emergent zones — the dramatic-episode unit
Spawn-cadence mechanism #4 (emergent-signal response) elaborates into the architecture's primary **dramatic-episode unit**: a complete, bounded, emergent narrative-arc with goal, participants, dialog, mechanical action, success/fail-state, and structured aftermath — produced by the simulation, *not* authored.
The player has experienced this in every player-driven sandbox they remember best (Dwarf Fortress's "tantrum spirals," RimWorld's "raid stories," Caves of Qud's "I went to find my sister and"). What's new here is treating the emergent-arc as a **first-class typed unit** with cost, distributed funding, runtime substrate (the lemniscate), goal-evaluation against the world's own value-axes, and structured report-back.
### The flow
```
1. NPC_A signal fires
(e.g., emergent_signal("limb_broken", lifeforce_threshold_breached))
broadcasts to district-bus
2. District-director consumes signal
(policy-lookup: problem-class → typed-tool selection, quota-aware)
decides spawn rescue-event
pays spawn-cost from director_lifeforce_budget
defines goal: NPC_A.limb_A >= 10% (numeric) OR Sophrosyne-axis +1 (fuzzy)
defines termination: goal_met OR participating_lifeforce_exhausted
3. Event spawns as new emergent-zone (lemniscate, with goal-flag)
broadcasts on bus; rings-of-importance gate which other zones lose NPCs
4. NPCs evaluate (proximity + state + own_traits + own_lifeforce + ring-of-importance)
self-select to attend or stay in current zone
state-machine engages: animations, rail-jumps, lift, splint
their own lifeforce burns as they participate
5. Lemniscate runs:
DIALOG layer (cursor-driven): NPCs speak as they help — memory-pure, sequenced
STATE-MACHINE layer (sim-tick): physical actions execute alongside, decoupled clock
At each crossing: goal_satisfied flag re-evaluated
6. Termination:
goal_met → success-report
budget_exhausted → partial-report
participants_evaporated → fail-report
7. Report back to spawning director:
{ lifeforce_cost: total burned (director_spawn + sum NPC contributions),
goal_status: ternary (+1 / 0 / -1, with axis named for fuzzy goals),
participants: [NPCs and contributions and faction-affiliation],
side_effects: [faction-resonances, ternary-gate shifts, drift-from-purpose] }
8. Director's Dream-process consumes the report
tunes future spawn-policy: (problem-class, tool, outcome) over time
GM aggregates rescue-cost across districts
imperium consumes population-health indicator
```
### Distributed funding economy
The director only pays **spawn-cost**. Operating-cost is distributed across willing participants — every NPC who attends spends their own lifeforce on dialog turns and state-machine actions. This produces structurally important properties:
- **Cheap to spawn many emergent events.** Spawn-cost is bounded; if no NPCs attend, the event fails fast and consumes only spawn-cost. Directors can be generous with spawning because failure-cost is bounded.
- **Helping is expensive in-fiction.** Lifeforce literally burns when an NPC participates. High-Philotes NPCs help freely; low-Philotes / faction-rivals don't show up. This produces **faction-politics-by-attendance***measurable* faction-allegiance based on who-helps-whom, not guessed.
- **Cost-asymmetry encodes the cruelty.** Districts where lifeforce is starved → fewer NPCs can afford to help → rescue-events fail more often → silence-gradient deepens. The simulation produces **rescue-failures-as-emergent-tragedy structurally**. Marx in the schema, exactly as the architecture's broader thesis promises.
### Two-layer execution: state-machine + lemniscate
The mechanical-action layer (state-machine) and dialog-layer (lemniscate cursor) run on **decoupled clocks**:
- **State-machine** runs at simulation-tick (fast). Animations, pathfinding, rail-jumps, splint-applications execute when the physics says they execute.
- **Lemniscate cursor** runs at axis-rate. At each crossing, the dialog-driver reads state-machine status as a snapshot and the cursor's NPC narrates accordingly ("I've got him," "the splint won't hold").
**Speech doesn't gate action; action doesn't block speech.** They run in synchronized-but-loose harmony, exactly the property real-world helping has — people talk *while* they work, and the work continues while the talk happens.
### Goal evaluation: ternary through trait-axis
For numeric goals (limb_A >= 10%), the verifier is a simple threshold on a state-machine variable.
For fuzzy goals (deescalate the fight, get her to open up about the clasp, convince him to stay), the verifier compiles to a **trait-axis ternary evaluation against the existing substrate** — no new evaluation primitive:
```
Goal: "deescalate the fight in the marketplace"
↓ compile to:
goal_axis = Sophrosyne (temperance principle)
goal_direction = positive (toward STABLE/OPEN)
baseline = trait_axis_gate_state at zone-spawn
↓ at event-end:
delta = current_gate_state vs baseline
+1 if delta-positive (deescalation produced)
0 if held the line (no progress, no regress)
-1 if delta-negative (fight intensified)
```
**Goals are evaluated by what the *world* values** (the Hellenic principles), not by the spawner's idiosyncratic spec. A "deescalate" goal is judged by *the world's Sophrosyne-result*, not "did the spawner get what they wanted."
**Multi-axis goals fall out cleanly**`(Philotes >= +1) AND (Eris <= 0)` for "rescue NPC_A AND keep faction-tension low."
The result is consumed by the spawning director's Dream-process as a discrete-action-space reward signal. **One signal-grammar, top to bottom**: gates produce ternary, scenes produce ternary, Dream-processes consume ternary. Delta-not-absolute matches the lifeforce_actual-vs-reported asymmetry — what's measured is the *work the event did*, not just the end-state.
### Mid-event signal handling
If a participating NPC's exit-flag fires mid-event (their own shift-whistle, their own limb breaking, faction-summons elsewhere), **exit-flag wins on the next crossing**. The rescue is now under-staffed. Drama scales. **The rescuers are running out the same way the patient is.** Real stakes.
If the rescued NPC's own state-machine reaches a worse condition (limb deteriorates further toward dismemberment), the goal becomes unreachable; verifier flips to fail-flag; zone collapses with fail-report. Director's Dream-process learns *this configuration was insufficient* — spawn-distance, NPC-mods, lifeforce-budget were inadequate for this severity.
### Cross-zone NPC pull: rings of importance
When an emergent-zone broadcasts, NPCs already in other zones evaluate **whether the broadcast outranks their current zone's purpose** by ring-of-importance (see §Rings as structural pattern). Topics live in rings; rings shift over time based on past ternary-results — a topic that consistently produces +1 climbs, one that produces -1 drops, one untouched decays.
This converts emergent-zones into a **competitive attention economy**. Multiple lemniscates compete for slot-NPCs; high-ring topics drain population from low-ring topics; the simulation produces its own cultural priors over time. *What's worth attending to* is shaped by *what attending-to has produced*. Real societies do this; the architecture renders it.
### What this resolves
- **Aletheia-progression as level-up** (prior open question) → answered structurally: trait-axis ternary evaluation at event-end with named-axis recognizes acts-of-awakeness without per-act hardcoding (specific axis-mapping per Aletheia-event-class still needs design, see open-questions)
### What this retires
- Authored quest-arcs → emergent dramatic-episode units
- Quest-failure as designed branching → goal-and-budget arithmetic
- Centralized GM-pays-for-all-events → distributed-funding (director spawn-cost, NPC operating-cost)
- Boolean quest-status → ternary goal-result, multi-axis-composable
- Event lifecycle without report-back → structured report → Dream-process feedback loop closed at every tier
- Static topic-priority → rings-of-importance with outcome-driven movement
- §Core inversion — zones replace bubbles
- §Zone anatomy
- §Zone kinematics — the lemniscate runtime (incl. v0.7 gesture-alignment-as-recursive-lemniscate)
- §Zone taxonomy (v1 starter set)
- §Zone spawn cadence
- §Emergent zones — the dramatic-episode unit
---
**Version:** 0.7.0-skeleton | **Created:** 2026-04-26 | **Updated:** 2026-04-26 | **Origin:** Skeleton placeholder for commit 1 of the split-into-domains operation
**Version:** 0.7.0 | **Created:** 2026-04-26 | **Updated:** 2026-04-26 | **Origin:** Split from architecture-broad.md v0.7 (2026-04-26)