From 948a4151c147b577fb062ca6fcc286bdd5af817c Mon Sep 17 00:00:00 2001 From: dafit Date: Sun, 26 Apr 2026 01:01:11 +0200 Subject: [PATCH] =?UTF-8?q?split=20nimmerworld=20architecture:=20phase=202?= =?UTF-8?q?=20of=203=20=E2=80=94=20migrate=20larger=20domains=20Replace=20?= =?UTF-8?q?the=204=20skeleton=20placeholders=20with=20full=20architecture.?= =?UTF-8?q?md=20content,=20extracted=20via=20sed=20from=20architecture-bro?= =?UTF-8?q?ad.md=20(which=20remains=20untouched=20as=20the=20canonical=20s?= =?UTF-8?q?ource-of-truth=20fallback=20for=20the=20safety=20pattern)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inference-and-memory/architecture.md | 446 +++++++++++++++++++++++++- narrative-composition/architecture.md | 255 ++++++++++++++- political-register/architecture.md | 363 ++++++++++++++++++++- runtime-engine/architecture.md | 347 +++++++++++++++++++- 4 files changed, 1368 insertions(+), 43 deletions(-) diff --git a/inference-and-memory/architecture.md b/inference-and-memory/architecture.md index a02041d..e1cb610 100644 --- a/inference-and-memory/architecture.md +++ b/inference-and-memory/architecture.md @@ -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) diff --git a/narrative-composition/architecture.md b/narrative-composition/architecture.md index a04162f..fd2eb05 100644 --- a/narrative-composition/architecture.md +++ b/narrative-composition/architecture.md @@ -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) diff --git a/political-register/architecture.md b/political-register/architecture.md index 955beba..fbd852f 100644 --- a/political-register/architecture.md +++ b/political-register/architecture.md @@ -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) diff --git a/runtime-engine/architecture.md b/runtime-engine/architecture.md index d2d3bf1..5fce81e 100644 --- a/runtime-engine/architecture.md +++ b/runtime-engine/architecture.md @@ -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** — 2–3 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 | 2–4 dialog | director | persistent | +| Street brawl | physical | fighter + spectator | director | persistent | +| Ritual | physical | fixed ceremonial | director | persistent | +| Maintenance | physical | 1–2 workbench | director | persistent | +| Wall-writing | physical / liminal | 1 author + witnesses | director | persistent / ephemeral | +| Market exchange | physical | 2–3 + ambient | director | persistent | +| Memorial gathering | physical | 1 mourner + N witnesses | director | persistent | +| Salvage | physical (dump) | N scavengers | director | persistent | +| Transit-encounter | physical (pipe) | 2–6, 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)