chore(meta): plan Sprint 34: Pulse

Close Phase 2 — wire econ-sim into game server tick loop, expose price
history and trade flows via implant insert panel, add economics debug
console commands for runtime event injection and parameter mutation.

New tickets: #821 (server tick integration), #822 (IPC bridge v21),
#823 (debug command handler), #824 (economics insert panel),
#825 (debug console econ commands). Existing: #810, #785, #811, #748,
#814, #695. 11 tickets total across server, client, copy, planning.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-08 16:20:29 +02:00
co-authored by Claude Sonnet 4.6
parent 385f07b11e
commit 9d9ea96be1
6 changed files with 494 additions and 0 deletions
Binary file not shown.
+92
View File
@@ -0,0 +1,92 @@
# Sprint 34: Pulse — Client Tasks
**Goal:** Close Phase 2 — wire the economics simulation into the live game, expose price history and trade flows in the implant, and make the economy observable and tweakable at runtime.
**Branch:** `sprint-34/client`
**Agents:** Stig (UI), Tyre (architecture)
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #785 | Add system population and GDP to star map info panel | — |
| #824 | Economics insert panel — price history charts and GDP display | #822 (server) |
| #825 | Economics debug console commands — event triggers and param sliders | #823 (server) |
## Key Decisions
- `decisions/economics.md` — D-181 (7-signal vocabulary — signals 1-2 are Phase 2: price_current, price_trend), D-180 (event port — the commands #825 fires)
- `decisions/architecture.md` — D-169 (implant UI component library — compose from client/ui/implant/), D-170 (HUD visibility groups — economics panel lives in INSERT mode), D-020 (IPC — EconomySnapshot arrives in ObserverSnapshot)
## Notes
### #785 — System population and GDP to star map info panel
When a system is selected in the star map (`client/ui/star_map.gd`, `client/ui/star_map.tscn`), the popup built with ImplantPanel components shows: name, star type, hop distance, corridor, GTTR excerpt, bodies, adjacents. Add two new `ImplantDataRow` entries: `POPULATION` and `GDP`. Data is already in `res://data/star_map_data.json` (regenerated by `tooling/generate-star-map-data.py` from `systems.db`). Check whether population and GDP fields are present in the JSON; if not, update the generation script as part of this ticket. This is standalone — no server dependency. Good warmup ticket; complete it first.
### #824 — Economics insert panel
New implant panel: **Economics Monitor**. Lives in INSERT mode (D-170), accessible via implant navigation alongside the star map.
Scene: `client/ui/implant/economics_panel.tscn` + `client/ui/implant/economics_panel.gd`
Compose strictly from the existing component library (`client/ui/implant/`):
- `ImplantPanel` — root container
- `ImplantHeader` — "ECONOMICS MONITOR" title + selected system subtitle
- `ImplantSeparator` — section dividers
- `ImplantDataRow` — key/value rows for price and GDP data
- `ImplantTextBlock` — top commodity summary text
Layout (three sections):
1. **System selector** — searchable/scrollable list of systems (can reuse star map system data). Selecting a system triggers an `EconStateQuery` PlayerAction to the server.
2. **Price table** — top 6 commodities for selected system, each as an `ImplantDataRow` with `price_current` and a directional trend indicator (▲ / ▼ / —) derived from `price_trend`.
3. **GDP strip** — total economic activity for the system displayed as a single row. Update each time a new `EconomySnapshot` arrives.
Data flow: `snapshot_handler.gd` receives ObserverSnapshot v21. When `economy_snapshot` is present, forward to `economics_panel.gd` via a signal or direct call. The panel caches the last 20 ticks of price data per system for trend display (ring buffer in GDScript Dictionary).
Do NOT draw custom canvas sparklines unless time allows — `ImplantDataRow` with a trend arrow is the MVP. The price chart can be a follow-on.
Register the panel in `client/scripts/autoloads/hud_groups.gd` under path `implant/economics`. Add a keyboard shortcut (e.g. `E` in implant mode) and an entry in the implant navigation menu.
Blocked by #822 (server must expose EconomySnapshot before the panel has real data). Build the panel with placeholder data first; wire live data once #822 ships.
### #825 — Economics debug console commands
The debug console exists at `client/ui/debug_console.gd` + `client/ui/debug_console.tscn`. The console already dispatches `DebugCommandKind` variants via `PlayerAction::DebugCommand` through the IPC bridge.
Add three new command parsers in `_parse_command()` / `_dispatch_command()`:
```
econ inject <system_id> [commodity_id] <shock|boost> <magnitude> [ticks]
→ InjectEconEvent { system_id, commodity_id, effect, magnitude, duration_ticks }
econ param <alpha|beta|friction> <value> [system_a] [system_b]
→ SetEconParam { param, value }
econ inspect <system_id>
→ GetEconState { system_id }
```
`econ inspect` returns all 7 D-181 signals for the system; display in console output log as a multi-line block. `econ inject` and `econ param` print a confirmation + the server's `DebugResponsePayload.text`.
Update `_print_help()` to include the `econ` command family. Blocked by #823 (server must handle the variants before the client can send them meaningfully, though client-side parsing can be built in parallel).
## Dependency Chain
```
#785 (star map GDP) — standalone, start here
#822 (server IPC, Sprint 34/server) → #824 (economics insert panel)
#823 (server debug handler, Sprint 34/server) → #825 (debug console commands)
#824 and #825 are parallel after their respective server blockers clear.
```
## PR Workflow
```bash
tea pr create --repo jpmschweitzer/settled-reach --login schweitz \
--title "feat(ui): economics insert panel and debug console econ commands" \
--description "Sprint 34 client work" \
--base main --head sprint-34/client
```
+61
View File
@@ -0,0 +1,61 @@
# Sprint 34: Pulse — Copy Tasks
**Goal:** Close Phase 2 — wire the economics simulation into the live game, expose price history and trade flows in the implant, and make the economy observable and tweakable at runtime.
**Branch:** `sprint-34/copy`
**Agents:** Mellanie (author), Paula (narrative)
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #814 | Rail infrastructure corporation gap | — |
| #695 | Author overheard conversations for remaining 24 zone types | — |
## Key Decisions
- `decisions/economics.md` — D-182 (TOML source of truth — all economics content lives in `wiki/economics/`), D-175 (corporation taxonomy — Tier 1/2/3 structure)
- `decisions/content.md` — D-142 (zone-type template architecture — 31 zone types defined), D-139 (composable behavior primitives — overheard conversations are Layer 2 cultural flavor)
## Notes
### #814 — Rail infrastructure corporation gap
**Context:** The corporation validation pipeline (`tooling/economy-db/import_economics.py`) flagged a gap: no existing wiki corporation produces the `rail_infrastructure` commodity. This is a lore-world gap as much as a data gap — rail is the primary intra-continental transit system on inhabited worlds (see `decisions/architecture.md` D-093 for Sova Transit context, `wiki/economics/production_chains.toml` for chain definitions).
**Deliverable:** Either (a) assign `rail_infrastructure` production to an existing Tier 1 or Tier 2 corporation (MVG — Marvian Gravity Works — is the most plausible candidate given its Tier 1 infrastructure mandate) or (b) create a new corporation if no existing corp fits. Update:
- `wiki/economics/corporations.toml` — add production entry
- Corresponding wiki corporation page (if new corp: `wiki/corporations/<name>.md`)
- Verify `make economy-db` passes after the change
Do not assign to a Tier 3 regional corp — rail infrastructure is a systemic commodity that should have Tier 1 or Tier 2 backing.
### #695 — Overheard conversations for remaining 24 zone types
**Context:** `server/content/global/overheard.ron` currently covers 5 of 29 zone types (~17% coverage). The remaining 24 types need 2-4 role-pair conversations each. These are the passive ambient dialogue lines that play when NPCs are overheard by the player without direct engagement (D-078).
**Format:** Each conversation entry in `overheard.ron` follows the existing pattern — two role slugs, a setting line (terse, 1 sentence describing where/when), and 3-5 lines of dialogue. Lines should feel naturalistic for the zone type; the NPC pair should be plausible co-workers or passers-by given the zone's economic activity.
**Zone types to cover:** Check `server/content/global/zone-types/` for the full list. Currently covered: the 5 types already in `overheard.ron` (verify by reading the file). Write 2-4 conversations per remaining zone type. Prioritize the zone types most likely to be visited first in a playthrough: `residential_dense`, `commercial_retail`, `transit_hub`, `office_district`, `industrial_light`.
**Lore anchors:** Use the wiki cultural pages (`wiki/cultures/`) for voice and slang. Zone types that map to specific planetary environments (agricultural, wilderness) should reflect the relevant culture. Avoid generic SF clichés — these lines should feel like they belong in the Reach.
**Volume:** 24 zone types × 3 conversations average × 4 lines each = ~288 lines total. Work zone-type by zone-type; commit partial coverage. Do not block on completing all 24 before committing.
## Dependency Chain
```
#814 (rail corp gap) — standalone
#695 (overheard conversations) — standalone, parallel
```
Both tickets are independent and can run in parallel.
## PR Workflow
```bash
tea pr create --repo jpmschweitzer/settled-reach --login schweitz \
--title "content(economics): rail corp gap and overheard conversation coverage" \
--description "Sprint 34 copy work" \
--base main --head sprint-34/copy
```
+115
View File
@@ -0,0 +1,115 @@
# Sprint 34: Pulse — Joint Briefing
**Goal:** Close Phase 2 — wire the economics simulation into the live game, expose price history and trade flows in the implant, and make the economy observable and tweakable at runtime.
---
## Pre-Sprint: Decisions and Schema
No blocking pre-sprint decisions required. All economic architecture decisions (D-178 through D-188) are confirmed. #810 (event port) is the technical gate for the full chain — it must be the first ticket the server team starts.
| Item | Owner | Status |
|------|-------|--------|
| D-178: Economic Model Architecture | decisions/economics.md | Confirmed |
| D-179: Stability Acceptance Criteria | decisions/economics.md | Confirmed |
| D-180: Event Input Port | decisions/economics.md | Confirmed |
| D-181: Signal Vocabulary | decisions/economics.md | Confirmed |
| ObserverSnapshot v21 schema | Server → client | New this sprint (#822) |
---
## Sprint Ticket Map
### Server (sprint-34/server)
```
#810 Event port implementation
→ #821 Integrate econ-sim into server tick loop
→ #822 Expose economy state over IPC (ObserverSnapshot v21)
→ #823 Economics debug command handler
```
### Client (sprint-34/client)
```
#785 Star map: system population + GDP (standalone)
#822 (server, blocker) → #824 Economics insert panel
#823 (server, blocker) → #825 Debug console econ commands
```
### Copy (sprint-34/copy)
```
#814 Rail infrastructure corporation gap (standalone)
#695 Overheard conversations — 24 zone types (standalone, parallel)
```
### Planning (sprint-34/planning)
```
#811 Brand layer design (early sprint)
#748 Phase 3 breakdown workshop (after server tickets in_progress)
```
---
## Cross-Team Integration Points
**ObserverSnapshot v21 (server → client)**
- Server: `server/src/bridge/types.rs` — add `EconomySnapshot` struct, bump `PROTOCOL_VERSION` to 21
- Client: `client/scripts/snapshot_handler.gd` — parse `economy_snapshot` field, route to economics panel
- Coordination: Server team defines the struct; client team consumes it. Server team ships #822 first; client team builds #824 with placeholder data in the meantime.
**Debug command flow (both teams)**
- Server: `server/src/bridge/types.rs` — add `InjectEconEvent`, `SetEconParam`, `GetEconState` to `DebugCommandKind`
- Client: `client/ui/debug_console.gd` — add `econ inject`, `econ param`, `econ inspect` command parsers
- Coordination: Server team ships #823 before client team wires #825. Client team can build command parsing and help text independently; just gate the send path on #823 being merged.
**Star map GDP (#785)**
- Client-only ticket. Check whether `res://data/star_map_data.json` already includes `population` and `gdp` fields. If not, update `tooling/generate-star-map-data.py` to include them from `server/data/systems.db`. This is a self-contained warmup — complete before #824.
---
## Cascade Enforcement
**No Phase 4 tickets.** This sprint closes Phase 2 and initiates Phase 3 planning via #748 and #811. The following are explicitly out of scope and must not be started, designed, or discussed:
- Character creation (#618, #619, #694, #606)
- Tycoon starting states (#615)
- Bookmark system (#614)
- NPC personality surface area (#621)
- Apartment generator (#617, #681)
- Any ticket under Phase 4 epic #749
Phase 4 cannot start until Phase 3 delivers (Atlas of the Reach). Phase 3 planning workshop (#748) runs this sprint — but Phase 3 implementation tickets do not start until Sprint 35+.
---
## Sprint Completion Proof
The sprint is done when a developer can do all three of the following in the running game:
1. **Open the implant economics panel** — select any system, see live price data (price_current and price_trend for at least 6 commodities) updating in real time as the economy runs.
2. **Trigger a supply shock from the debug console** — type `econ inject <system_id> shock 0.5 200`, observe the price_current values shift in the economics panel within a few ticks, then recover toward equilibrium over the next 200 ticks.
3. **Mutate α from the debug console** — type `econ param alpha 0.01`, observe slower price adjustment in the panel; type `econ param alpha 0.06`, observe faster adjustment.
None of the above require a character. The economics panel and debug console can be exercised from the main game loop without entering the simulation world — they operate via the IPC bridge on whatever player session is active.
---
## Test Plan
**Phase alignment:** Sprint 34 is Phase 2 delivery infrastructure. Test focus is economic state correctness over IPC, not simulation model correctness (that was Sprint 33 / D-179 stability tests).
| Test | Tier | Owner |
|------|------|-------|
| ObserverSnapshot v21 roundtrip — serialize/deserialize EconomySnapshot | Tier 1 (fixture) | Server |
| EconStateQuery → economy_snapshot present in next snapshot | Tier 2 (bridge) | Server |
| `econ inject` → DebugResponsePayload.success true + price shift observable | Tier 2 (bridge) | Server |
| Economics insert panel renders with fixture EconomySnapshot | Tier 3 (client live) | Client |
| Debug console parses `econ inject` without error | Tier 3 (client live) | Client |
| Star map popup shows population + GDP fields | Tier 3 (client live) | Client |
---
## Open Questions
None blocking implementation. One design question in-flight:
- **Q: Brand layer architecture** (#811 planning) — not blocking Sprint 34 implementation work. Resolved by planning team this sprint; produces Phase 3 tickets for Sprint 35.
+103
View File
@@ -0,0 +1,103 @@
# Sprint 34: Pulse — Planning Tasks
**Goal:** Close Phase 2 — wire the economics simulation into the live game, expose price history and trade flows in the implant, and make the economy observable and tweakable at runtime.
**Branch:** `sprint-34/planning`
**Agents:** Gestalt (systems), Burnelli-Sheldon (economics), Tyre (technical), Miri (worldbuilding), Qatux (documenter), SI (project manager)
## Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #748 | Phase 3: Planetary/moon maps and station layouts — Atlas of the Reach | #747 (in progress → closes this sprint) |
| #811 | Brand layer design | — |
## Context to Read Before Discussion
For **#811 (Brand layer design):**
- `decisions/economics.md` — D-185 (Brands Are Not Commodities), D-184 (Commodity Catalog — what exists), D-173 (Commodity Taxonomy — three-tier structure)
- `decisions/scope.md` — D-131 (broad economic verb vocabulary), D-118 (small business owner starting state — brands are the Phase 3 player layer)
- `wiki/economics/commodities.toml`, `wiki/economics/production_chains.toml`
For **#748 (Phase 3 breakdown):**
- `CLAUDE.md` — Development cascade table (Phase 3 = Planetary/moon maps, deliverable = Atlas of the Reach)
- `decisions/architecture.md` — D-093 (Sova Transit District spatial layout), D-094 (district spatial hierarchy), D-095 (Horizon stations and gate infrastructure)
- Sprint 33 deliverable: `server/data/systems.db` populated with 300+ systems, gate links, currency zones
- `docs/atlas/` — existing atlas content
---
## #811 — Brand Layer Design
**Type:** Planning discussion — produces a D-record in `decisions/economics.md`
**What this is:** The brand/luxury goods system sits on top of the commodity layer (D-185 confirms brands are NOT commodities). Brands consume commodities as inputs. Brand pricing is driven by cultural/emotional/want mechanics, not tâtonnement. This design work answers the Phase 3 question: how does a player engage with the economy as a participant (producer/trader/brand-builder) rather than an observer?
**Discussion rounds:**
**Round 1 — Inventory (what exists, what is missing)**
- What is the full design space of "brand" in the Reach? (Gestalt, Miri)
- What D-records already constrain brand design? (Tyre reads economics.md, scope.md)
- What is the player's economic verb set when brands exist? (Burnelli-Sheldon, Gestalt)
**Round 2 — Proposals**
- Brand representation: is a brand a DB entity, a modifier on a commodity, or a separate production chain layer? (Tyre, Burnelli-Sheldon)
- Cultural pricing model: how does a brand's cultural origin affect demand across currency zones? (Miri, Gestalt)
- Player access: what verbs does a player have toward an existing brand vs. founding one? (Gestalt)
**Round 3 — Convergence**
- Draft one D-record covering: brand representation in the data model, cultural demand pricing, player access verbs, and the boundary with Phase 2 commodity tâtonnement
- SI creates follow-up implementation tickets for Phase 3 sprint
**Output:** D-NNN in `decisions/economics.md` (claim ID via `tooling/db/decision claim D economics "Brand layer architecture"`). Qatux files the record. SI creates 2-4 Phase 3 implementation tickets from the decision.
**CONSTRAINT:** This design session covers brand layer architecture only. No character creation, no tycoon states, no apartment generators. Phase 4 work is out of scope until Phase 3 delivers.
---
## #748 — Phase 3 Planetary Maps Breakdown Workshop
**Type:** Planning discussion — produces a sprint-ready ticket breakdown for Phase 3
**What this is:** Phase 3 deliverable is the Atlas of the Reach (implant app) — region-level maps at hundreds-of-km scale. Cities, rivers, mountains, rail lines, gate/portal locations, road hierarchy, named areas. This workshop answers: what is the minimal scope for a shippable Phase 3, and what tickets does it generate?
**Timing:** This discussion runs AFTER the server team confirms Phase 2 is closing (economics in-game, IPC bridge live). Do not start this discussion until Sprint 34 server tickets are at least in_progress.
**Discussion rounds:**
**Round 1 — Inventory**
- What does Phase 3 require that does not exist? Read `docs/atlas/`, existing world data in `server/data/systems.db`. (Miri, Tyre)
- What systems from Phase 2 does Phase 3 build on (gate network, system data, planet_class)? (Gestalt, Tyre)
- What is the rendering target? (Implant app panel — same component library as economics panel?) (Tyre)
**Round 2 — Scope definition**
- Define the MVP Atlas: which systems get maps first? (Miri — Sova/Krenn as canonical first-system per D-036)
- Data authoring pipeline: how are planetary maps authored? Hand-drawn overlays on procedural heightmaps? Pure procedural? (Miri, Gestalt)
- Implant app design: what does the Atlas panel look like? Click-through from the star map? (Tyre)
**Round 3 — Ticket breakdown**
- Break Phase 3 into 4-8 implementation tickets across server, client, copy, visual teams
- Assign team and priority to each
- SI creates the tickets and blocks them appropriately under #748
**Output:** 4-8 new tickets (server + client + copy + visual) with team assignments, priorities, and explicit dependencies. SI creates them immediately at round end.
---
## Dependency Chain
```
#811 (brand layer design) — run early in sprint, unblocks Phase 3 planning
#748 (Phase 3 breakdown) — run after server Sprint 34 tickets are in_progress
```
## PR Workflow
Planning branch produces decisions and ticket updates only — no code. Commit decisions and close tickets:
```bash
tea pr create --repo jpmschweitzer/settled-reach --login schweitz \
--title "planning(economics): brand layer design and Phase 3 breakdown" \
--description "Sprint 34 planning work" \
--base main --head sprint-34/planning
```
+123
View File
@@ -0,0 +1,123 @@
# Sprint 34: Pulse — Server Tasks
**Goal:** Close Phase 2 — wire the economics simulation into the live game, expose price history and trade flows in the implant, and make the economy observable and tweakable at runtime.
**Branch:** `sprint-34/server`
**Agents:** Dudley (simulation), Tyre (architecture)
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #810 | Event input port implementation | #809 (done) |
| #821 | Integrate econ-sim into game server tick loop | #810 |
| #822 | Expose economy state over IPC bridge to client | #821 |
| #823 | Economics debug command handler — event injection and parameter mutation | #821 |
## Key Decisions
- `decisions/economics.md` — D-178 (model architecture — Leontief + tâtonnement + agents), D-179 (stability criteria), D-180 (event input port — EconEvent struct and visibility modes), D-181 (7-signal vocabulary per node), D-183 (iterative dev cycle)
- `decisions/architecture.md` — D-020 (IPC architecture — ObserverSnapshot + PlayerAction), D-031 (tick-to-time mapping — 10 ticks = 1 game-minute)
## Notes
### #810 — Event input port implementation
The EconEvent struct (D-180) must be added to `tooling/econ-sim/src/model.rs` or a new `events.rs` module. The port is the typed interface through which all external disruptions enter the simulation. An event carries:
```
EconEvent {
target: Node | NodeSet | Corridor | TradeRoute | Currency | Commodity,
effect: ProductivityMultiplier | CapacityMultiplier | DemandShock | ExchangeShock,
duration: ticks,
visibility: Global | Proximate(hops) | Disclosed(specific_nodes) | Hidden,
}
```
Visibility modes are defined in D-180. For this sprint, only `Global` and `Proximate` need to be exercised — `Hidden` is Phase 3 territory (requires the player inspect verb). The port must accept events from: (a) the server tick loop (#821), and (b) debug commands (#823). Test: inject a supply shock, verify cascade propagates and prices recover within 200 ticks per D-179 Test 3.
### #821 — Integrate econ-sim into game server tick loop
The econ-sim is currently a standalone CLI binary at `tooling/econ-sim/`. This ticket makes it run inside the server process. Approach:
1. Extract the simulation logic from `tooling/econ-sim/src/main.rs` into a reusable library crate (e.g. `tooling/econ-sim/src/lib.rs` or a new `server/src/economy/` module — Tyre to decide the crate boundary).
2. Add a `bevy_ecs` `System` that advances the economy N ticks per game tick (rate TBD — likely 1 economy tick per 10 game ticks given D-031 tick-to-time mapping).
3. Store the current economy state as a `Resource` in bevy_ecs so downstream systems (#822, #823) can query it.
4. Economy state must include all 7 D-181 signals per active node so the bridge can later serialize the relevant subset.
Key files: `server/src/simulation/ticker.rs` (where per-tick systems run), `tooling/econ-sim/src/model.rs` (simulation state), `tooling/econ-sim/src/trade.rs` (tâtonnement step). The DB at `server/data/systems.db` is already populated from Sprint 33.
Do NOT load the econ DB on every tick — load once at server startup into the bevy_ecs Resource.
### #822 — Expose economy state over IPC bridge to client
Extend `ObserverSnapshot` to version 21 with an `economy_snapshot` field:
```rust
#[serde(default)]
pub economy_snapshot: Option<EconomySnapshot>,
```
`EconomySnapshot` carries per-system data for the client's economics panel (#824). Phase 2 deliverable is D-181 signals 12 only (price_current, price_trend). Struct sketch:
```rust
pub struct EconomySnapshot {
pub tick: u64,
pub nodes: Vec<EconNodeSnapshot>,
}
pub struct EconNodeSnapshot {
pub system_id: u32,
pub commodity_id: u32,
pub price_current: f64,
pub price_trend: f64, // delta over last N ticks
}
```
Add `EconStateQuery` to the `PlayerAction` enum for on-demand pulls — the client does not need economy data every tick (that would balloon snapshot size). The server responds to `EconStateQuery` by populating `economy_snapshot` on the next snapshot. Without a query, `economy_snapshot` is `None`.
Update `PROTOCOL_VERSION` to 21 in `server/src/bridge/types.rs`.
### #823 — Economics debug command handler
Extend `DebugCommandKind` in `server/src/bridge/types.rs` with three new variants:
```rust
/// Inject an economic event into the running simulation.
InjectEconEvent {
system_id: u32,
commodity_id: Option<u32>, // None = system-wide
effect: EconDebugEffect,
magnitude: f64,
duration_ticks: u32,
},
/// Mutate a tâtonnement parameter at runtime.
SetEconParam {
param: EconParamKind, // Alpha | Beta | CorridorFriction { system_a, system_b }
value: f64,
},
/// Return all 7 D-181 signals for a named system.
GetEconState {
system_id: u32,
},
```
Wire these into the existing debug command dispatch in `server/src/simulation/` (wherever `DebugCommandKind` is matched). Return results via `DebugResponsePayload.text` as a human-readable multi-line string. Blocked by #821 (economy resource must exist to query or mutate).
## Dependency Chain
```
#810 (event port) → #821 (server tick integration) → #822 (IPC exposure)
→ #823 (debug command handler)
```
#822 and #823 are parallel after #821 completes.
## PR Workflow
```bash
tea pr create --repo jpmschweitzer/settled-reach --login schweitz \
--title "feat(simulation): economics in-game tick loop and IPC bridge" \
--description "Sprint 34 server work" \
--base main --head sprint-34/server
```