Files
settled-reach/docs/sprints/sprint-33/server.md
T
jpmschweitzerandClaude Sonnet 4.6 7270b860cb chore(meta): plan Sprint 33: Pecunia
Economics simulation sprint — skeleton binary through corporate agents.
13 tickets across server/copy/client/ci. Stability tests (D-179) are
the sprint exit condition.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 08:36:31 +02:00

9.9 KiB
Raw Blame History

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 <id> 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.41.8× multiplier for standard nodes, 0.71.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: 512%/hop on gate edges, 13% 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.01.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):

tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(simulation): description" --description "body" --base main --head sprint-33/server