Files
settled-reach/docs/workshops/planet-down-cascade/round-3-notes.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

25 KiB
Raw Blame History

title, author, workshop, round, created
title author workshop round created
Round 3 Notes — Planet-Down Cascade Workshop qatux planet-down-cascade 3 2026-05-01

Round 3 Notes — Planet-Down Cascade Workshop

Compiled from five Round 3 agent files: Gestalt, Tyre, Paula, Burnelli-Sheldon, Ozzie.


1. Resolution of All Round 2 Open Items

Q1 — Mismatch Flag Threshold: RESOLVED (Lead Decision)

Lead decision: Two-tier system.

Tier Threshold Behavior
Soft (MismatchSeverity::Soft) score < 0.35 Logged to generation log; placement proceeds
Hard (MismatchSeverity::Hard) score < 0.15 Assignment overridden to Synthetic { reason: PoliticalDecision }; city placed at Province centroid; FoundingOrientation = AdminFacing; generation proceeds without panic

Implementation detail (Tyre): Hard mismatch is a policy decision, not a generation failure. The city exists but was placed politically rather than geographically. The flag surfaces in developer tooling.

Validation (Burnelli-Sheldon): Thresholds validated against real systems.db body types. Representative cases:

  • agricultural + Defensible (score 2/10 = 0.20): Warning. Farming at a defensible site — unusual but real. Warning is correct.
  • agricultural + NaturalBarrier (score 0): Error. Impossible. Correct.
  • extraction + MountainPass (score 5/10 = 0.50): No flag. Valid. Correct.

Paula's integration: HQ-constrained reservations (corp_id IS NOT NULL with active trade routes) escalate one tier: Warning → Error. A misplaced HQ with active supply chain dependencies is a more serious data quality problem.


Q2 — founding_age → layout_mode: RESOLVED (All Agents Adopted)

All agents adopted the principle. The implementation converges on a new field on DistrictSkeleton, orthogonal to layout_mode (which governs archetype macro-geometry and stays fixed).

Tyre's enum (the stored field):

enum BlockIrregularity {
    Grid,         // Regular 64m × 64m; planned geometry
    SlightlyWorn, // ~10% deviation from grid
    Irregular,    // ~25% deviation; multiple planning generations visible
    Organic,      // No regular grid; emerged rather than planned
}

Derivation (from_age_and_archetype): reference step size varies by archetype — CompanyTown 40 years/tier, AdminCapital 100, FreePort 60, Contested 35, OrganicGrowth 20. Each tier of founding_age_years / step advances one enum value.

Gestalt's complementary weighting: Within each BlockIrregularity tier, the age organic bonus shifts block-edge probability distributions. CompanyTown Industrial districts resist age influence (age_resistance = 0.9); FreePort districts absorb it fully (0.0). Ancient AdminCapitals maintain planned cores while outer rings grow organic.

Ozzie's minimum floor: irregularity_factor minimum 0.05 even for brand-new cities — construction variance means no city is a perfect simulation artifact.

Paula's per-archetype rules:

  • CompanyTown: spine always grid (corporate planning maintained); age deepens character tags not geometry
  • AdminCapital: core Administrative always planned; outer rings accumulate irregularity
  • FreePort: node centers planned; between-node fill organic with age
  • Contested: each faction's half uses its archetype's rules; boundary zone always irregular (0.7+)
  • OrganicGrowth: fixed at 0.8 irregularity; age has no additional effect (already maximally irregular)

Field placement: block_irregularity: BlockIrregularity added to DistrictSkeleton. Set at Layer 3. Consumed at Layer 4. No effect on Phase 2-3 deliverables.


Q3 — Province Boundary Legibility: RESOLVED

Principle agreed by all agents: Province boundaries ARE watershed/ridgeline features produced by D8 drainage. They render as terrain, not political overlays.

Technical solution (Tyre): Pre-computed at build time by Python (generate_atlas.py watershed extraction), stored as float32 UV-space polylines in atlas_province_boundaries table. Renderer loads directly; zero dependency on Rust generation status.

New schema (ARCH-5):

