# Sprint 33: Pecunia — Server Tasks **Goal:** Full economics simulation running — Leontief production, spatial price equilibrium, currency zones, corporate behavioral agents across all three corporation tiers, stability tests passing. **Branch:** `sprint-33/server` **Agents:** Dudley (simulation dev), Tyre (architecture), Hoshe (QA) ## New Tickets | # | Title | Blocked by | |---|-------|------------| | #813 | Energy-over-gate schema extension | — | | #805 | Extend economy-db with corporation pipeline and validation | #804 (DONE) | | #806 | Build skeleton economy_sim binary | #805 | | #807 | Add trade flows and stability testing | #806 | | #808 | Add currency zones and exchange rates | #807 | | #809 | Add corporate agent behavior | #808, #799, #800 | Use `tooling/db/ticket show ` for full ticket details. ## Key Decisions - `decisions/economics.md` — D-171 (three-currency system), D-172 (currency zone initialization), D-173 (commodity taxonomy), D-174 (shadow economy layer), D-175 (corporation taxonomy), D-176 (productivity seeding), D-177 (productivity constraints), D-178 (economic model architecture), D-179 (stability acceptance criteria), D-180 (event input port), D-181 (signal vocabulary), D-182 (TOML source of truth), D-183 (iterative development cycle), D-184 (commodity catalog 36 types), D-185 (brands not commodities), D-186 (gate transmission levels), D-187 (fusion fuel as intermediate) - `decisions/architecture.md` — D-166 (development cascade: Phase 2 deliverable = economics spreadsheets/graphs with runtime-tweakable simulation) ## Notes **#813 — Energy-over-gate schema extension** - `currency_zone` column already exists on `star_systems` (`server/data/systems-schema.sql`). Need to add `gate_energy_connected` boolean column to the appropriate node table. - Per D-186: `MARK_PRIMARY` zones default to `gate_energy_connected = false` (Compact refused Gate Corp dependency deliberately). All other zones default to `true`. - Demand reduction: nodes with `gate_energy_connected = true` get ~0.3× `fusion_fuel` utility demand. The reduction applies only to utility/habitation consumption — industrial chain inputs (`smelt_ore` 0.3, `alloy_fabrication` 0.2, `electronics_fabrication` 0.2) are unaffected. - This is a schema + migration ticket. No simulation logic yet — that is consumed by #806. - The `gate_energy_connected` field will be read by the sim binary when it computes per-node utility demand. **#805 — Extend economy-db with corporation pipeline and validation** - The existing import pipeline (`tooling/economy-db/import_economics.py`) already handles: gate_links, commodities, production_chains, currency_zone on star_systems. The `corp_presence` table exists in schema but the comment at line 12 reads "Does NOT populate corp_presence — that's a future pipeline step." This is that step. - Extend the pipeline to: read `wiki/corporations/*.md` and/or the DB `corporations` table, populate `corp_presence` rows from authored location data, validate that wiki corporation names match DB `corporations.proper_name` records (sync constraint from D-182), enforce coverage rules: 3+ corporations per major commodity type, 1+ per inhabited system with population > 100K. - Add chain completeness validation: every intermediate commodity must have at least one production chain that produces it. - Coverage validation failures must be hard errors (non-zero exit), not warnings. The Phase 2 prerequisite from D-175 requires this gate. - Input: `wiki/corporations/` markdown files, `server/data/systems.db` (corporations and system_economy tables). Output: populated `corp_presence` table. **#806 — Build skeleton economy_sim binary** - New Rust binary at `tooling/econ-sim/`. Follow patterns from `server/src/bin/atlas/` for CLI structure (argparse via clap, SQLite reads via rusqlite). - Loads transport graph from `systems.db` (`gate_links` table, bidirectional). Reads economy config from the built `.db` (commodities, production_chains, chain_inputs, corp_presence). - Seeds per-corporation productivity from PRNG seed (D-176): five dimensions (`extraction_rate`, `processing_throughput`, `transit_capacity`, `service_throughput`, `service_capacity`). Log-normal distribution, 0.4–1.8× multiplier for standard nodes, 0.7–1.4× for monopoly-source nodes. Corridor correlation ~0.6 — nearby sites should draw correlated samples. - Initial scope: Leontief production + consumption + price adjustment (Layer 1 only, per D-178). No inter-system trade flows, no currency zones, no corporate behavior. - Outputs per-node CSV with: node_id, commodity_id, supply, demand, price, tick. - The `--stability-check` flag is scaffolded here but not yet meaningful — it will be exercised in #807. - Lore-derived constraints from D-177 must be respected: do not seed location of production, biological monopoly ceilings, aging pipeline contents, or gate topology. **#807 — Add trade flows and stability testing** - Extends the binary from #806 with Layer 2 (spatial price equilibrium via damped tâtonnement, α=0.03, β=0.4, per D-178). - Prices propagate through the gate transport graph. Lagged adjustment — not instant equilibrium. Transport costs: 5–12%/hop on gate edges, 1–3% on orbital edges. - Market node tiering (D-178): ~760 active market nodes (inhabited bodies + all stations), ~240 passive producers (feed output to nearest active node), ~2,700 inert. Floyd-Warshall over active subgraph at startup (~0.5s expected, one-time cost). - Stockpile buffers per node: prevents instantaneous price explosions on single-tick supply disruptions. - `--stability-check` mode must now pass Tests 1 and 2 from D-179: - Test 1: Cold-start convergence — prices settle within ±5% of equilibrium within 100 game-days. - Test 2: Long-run stability — zero drift > ±2% over 1,000 game-days with zero external events. - If the model oscillates or diverges under no external input, that is a broken model, not a feature. Tune α/β first before concluding the model is wrong. **#808 — Add currency zones and exchange rates** - Extends the binary with Layer 2 currency dynamics (per D-171, D-172). - Three currencies: Tractus (numeraire), Mark (Compact zone), Sol (shadow only — no formal exchange rate, modeled as shadow economy commodity per D-174). - Cross-zone conversion friction: ~3% cost on Tractus↔Mark trade. Zero internal friction within `MARK_PRIMARY` zones (Compact "no internal tariffs" principle). - Exchange rate float driven by trade balance — Tractus/Mark rate adjusts over time based on cross-zone import/export imbalances. - Shadow economy modifier: apply per-node `shadow_economy_intensity` (0.0–1.0, from authored `wiki/economics/shadow_economy.toml` — authored by copy team in #803) to adjust shadow pricing signals. The `official_coverage_ratio` signal (D-181 signal 7) is derived from this. - `--stability-check` must now also pass Tests 3 and 4 from D-179: - Test 3: Shock response — after single supply shock, cascade propagates realistically, recovery within 200 ticks, no price explosions or negative prices. - Test 4: Cross-zone trade balance — after cross-zone trade volume change, exchange rate adjusts and re-stabilizes within 50 ticks. - Compact zone connectivity: `gate_energy_connected = false` nodes (from #813) should show elevated `fusion_fuel` utility demand in their signals. **#809 — Add corporate agent behavior** - Extends the binary with Layer 3 (corporate behavioral agents, per D-178). - Six behavioral archetypes (D-175): Monopolist, Distributor, Producer, Specialist, Cooperative, Intermediary. Parameters are template-instantiated — read archetype templates from `wiki/economics/archetypes/behavioral.toml`, then instantiate per corporation from the populated `corp_presence` table. - Corporations must be loaded from the DB (populated by #805 and seeded by copy team work in #799/#800). Do not hardcode corporation data. - Each archetype has distinct price-setting behavior, trade routing preferences, and response to competitor presence. Details in `decisions/economics.md` D-175 and `wiki/economics/archetypes/behavioral.toml`. - The event input port (D-180) is stubbed here — define the `EconEvent` struct with all fields (`target`, `effect`, `duration`, `visibility`) and a no-op handler. The port is not exercised until Phase 3, but must compile. - All 7 signals from D-181 must be produced per active node: `price_current`, `price_trend`, `trade_flow_volume`, `corporate_presence`, `stockpile_weeks`, `production_vs_baseline`, `official_coverage_ratio`. - This ticket closes the sprint: when all four stability tests pass with corporate agents active, the Phase 2 economics simulation is functionally complete. - Blocked by #808 (currency layer must be in place) and #799/#800 (copy team corporation corpus must be available in DB). ## Dependency Chain ``` #813 (energy-over-gate schema) → consumed by #806, #808 #805 (corp pipeline + validation) → #806 (skeleton sim) → #807 (trade flows + stability) → #808 (currency zones) → #809 (corporate agents) #799 (Tier-2 corps, copy) ─────────────────────────────────┐ #800 (Tier-3 pipeline, server) ────────────────────────────→ #809 (corporate agents) ``` Note: #800 (Tier-3 generation pipeline) is assigned to the server team (it is a Rust binary), but its output depends on archetype taxonomy (#798, DONE) from copy. Coordinate with copy team on `wiki/economics/archetypes/` TOML format before starting #800. ## PR Workflow When ready to submit, create a PR with `tea` CLI. **All flags are required** to avoid TTY prompts (see CLAUDE.md "Gitea access" section): ```bash tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(simulation): description" --description "body" --base main --head sprint-33/server ```