fix(simulation): synthetic-overflow placements get the ocean-mask guard (T-1206)
synthetic_attractor now takes the terrain analysis and land-corrects its pure-arithmetic position via a bounded nearest-land ring walk (T-1116's pattern: row-major tie-break, column wrap, row clamp, MAX_LAND_SEARCH_RING=128 sized empirically — real polar ocean bands push nearest land up to 125 cells). Land positions pass through UNTOUCHED — verified by direct before/after scan of all 267 real bodies: 63 land-arithmetic placements byte-identical, and every golden/determinism harness passes unchanged. The gap was real and widespread: 46 of 109 synthetic-overflow placements sat in open water at seed 42 (e.g. GJ903c at a genuine polar ocean cell); post-fix zero, with all 109 preserved (confirmed at a second seed). Degradation is defined and pinned: no land within the bound -> the synthetic attractor is skipped and Phase 5's existing not-placed warning reports it — never a panic, never a fabricated water position (the bound never triggers on any scanned real body). 9 new unit tests; road_graph's anchor comment and the D-210 amendment record the gap CLOSED (validated). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1105,6 +1105,8 @@ Technical foundation decisions that constrain implementation: engine, client-ser
|
||||
|
||||
**Amended 2026-07-26 (T-1116 — surrogate-anchor-at-cost carve-out for the Layer-2 road graph):** the road graph's routing grid (`RouteGrid`, `road_graph.rs`) downsamples `terrain_modification_cost` onto coarse routing cells (up to `scale²` native pixels per cell) and marks a cell `IMPASSABLE` when it is water-majority. A settlement's exact placement pixel is always land (D-209's attractor extraction guards `!ocean_mask` on every real attractor type), but at this downsample granularity the settlement's *routing cell* can still be majority water — a coastal-cell/downsample artifact, not a placement error. **Ruling:** a routing anchor (A\* start/goal) whose own cell is water-majority MAY be surrogated to the nearest passable cell within a bounded search radius, priced as an explicit access-cost surcharge on the routed edge's reported length (never free, modeling a short quay/causeway link) — but general water-cell transit stays `IMPASSABLE` exactly as before; only the anchor *lookup* for a start/goal settlement is relaxed, not open-ocean pathfinding. This was adjudicated as a routing-layer relaxation rather than a D-211 placement nudge specifically because D-211's positions are seed-derived and already land-guaranteed for every *real* attractor path — moving them would touch a different layer's invariant to fix a downsample artifact that belongs to the router. **Known gap flagged, not fixed here:** D-211's Phase-4 synthetic-overflow path (`synthetic_attractor`) computes its position by grid arithmetic alone, with no terrain/`ocean_mask` check at all — unlike every real attractor type, a synthetic-overflow settlement is not guaranteed land. The routing relaxation above still degrades that case gracefully (surrogate-anchors it or leaves it unrouted beyond the search radius), but the placement guarantee gap itself is D-211's, unticketed as of this amendment.
|
||||
|
||||
**Gap CLOSED 2026-07-26 (T-1206):** `synthetic_attractor` now takes an `Option<&TerrainAnalysis>` and guards its grid-arithmetic position against `ocean_mask` — land-passthrough (an already-land position is untouched; verified byte-identical on all 63 real bodies' land-arithmetic synthetic placements at world seed 42), water-only-correction (a deterministic ring-walk, the T-1116 `nearest_passable_cell` pattern at native resolution, nudges a water position to the nearest land cell — verified on all 46 real bodies found water-stranded pre-fix), and a defined skip (never a fabricated position or a panic) when no land exists within the bounded search radius. D-211's seed-derived-position promise holds: no existing land placement moved on any scanned body.
|
||||
|
||||
### D-211: Attractor-Matching Five-Phase Pipeline for Settlement Placement
|
||||
- **Date:** 2026-05-01
|
||||
- **Decision:** Given a body's `Vec<GeographicAttractor>` and a set of cities from `atlas_city_names`, settlement placement runs a five-phase matching pipeline:
|
||||
|
||||
Reference in New Issue
Block a user