CREATE TABLE atlas_province_boundaries (
    body_id     INTEGER NOT NULL REFERENCES bodies(id),
    province_x  INTEGER NOT NULL,
    province_y  INTEGER NOT NULL,
    boundary    BLOB NOT NULL,
    -- float32 pairs [u0,v0, u1,v1, ...] in atlas UV space (0.0..1.0)
    PRIMARY KEY (body_id, province_x, province_y)
);
CREATE INDEX idx_province_bounds_body ON atlas_province_boundaries(body_id);

Storage: ~82KB/body → ~32MB for 400 bodies.

Map UI specification (Ozzie, Paula):

  • Province boundary = thin watershed/ridgeline rendering from polyline data (not thick colored borders)
  • TerritorialStatus = Province fill color/texture (subtle, readable at glance)
  • CoreTerritory: dense settlement markers, road lines visible
  • FrontierTerritory: scattered markers, road lines thin toward Province edge
  • ExtractiveZone: industrial tinting, road lines heavy toward resource sites
  • ContestZone: contested visual treatment (two-color or cross-hatched)
  • WildernessBuffer: empty, natural terrain only
  • AbandonedZone: reduced markers, ruins indicator

This is a player experience requirement (Ozzie): Province boundary legibility is non-negotiable for TerritorialStatus to communicate to the player. Filed as a Phase 3 map implementation requirement.


Q4 — atlas_city_names Population Path: RESOLVED

Two-tier authorship (Tyre, Paula, Gestalt all aligned):

Tier Source reserved flag Who authors
Authored wiki/worlds/{body_slug}.toml[[cities]] true Miri (wiki authors)
Generated import_economics.py from brand files, corp HQ data false Generator

Authoring format:

# wiki/worlds/nova-kassel.toml
[[cities]]
name = "Port Cassidy"
corp_slug = "meridian-transit"   # nullable
tier_hint = 3                    # nullable
reserved = true

Import pipeline: import_economics.py reads wiki TOMLs, preserves reserved = true rows across reruns, deletes and regenerates reserved = false rows each run. Paula's Stage 03 fulfillment operates on both tiers at runtime.

Paula's schema extension flags: Tyre's ARCH-3 schema is missing population and economic_role columns, both required for attractor priority sorting and compatibility scoring. These must be added. The reserved column's purpose is clarified: it means "wiki-authored canonical name" — not equivalent to corp_id IS NOT NULL.


Q5 / Q6 — Full Multiplier Table and Logistics Column: RESOLVED (D-194 Authoritative)

Burnelli-Sheldon's D-194 (real claimed ID) is the authoritative table. It has 10 economic roles × 9 district types. Tyre's table from Round 2 notes (8×8) and Tyre's Round 3 addition of Logistics are superseded by D-194.

D-194 district type columns: Residential, Commercial, Industrial, Administrative, Logistics, Entertainment, Mixed, Transit, Specialized (9 types)

Burnelli-Sheldon's political archetype modifiers (locked in D-194):

political_archetype Modifiers
CompanyTown Adm 10, Ind +10, Log +5, Res +5
AdminCapital Adm +20, Ent +5, Spe +5, Ind 15
FreePort Com +15, Trn +10, Mix +5, Adm 15
Contested No modifier (competing forces cancel)
OrganicGrowth Mix +15, Res +10, Ind 10, Adm 5

Floor at 3 applied after all modifiers. Paula's FreePort/Administrative flag: FreePort modifier Adm 15 on Transit/Port base Adm = 5 → net 10 → floor applies → value = 3. Correct; floor must be applied after all modifiers are stacked.

Ozzie's new proposal: SyntheticPlacementReason should inform default political archetype when no geographic trigger exists: CorpExpansion → CompanyTown, PoliticalDecision → AdminCapital, PopulationOverflow → OrganicGrowth. Filed for Phase 3 design.


2. D-Record Consolidation

Six real D-record IDs were claimed by Burnelli-Sheldon via the decision CLI. All other agents used placeholder numbering (D-C-XX, ARCH-N, GEN-N, D-C-NAME). Real IDs take precedence where topics overlap.

Real D-Records (Claimed, D-194 through D-199)

