architecture-broad - v0.4.2 with the LLM-tiering section now covering three rings of inference plus opt-in data-sharing tiers.
This commit is contained in:
874
findings.md
Normal file
874
findings.md
Normal file
@@ -0,0 +1,874 @@
|
||||
# Nimmerworld Architecture — Schema Findings & Hypothesis
|
||||
|
||||
> *Hypothesis-notes, not carved migration spec. Working-out-loud in DDL register.*
|
||||
> *dafit + chrysalis — initial sketch 2026-04-24 afternoon; v0.2 evening; v0.3 late-evening / early 2026-04-25 absorbing architecture-broad v0.4.*
|
||||
|
||||
---
|
||||
|
||||
## Status
|
||||
|
||||
This document is **findings**, not a committed migration plan. DDL sketches exist to surface worries, explore tradeoffs, and prepare for a formal `nimmerverse-core/migrations/00X_nimmerworld_v1.sql` spec once the open forks resolve.
|
||||
|
||||
**Companion to**: [`architecture-broad.md`](architecture-broad.md) v0.4, which captures the full ontology these schemas serve.
|
||||
|
||||
**Why DDL register**: prose architecture lets us say *"zones are slot-indexed event-instances"* and feel like we've said something. DDL forces us to name a row size, an index strategy, a commit boundary, a failure mode. This document is a worry-audit in executable form.
|
||||
|
||||
---
|
||||
|
||||
## 1. Zones (dafit's original sketch, annotated)
|
||||
|
||||
Original sketch from 2026-04-24 afternoon:
|
||||
|
||||
```sql
|
||||
CREATE TABLE zones (
|
||||
zone_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
lifecycle TEXT NOT NULL DEFAULT 'emergent', -- emergent, active, dissolving
|
||||
|
||||
slot_count INT DEFAULT 5,
|
||||
persistence_flag BOOLEAN DEFAULT false,
|
||||
|
||||
-- Hot data < 2KB to avoid TOAST performance hits
|
||||
data JSONB NOT NULL,
|
||||
|
||||
-- Generated column for NATS routing
|
||||
nats_subject TEXT GENERATED ALWAYS AS (
|
||||
'zones.' || lifecycle || '.' || (data->>'trait_filter')
|
||||
) STORED
|
||||
);
|
||||
|
||||
ALTER TABLE zones ADD CONSTRAINT check_zone_integrity
|
||||
CHECK (data ? 'director' AND data ? 'slots' AND data ? 'memory_context');
|
||||
|
||||
CREATE INDEX idx_zone_traits ON zones USING GIN (data jsonb_path_ops);
|
||||
CREATE INDEX idx_active_directors ON zones ((data->>'director'))
|
||||
WHERE (lifecycle = 'active');
|
||||
```
|
||||
|
||||
### v0.4 additions (register-tagging + signal-causation)
|
||||
|
||||
```sql
|
||||
ALTER TABLE zones ADD COLUMN register TEXT NOT NULL DEFAULT 'physical'
|
||||
CHECK (register IN ('physical','liminal','imperial'));
|
||||
ALTER TABLE zones ADD COLUMN anchor_district UUID;
|
||||
ALTER TABLE zones ADD COLUMN anchor_cell UUID;
|
||||
ALTER TABLE zones ADD COLUMN spawned_by_signal UUID; -- emergent-signal that caused this spawn
|
||||
```
|
||||
|
||||
NATS subject hierarchy refined:
|
||||
|
||||
```
|
||||
zones.<lifecycle>.<register>.<district_id>.<zone_type>.<trait_filter>
|
||||
```
|
||||
|
||||
e.g., `zones.active.physical.district_7.brawl.dikaiosyne_low`
|
||||
|
||||
### Three open forks
|
||||
|
||||
**Fork 1.1** — one jsonb vs. two-table split (MVCC concern). Leaning split: `zones` (small, structural, high-churn cols) + `zone_state` (jsonb, referenced, updated rarely).
|
||||
|
||||
**Fork 1.2** — pg_notify vs. WAL logical decoding. Leaning WAL via pgnats. `pg_notify` fallback only.
|
||||
|
||||
**Fork 1.3** — slot occupancy nested vs. relational. **Leaning relational** (sketch in Section 1.4).
|
||||
|
||||
### 1.4 zone_slot_occupancy (relational resolution of Fork 1.3)
|
||||
|
||||
```sql
|
||||
CREATE TABLE zone_slot_occupancy (
|
||||
zone_id UUID NOT NULL REFERENCES zones(zone_id),
|
||||
slot_index INT NOT NULL,
|
||||
npc_id UUID NOT NULL REFERENCES npcs(npc_id),
|
||||
slot_type TEXT, -- 'dialog', 'fighter', 'spectator', 'sofa', 'kitchen', etc.
|
||||
occupied_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
current_turn BOOLEAN DEFAULT false,
|
||||
PRIMARY KEY (zone_id, slot_index)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_occupancy_npc ON zone_slot_occupancy (npc_id);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. NPCs — shift state + body/layer/lifeforce/trait-vector columns
|
||||
|
||||
Shift-based temporal decomposition (architecture-broad v0.4 §"Labor-cycle architecture"). Shift fields live on the NPC row, overwritten daily by the district director.
|
||||
|
||||
```sql
|
||||
-- Shift state
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_id UUID;
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_cycle_day INT;
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_phase TEXT;
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_start_tick BIGINT;
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_end_tick BIGINT;
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_vocation TEXT;
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_anchor_cell UUID;
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_anchor_zone TEXT;
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_faction_ref UUID;
|
||||
ALTER TABLE npcs ADD COLUMN current_shift_status TEXT NOT NULL DEFAULT 'scheduled'
|
||||
CHECK (current_shift_status IN ('scheduled','active','completed','preempted','deviant'));
|
||||
|
||||
-- v0.4: trait-vector split (intrinsic vs. expressed)
|
||||
ALTER TABLE npcs ADD COLUMN intrinsic_trait_vector REAL[] NOT NULL; -- who you actually are
|
||||
ALTER TABLE npcs ADD COLUMN expressed_trait_vector REAL[] NOT NULL; -- intrinsic + worn-mod contributions
|
||||
|
||||
-- Body / layer / lifeforce
|
||||
ALTER TABLE npcs ADD COLUMN inner_body_projection JSONB; -- trait-derived body params
|
||||
ALTER TABLE npcs ADD COLUMN trait_color_signature JSONB; -- derived from trait_vector via trait_colors
|
||||
ALTER TABLE npcs ADD COLUMN net_access_gate REAL CHECK (net_access_gate BETWEEN -1 AND 1) DEFAULT -1;
|
||||
ALTER TABLE npcs ADD COLUMN net_access_discrete TEXT CHECK (net_access_discrete IN ('closed','stable','open')) DEFAULT 'closed';
|
||||
ALTER TABLE npcs ADD COLUMN per_npc_lifeforce REAL NOT NULL DEFAULT 1.0;
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_npc_shift_active_cell
|
||||
ON npcs (current_shift_anchor_cell, current_shift_anchor_zone)
|
||||
WHERE current_shift_status = 'active';
|
||||
CREATE INDEX idx_npc_shift_current ON npcs (npc_id, current_shift_cycle_day);
|
||||
```
|
||||
|
||||
The intrinsic/expressed split is critical: the regime reads expressed; the simulation arithmetic reads intrinsic; clasp-partners in liminal read intrinsic; Aletheia-vision pierces expressed to intrinsic.
|
||||
|
||||
---
|
||||
|
||||
## 3. shift_history — append-only archive
|
||||
|
||||
```sql
|
||||
CREATE TABLE shift_history (
|
||||
shift_id UUID PRIMARY KEY,
|
||||
npc_id UUID NOT NULL REFERENCES npcs(npc_id),
|
||||
cycle_day INT NOT NULL,
|
||||
phase TEXT NOT NULL,
|
||||
start_tick BIGINT NOT NULL,
|
||||
end_tick BIGINT NOT NULL,
|
||||
vocation TEXT NOT NULL,
|
||||
anchor_cell_id UUID,
|
||||
anchor_zone_type TEXT,
|
||||
faction_ref UUID,
|
||||
status TEXT NOT NULL,
|
||||
outcome JSONB NOT NULL,
|
||||
archived_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_shift_history_npc_day ON shift_history (npc_id, cycle_day DESC);
|
||||
CREATE INDEX idx_shift_history_district_day ON shift_history (anchor_cell_id, cycle_day DESC);
|
||||
CREATE INDEX idx_shift_history_deviant ON shift_history (anchor_cell_id, status)
|
||||
WHERE status IN ('preempted', 'deviant');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. emergent_signals — zone-emitted relational transitions
|
||||
|
||||
```sql
|
||||
CREATE TABLE emergent_signals (
|
||||
signal_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
source_zone_id UUID NOT NULL REFERENCES zones(zone_id),
|
||||
district_id UUID NOT NULL,
|
||||
signal_type TEXT NOT NULL,
|
||||
participants UUID[] NOT NULL,
|
||||
intensity REAL NOT NULL CHECK (intensity BETWEEN 0 AND 1),
|
||||
gate_state REAL NOT NULL CHECK (gate_state BETWEEN -1 AND 1),
|
||||
gate_transition TEXT NOT NULL CHECK (gate_transition IN
|
||||
('stable_to_open','stable_to_closed','open_to_stable','closed_to_stable')),
|
||||
composition JSONB NOT NULL,
|
||||
emitted_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
expires_at TIMESTAMPTZ NOT NULL,
|
||||
|
||||
-- Mandatory disposition
|
||||
disposition TEXT CHECK (disposition IN ('acked','deferred','dropped','expired')),
|
||||
disposition_reason TEXT,
|
||||
consumed_by_zone UUID REFERENCES zones(zone_id),
|
||||
disposed_at TIMESTAMPTZ,
|
||||
outcome JSONB
|
||||
);
|
||||
|
||||
CREATE INDEX idx_signals_live_by_district ON emergent_signals (district_id, emitted_at)
|
||||
WHERE disposition IS NULL;
|
||||
CREATE INDEX idx_signals_participants ON emergent_signals USING GIN (participants);
|
||||
CREATE INDEX idx_signals_training ON emergent_signals (signal_type, disposition, disposed_at DESC);
|
||||
```
|
||||
|
||||
Notice `disposition` is mandatory at resolution. Silence-discards are bugs; audit-trails are features.
|
||||
|
||||
---
|
||||
|
||||
## 5. district_reports — per-cycle aggregates with double-ledger
|
||||
|
||||
```sql
|
||||
CREATE TABLE district_reports (
|
||||
report_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
district_id UUID NOT NULL,
|
||||
cycle_tick BIGINT NOT NULL,
|
||||
reported_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
|
||||
-- v0.4 DOUBLE LEDGER (the politically load-bearing distinction)
|
||||
lifeforce_reported REAL NOT NULL, -- what GM/imperium see
|
||||
lifeforce_actual REAL NOT NULL, -- the true value (Memorialist-trackable)
|
||||
lifeforce_delta REAL NOT NULL,
|
||||
-- gap = corruption-extraction over time
|
||||
|
||||
population_count INT NOT NULL,
|
||||
aggregate_happiness REAL,
|
||||
aggregate_need_state JSONB,
|
||||
aggregate_limb_state JSONB,
|
||||
mind_turnover_in INT,
|
||||
mind_turnover_out INT,
|
||||
decision_budget_used_pct REAL,
|
||||
|
||||
labor_available JSONB,
|
||||
resources_on_hand JSONB,
|
||||
space_utilization JSONB,
|
||||
faction_member_counts JSONB,
|
||||
aggregate_trait_vector REAL[],
|
||||
pending_demand_backlog JSONB,
|
||||
player_presence JSONB,
|
||||
|
||||
specialty_resource_type TEXT,
|
||||
specialty_output_qty REAL,
|
||||
|
||||
reporting_gate_state TEXT NOT NULL DEFAULT 'stable'
|
||||
CHECK (reporting_gate_state IN ('stable','scream','silent'))
|
||||
);
|
||||
|
||||
CREATE INDEX idx_district_reports_timeline ON district_reports (district_id, cycle_tick DESC);
|
||||
CREATE INDEX idx_district_reports_crisis ON district_reports (district_id, reported_at)
|
||||
WHERE reporting_gate_state IN ('scream', 'silent');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. decision_log — per-decision audit trail
|
||||
|
||||
```sql
|
||||
CREATE TABLE decision_log (
|
||||
decision_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
decider_type TEXT NOT NULL CHECK (decider_type IN
|
||||
('imperium','gamemaster','district_director','overseer',
|
||||
'audit_overseer','zone_director','net_director')),
|
||||
decider_id UUID NOT NULL,
|
||||
context_ref JSONB NOT NULL,
|
||||
decision TEXT NOT NULL,
|
||||
decision_params JSONB NOT NULL,
|
||||
expected_outcome JSONB NOT NULL,
|
||||
confidence REAL NOT NULL CHECK (confidence BETWEEN 0 AND 1),
|
||||
lifeforce_cost REAL NOT NULL,
|
||||
escalated_to_llm BOOLEAN NOT NULL DEFAULT false,
|
||||
decided_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
actual_outcome JSONB,
|
||||
outcome_settled_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE INDEX idx_decision_log_decider ON decision_log (decider_type, decider_id, decided_at DESC);
|
||||
CREATE INDEX idx_decision_log_escalated ON decision_log (decider_id, decided_at)
|
||||
WHERE escalated_to_llm = true;
|
||||
CREATE INDEX idx_decision_log_pending ON decision_log (decided_at)
|
||||
WHERE actual_outcome IS NULL;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. mind_pool — recycled minds
|
||||
|
||||
```sql
|
||||
CREATE TABLE mind_pool (
|
||||
mind_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
original_npc_id UUID,
|
||||
last_district_id UUID,
|
||||
death_tick BIGINT NOT NULL,
|
||||
death_cause TEXT,
|
||||
trait_vector REAL[] NOT NULL,
|
||||
memory_token_residue JSONB,
|
||||
inner_body_template JSONB,
|
||||
pooled_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
redistributed_to UUID,
|
||||
redistributed_at TIMESTAMPTZ,
|
||||
memorialist_protected BOOLEAN NOT NULL DEFAULT false,
|
||||
memorialist_ritual_ref UUID
|
||||
);
|
||||
|
||||
CREATE INDEX idx_mind_pool_available ON mind_pool (pooled_at)
|
||||
WHERE redistributed_to IS NULL;
|
||||
CREATE INDEX idx_mind_pool_protected ON mind_pool (memorialist_protected)
|
||||
WHERE memorialist_protected = true;
|
||||
```
|
||||
|
||||
`memorialist_protected` is the architectural anchor of Memorialist anti-necrocommerce politics.
|
||||
|
||||
---
|
||||
|
||||
## 8. Cells — wall content per register
|
||||
|
||||
```sql
|
||||
ALTER TABLE cells ADD COLUMN wall_content_per_register JSONB;
|
||||
-- Shape: { "gameworld": "...", "liminal": "...", "imperial_net": "..." }
|
||||
```
|
||||
|
||||
The three-layer ontology renders different wall content at the same spatial coordinate per observer's current register.
|
||||
|
||||
---
|
||||
|
||||
## 9. rail_segments — topology graph (v0.4 NEW)
|
||||
|
||||
The world is a rail-graph in the outer world (NPCs traverse rails; the player is freeform navmesh and can plug-into-rails for co-walking).
|
||||
|
||||
```sql
|
||||
CREATE TABLE rail_segments (
|
||||
segment_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
from_cell_id UUID NOT NULL REFERENCES cells(cell_id),
|
||||
to_cell_id UUID NOT NULL REFERENCES cells(cell_id),
|
||||
direction TEXT NOT NULL CHECK (direction IN ('bidirectional','forward')),
|
||||
|
||||
-- Traversal
|
||||
length_ticks INT NOT NULL,
|
||||
capacity INT DEFAULT 10, -- max concurrent traversers (3-way co-walk: 2-3)
|
||||
|
||||
-- Typology
|
||||
segment_class TEXT NOT NULL,
|
||||
-- 'district_interior' | 'pipe_heterotopia' | 'dump_approach' |
|
||||
-- 'machine_infrastructure' | 'ruin_passage' | 'inter_district' | ...
|
||||
heterotopia_grade REAL DEFAULT 0 CHECK (heterotopia_grade BETWEEN 0 AND 1),
|
||||
-- 0 = full regime visibility, 1 = deep heterotopia
|
||||
|
||||
-- Surveillance / politics
|
||||
overseer_density REAL DEFAULT 0 CHECK (overseer_density BETWEEN 0 AND 1),
|
||||
patrol_frequency REAL DEFAULT 0,
|
||||
propaganda_intensity REAL DEFAULT 0,
|
||||
|
||||
-- Per-register ambient content (three-layer)
|
||||
ambient_content JSONB, -- { gameworld: ..., liminal: ..., imperial_net: ... }
|
||||
|
||||
-- Encounter mechanics
|
||||
encounter_spawn_rate REAL DEFAULT 0,
|
||||
encounter_type_weights JSONB,
|
||||
|
||||
-- Visual / shader
|
||||
illumination_profile JSONB,
|
||||
degradation_level REAL DEFAULT 0,
|
||||
|
||||
-- State
|
||||
blocked BOOLEAN DEFAULT false,
|
||||
current_traversers UUID[]
|
||||
);
|
||||
|
||||
CREATE INDEX idx_segments_from ON rail_segments (from_cell_id);
|
||||
CREATE INDEX idx_segments_to ON rail_segments (to_cell_id);
|
||||
CREATE INDEX idx_segments_class ON rail_segments (segment_class);
|
||||
```
|
||||
|
||||
A* on this graph is microseconds. Rich metadata-per-edge is what navmesh cannot natively carry.
|
||||
|
||||
---
|
||||
|
||||
## 10. interiors — small navmesh-zones with slot-inventory (v0.4 NEW)
|
||||
|
||||
Interiors are zones at sub-cell scale. Each has a navmesh inside (only when active) and a slot-inventory.
|
||||
|
||||
```sql
|
||||
CREATE TABLE interiors (
|
||||
interior_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
containing_cell UUID NOT NULL REFERENCES cells(cell_id),
|
||||
interior_type TEXT NOT NULL,
|
||||
-- 'hovel' | 'cantina' | 'workshop' | 'memorial_crypt' |
|
||||
-- 'preacher_hall' | 'brothel_physical' | 'ruin_interior' | ...
|
||||
owner_npc_id UUID REFERENCES npcs(npc_id),
|
||||
register TEXT NOT NULL DEFAULT 'physical'
|
||||
CHECK (register IN ('physical','liminal','imperial')),
|
||||
|
||||
-- Spatial / slot
|
||||
navmesh_ref TEXT,
|
||||
slot_inventory JSONB NOT NULL,
|
||||
-- { "sofa": {count, positions, allowed_verbs},
|
||||
-- "kitchen": {...}, "bed": {...}, "shower": {...}, ... }
|
||||
current_occupants UUID[],
|
||||
|
||||
-- Privacy / visibility
|
||||
surveillance_density REAL DEFAULT 0.1, -- typically lower than pipe baseline
|
||||
visible_to_faction TEXT[],
|
||||
|
||||
-- Lifecycle
|
||||
active BOOLEAN DEFAULT false, -- true when ≥1 occupant; drives sim cost
|
||||
last_activated TIMESTAMPTZ,
|
||||
last_deactivated TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE INDEX idx_interiors_owner ON interiors (owner_npc_id);
|
||||
CREATE INDEX idx_interiors_active ON interiors (containing_cell) WHERE active = true;
|
||||
```
|
||||
|
||||
**Liminal-interior special case:** clasping-pair-shared-construct. `register = 'liminal'`, `owner_npc_id = NULL`, `slot_inventory` derived from both dreamers' merged memory-residue. Stabilizes across repeated clasps.
|
||||
|
||||
---
|
||||
|
||||
## 11. mods + npc_mod_slots + mod_wear_history (v0.4 NEW)
|
||||
|
||||
Mods as trait-bearers — they modify expressed_trait_vector while worn. Four classes (amplifier/bridge/divergent/mask) with self-alienation-tax pricing.
|
||||
|
||||
```sql
|
||||
CREATE TABLE mods (
|
||||
mod_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
base_slot TEXT NOT NULL,
|
||||
mod_class TEXT NOT NULL CHECK (mod_class IN
|
||||
('amplifier','bridge','divergent','mask')),
|
||||
trait_contributions REAL[] NOT NULL, -- delta-vector applied to wearer
|
||||
visual_template JSONB NOT NULL,
|
||||
motion_signature TEXT,
|
||||
creator_npc_id UUID,
|
||||
inherited_from UUID,
|
||||
memorialist_protected BOOLEAN DEFAULT false,
|
||||
market_class TEXT NOT NULL CHECK (market_class IN
|
||||
('blackmarket','regime_licensed','inherited','memorial_kept')),
|
||||
scrip_cost REAL,
|
||||
lifeforce_cost REAL,
|
||||
rarity TEXT DEFAULT 'common',
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE npc_mod_slots (
|
||||
npc_id UUID NOT NULL REFERENCES npcs(npc_id),
|
||||
slot_type TEXT NOT NULL,
|
||||
mod_id UUID REFERENCES mods(mod_id),
|
||||
fitted_at TIMESTAMPTZ,
|
||||
PRIMARY KEY (npc_id, slot_type)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_mods_blackmarket ON mods (market_class, mod_class)
|
||||
WHERE market_class = 'blackmarket';
|
||||
|
||||
-- Audit: who has worn this mod across its lifetime
|
||||
CREATE TABLE mod_wear_history (
|
||||
mod_id UUID NOT NULL REFERENCES mods(mod_id),
|
||||
npc_id UUID NOT NULL,
|
||||
fitted_at TIMESTAMPTZ NOT NULL,
|
||||
removed_at TIMESTAMPTZ,
|
||||
PRIMARY KEY (mod_id, fitted_at)
|
||||
);
|
||||
```
|
||||
|
||||
`mod_wear_history` carries Memorialist-relevant continuity tracking. Inherited-mods retain residual trait-signature of the deceased.
|
||||
|
||||
---
|
||||
|
||||
## 12. trait_colors — canonical color/motion mapping (v0.4 NEW)
|
||||
|
||||
```sql
|
||||
CREATE TABLE trait_colors (
|
||||
trait_name TEXT PRIMARY KEY,
|
||||
hex_color TEXT NOT NULL,
|
||||
hsv_hue REAL NOT NULL,
|
||||
motion_signature TEXT NOT NULL, -- accessibility: pair color with motion
|
||||
canonical_name TEXT NOT NULL,
|
||||
narrative_note TEXT
|
||||
);
|
||||
|
||||
-- Populated via designer artistic decision; values below are placeholders
|
||||
INSERT INTO trait_colors VALUES
|
||||
('sophrosyne', '#4A7C9E', 216, 'steady', 'Sophrosyne-blue', 'cool, composed, measured'),
|
||||
('dikaiosyne', '#B8860B', 42, 'weighted_pulse', 'Dikaiosyne-gold', 'grave, weighty, judicial'),
|
||||
('philotes', '#E8848C', 355, 'warm_pulse', 'Philotes-rose', 'attachment, embrace-ready'),
|
||||
('mnemosyne', '#6B4E9C', 266, 'depth_shimmer', 'Mnemosyne-violet', 'memory-lit, twilight'),
|
||||
('aletheia', '#F0EEEB', 30, 'luminous', 'Aletheia-white', 'unconcealed, bright'),
|
||||
('kairos', '#F5D540', 50, 'lightning_flicker', 'Kairos-yellow', 'opportune, sparking'),
|
||||
('moira', '#7A2323', 0, 'slow_thread', 'Moira-crimson', 'fate-thread, bound'),
|
||||
('eros', '#E05030', 10, 'flame_flicker', 'Eros-orange', 'reaching, flushed');
|
||||
```
|
||||
|
||||
Color paired with motion-signature ensures color-blind accessibility — each trait uniquely identifiable via two independent channels.
|
||||
|
||||
---
|
||||
|
||||
## 13. proximity_candidates — lightweight zone-detection (v0.4 NEW)
|
||||
|
||||
For player-navmesh-driven proximity-detection (offering interactions without director-arbitration cost).
|
||||
|
||||
```sql
|
||||
CREATE TABLE proximity_candidates (
|
||||
candidate_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
observer_id UUID NOT NULL, -- usually the player
|
||||
target_type TEXT NOT NULL, -- 'npc' | 'wall' | 'object' | 'interior_door' | 'rail_segment'
|
||||
target_id UUID NOT NULL,
|
||||
candidate_zone_type TEXT NOT NULL, -- 'greeting' | 'wall_read' | 'plug_in' | ...
|
||||
eligibility_score REAL NOT NULL CHECK (eligibility_score BETWEEN 0 AND 1),
|
||||
shader_intensity REAL,
|
||||
detected_at TIMESTAMPTZ DEFAULT now(),
|
||||
expires_at TIMESTAMPTZ NOT NULL,
|
||||
engaged BOOLEAN DEFAULT false
|
||||
);
|
||||
|
||||
CREATE INDEX idx_prox_observer_active ON proximity_candidates (observer_id, expires_at)
|
||||
WHERE engaged = false;
|
||||
```
|
||||
|
||||
Ephemeral, short-lived, light-weight. Director doesn't arbitrate; they appear and fade with navmesh-proximity deltas.
|
||||
|
||||
---
|
||||
|
||||
## 14. district_cheat_ops — director's illicit operations ledger (v0.4 NEW)
|
||||
|
||||
```sql
|
||||
CREATE TABLE district_cheat_ops (
|
||||
op_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
district_id UUID NOT NULL,
|
||||
director_id UUID NOT NULL,
|
||||
cheat_type TEXT NOT NULL CHECK (cheat_type IN
|
||||
('drug_ring','illegal_modshop','unlicensed_brothel',
|
||||
'stolen_parts_fence','ghost_shifts','phantom_workers',
|
||||
'necrocommerce_lite','black_clasp_market')),
|
||||
spawned_zone_id UUID REFERENCES zones(zone_id),
|
||||
|
||||
-- Economic reality
|
||||
lifeforce_extracted REAL NOT NULL,
|
||||
quota_credit REAL NOT NULL,
|
||||
|
||||
-- Detection state
|
||||
detection_risk REAL NOT NULL,
|
||||
detection_channel TEXT,
|
||||
detected_at TIMESTAMPTZ,
|
||||
punishment_severity TEXT, -- 'memo' | 'sanction' | 'replacement' | 'purge'
|
||||
|
||||
-- Faction-ecology
|
||||
participating_npcs UUID[],
|
||||
implicated_factions TEXT[],
|
||||
|
||||
started_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
ended_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cheat_ops_undetected_active
|
||||
ON district_cheat_ops (district_id)
|
||||
WHERE ended_at IS NULL AND detected_at IS NULL;
|
||||
|
||||
CREATE INDEX idx_cheat_ops_district_timeline
|
||||
ON district_cheat_ops (district_id, started_at DESC);
|
||||
```
|
||||
|
||||
The `district_reports.lifeforce_actual` minus `lifeforce_reported` gap accrues from the sum of active cheat-ops' `lifeforce_extracted`.
|
||||
|
||||
---
|
||||
|
||||
## 15. imperial_policies — policy issuance (v0.4 NEW)
|
||||
|
||||
```sql
|
||||
CREATE TABLE imperial_policies (
|
||||
policy_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
issued_at_tick BIGINT NOT NULL,
|
||||
policy_scope TEXT NOT NULL, -- 'citywide' | 'per_district' | 'per_faction'
|
||||
scope_ref UUID,
|
||||
policy_type TEXT NOT NULL CHECK (policy_type IN
|
||||
('quota_set','enforcement_rule','faction_weight','audit_directive',
|
||||
'crisis_authorization','emergency_provision','ratchet_tightening')),
|
||||
policy_content JSONB NOT NULL,
|
||||
rationale TEXT, -- imperium's stated reason (may be post-hoc)
|
||||
superseded_by UUID REFERENCES imperial_policies(policy_id),
|
||||
superseded_at_tick BIGINT
|
||||
);
|
||||
|
||||
CREATE INDEX idx_policies_active_scope
|
||||
ON imperial_policies (policy_scope, scope_ref, issued_at_tick DESC)
|
||||
WHERE superseded_by IS NULL;
|
||||
|
||||
CREATE INDEX idx_policies_timeline ON imperial_policies (issued_at_tick DESC);
|
||||
```
|
||||
|
||||
The `rationale` is the regime's *stated reason*, which may differ from actual cause. Memorialists' four-ledger captures the gap.
|
||||
|
||||
---
|
||||
|
||||
## 16. overseer_reports — direct-to-imperium intelligence flow (v0.4 NEW)
|
||||
|
||||
Bypasses GM. Apex-loyal intelligence-apparatus.
|
||||
|
||||
```sql
|
||||
CREATE TABLE overseer_reports (
|
||||
report_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
overseer_id UUID NOT NULL REFERENCES npcs(npc_id),
|
||||
overseer_type TEXT NOT NULL CHECK (overseer_type IN
|
||||
('audit','enforcement','surveillance','internal_security')),
|
||||
observed_district UUID NOT NULL,
|
||||
observed_cell UUID,
|
||||
observed_target UUID,
|
||||
report_content JSONB NOT NULL,
|
||||
classification TEXT NOT NULL,
|
||||
-- 'attendance_tally' | 'resource_output' | 'illegal_op_detected' |
|
||||
-- 'trait_anomaly' | 'factional_dissidence' | 'director_corruption' |
|
||||
-- 'clasp_ring_detected' | 'aletheia_recruitment_signs' | ...
|
||||
severity TEXT NOT NULL CHECK (severity IN
|
||||
('nominal','suspicious','confirmed_violation','critical')),
|
||||
submitted_at TIMESTAMPTZ DEFAULT now(),
|
||||
|
||||
-- Imperial processing
|
||||
received_by_imperium BOOLEAN DEFAULT false,
|
||||
imperium_verdict TEXT CHECK (imperium_verdict IN
|
||||
('archive_only','flag_for_leverage','formulate_to_gm',
|
||||
'act_directly','verify_against_director_report',
|
||||
'cross_check_with_other_overseers')),
|
||||
verdict_at TIMESTAMPTZ,
|
||||
|
||||
-- Flow-3 linkage
|
||||
formulated_to_gm BOOLEAN DEFAULT false,
|
||||
formulation_id UUID
|
||||
);
|
||||
|
||||
CREATE INDEX idx_overseer_reports_unprocessed ON overseer_reports (submitted_at)
|
||||
WHERE received_by_imperium = false;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 17. imperial_to_gm_formulations — selective-disclosure downward (v0.4 NEW)
|
||||
|
||||
Where imperial sovereignty manifests as information-gating to the GM.
|
||||
|
||||
```sql
|
||||
CREATE TABLE imperial_to_gm_formulations (
|
||||
formulation_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
source_overseer_reports UUID[] NOT NULL,
|
||||
formulation_type TEXT NOT NULL CHECK (formulation_type IN
|
||||
('intelligence_brief','action_directive','policy_hint',
|
||||
'leverage_signal','decoy_advisory')),
|
||||
formulation_content JSONB NOT NULL,
|
||||
truth_distortion_level REAL, -- 0 = full truth, 1 = complete distortion
|
||||
strategic_intent TEXT, -- internal: why imperium framed it this way
|
||||
issued_at TIMESTAMPTZ DEFAULT now(),
|
||||
gm_acknowledged BOOLEAN DEFAULT false
|
||||
);
|
||||
|
||||
CREATE INDEX idx_formulations_gm_pending ON imperial_to_gm_formulations (issued_at)
|
||||
WHERE gm_acknowledged = false;
|
||||
```
|
||||
|
||||
`truth_distortion_level` is simulation-internal. Memorialists' four-ledger reconstructs from this column post-collapse.
|
||||
|
||||
---
|
||||
|
||||
## 18. imperial_budget_ledger + expenditures + construction (v0.4 NEW)
|
||||
|
||||
The four-tier lifeforce hierarchy's apex layer. Imperial budget gates enforcement; insolvency-spiral as endgame mechanism.
|
||||
|
||||
```sql
|
||||
CREATE TABLE imperial_budget_ledger (
|
||||
cycle_tick BIGINT PRIMARY KEY,
|
||||
reported_at TIMESTAMPTZ DEFAULT now(),
|
||||
|
||||
-- Income
|
||||
reported_income REAL NOT NULL,
|
||||
actual_income REAL NOT NULL,
|
||||
phantom_revenue REAL GENERATED ALWAYS AS
|
||||
(reported_income - actual_income) STORED,
|
||||
|
||||
-- Standing obligations
|
||||
overseer_corps_cost REAL NOT NULL,
|
||||
audit_operations_cost REAL NOT NULL,
|
||||
enforcement_standing REAL NOT NULL,
|
||||
construction_active_cost REAL NOT NULL,
|
||||
propaganda_broadcasts_cost REAL NOT NULL,
|
||||
|
||||
-- Discretionary
|
||||
discretionary_available REAL NOT NULL,
|
||||
discretionary_spent REAL NOT NULL,
|
||||
|
||||
-- Reserves
|
||||
reserves_start REAL NOT NULL,
|
||||
reserves_drawdown REAL NOT NULL DEFAULT 0,
|
||||
reserves_end REAL NOT NULL,
|
||||
|
||||
insolvency_risk_level TEXT NOT NULL CHECK (insolvency_risk_level IN
|
||||
('stable','phantom_accumulating','depletion_imminent','crisis'))
|
||||
);
|
||||
|
||||
CREATE TABLE imperial_expenditures (
|
||||
expenditure_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
cycle_tick BIGINT NOT NULL,
|
||||
category TEXT NOT NULL CHECK (category IN
|
||||
('martial_dispatch','overseer_hire','audit_op',
|
||||
'construction_investment','propaganda_burst',
|
||||
'reserve_draw','policy_announcement','emergency_provision')),
|
||||
amount REAL NOT NULL,
|
||||
target_district UUID,
|
||||
rationale TEXT,
|
||||
authorized_at_cycle BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE imperial_construction_projects (
|
||||
project_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
project_type TEXT NOT NULL CHECK (project_type IN
|
||||
('new_district','new_pipe','new_dump',
|
||||
'overseer_hq','ceremony_hall','audit_center',
|
||||
'martial_barracks','propaganda_broadcast_tower',
|
||||
'district_expansion','infrastructure_maintenance')),
|
||||
target_cells UUID[],
|
||||
budgeted_total REAL NOT NULL,
|
||||
spent_so_far REAL NOT NULL DEFAULT 0,
|
||||
completion_pct REAL NOT NULL DEFAULT 0,
|
||||
started_at_cycle BIGINT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active' CHECK (status IN
|
||||
('active','stalled_underfunded','completed','abandoned'))
|
||||
);
|
||||
|
||||
CREATE INDEX idx_construction_active
|
||||
ON imperial_construction_projects (target_cells)
|
||||
WHERE status = 'active';
|
||||
```
|
||||
|
||||
The city's physical state expresses imperial budget — construction cranes vs. abandoned-projects vs. visible decay.
|
||||
|
||||
---
|
||||
|
||||
## 19. imperial_net_transactions — the bypass mechanism (v0.4 NEW, the killer schema)
|
||||
|
||||
**Every imperial-net transaction routes revenue directly to imperium; districts get zero quota-credit.**
|
||||
|
||||
```sql
|
||||
CREATE TABLE imperial_net_transactions (
|
||||
transaction_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
cycle_tick BIGINT NOT NULL,
|
||||
transacted_at TIMESTAMPTZ DEFAULT now(),
|
||||
|
||||
-- Buyer
|
||||
buyer_id UUID NOT NULL REFERENCES npcs(npc_id),
|
||||
buyer_district_id UUID NOT NULL,
|
||||
scrip_paid REAL,
|
||||
lifeforce_spent REAL,
|
||||
memory_tokens_spent REAL,
|
||||
|
||||
-- Goods
|
||||
goods_type TEXT NOT NULL CHECK (goods_type IN
|
||||
('waifu_session','avatar_mod','costume','ceremony_entry',
|
||||
'character_edit','dream_architecture_session','taste_curation')),
|
||||
goods_id UUID,
|
||||
|
||||
-- Labor source — the asymmetric reveal
|
||||
producer_npc_id UUID REFERENCES npcs(npc_id),
|
||||
producer_district_id UUID,
|
||||
producer_labor_hours REAL,
|
||||
|
||||
-- Capture split — politically loaded
|
||||
imperial_revenue REAL NOT NULL,
|
||||
producer_payment REAL NOT NULL DEFAULT 0, -- survival-scrip only
|
||||
district_quota_credit REAL NOT NULL DEFAULT 0 -- ZERO by default
|
||||
);
|
||||
|
||||
CREATE INDEX idx_net_trans_producer_district
|
||||
ON imperial_net_transactions (producer_district_id, cycle_tick DESC);
|
||||
|
||||
CREATE INDEX idx_net_trans_imperial_flow
|
||||
ON imperial_net_transactions (cycle_tick, imperial_revenue DESC);
|
||||
```
|
||||
|
||||
**The `district_quota_credit REAL NOT NULL DEFAULT 0` does political work.** Every database row created by an imperial-net transaction explicitly memorializes that the producing-district got nothing. Memorialists querying this table see structural theft written in the numbers.
|
||||
|
||||
---
|
||||
|
||||
## 20. memorialist_true_ledger — four-column ground-truth archive (v0.4 NEW)
|
||||
|
||||
```sql
|
||||
CREATE TABLE memorialist_true_ledger (
|
||||
ledger_entry_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
cycle_tick BIGINT NOT NULL,
|
||||
district_id UUID,
|
||||
ledger_dimension TEXT NOT NULL CHECK (ledger_dimension IN
|
||||
('what_actually_happened',
|
||||
'what_overseer_reported',
|
||||
'what_imperium_received',
|
||||
'what_gm_was_told')),
|
||||
content JSONB NOT NULL,
|
||||
discrepancy_vs UUID[], -- other ledger_entry_ids this contradicts
|
||||
kept_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_memorialist_ledger_district_cycle
|
||||
ON memorialist_true_ledger (district_id, cycle_tick DESC);
|
||||
|
||||
CREATE INDEX idx_memorialist_ledger_dimension
|
||||
ON memorialist_true_ledger (ledger_dimension, cycle_tick DESC);
|
||||
```
|
||||
|
||||
**Memorialists' political project encoded as a schema.** Without this archive, post-collapse-investigation has only the regime's own (corrupt-by-construction) accounts. Memorialist-archive accessibility to the player is an open design question.
|
||||
|
||||
---
|
||||
|
||||
## 21. Concerns audit (reconciled across v0.2 + v0.4)
|
||||
|
||||
Six-worry concerns audit (v0.2) plus v0.4 additional concerns:
|
||||
|
||||
### Original six worries
|
||||
|
||||
1. **Hot-row TOAST + MVCC write amplification** → split hot/cold; shift-decomposition; reference-by-UUID for unbounded fields
|
||||
2. **Event-to-subscriber fan-out cost** → push filtering to NATS subject hierarchy, not DB
|
||||
3. **State/event atomicity** → WAL logical decoding via pgnats (outbox pattern)
|
||||
4. **LLM-induced jsonb corruption** → architectural separation: directors validate output before writing; CHECK constraints as second-line
|
||||
5. **Unbounded growth of hot jsonb** → append-only event tables; rolling-summary in hot row
|
||||
6. **Cognition cost of director decisions** → decomposition + typed tools + lifeforce-budgeted escalation
|
||||
|
||||
### v0.4 additional concerns
|
||||
|
||||
7. **Imperium's reward-function spiraling on phantom data** → require Memorialist-true-ledger as privileged-observer ground-truth for reward-input; designer's ethical guardrails encoded
|
||||
8. **GM's middle-management corruption (under-auditing)** → direct overseer-to-imperium intelligence flow bypasses GM; cross-channel divergence detection
|
||||
9. **Calibrated-misery as imperial optimum** → reward-function penalty on net-revenue-correlated-with-district-misery; explicit guardrail against this being learned
|
||||
10. **Necrocommerce of mind-pool patterns** → memorialist_protected flag; ritualistic protection enforced by SQL
|
||||
11. **Aletheia-truth-has-victims** → not a corruption-concern but a *narrative-authenticity* concern: corruption-exposure mechanics must produce real consequences for shadow-economy participants who depended on the corruption; *"truth has costs"* is encoded, not glossed
|
||||
12. **Construction-project abandonment** → reward-function penalty for projects-started-but-abandoned ratio; prevents propaganda-construction-as-bluff
|
||||
|
||||
---
|
||||
|
||||
## 22. Open forks (still to resolve before migration)
|
||||
|
||||
- **Fork 1.1** (zones hot/cold split) — leaning split; benchmark on phoebe-dev
|
||||
- **Fork 1.2** (pg_notify vs. WAL-decode) — pgnats evaluation
|
||||
- **Fork 1.3** (slot-occupancy nested vs. relational) — leaning relational (sketch in §1.4)
|
||||
- **NATS subject hierarchy final form** — sketched §1; needs review
|
||||
- **Ternary-gate storage shape** —
|
||||
- Option A: `npc_relations` table with state-cols per axis
|
||||
- Option B: per-axis append-only transition-log
|
||||
- Option C: hybrid — `npc_relations` for current + transition-log for history
|
||||
- Leaning **C** (matches hot/cold pattern adopted elsewhere)
|
||||
- **Register-tagging column on zones** — sketched §1; confirm jsonb vs. text column
|
||||
- **Wall-content encoding** — jsonb-per-cell leaning; review usage patterns
|
||||
- **v0.4 NEW: Inner-body-projection function** — trait → body-rendering: learned mapping vs. hand-authored vs. hybrid
|
||||
- **v0.4 NEW: Mod-rarity / inheritance economy tuning** — how often do Memorialist-protected mods accumulate; what fraction of dead-NPCs trigger protection
|
||||
- **v0.4 NEW: Overseer corruption pathway** — overseer's own trait-vector + lifeforce makes them bribable; how is this trait-arithmetic-detected?
|
||||
- **v0.4 NEW: Imperial budget allocation algorithm** — when imperium decides between construction/enforcement/reserves, what's the v1 rule-shape?
|
||||
- **v0.4 NEW: Imperial-net pricing dynamics** — character-editor cost as function of trait-divergence: linear, exponential, learned?
|
||||
- **v0.4 NEW: Memorialist-archive accessibility to the player** — when can the player query `memorialist_true_ledger`? Through what interaction-class? (Joining the faction; performing rituals; finding archive-cells)
|
||||
- **v0.4 NEW: Liminal mini-game design** — exact gameplay action: attention-based / rhythm-based / memory-based / trait-modulated difficulty?
|
||||
- **v0.4 NEW: Plug-in social-eligibility computation** — exact weighted formula combining proximity + traits + gates + shift-state for shader-intensity output
|
||||
- **v0.4 NEW: Imperial-net distortion algorithm** — exact transformation of trait-colors toward consumer-palette; reversibility for Aletheia-vision
|
||||
|
||||
---
|
||||
|
||||
## 23. Next steps (path to formal migration)
|
||||
|
||||
1. **Resolve Fork 1.1** (hot/cold split on zones) — sketch split-table; TOAST-curve micro-benchmark on phoebe-dev
|
||||
2. **Evaluate pgnats** (high-priority in phoebe-ledger) — resolves Fork 1.2
|
||||
3. **Decide ternary-gate storage shape** (A / B / C; leaning C)
|
||||
4. **Decide rail-segment NATS hierarchy** — exact subject-pattern for `zones.<lifecycle>.<register>.<district>.<zone_type>.<trait_filter>`
|
||||
5. **Draft formal migration `nimmerverse-core/migrations/001_nimmerworld_v1.sql`** incorporating all 22 tables above with resolved forks. Estimated ~600-1200 lines of DDL.
|
||||
6. **Review against architecture-broad v0.4** for any primitive missed
|
||||
7. **Run migration in dev** on phoebe-dev:35432
|
||||
8. **Wire first thalamus subscriber** for `zones.active.>` to validate NATS-routing
|
||||
9. **First end-to-end smoke test**:
|
||||
- fake district with 20 NPCs
|
||||
- assign shifts (write `current_shift_*` on each NPC row)
|
||||
- tick the simulation; let zone-spawn-candidates query fire
|
||||
- emit a fake emergent-signal
|
||||
- have director dispatch (write decision_log entry)
|
||||
- close zone with outcome
|
||||
- verify shift_history archive
|
||||
- verify district_report aggregates
|
||||
- verify imperial_budget_ledger income-aggregation from districts
|
||||
10. **Add second-tier integration test**:
|
||||
- simulate a corrupt director (insert district_cheat_ops)
|
||||
- verify lifeforce_actual diverges from lifeforce_reported
|
||||
- simulate audit-overseer detection
|
||||
- write overseer_reports → imperium consumes → formulates_to_gm with truth_distortion
|
||||
- verify Memorialist-true-ledger captures the gap
|
||||
- verify reward-function guardrails fire correctly
|
||||
|
||||
Migration is not yet written. This document is its preparation.
|
||||
|
||||
---
|
||||
|
||||
**Version:** 0.3 | **Created:** 2026-04-24 | **Updated:** 2026-04-24
|
||||
|
||||
*v0.1 (2026-04-24 afternoon, dafit): initial zones-table sketch, 76 lines, pure hypothetical.*
|
||||
|
||||
*v0.2 (2026-04-24 evening, dafit + chrysalis): reconciled with architecture-broad v0.3. Added 7 new table sketches (npcs-shift-cols + body/layer state, shift_history, emergent_signals, district_reports, decision_log, mind_pool, cells-wall-content-per-register, zone_slot_occupancy). Six-worry concerns audit. Three forks surfaced.*
|
||||
|
||||
*v0.3 (2026-04-24 late-evening / 2026-04-25 early-morning, dafit + chrysalis): absorbing architecture-broad v0.4. Added intrinsic/expressed trait-vector split on npcs. Added 13 new table sketches: rail_segments (topology), interiors (sub-cell navmesh-zones), mods + npc_mod_slots + mod_wear_history (mod-economy with Memorialist-relevant inheritance), trait_colors (canonical color/motion mapping), proximity_candidates (lightweight zone-detection), district_cheat_ops (director's illicit ledger), imperial_policies (policy issuance), overseer_reports (direct-to-imperium intelligence flow), imperial_to_gm_formulations (selective-disclosure downward), imperial_budget_ledger + imperial_expenditures + imperial_construction_projects (four-tier lifeforce apex), imperial_net_transactions (bypass mechanism with capture-split), memorialist_true_ledger (four-column ground-truth archive). Extended concerns audit with six v0.4 additions. Extended open-forks list with eight v0.4 questions. Concrete two-tier integration-test plan in next-steps. Twenty-two tables total in this preparation document; migration spec writing is the next concrete deliverable once forks resolve.*
|
||||
Reference in New Issue
Block a user