feat(simulation): Layer-2 road/rail graph (T-1038) + cascade-scale decisions D-242/D-243 #166

Closed
jpmschweitzer wants to merge 0 commits from layer2-road-rail-graph into main
Owner

Summary

Layer-2 inter-settlement road/rail graph (T-1038) plus the two cascade-scale architecture decisions that came out of reviewing it.

Feature — Layer 2 road/rail graph (T-1038)

Deterministic road_graph cascade layer (CascadeLayer::RoadGraph, stored on BodyWorldState.road_graph, never serialized):

  • MST force-connect (strict Kruskal) + secondary links (30–60% body-scale band, >1.5× MST detour)
  • A* over the L1 terrain-cost field (ocean/lake impassable, river ½, slope ≥35° ×10, else D-210 terrain_modification_cost) on a coarse 64-wide grid, equirectangular wrap
  • MaintenanceAuthority per edge (new enum) from endpoint archetypes + haul length; waypoints; named-route join (designed-for, pool empty post-D-223); junction detection
  • 10 road_graph unit tests + cascade e2e test; full suite + clippy --all-targets -D warnings green

Decisions

  • D-242 — corp-HQ settlement model: HQs leave the city name pool; placement is a specialization-keyed CityTenant/Standalone preference; population/settlement_class install-baked. Tickets T-1074/1075/1076.
  • D-243 — spatial scale ladder (resolves Q-110): nested absolute containment voxel → chunk → block → quarter → district → region (~205 km) with a single elastic region ↔ planet seam; region is the climate/weather/season lockdown scale, edge-fuzzed; D-201 tier-4 Region → Province. Recorded in CLAUDE.md. Tickets T-1077/1078; unblocks T-1046.

Verification

  • cargo fmt --check, cargo clippy --all-targets -D warnings, full cargo test — all green
  • pql decisions validate + sync — 0 broken refs
  • pre-push gate passed

🤖 Generated with Claude Code

## Summary Layer-2 inter-settlement road/rail graph (T-1038) plus the two cascade-scale architecture decisions that came out of reviewing it. ### Feature — Layer 2 road/rail graph (T-1038) Deterministic `road_graph` cascade layer (`CascadeLayer::RoadGraph`, stored on `BodyWorldState.road_graph`, never serialized): - MST force-connect (strict Kruskal) + secondary links (30–60% body-scale band, >1.5× MST detour) - A* over the L1 terrain-cost field (ocean/lake impassable, river ½, slope ≥35° ×10, else D-210 `terrain_modification_cost`) on a coarse 64-wide grid, equirectangular wrap - `MaintenanceAuthority` per edge (new enum) from endpoint archetypes + haul length; waypoints; named-route join (designed-for, pool empty post-D-223); junction detection - 10 road_graph unit tests + cascade e2e test; full suite + `clippy --all-targets -D warnings` green ### Decisions - **D-242** — corp-HQ settlement model: HQs leave the city name pool; placement is a specialization-keyed CityTenant/Standalone preference; population/settlement_class install-baked. Tickets T-1074/1075/1076. - **D-243** — spatial scale ladder (resolves Q-110): nested absolute containment `voxel → chunk → block → quarter → district → region (~205 km)` with a single elastic `region ↔ planet` seam; region is the climate/weather/season lockdown scale, edge-fuzzed; D-201 tier-4 `Region → Province`. Recorded in CLAUDE.md. Tickets T-1077/1078; unblocks T-1046. ## Verification - `cargo fmt --check`, `cargo clippy --all-targets -D warnings`, full `cargo test` — all green - `pql decisions validate` + `sync` — 0 broken refs - pre-push gate passed 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jpmschweitzer added 4 commits 2026-06-14 21:32:37 +02:00
Reviewing the T-1038 road-graph hub model surfaced that corp HQs are
cross-referenced into atlas_city_names as reserved rows — one per corp —
producing duplicate co-named "cities" (e.g. 10 'Groombridge' rows on
GJ380c) that the spatial layers place as separate settlements.

