feat(simulation): T-1119 QuarterFootprintLayer — server half (touch points 1-2) + populated wire fixtures

ZoningType gains PartialOrd/Ord (DistrictType T-994 mirror) for the
dominant_zoning declaration-order tie-break. layer_proxy:
QuarterFootprintEntry/QuarterFootprintLayer (BTreeMap keyed by
city_id; density_avg_pct floor-mean, dominant_* mode with
declaration-order tie-break, landmark/corridor counts) +
build_quarter_footprint_layer gated None on empty state.quarters;
sixth AtlasLayerResponse field wired into all construction sites;
growth-ceiling doc updated to say the whole-body budget is consumed
(what carries a seventh is T-1124's design, resolved in the same
branch's amendment). Placements whose derived Layer4Quarter id is not
yet in state.quarters are SKIPPED (skeleton gen is async Low-priority
— entries may be a proper subset; client decodes defensively). Stale
TODO(#957) removed (premise predates T-957 landing).

Tie-break bug caught by its own test: Iterator::max_by_key over a
BTreeMap returns the LAST max on ties — backwards from
declaration-order-first; replaced with an explicit forward walk that
replaces only on strictly-greater count.

gen_fixtures: populated RegionGridLayer (T-1118 replay coverage) +
QuarterFootprintLayer literals in the ready fixture; msgpack fixtures
regenerated via make fixtures. Note: landmark_count is inert on real
data today (BlockSkeleton.landmark hardcoded None until landmark
placement lands); fixtures use non-zero counts to exercise the logic.

5 new unit tests + populated round-trip; atlas:: 549 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 12:03:28 +02:00
co-authored by Claude Fable 5
parent 67bd0ec294
commit 8165c61186
7 changed files with 599 additions and 18 deletions
+2 -3
View File
@@ -121,6 +121,7 @@ fn serve_atlas_requests(
road_graph: None,
settlements: None,
region_grid: None,
quarter_footprints: None,
},
};
responses.0.push((conn_id, resp));
@@ -358,9 +359,7 @@ fn drain_generation_completions(
// Key by state.skeleton.quarter_id (D-194/D-230): a city has many
// quarters, each with its own QuarterId. `city_id` is only the
// dispatch key used in the work item — the canonical insert key is
// the quarter's own stable id. TODO(#957): the stub GenerateSkeleton
// returns a default skeleton with quarter_id=0; real gen (#957) will
// populate it from CityGenerationContext.
// the quarter's own stable id.
let _ = city_id; // used as dispatch key only; quarter_id is the map key
body_state
.quarters