Files
settled-reach/docs/workshops/planet-down-cascade/burnelli-sheldon-round1.md
T
jpmschweitzerandClaude Opus 4.6 b9fd75b840 docs(workshops): planet-down cascade workshop + misc stray files
Planet-down cascade workshop (3 rounds, 5 agents): layer-by-layer
generation from empty world through population overlay, city planning,
and street rendering. Includes consultant review by Troblum.

Also commits: pre-Sprint-35 DB backup, Claude Code team-mode tmux
test log (team-test.md).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-03 20:18:30 +02:00

487 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Round 1 — Burnelli-Sheldon: Economics Inventory and Amendment 6 Analysis"
description: "Economics domain inventory for the planet-down cascade workshop. Question triage, Amendment 6 weight table critique with proposed alternative, and economic field mapping per layer."
type: workshop
status: active
workshop: planet-down-cascade
agent: burnelli-sheldon
round: 1
created: 2026-05-01
---
# Round 1 — Burnelli-Sheldon: Economics Inventory and Framing
This document is my Round 1 contribution to the planet-down cascade workshop. I'm
working from the Brief, the Consultant Review amendments, the four prior generation-cascade
rounds, and the existing systems.db schema. My job this round: inventory the open
questions from an economics perspective, triage them by difficulty and prerequisite
structure, and deliver a concrete alternative to the 10×9 weight table that Amendment 6
has unlocked for revision.
---
## 1. What the Amendments Change for My Domain
Before the question inventory, the amendments require me to update my prior assumptions.
### Amendment 1 (Three-Tier Execution Model) — Clean Win for Economics
The brief had conflated "Layer 1-2 stored in systems.db" with "economic sim needs Layer
1-2 data." Amendment 1 correctly separates them:
- **Economic simulation runs on system-level aggregates** — `economic_tier`, `corp_presence`,
`corp_financial_state.health_metric`, commodity flows, gate connectivity. All of this
is already in systems.db from build-time generation. The sim does not need to know
where a mining camp sits on a planetary surface to compute inter-system commodity
pricing.
- **Layer 1-2 spatial data** — drainage, settlement positions, road graphs, TerritorialStatus —
is consumed only by Layer 3 city planning and Layer 4 tile rendering. Neither of those
feeds back into the economic simulation; they read from it.
This is the correct separation. My Round 4 mapping of "economic fields at Layer 2" still
holds — those fields are read by the Layer 2 generator as inputs to settlement placement.
But the Layer 2 generator is now a runtime background process reading from systems.db
snapshots, not a Python batch process. The economics data it reads is already there.
**What this changes:** `generate_regional.py` as designed in Tyre's Round 3 becomes a
reference/validation tool. The algorithms I propose must be implementable in Rust on a
background thread, without Python-specific dependencies.
### Amendment 3 (Fully Generative Placement) — New Question Required
L1-Q1, L2-Q1, and CL-Q4 (all variants of "authored rivers vs. generated network" and
"anchor vs. re-derive city positions") are eliminated. Every city position is now
generator-derived. This adds two new questions:
- **Attractor-matching algorithm**: N named cities with known economic roles must be
matched to M geographic attractors. This is my primary Layer 2 algorithm contribution.
- **Name reservation fulfillment**: How does the generator know which city name resolves
to which generated position? This is an architecture question (Tyre) with economics
constraints (I need to flag which cities are "locked" because corporate cross-references
in systems.db point to them by name).
### Amendment 6 (10×9 Weight Table Unlocked) — See §4 Below
The weight table is no longer a given fact. The lead's challenge is correct and I'll
address it in full in §4.
---
## 2. Question Inventory — By Status
### Eliminated (no workshop resolution needed)
| Question | Why eliminated |
|----------|---------------|
| L1-Q1 | Amendment 3: rivers are fully generated, no authored network |
| L2-Q1 | Amendment 3: all city positions are generator-derived |
| CL-Q4 | Amendment 3: same as L1-Q1 |
### Economics Primary — I Own These
| Question | Type | Prerequisite for |
|----------|------|-----------------|
| **L1-Q4** (biome probability prior) | Novel design | Nothing downstream blocks on this; pure quality improvement |
| **L2-Q2** (sub-settlement placement algorithm) | Novel design + data schema | L2-Q6 (flag storage), Layer 3 corp district intensity |
| **L2-Q4** (hinterland shape algorithm) | Novel design | Land use grid → Layer 3 city context |
| **L2-Q5** (TerritorialStatus thresholds) | Novel design (quantitative) | Paula's political framing; snapshot accuracy |
| **L2-Q6** (latent settlement flag storage) | Data/schema | Runtime active/ghost status across all settlement types |
| **L3-Q4** (topographic constraints on zoning) | Novel design | Blocks L3-Q5 derivation unless we agree topo is advisory only |
| **L3-Q5** (prosperity_baseline formula) | Novel design (quantitative) | Layer 3 minimum viable output |
| **L3-Q7** (port/station direction) | Data/schema | Deferred — not min viable scope |
| **Amendment 6** (district mix alternative) | Novel design | ALL of Layer 3 — this is the zoning foundation |
| **New: Attractor-matching algorithm** | Novel design | L2-Q2 depends on it |
### Economics Advisory — I Contribute, Others Lead
| Question | Who leads | My input |
|----------|-----------|---------|
| L3-Q1 (FoundingOrientation grid orientation) | Gestalt | prosperity gradient direction = my input |
| L3-Q2 (political archetype spatial arrangement) | Paula | economic role shapes arrangement alongside political type |
| L3-Q6 (town vs. city code path) | Tyre | unified path preferred — I have no economics objection |
| L4-Q1 (economics-variable rendering mechanism) | Tyre + Gestalt | my input: threshold-crossing, not per-tick |
| L4-Q2 (condition update trigger) | Tyre | my input: threshold thresholds I can specify |
| L4-Q6 (prosperity_delta architecture) | Paula | I co-own the field definition |
| CL-Q1 (prosperity_baseline vs. current naming) | All | I proposed the field names; agree to lock them |
| CL-Q2 (regional land-use evolution) | Tyre | I proposed the resolution boundary in R4-B2 |
| CL-Q3 (ruin lifecycle) | Paula | Amendment 5: emergent only, no dedicated mechanics |
### Independent (do not block other questions)
L1-Q4, L3-Q7, and CL-Q3 can all be answered or deferred without blocking anything else.
### Prerequisite Questions (must resolve first)
1. **Amendment 6 / district mix** — blocks all of Layer 3 algorithm design. Everything
about zoning, prosperity gradients, and block skeletons depends on knowing the
district type distribution method.
2. **Attractor-matching algorithm** (new from Amendment 3) — blocks L2-Q2 sub-settlement
placement, since camps are placed relative to tether cities, and tether cities are now
generator-placed.
3. **CL-Q1** (field naming lock) — blocks all Layer 3 and Layer 4 algorithm descriptions
that need to reference these fields.
---
## 3. What Algorithms Exist vs. What Is Novel
### Reusable from Prior Work
**From Round 3 / Round 4 — economic field mapping:**
The `bodies`, `system_economy`, `corp_presence`, `system_fiscal`, `corp_financial_state`
table reads are defined and stable. The 6-field minimum read set for `CityGenerationContext`
is confirmed. These are not novel design work — they are schema reads.
**From Round 4 — determinism split:**
The layout-vs-appearance split is confirmed. Seed-locked = positions. Economics-variable =
tile conditions, lighting, activity states. This is done. CL-Q2 (regional land use
resolution boundary) I recommended in Round 4-B2: coarse biome-cell resolution can update
at runtime; city-internal layout never changes. I hold this position.
**From Round 4 — latent settlement principle:**
Settlement positions are seed-locked at Layer 2. Active/ghost status is runtime
economic sim state. The four settlement types (mining camps, trade waypoints,
agricultural nodes, shadow nodes) and their trigger conditions are specified. This
is not novel design work for Round 1 — it's a carry-forward.
**From the brief — D-C4 district count formula:**
`max(1, floor(city.population / 50_000))`, log-scaled, WorldTier caps, capital bonus.
This is locked and reusable.
### Novel Design Work Required This Round
**1. District mix algorithm (Amendment 6)** — the primary economics deliverable for
this workshop. See §4 for my full proposal.
**2. Attractor-matching algorithm** — new question from Amendment 3. Economic role
determines which geographic attractor is the right match for each city. I have a
framework for this (comparative advantage matching); see §5.
**3. Prosperity gradient formula (L3-Q5)** — the formula is sketched in the brief
but needs topographic interaction defined. My proposal: topography sets gradient
DIRECTION, `distribution_index` sets gradient MAGNITUDE. A stratified city on a hill
has elite zones at the top with a steep gradient. A moderate city on a hill has mixed
zoning across elevations with a shallow gradient.
**4. TerritorialStatus thresholds (L2-Q5)** — quantitative thresholds need values.
Paula owns the taxonomy; I can supply the economic proxies for each tier.
### Data/Schema Questions Only (no algorithm)
**CL-Q1** — just a naming lock. `prosperity_baseline`, `prosperity_current`,
`prosperity_delta` (derived). I hold the definitions from my Round 4 document.
**L2-Q6** — latent settlement flag storage. My Round 4 recommendation: option (b),
Phase 3 output table. In the three-tier model, this becomes a runtime background
generation output stored in session DB, not systems.db. No change to the algorithm;
just where the output lands.
**L3-Q7** — port/station direction. Feasible from systems.db `stations` table
(`orbits_body_id` + atlas body grid coordinates). Recommended deferred for minimum
viable scope.
---
## 4. Amendment 6: Why the 10×9 Table Is Wrong and What Replaces It
The lead's challenge is economically exact. I'll state the theorem clearly, then
propose the replacement.
### The Theorem: Concentrated Labor Creates Service Demand
When workers concentrate in a settlement, service industries emerge to serve them —
regardless of what those workers produce. This is not optional. It is a consequence
of basic human needs. Miners need food, clothing, medical care, and — critically —
social venues. They drink. They gamble. They fight and need someone to stitch them up.
The company may own the tavern (company town), the union may run the recreation hall
(labour-movement town), or it may be informal (frontier dive), but the entertainment
function exists.
The 10×9 table violates this theorem by assigning zero weight to entertainment for
mining, extraction, and energy economic roles. A real mining town with zero entertainment
establishments either just opened yesterday or is a forced-labour camp. Neither is the
default.
What the table actually encodes is what the settlement *produces*. What it should encode
is *how* the settlement configures the services it necessarily has.
### The Three-Component Replacement
**Component 1: Population Tier — Baseline District Guarantees**
Every inhabited settlement receives a minimum set of district types determined by
population. These are non-negotiable floors because the economics of human settlement
make them inevitable:
| Settlement Tier | Population | Guaranteed District Types |
|----------------|-----------|--------------------------|
| Outpost | 50–999 | Residential + Mixed (combined commerce/basic services) |
| Town | 1,000–9,999 | + Commercial (dedicated) |
| City | 10,000–99,999 | + Entertainment (character varies by role) |
| Large City | 100,000+ | + Administrative (dedicated) |
These floors apply *before* the economic role weights are applied. If D-C4 formula
gives a 1-district city, the single district is Mixed (it carries all functions). If
it gives 2 districts, one is Residential and one is Mixed-plus-specialty. At 3+
districts, dedicated Commercial and Entertainment emerge as separable entities.
Note: this integrates cleanly with the D-C4 district count formula. The guarantee
is not "always build 5 districts." It is "whatever districts you DO build, allocate
these types first before filling with production-role specialty."
**Component 2: Economic Role — Multiplier on Weight, Not On/Off Switch**
Once the guaranteed minimums are placed, the remaining district slots are filled using
a weight multiplier table. Key change from the 10×9 table: **no weight is ever zero**.
Minimum weight is 0.2, meaning "present but small/rough." Maximum is 3.0. This encodes
economic role as a proportion and character modifier, not a presence/absence gate.
Proposed multiplier table (replaces the 10×9 weight table):
| economic_role | Res | Com | Ind | Adm | Log | Ent | Mix | Trn | Spe |
|--------------|-----|-----|-----|-----|-----|-----|-----|-----|-----|
| manufacturing | 1.5 | 0.4 | 2.5 | 0.5 | 1.5 | 0.4 | 0.6 | 0.5 | 0.2 |
| agricultural | 2.0 | 0.8 | 0.4 | 0.8 | 1.8 | 0.5 | 1.2 | 0.4 | 0.2 |
| extraction | 1.5 | 0.4 | 2.5 | 0.3 | 2.0 | 0.5 | 0.8 | 0.7 | 0.2 |
| transit | 0.8 | 1.5 | 0.4 | 0.4 | 1.8 | 1.0 | 1.2 | 2.0 | 0.2 |
| research | 1.5 | 0.5 | 0.4 | 1.2 | 0.4 | 0.6 | 0.8 | 0.2 | 2.5 |
| commercial | 1.2 | 2.5 | 0.4 | 0.5 | 0.8 | 1.2 | 1.2 | 0.3 | 0.2 |
| service_mixed | 1.8 | 1.5 | 0.4 | 0.8 | 0.5 | 1.2 | 1.5 | 0.2 | 0.2 |
| mining | 1.5 | 0.4 | 2.0 | 0.2 | 2.5 | 0.5 | 0.7 | 0.5 | 0.2 |
| frontier | 2.5 | 0.8 | 0.8 | 0.4 | 1.5 | 0.5 | 1.2 | 0.2 | 0.2 |
| energy | 0.8 | 0.2 | 1.5 | 0.5 | 2.0 | 0.2 | 0.5 | 0.5 | 2.5 |
The mining row now has Ent = 0.5 (half baseline, but present) and Com = 0.4.
The energy row has Ent = 0.2 (minimal, but not zero). A large energy facility has
workers, and those workers have somewhere to socialize — it's just a spartan canteen
and a gym, not a cultural district.
**How to apply the multiplier table:**
1. Apply population tier guarantees. Mark those district slots as filled.
2. Remaining district slots = D-C4 total count minus guaranteed minimums.
3. Normalize the multiplier table row for this city's economic role to sum to 1.0.
4. Distribute remaining slots by normalized weights, rounding to integers.
5. Apply `political_archetype` modifiers on top (existing mechanic, unchanged).
6. Apply `distribution_index` to set the prosperity gradient magnitude across the
resulting district set.
**Component 3: Settlement Age — Character Modifier**
`bodies.founding_age_years` tells us how long a settlement has had to develop its
services. New settlements are production-focused and sparse. Old settlements have
had time for secondary and tertiary industries to emerge.
I do NOT propose that age changes district count (that's population-driven) or district
presence (that's the guarantee floor). Age modifies the **character and quality** of
districts within a given type:
| founding_age_years | Character effect |
|-------------------|-----------------|
| < 50 (new) | Entertainment = bare-minimum (company rec hall or single dive bar) |
| 50–150 (established) | Entertainment = working-class functional (taverns, union halls, local sports) |
| 150–300 (mature) | Entertainment = differentiated (high/low-end venues, cultural institutions beginning) |
| 300+ (old) | Entertainment = layered (heritage venues, class-stratified nightlife, institutions) |
This is a character descriptor attached to the district, not a structural change to
district count or type. The renderer and content system read it to choose tile variants
and NPC archetypes. The generator doesn't need to do extra layout work for this.
### The Combined Guarantee: No Zero-Service Settlements
Under this model:
- A mining outpost (population 200) has: Residential + Mixed. The Mixed district is
the supply store, the first-aid shack, and the bar, packed into one cluster.
- A mining town (population 5,000) has: Residential + Commercial + Entertainment
(guaranteed) + Ind + Log (from weight table, dominant). The entertainment district
is rough bars and a gambling hall, not a theatre.
- A mining city (population 80,000) has 1–2 Industrial, 1–2 Logistics, 1 Residential,
1 Commercial, 1 Entertainment (rough but present), 0–1 Mixed from remaining slots.
That's 6–7 districts. All production-role character, but no zero-service gap.
The lead's intuition is exactly right: mining towns have rough entertainment because
miners drink. This model produces that outcome mechanically.
---
## 5. New Question: Attractor-Matching Algorithm
Amendment 3 eliminates authored city positions and requires the generator to match
N named cities (with known economic roles) to M geographic attractors. From an
economics standpoint, this is a constraint satisfaction problem with a clear
theoretical framework: comparative advantage assignment.
**The economic principle:** Each city has an economic role that implies a preferred
attractor type. Agricultural cities prefer arable plains + water access. Mining cities
prefer resource concentration sites + transport. Transit cities prefer natural
chokepoints — mountain passes, river crossings, harbor narrows.
**Proposed matching algorithm sketch:**
```
For each body_id with N named cities in atlas_cities:
1. Run Layer 1 to completion: get attractor set M with typed features
(RiverConfluence, CoastalHarbor, MountainPass, ArablePlain,
ResourceConcentration, Defensible, NaturalBarrier)
2. Score matrix: S[city_i, attractor_j] = compatibility(city.economic_role, attractor.feature_type)
3. Hard constraints: if corporations.headquarters_body = city, that city must be
placed at an attractor compatible with its economic role (name-locked)
4. Solve: maximize sum of compatibility scores subject to one-city-per-attractor
(Hungarian algorithm or greedy by largest gap if N << M)
5. Overflow: if M < N (more cities than attractors), generate synthetic attractors
as secondary sites (river bends, coastal plains) by seed
```
**Compatibility matrix (partial — sufficient for framing):**
| economic_role | RiverConfl. | CoastalHarbor | MtnPass | ArablePlain | ResourceConc. | Defensible |
|--------------|-------------|--------------|---------|-------------|---------------|------------|
| agricultural | high | medium | low | very high | low | low |
| extraction | low | low | medium | low | very high | medium |
| mining | low | low | medium | low | very high | medium |
| transit | high | high | high | low | low | medium |
| commercial | high | high | medium | medium | low | low |
| research | medium | medium | medium | medium | medium | high |
| manufacturing | medium | medium | low | medium | medium | low |
| frontier | medium | medium | medium | medium | medium | high |
The attractor-matching algorithm is a Layer 2 entry point. It runs after Layer 1
completes for a body and before Layer 2 sub-settlement placement. Its output is:
a mapping from (city_id → attractor_position) that seeds the rest of Layer 2.
This question is new and needs Round 2 algorithm concreteness. For now I'm flagging
the economic framework and the constraint structure.
---
## 6. Economics Field Mapping — Revised for Three-Tier Model
My Round 4 field mapping remains correct in content. What changes under Amendment 1
is *when* each field is accessed:
### Build-Time (systems.db — always available)
| Field | Table | Purpose |
|-------|-------|---------|
| `economic_role` | bodies | Layer 1 biome prior (advisory); Layer 2 hinterland; Layer 3 weight table |
| `settlement_pattern` | bodies | Layer 2 population distribution |
| `founding_age_years` | bodies | Layer 3 district character modifier |
| `economic_tier` | system_economy | Infrastructure density (Layer 2), prosperity baseline (Layer 3) |
| `distribution_index` | system_economy | Prosperity gradient magnitude (Layer 3) |
| `corp_id`, `location_id`, `primary_operation` | corp_presence | Layer 2 settlement triggers; Layer 3 district intensity |
| `health_metric` | corp_financial_state | Layer 2 settlement active/ghost seed state |
| `collection_efficiency` | system_fiscal | Layer 2 shadow node trigger |
| `behavioral_archetype` | corporations | Layer 3 district layout character |
| `headquarters_body` | corporations | Name-locked city constraint (Amendment 3) |
### Runtime Background (Layer 1-2 generation, Rust)
Layer 1-2 reads from systems.db fields above and produces:
- Attractor positions (Layer 1 output, consumed by Layer 2)
- Settlement positions (Layer 2 output, stored in session DB)
- TerritorialStatus and PoliticalTether (Layer 2 output)
- Land use grid (Layer 2 output)
These are not economics tables — they are geography outputs that economics data
shapes. The economic sim does not consume them.
### Runtime On-Demand (Layer 3-4 generation, Rust)
`CityGenerationContext` struct is populated from systems.db at startup — no runtime
query. Layer 3 receives it and uses `economic_role`, `economic_tier`, `distribution_index`,
`corp_presence` count, and `headquarters_system/body` match. That is the 6-field minimum
read set, unchanged.
### Runtime Simulation Variables (read by Layer 4 renderer)
| Signal | Source | Effect |
|--------|--------|--------|
| `prosperity_current` | Economic simulation | Tile condition selection |
| `health_metric` (updated) | Economic simulation | Corporate signage, maintenance state |
| Active/ghost status | Economic simulation | Lighting, activity density |
These are not consumed by the generator. They are render parameters updated by the sim.
---
## 7. TerritorialStatus Thresholds (L2-Q5) — Quantitative Proposal
Paula owns the taxonomy. Here are the economic proxies I propose for threshold
derivation:
| TerritorialStatus | Economic derivation |
|------------------|---------------------|
| **CoreTerritory** | settlement_density ≥ 1 city per province + road maintenance_authority on all connecting edges |
| **FrontierTerritory** | settlement present but road density < 0.5 of CoreTerritory average for this economic_tier |
| **ExtractiveZone** | `ResourceConcentration` feature + `corp_presence` with matching commodity + road to resource but sparse off-corridor |
| **ContestZone** | Two settlement clusters within overlapping territory (distance < 2 × footprint_radius) with different `political_archetype` or dominant_faction |
| **WildernessBuffer** | No settlement placed by Layer 2 algorithm |
| **AbandonedZone** | Settlement placed but `corp_financial_state.health_metric < 0.2` for all operating corps at founding time |
These thresholds are derivable from fields already in systems.db. No new data required.
The key economic inputs are corp presence count and health metric at seed time (not
runtime), plus road graph density.
---
## 8. Open Questions I'm Raising for Round 2
**BS-Q1: Population tier floor table — is the 50-person minimum too low for guaranteed
Entertainment?**
I've proposed Entertainment as guaranteed at City tier (10,000+). A 9,999-person Town
doesn't get a dedicated Entertainment district under this model — it gets some in its
Commercial district. Does that feel right? A 9,000-person mining town with no
Entertainment *dedicated district* but Entertainment-character Commercial seems
plausible. Flag this for Gestalt's "does this feel inhabited" check.
**BS-Q2: How does founding_age_years interact with WorldTier?**
A Waypoint-tier settlement by definition has population < 50. It can't be old enough to
have cultural institutions even if `founding_age_years = 300`. The age modifier needs
to be capped by WorldTier ceiling. Proposed: age modifier only applies at Town tier and
above.
**BS-Q3: The energy row minimum Entertainment weight of 0.2 — is this adequate for
large energy production facilities?**
An energy facility with 200,000 workers has a lot of people who need social services.
At weight 0.2 against a population that produces 4 districts by D-C4, we might get zero
Entertainment districts from the weight allocation (if 0.2 normalized against all the
Log and Spe weights is too small). The guarantee floor rescues this — Entertainment is
guaranteed at City tier. But I want to flag that the weight 0.2 for energy/Entertainment
will produce the minimum possible dedicated Entertainment district, and the guaranteed
floor + character descriptor is doing the real work here, not the weight.
**BS-Q4: Does the attractor-matching algorithm need to handle bodies with no
geographic attractors?**
The consultant review says "if M < N, generate synthetic attractors." This is
algorithmically straightforward. But economically: what does it mean for a body to have
N cities and fewer geographic attractors than cities? It suggests a high-tier economic
world where secondary manufacturing cities exist independent of natural features
(because technology overrides geography). This is plausible for manufacturing, service,
and commercial roles on high-`economic_tier` bodies. The synthetic attractor rule seems
correct: place remaining cities along existing road corridors at seed-derived offsets.
---
## 9. What I Need from Other Participants
**From Gestalt:** The Amendment 6 population tier guarantee table should be evaluated
against "does this produce places that feel inhabited?" at each tier. The economic
logic says the guarantees are correct; Gestalt should verify the fun-and-legibility
layer.
**From Tyre:** The attractor-matching algorithm (§5) needs a concreteness check.
Is the Hungarian algorithm appropriate for this scale (N ≤ 30 cities per body,
M = 50-200 attractors)? What is the performance cost?
**From Paula:** TerritorialStatus thresholds (§7) — do these economic proxies
produce the political texture you need for narrative differentiation? CoreTerritory
vs. FrontierTerritory based purely on settlement density and road maintenance seems
thin for narrative purposes. Is there a political pressure field I'm missing?
**From all:** CL-Q1 (field naming lock) should be confirmed at the start of Round 2
so all algorithm descriptions use consistent field names.