D-242 resolves the data model: corp HQs are not cities. The HQ relationship
lives with the corp; placement is a baked, specialization-keyed preference
(CityTenant vs Standalone, since corp_type is degenerate); population and
settlement_class are install-baked with only position seed-derived. This
supersedes the D-223 corp-HQ-cross-ref and deferred-pop/class notes.

Companion tickets under T-750: T-1074 (corp-HQ model / remove the cross-ref /
specialization map / standalone HQ settlements), T-1075 (bake per-settlement
population + settlement_class), T-1076 (road-graph hub refinement — scaled-cap
hubs, co-location collapse, hybrid minor attach, deferred RailHeadFacing pass;
blocked on T-1074 + T-1075). T-1038 annotated with shipped-vs-deferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New deterministic cascade layer (CascadeLayer::RoadGraph) building the
transport topology between Layer-3 settlement placements, stored on
BodyWorldState.road_graph (session-cached, never serialized).

- MST force-connect (strict Kruskal over squared distance) + secondary
  links across a 30-60% body-scale band where the MST detours >1.5x.
- A* over the Layer-1 terrain-cost field on a coarse ~64-wide routing grid:
  ocean/lake impassable, river corridors 1/2 cost, slope >=35deg (D-210
  roughness ~0.7) 10x, else the D-210 terrain_modification_cost. Columns
  wrap (equirectangular); integer costs + index tie-break keep A*
  deterministic.
- MaintenanceAuthority per edge (new generator.rs enum) from endpoint
  political archetypes + haul length; waypoint nodes at long-edge midpoints;
  named-route identity join (designed-for, pool empty post-D-223); junction
  detection (high_connectivity_junctions, degree>=3).

Wired into the cascade (gen_queue requests CascadeLayer::RoadGraph). Adds
Copy to PoliticalArchetype. 10 road_graph unit tests + a cascade e2e test;
full suite + clippy --all-targets -D warnings green.

Deferred to T-1076 (gated on the D-242 settlement model): the RailHeadFacing
junction pass (needs a D-213 FoundingOrientation amendment + Layer-4 handling)
and the hub-selection refinement (needs baked population/specialization).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolves Q-110 (region/chunk physical-scale anchoring), which had three
contradictory metres-per-scale assumptions in the cascade and no record
fixing metres-per-heightmap-pixel.

D-243 establishes a nested absolute-metre containment ladder with a single
elastic seam at planetary scale:
  voxel 1m -> chunk 64m -> block 128m -> quarter 512m -> district 2km
  -> region ~205km (100x100 districts) -> (elastic) -> planet
A body holds round(2*pi*R/204.8km) regions (the only per-body-floating
quantity); everything below is fixed integer math, so ChunkPos->RegionPos
is body-independent. The region is the largest hard block: the climate/
weather/season lockdown scale (the Q-105 cheap-dynamism source) and the
sane planetary grid. Sub-heightmap detail is invented deterministically
(interpolation + domain warp + detail-scatter, never stored, D-227); climate
is edge-fuzzed so the grid never shows ('climate does not change on a line').

Vocabulary locked and recorded in CLAUDE.md: 'region' = the 205km metric
cell only; the old 1km RegionProfile is dropped onto the 2km district; D-201
tier-4 'Region' renamed Province (the watershed/political overlay), amended
here. Refines D-239 §2 (district temperature now modulates a region baseline).

Implementation tickets: T-1077 (re-scale the code to the ladder + elastic-seam
resampling; blocks T-1046) and T-1078 (region climate stack + edge fuzz).
T-1046 is un-gated on Q-110 and now blocked only by T-1077.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jpmschweitzer closed this pull request 2026-06-14 21:38:48 +02:00
jpmschweitzer deleted branch layer2-road-rail-graph 2026-06-14 21:38:48 +02:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jpmschweitzer/settled-reach#166