ID Title Agent Overlap with placeholders
D-194 Three-Component District Mix Algorithm Burnelli-Sheldon Supersedes D-C28, GEN-3
D-195 Attractor-Matching Compatibility Matrix Burnelli-Sheldon Sub-component of D-C25/GEN-2 (D-C25 covers the full five-phase pipeline; D-195 is the scoring matrix)
D-196 SettlementClass Enum and Active/Ghost Logic Burnelli-Sheldon Supersedes D-C26, GEN-6
D-197 prosperity_baseline Derivation Formula Burnelli-Sheldon Referenced in D-C28 body but not a separate record in other agents' lists
D-198 Economic Simulation Independence from Layer 1-2 Burnelli-Sheldon Implicit in D-C18 (three-tier model) but not separately named
D-199 6-Field Minimum Economic Read Set Burnelli-Sheldon Extends prior workshop's D-C17; updates CityGenerationContext struct

Placeholder D-Records Still Needing Real IDs

These are ready to claim via tooling/db/decision claim D <domain> "title". Grouped by domain:

Architecture (build-time and data model):

Placeholder Title Ready to claim
D-C18 Three-Tier Execution Model Yes
D-C21 Spatial Hierarchy — Eight Tiers with Locked Dimensions Yes
D-C33 / ARCH-1 Heightmap BLOB Storage Schema (atlas_body_heightmaps) Yes
ARCH-2 / D-C34 BodyWorldState Bevy Resource + LRU Cache Yes
ARCH-4 body_radius_km Column on bodies Yes
ARCH-5 Province Boundary Pre-Computation (atlas_province_boundaries) Yes — new this round
GEN-9 atlas_feature_names Schema Yes

Generation algorithms (runtime):

Placeholder Title Ready to claim
D-C19 / GEN-7 Background Generation Priority Queue + Rayon Infrastructure Yes
D-C20 Fully Generative Placement (Amendment 3) Yes
D-C22 / GEN-1 D8 Priority-Flood Drainage Routing Yes
D-C23 Geographic Feature Tag Extraction (7 tags) Yes
D-C24 Sub-Biome Variant Classification Yes
D-C25 / GEN-2 Attractor-Matching Five-Phase Pipeline (references D-195 for matrix) Yes
D-C27 / GEN-5 TerritorialStatus Priority-Ordered Derivation Yes
D-C29 / D-C-FO / D-C-AA FoundingOrientation Enum + AttractorAssignment Enum Yes (may split)
D-C30 / D-C-SA Five Explicit Political Archetype Spatial Patterns Yes
D-C31 / GEN-4 BlockIrregularity from founding_age (Tyre's enum) Yes
D-C32 Tile Condition Threshold Values (0.63/0.43/0.23) Yes
GEN-8 WorldTier Enum Bug Fix Yes — critical, claim first

Narrative (naming and content):

Placeholder Title Ready to claim
D-C-NL Naming Registers Lookup Table (Paula) Yes

3. Pre-Implementation Blockers — Data Quality Flags (Burnelli-Sheldon)

Three data gaps in systems.db that will block implementation immediately. These must be addressed before Phase 3 begins.

Blocker 1: bodies.founding_age_years NULL for All 273 Inhabited Bodies

Component 3 of D-194 depends on this field. It is entirely unpopulated. Phase 1 implementation will run on fallback values only.

Fallback (Burnelli-Sheldon): Derive from system_history.settlement_wave:

settlement_wave founding_age_years (approx) Age bracket
origin 500+ mature
wave_1 350 mature
wave_2 250 established
wave_3 150 established
wave_4 75 young
wave_5 30 nascent
unsettled N/A not inhabited

Action required: Populate bodies.founding_age_years from wiki content as part of wiki/content work. Every inhabited body should have an approximate founding year.

Blocker 2: system_economy.economic_tier and distribution_index NULL for 97% of Systems

290 of 300 system_economy rows have NULL for both fields. D-197 (prosperity_baseline formula) depends on economic_tier.

Fallback (Burnelli-Sheldon):

economic_tier_derived:
  population >= 5B  → 5
  population >= 1B  → 4
  population >= 100M → 3
  population >= 10M  → 2
  else               → 1

distribution_index fallback: "moderate" (NULL → moderate is the baseline)

Action required: Either populate system_economy fields from wiki data, or formally document the fallback derivation as canonical (which removes the need for authored data for most systems). The fallback is economically sound; the lead should decide if it's sufficient for release.

Blocker 3: economic_role Values Not Normalized in bodies Table

Inconsistent values that break the D-194 weight table lookup:

Raw value Canonical Bodies affected
"agriculture" "agricultural" 16 bodies
"resource_extraction" "extraction" 1 body
"coordination" "service_mixed" 2 bodies (including Bunbury pop 800M)
"mixed-agriculture" "agricultural" 1 body
NULL "service_mixed" 1 body

Action required: Add normalization step to import_economics.py as a data validation pass. Run on make regen-db. This is a schema migration, not a source data authoring task.


4. Paula's Schema Consistency Flags

Flag 1: atlas_city_names Missing Required Columns

Tyre's locked ARCH-3 schema lacks population and economic_role columns. Both are required by the Stage 2 name fulfillment pipeline:

  • population: needed to sort named cities for attractor assignment priority (largest first within Tier B/C)
  • economic_role: needed for compatibility scoring (hard constraints H1-H4 + soft constraint table)

Resolution: Add both columns to ARCH-3 schema. Paula's D-C-NR has the extended schema. The reserved column is clarified as "wiki-authored canonical name" (not redundant with corp_id).

Flag 2: Paula's Agricultural Commercial Weight Concern

Paula flagged the Round 2 table's Agricultural Commercial weight of 18 as too high. Resolved by D-194: Burnelli-Sheldon's real table sets Agricultural Commercial = 12. Paula's concern is addressed.

Flag 3: FreePort Modifier Floor Interaction

FreePort modifier on Administrative: 15 (D-194). For Transit/Port economic_role, Administrative base weight = 5. After modifier: 5 15 = 10 → floor at 3. Confirmed: floor must be applied after all modifiers are stacked, not before.

Flag 4: Contested Archetype Weight Modifier

Paula flagged this as missing. Resolved by D-194: Contested = no modifier ("competing forces cancel"). This is the most narratively coherent answer — two competing planning authorities produce a district mix that reflects neither faction's priorities.

Flag 5: corporate_presence_score Derivation Undefined

Burnelli-Sheldon flagged this in their own document: corporate_presence_score is used by TerritorialStatus but its derivation formula is not specified. Proposed: sum(health_metric for corps in province) / corp_count. Zero corps = score of 0. Tyre must confirm in implementation spec.


5. Complete Ticket Dependency Chain

Consolidated from Gestalt's and Tyre's Round 3 tickets. Tyre's more granular breakdown takes precedence.

Tier 0 — Prerequisites (No Dependencies; All Can Start Immediately in Parallel)

Ticket Work Effort
BUG-WorldTier Fix WorldTier enum: Peripheral|Connected|CoreEpicenter|Regional|Backwater|Passage|Waypoint; update all match arms 0.5d
SCHEMA-bodies body_radius_km REAL column on bodies 0.25d
SCHEMA-heightmaps atlas_body_heightmaps DDL 0.25d
SCHEMA-city-names atlas_city_names DDL + index (extended schema with population, economic_role) 0.25d
SCHEMA-feature-names atlas_feature_names DDL + index 0.25d
SCHEMA-province-bounds atlas_province_boundaries DDL + index 0.25d

All SCHEMA-* tickets can be grouped into a single migration PR.

BUG-WorldTier is a hard prerequisite blocker for every generation implementation ticket.

Tier 1 — Python Pipeline (Depends on Tier 0 Schemas)

Ticket Work Effort Depends on
PY-heightmap-import generate_atlas.py: BLOB-pack elevation float32; INSERT into atlas_body_heightmaps 1d SCHEMA-heightmaps
PY-province-bounds generate_atlas.py: watershed extraction from DEM; store boundary polylines 2d SCHEMA-province-bounds, PY-heightmap-import
PY-city-names-authored import_economics.py: read wiki/worlds/*.toml [[cities]]; INSERT reserved=true 1d SCHEMA-city-names
PY-city-names-corp import_economics.py: generate corp-derived name rows for under-quota bodies 1d PY-city-names-authored
PY-body-radius import_economics.py: populate body_radius_km 0.5d SCHEMA-bodies
PY-economic-role-normalize import_economics.py: add economic_role normalization validation step (blocker 3) 0.5d

Tier 2 — Rust Type Definitions (Depends on Tier 0)

Ticket Work Effort Depends on
RS-types-worldtier Fix WorldTier enum in Rust; update all match arms 0.5d BUG-WorldTier
RS-types-settlement SettlementClass, MismatchSeverity, AttractorAssignment, SyntheticPlacementReason 0.5d RS-types-worldtier
RS-types-district Add BlockIrregularity to DistrictSkeleton; SpatialArchetype, EconomicRole, updated DistrictType enum 0.5d
RS-types-territorial TerritorialStatus with correct variants 0.5d
RS-types-city-ctx Finalize CityGenerationContext with all new fields (see D-199) 1d RS-types-settlement, RS-types-territorial

Tier 3 — Rust Core (Depends on Tier 1 + Tier 2)

Ticket Work Effort Depends on
RS-heightmap-load load_heightmap() via bytemuck; integration into BodyWorldState init 0.5d PY-heightmap-import, RS-types-city-ctx
RS-body-state BodyWorldState struct + GenerationCache Bevy Resource + LRU(50) 1.5d RS-heightmap-load
RS-drainage D8 priority-flood drainage; attractor extraction; RiverNetwork construction 3d RS-body-state
RS-attractor-types GeographicAttractor, AttractorType, CompatibilityMatrix 0.5d RS-types-settlement

Tier 4 — Generation Algorithms (Depends on Tier 3)

Ticket Work Effort Depends on
RS-attractor-assign Five-phase attractor assignment + D-195 compatibility matrix + Hungarian + synthetic overflow + mismatch flags 4d RS-drainage, RS-attractor-types, PY-city-names-authored
RS-district-mix D-194 three-component district mix + locked multiplier table + archetype modifiers (floor-after-modifiers) 3d RS-attractor-assign, RS-types-district
RS-territorial TerritorialStatus priority-ordered derivation; ProvinceWorldState population 2d RS-attractor-assign
RS-block-irregularity BlockIrregularity::from_age_and_archetype() + DistrictSkeleton integration 1d RS-district-mix
RS-tile-conditions Threshold cache with 0.63/0.43/0.23 invalidation for tile conditions 1.5d RS-district-mix

Tier 5 — Background + UI (Depends on Tier 4)

Ticket Work Effort Depends on
RS-bg-queue GenerationQueue + rayon thread pool + priority ordering 2d RS-body-state
RS-aho-corasick SystemNameIndex + text scanning → generation trigger 1d RS-bg-queue
UI-province-bounds Godot planetary map: load atlas_province_boundaries; render as natural polylines + TerritorialStatus fill 2d PY-province-bounds

Dependency Graph (Critical Path)

SCHEMA-heightmaps
  → PY-heightmap-import
  → RS-heightmap-load
  → RS-body-state
  → RS-drainage
  → RS-attractor-assign
  → RS-district-mix
  → RS-tile-conditions

Critical path effort: 0.25 + 1 + 0.5 + 1.5 + 3 + 4 + 3 + 1.5 = 14.75 dev-days

Total effort (all tiers, parallel where possible): ~33 dev-days

Parallel acceleration (two-agent split — Python team / Rust team): calendar time ~20 days


6. New Items Introduced in Round 3

Province Boundary Pre-Computation (ARCH-5 — New)

Not in prior rounds. Tyre introduced the atlas_province_boundaries table and the build-time Python extraction approach. This is a new schema ticket (SCHEMA-province-bounds) and a new Python ticket (PY-province-bounds) that was not in any Round 1-2 discussion.

Naming Registers Lookup Table (Paula — New)

Paula's D-C-NL introduces the full naming architecture: seven registers (Geographic, Functional, Commemorative, Aspirational, Folk, Corporate, Dual), a lookup table by (DistrictType, WorldTier), and political archetype overrides. Names themselves are content work (Mellanie's domain); the register selection architecture is a locking decision.

SyntheticPlacementReason → Political Archetype Mapping (Ozzie — New Proposal)

Ozzie proposes that when a settlement lacks a geographic trigger, SyntheticPlacementReason should determine its default political archetype: CorpExpansion → CompanyTown, PoliticalDecision → AdminCapital, PopulationOverflow → OrganicGrowth. This is a proposal; not yet locked.

economic_role Normalization Ticket (Burnelli-Sheldon — New)

PY-economic-role-normalize is a new ticket not identified in prior rounds. It is a pre-implementation blocker.


7. Open Items After Round 3

For Lead Resolution

Item What's needed
corporate_presence_score derivation Confirm formula: sum(health_metric for corps in province) / corp_count
SyntheticPlacementReason → political archetype (Ozzie proposal) Lock or defer to Phase 3 design
L3-Q7 (port/station direction) Paula designed mechanism; Ozzie formally requested for Phase 4 scope; Gestalt classified deferred; lead final call
Province watershed algorithm detail spec Before PY-province-bounds ticket begins; brief technical sidequest recommended
Q4 orbital station type SpatialArchetype::SpaceStation as sixth variant? Deferred; lead disposition
Populate bodies.founding_age_years Content work; wiki authors (Miri domain)
Confirm system_economy fallback is sufficient for release Formal acknowledgment that 97% NULL is acceptable with fallback derivation
Contested/OrganicGrowth archetype modifiers D-194 is locked (Contested = no modifier, OrganicGrowth = Mix+15/Res+10/Ind-10/Adm-5). This is resolved.

For Implementation Tickets

  • BUG-WorldTier: claim and file immediately (hard prerequisite for everything)
  • All placeholder D-records: claim real IDs before decisions/ domain files are written
  • Extended atlas_city_names schema: add population and economic_role before PY-city-names-authored begins

Items Confirmed Closed — No Further Discussion

Item Closed by
Mismatch flag threshold Lead two-tier decision
founding_age → BlockIrregularity All agents adopted; Tyre's enum is the stored field
Province boundary legibility ARCH-5 + map UI spec
atlas_city_names population path Two-tier authorship, both via import_economics.py
Full multiplier table D-194 authoritative (10 roles × 9 types)
Contested archetype modifier D-194: no modifier
OrganicGrowth archetype modifier D-194: Mix +15, Res +10, Ind 10, Adm 5
prosperity_baseline vs. prosperity_current field naming D-197 locks both names; delta is always derived
Self-contained district generation Confirmed D-194
SeedChain (FNV-1a) Carried from generation-cascade workshop (D-010)

8. Agent Positions Summary — Round 3

Item Gestalt Tyre Paula Burnelli-Sheldon Ozzie
Q1 (mismatch threshold) Lead decision absorbed Two-tier with Synthetic override on Hard Integration with name pipeline Validated against real data Accepted
Q2 (founding_age) Probability weighting BlockIrregularity enum (stored field) Per-archetype layout_irregularity rules Age bracket affects character_class Minimum 0.05 floor; archetype age_weight
Q3 (Province boundaries) Already satisfied by terrain ARCH-5 pre-computed polylines Rendering chain specified Confirmed correct Map UI spec
Q4 (city names path) Wiki import pipeline Two-tier authorship TOML+corp Stage 0-3 pipeline, extended schema Fallback derivations for missing data Accepted
Full multiplier table Confirmed (ref Burnelli-Sheldon) 8×8 table + Logistics (superseded by D-194) Flag on Agricultural Commercial weight D-194: 10×9 authoritative table Accepted
Ticket chain 11 tickets, 13.5d critical path 22 tickets, 14.75d critical path Data quality flags Data quality blockers PX requirements

Round 3 complete. All Round 2 open questions resolved. Six real D-records (D-194 through D-199). Three data quality pre-implementation blockers identified. Ticket chain: 22+ tickets, 14.75-day critical path. Workshop outcomes document follows.