From c2f236e26eada838763cca422cfc7eb3ca66e793 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Thu, 16 Jul 2026 18:29:37 +0200 Subject: [PATCH] =?UTF-8?q?chore(meta):=20activate=20T-1112/T-1113=20atlas?= =?UTF-8?q?-layer=20batch=20=E2=80=94=20Si=20refinement=20appended=20(both?= =?UTF-8?q?=20READY)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pql/changelog/ticket_history/2026-07.sql | 29 +++++++++ .pql/changelog/tickets/2026-07.sql | 75 +++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/.pql/changelog/ticket_history/2026-07.sql b/.pql/changelog/ticket_history/2026-07.sql index e44bbf1a5..f8b7193ab 100644 --- a/.pql/changelog/ticket_history/2026-07.sql +++ b/.pql/changelog/ticket_history/2026-07.sql @@ -1374,3 +1374,32 @@ INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, chang INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCDG73V9R6N024QSFDEJ4R68', 'assigned_to', NULL, 'dudley', NULL, '2026-07-16 13:34:49', '2026-07-16 13:34:49.724', '2026-07-16 13:34:49.724', NULL, '974c9ac15c87788ce7b7bc1af07548d5', 2) ON CONFLICT(hash) DO NOTHING; INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCDG73V9R6N024QSFDEJ4R68', 'status', 'in_progress', 'review', NULL, '2026-07-16 14:25:25', '2026-07-16 14:25:25.191', '2026-07-16 14:25:25.191', NULL, '4db8483f0395e003366d0313acca2bbb', 2) ON CONFLICT(hash) DO NOTHING; INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCDG73V9R6N024QSFDEJ4R68', 'status', 'review', 'done', NULL, '2026-07-16 15:15:16', '2026-07-16 15:15:16.465', '2026-07-16 15:15:16.465', NULL, '45ac7e300870b581b76c0a195c32ff67', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXF0JB8E6PDQRASQ18E9ER', 'description', 'Si audit of T-960 (2026-07-13): region_profile.rs (T-1078 — RegionProfile, derive_regions_for_body, region_baseline_at_district) is implemented and unit-tested but never called from cascade.rs: no CascadeLayer::Region variant, nothing on BodyWorldState, nothing in the layer proxy. Prerequisite for any climate Atlas overlay (explicitly out of T-960 scope per 2026-07-13 ruling): add the cascade layer, populate BodyWorldState, expose via AtlasLayerResponse following the T-1046 district-grid precedent. The climate OVERLAY itself is a small follow-up once this serves data.', 'Si audit of T-960 (2026-07-13): region_profile.rs (T-1078 — RegionProfile, derive_regions_for_body, region_baseline_at_district) is implemented and unit-tested but never called from cascade.rs: no CascadeLayer::Region variant, nothing on BodyWorldState, nothing in the layer proxy. Prerequisite for any climate Atlas overlay (explicitly out of T-960 scope per 2026-07-13 ruling): add the cascade layer, populate BodyWorldState, expose via AtlasLayerResponse following the T-1046 district-grid precedent. The climate OVERLAY itself is a small follow-up once this serves data. + +--- +Refinement (2026-07-16, /whats-next Si review): READY, no gaps. + +Key implementation facts (Si-verified against post-PR#178 main): +- region_profile.rs (T-1078) exposes exactly what''s needed: RegionProfile{pos, clock: RegionClock{season, weather, mean_temp_c}, latitude_deg, moisture_q}, derive_regions_for_body(...) -> BTreeMap, region_baseline_at_district(...). Deterministic, unit-tested. +- CRITICAL: district_profile.rs::derive_all_districts (~1434-1509) ALREADY builds the region cache internally (incl. neighbours for edge-fuzz) and discards it — this ticket is retention, not new derivation. Chosen shape: option (a) — independent CascadeLayer::Region step in run_cascade_from_heightmap (one-layer-one-concern, mirrors existing layers; accept the cheap double-derive). +- CascadeLayer Ord today: Heightmap < Topography < Settlement < DistrictProfile < RoadGraph. Region slots as its own step. +- BodyWorldState: add pub regions: BTreeMap per the districts precedent (same determinism rationale, same empty-until-run convention). Footprint trivial (~195×98 max). +- layer_proxy.rs doc comment (76-79) already earmarks T-1113 as one of the two final layer fields. Mirror build_district_grid: RegionGridLayer + build_region_grid(state) -> Option<...>, called from handle_atlas_request cache-hit branch. Encoding: dense row-major grid per the T-1046 precedent (implementer''s low-stakes call on exact fields/quantization). +- Client wire-decode IS in scope (one line): protocol.gd::atlas_response_from_raw raw.get("region_grid") passthrough, matching district_grid. The VISUAL overlay (atlas_viewer/marker_overlay/legend) is explicitly OUT of scope — small follow-up per D-226 amendment (a) incremental-overlay pattern. +- Edge-fuzz (D-243 §4) is consumer-side sampling behavior already implemented in region_baseline_at_district — not this ticket''s concern. +- Q-105 resolved into D-243; RegionClock tick-phase callbacks stay deferred — only the mean-state fields are served.', NULL, '2026-07-16 16:28:52', '2026-07-16 16:28:52.948', '2026-07-16 16:28:52.948', NULL, '28022a866ff419d9ac72dca1c7f5e0fe', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXEM9NM5M5SX9WQAAA40SC', 'description', 'Si audit of T-960 (2026-07-13): L4 quarter/block skeletons (T-957/T-976) auto-generate server-side into BodyWorldState.quarters, but carry full per-block zoning/street/tag detail — too fine for a planetary map, and unlike the district grid there is no existing coarse shape to reuse. DESIGN ticket (Araminta encoding + Tyre data shape) before any wiring: define a QuarterFootprintLayer (city outline + aggregate stats?) for AtlasLayerResponse and its overlay encoding per the D-226 amended (2026-07-13) overlay pattern. Wiring is a follow-up once the design is recorded.', 'Si audit of T-960 (2026-07-13): L4 quarter/block skeletons (T-957/T-976) auto-generate server-side into BodyWorldState.quarters, but carry full per-block zoning/street/tag detail — too fine for a planetary map, and unlike the district grid there is no existing coarse shape to reuse. DESIGN ticket (Araminta encoding + Tyre data shape) before any wiring: define a QuarterFootprintLayer (city outline + aggregate stats?) for AtlasLayerResponse and its overlay encoding per the D-226 amended (2026-07-13) overlay pattern. Wiring is a follow-up once the design is recorded. + +--- +Refinement (2026-07-16, /whats-next Si review): READY, one scoping note made explicit. + +- DELIVERABLE FORMAT (was unpinned): record the design as a **D-226 amendment** — the established mechanism (the 2026-07-13 overlay pattern itself was recorded that way); no docs/design Atlas-overlay doc precedent exists (T-1046 shipped design-in-ticket+code-comments). The design pass ends at the recorded amendment; the wiring follow-up ticket is filed by the lead afterwards, not by the design pass. +- BINDING CONSTRAINT: D-226 amendment (d) is a hard ceiling — planetary Atlas tops out at settlement/quarter-skeleton granularity with AT MOST aggregate stats. No per-block zoning/street/tag detail at planetary scale. City outline + aggregate stats only. +- DATA SOURCE: BodyWorldState.quarters stores QuarterWorldState{skeleton: QuarterSkeleton, block_tags: BTreeMap<(u8,u8), Vec>}; QuarterSkeleton carries [[BlockSkeleton;4];4] with zoning/district_type/density_pct/landmark + reservations/corridors. All aggregatable (density avg, dominant zoning/district-type mix, landmark count, corridor count) without inventing new simulation truth — same derivation class as build_district_grid/build_settlement_layer. +- PRECEDENT TO IMITATE (five touch points, each with a working example): server AtlasLayerResponse field + build_quarter_footprint_layer() mirroring build_district_grid (keyed off non-empty state.quarters); client OVERLAY_DEFS gen_* id (atlas_viewer.gd), _draw_gen_* fn (atlas_marker_overlay.gd, imitate _draw_gen_district ~185-188), GENERATION_LEGEND entry (atlas_legend_panel.gd). These are named in the amendment for the wiring follow-up — not implemented in this ticket. +- PARTICIPANT SPLIT: Tyre owns the aggregate-stats data shape (fields, structure, D-010 integer discipline); Araminta owns the overlay encoding (outline vs filled block, color axis per the shape-vs-color convention in atlas_legend_panel.gd) — the same division D-226 originally used. Two coordinated agents, not a workshop round. +- pql metadata quirk noted: the ticket''s decision_ref D-226 resolves to a wrong title in show-summary; `pql decisions read D-226` returns the correct record.', NULL, '2026-07-16 16:29:00', '2026-07-16 16:29:00.676', '2026-07-16 16:29:00.676', NULL, '175b39a57958906d4f3d80816499a617', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXEM9NM5M5SX9WQAAA40SC', 'status', 'backlog', 'in_progress', NULL, '2026-07-16 16:29:07', '2026-07-16 16:29:07.857', '2026-07-16 16:29:07.857', NULL, '672f4ada58be5b83ccd4eb0db737843c', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXF0JB8E6PDQRASQ18E9ER', 'status', 'backlog', 'in_progress', NULL, '2026-07-16 16:29:07', '2026-07-16 16:29:07.859', '2026-07-16 16:29:07.859', NULL, '0982ecc37d460add179eae8491ce496d', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXF0JB8E6PDQRASQ18E9ER', 'assigned_to', NULL, 'dudley', NULL, '2026-07-16 16:29:14', '2026-07-16 16:29:14.525', '2026-07-16 16:29:14.525', NULL, 'eda3d1391d0ea48a59277fd6486cdbe5', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXEM9NM5M5SX9WQAAA40SC', 'assigned_to', NULL, 'tyre', NULL, '2026-07-16 16:29:22', '2026-07-16 16:29:22.162', '2026-07-16 16:29:22.162', NULL, 'c9cfbbab6a28aa1e01b21c60f30624f5', 2) ON CONFLICT(hash) DO NOTHING; diff --git a/.pql/changelog/tickets/2026-07.sql b/.pql/changelog/tickets/2026-07.sql index fa710bb12..8252af475 100644 --- a/.pql/changelog/tickets/2026-07.sql +++ b/.pql/changelog/tickets/2026-07.sql @@ -1814,3 +1814,78 @@ SCOPE ITEM 0 (added — placement-map correction, precedes hub work): corp_hq_pl Deferred (no preference given): standalone-HQ Zipf population shares stay as-is (e.g. Gate Corporation 909M on GJ251c); the item-0 re-tune shrinks standalone rows to genuine company-towns where a real share is defensible. Revisit if Atlas numbers read wrong. Si verification notes: road_graph.rs has NO hub concept and NO edge-split machinery today (T-1038 treats every placement as a uniform MST node); RoadGraph::high_connectivity_junctions() exists (JUNCTION_DEGREE=3); FoundingOrientation consumers are founding_orientation() and coastal_edge() (if-let, safe); skeleton_gen has zero rail-facing rotation logic (new work, scoped); PR #177 data preconditions verified (population>0 + settlement_class on all rows; standalone HQs present as ordinary rows).', 'done', 'medium', 'dudley', 'server', 'D-242', '2026-06-14 15:29:50', '2026-07-16 15:15:16.460', NULL, 'fa5cf116e084387017b5d6a0d280c768', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXF0JB8E6PDQRASQ18E9ER', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Wire region climate stack into the cascade (CascadeLayer::Region + proxy exposure)', 'Si audit of T-960 (2026-07-13): region_profile.rs (T-1078 — RegionProfile, derive_regions_for_body, region_baseline_at_district) is implemented and unit-tested but never called from cascade.rs: no CascadeLayer::Region variant, nothing on BodyWorldState, nothing in the layer proxy. Prerequisite for any climate Atlas overlay (explicitly out of T-960 scope per 2026-07-13 ruling): add the cascade layer, populate BodyWorldState, expose via AtlasLayerResponse following the T-1046 district-grid precedent. The climate OVERLAY itself is a small follow-up once this serves data. + +--- +Refinement (2026-07-16, /whats-next Si review): READY, no gaps. + +Key implementation facts (Si-verified against post-PR#178 main): +- region_profile.rs (T-1078) exposes exactly what''s needed: RegionProfile{pos, clock: RegionClock{season, weather, mean_temp_c}, latitude_deg, moisture_q}, derive_regions_for_body(...) -> BTreeMap, region_baseline_at_district(...). Deterministic, unit-tested. +- CRITICAL: district_profile.rs::derive_all_districts (~1434-1509) ALREADY builds the region cache internally (incl. neighbours for edge-fuzz) and discards it — this ticket is retention, not new derivation. Chosen shape: option (a) — independent CascadeLayer::Region step in run_cascade_from_heightmap (one-layer-one-concern, mirrors existing layers; accept the cheap double-derive). +- CascadeLayer Ord today: Heightmap < Topography < Settlement < DistrictProfile < RoadGraph. Region slots as its own step. +- BodyWorldState: add pub regions: BTreeMap per the districts precedent (same determinism rationale, same empty-until-run convention). Footprint trivial (~195×98 max). +- layer_proxy.rs doc comment (76-79) already earmarks T-1113 as one of the two final layer fields. Mirror build_district_grid: RegionGridLayer + build_region_grid(state) -> Option<...>, called from handle_atlas_request cache-hit branch. Encoding: dense row-major grid per the T-1046 precedent (implementer''s low-stakes call on exact fields/quantization). +- Client wire-decode IS in scope (one line): protocol.gd::atlas_response_from_raw raw.get("region_grid") passthrough, matching district_grid. The VISUAL overlay (atlas_viewer/marker_overlay/legend) is explicitly OUT of scope — small follow-up per D-226 amendment (a) incremental-overlay pattern. +- Edge-fuzz (D-243 §4) is consumer-side sampling behavior already implemented in region_baseline_at_district — not this ticket''s concern. +- Q-105 resolved into D-243; RegionClock tick-phase callbacks stay deferred — only the mean-state fields are served.', 'backlog', 'medium', NULL, 'server', 'D-243', '2026-07-13 21:50:34.130', '2026-07-16 16:28:52.947', NULL, 'b1ac72a5909879e07725f150340fb5cf', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXEM9NM5M5SX9WQAAA40SC', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Design: coarse quarter-footprint Atlas layer (L4 skeleton on the planetary map)', 'Si audit of T-960 (2026-07-13): L4 quarter/block skeletons (T-957/T-976) auto-generate server-side into BodyWorldState.quarters, but carry full per-block zoning/street/tag detail — too fine for a planetary map, and unlike the district grid there is no existing coarse shape to reuse. DESIGN ticket (Araminta encoding + Tyre data shape) before any wiring: define a QuarterFootprintLayer (city outline + aggregate stats?) for AtlasLayerResponse and its overlay encoding per the D-226 amended (2026-07-13) overlay pattern. Wiring is a follow-up once the design is recorded. + +--- +Refinement (2026-07-16, /whats-next Si review): READY, one scoping note made explicit. + +- DELIVERABLE FORMAT (was unpinned): record the design as a **D-226 amendment** — the established mechanism (the 2026-07-13 overlay pattern itself was recorded that way); no docs/design Atlas-overlay doc precedent exists (T-1046 shipped design-in-ticket+code-comments). The design pass ends at the recorded amendment; the wiring follow-up ticket is filed by the lead afterwards, not by the design pass. +- BINDING CONSTRAINT: D-226 amendment (d) is a hard ceiling — planetary Atlas tops out at settlement/quarter-skeleton granularity with AT MOST aggregate stats. No per-block zoning/street/tag detail at planetary scale. City outline + aggregate stats only. +- DATA SOURCE: BodyWorldState.quarters stores QuarterWorldState{skeleton: QuarterSkeleton, block_tags: BTreeMap<(u8,u8), Vec>}; QuarterSkeleton carries [[BlockSkeleton;4];4] with zoning/district_type/density_pct/landmark + reservations/corridors. All aggregatable (density avg, dominant zoning/district-type mix, landmark count, corridor count) without inventing new simulation truth — same derivation class as build_district_grid/build_settlement_layer. +- PRECEDENT TO IMITATE (five touch points, each with a working example): server AtlasLayerResponse field + build_quarter_footprint_layer() mirroring build_district_grid (keyed off non-empty state.quarters); client OVERLAY_DEFS gen_* id (atlas_viewer.gd), _draw_gen_* fn (atlas_marker_overlay.gd, imitate _draw_gen_district ~185-188), GENERATION_LEGEND entry (atlas_legend_panel.gd). These are named in the amendment for the wiring follow-up — not implemented in this ticket. +- PARTICIPANT SPLIT: Tyre owns the aggregate-stats data shape (fields, structure, D-010 integer discipline); Araminta owns the overlay encoding (outline vs filled block, color axis per the shape-vs-color convention in atlas_legend_panel.gd) — the same division D-226 originally used. Two coordinated agents, not a workshop round. +- pql metadata quirk noted: the ticket''s decision_ref D-226 resolves to a wrong title in show-summary; `pql decisions read D-226` returns the correct record.', 'backlog', 'medium', NULL, 'client', 'D-226', '2026-07-13 21:50:30.989', '2026-07-16 16:29:00.676', NULL, 'e7e2c4c9c632f28a8dea8230d56d8e9e', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXEM9NM5M5SX9WQAAA40SC', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Design: coarse quarter-footprint Atlas layer (L4 skeleton on the planetary map)', 'Si audit of T-960 (2026-07-13): L4 quarter/block skeletons (T-957/T-976) auto-generate server-side into BodyWorldState.quarters, but carry full per-block zoning/street/tag detail — too fine for a planetary map, and unlike the district grid there is no existing coarse shape to reuse. DESIGN ticket (Araminta encoding + Tyre data shape) before any wiring: define a QuarterFootprintLayer (city outline + aggregate stats?) for AtlasLayerResponse and its overlay encoding per the D-226 amended (2026-07-13) overlay pattern. Wiring is a follow-up once the design is recorded. + +--- +Refinement (2026-07-16, /whats-next Si review): READY, one scoping note made explicit. + +- DELIVERABLE FORMAT (was unpinned): record the design as a **D-226 amendment** — the established mechanism (the 2026-07-13 overlay pattern itself was recorded that way); no docs/design Atlas-overlay doc precedent exists (T-1046 shipped design-in-ticket+code-comments). The design pass ends at the recorded amendment; the wiring follow-up ticket is filed by the lead afterwards, not by the design pass. +- BINDING CONSTRAINT: D-226 amendment (d) is a hard ceiling — planetary Atlas tops out at settlement/quarter-skeleton granularity with AT MOST aggregate stats. No per-block zoning/street/tag detail at planetary scale. City outline + aggregate stats only. +- DATA SOURCE: BodyWorldState.quarters stores QuarterWorldState{skeleton: QuarterSkeleton, block_tags: BTreeMap<(u8,u8), Vec>}; QuarterSkeleton carries [[BlockSkeleton;4];4] with zoning/district_type/density_pct/landmark + reservations/corridors. All aggregatable (density avg, dominant zoning/district-type mix, landmark count, corridor count) without inventing new simulation truth — same derivation class as build_district_grid/build_settlement_layer. +- PRECEDENT TO IMITATE (five touch points, each with a working example): server AtlasLayerResponse field + build_quarter_footprint_layer() mirroring build_district_grid (keyed off non-empty state.quarters); client OVERLAY_DEFS gen_* id (atlas_viewer.gd), _draw_gen_* fn (atlas_marker_overlay.gd, imitate _draw_gen_district ~185-188), GENERATION_LEGEND entry (atlas_legend_panel.gd). These are named in the amendment for the wiring follow-up — not implemented in this ticket. +- PARTICIPANT SPLIT: Tyre owns the aggregate-stats data shape (fields, structure, D-010 integer discipline); Araminta owns the overlay encoding (outline vs filled block, color axis per the shape-vs-color convention in atlas_legend_panel.gd) — the same division D-226 originally used. Two coordinated agents, not a workshop round. +- pql metadata quirk noted: the ticket''s decision_ref D-226 resolves to a wrong title in show-summary; `pql decisions read D-226` returns the correct record.', 'in_progress', 'medium', NULL, 'client', 'D-226', '2026-07-13 21:50:30.989', '2026-07-16 16:29:07.852', NULL, '80c50822d552dfbf0c8452a9e5e2df99', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXF0JB8E6PDQRASQ18E9ER', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Wire region climate stack into the cascade (CascadeLayer::Region + proxy exposure)', 'Si audit of T-960 (2026-07-13): region_profile.rs (T-1078 — RegionProfile, derive_regions_for_body, region_baseline_at_district) is implemented and unit-tested but never called from cascade.rs: no CascadeLayer::Region variant, nothing on BodyWorldState, nothing in the layer proxy. Prerequisite for any climate Atlas overlay (explicitly out of T-960 scope per 2026-07-13 ruling): add the cascade layer, populate BodyWorldState, expose via AtlasLayerResponse following the T-1046 district-grid precedent. The climate OVERLAY itself is a small follow-up once this serves data. + +--- +Refinement (2026-07-16, /whats-next Si review): READY, no gaps. + +Key implementation facts (Si-verified against post-PR#178 main): +- region_profile.rs (T-1078) exposes exactly what''s needed: RegionProfile{pos, clock: RegionClock{season, weather, mean_temp_c}, latitude_deg, moisture_q}, derive_regions_for_body(...) -> BTreeMap, region_baseline_at_district(...). Deterministic, unit-tested. +- CRITICAL: district_profile.rs::derive_all_districts (~1434-1509) ALREADY builds the region cache internally (incl. neighbours for edge-fuzz) and discards it — this ticket is retention, not new derivation. Chosen shape: option (a) — independent CascadeLayer::Region step in run_cascade_from_heightmap (one-layer-one-concern, mirrors existing layers; accept the cheap double-derive). +- CascadeLayer Ord today: Heightmap < Topography < Settlement < DistrictProfile < RoadGraph. Region slots as its own step. +- BodyWorldState: add pub regions: BTreeMap per the districts precedent (same determinism rationale, same empty-until-run convention). Footprint trivial (~195×98 max). +- layer_proxy.rs doc comment (76-79) already earmarks T-1113 as one of the two final layer fields. Mirror build_district_grid: RegionGridLayer + build_region_grid(state) -> Option<...>, called from handle_atlas_request cache-hit branch. Encoding: dense row-major grid per the T-1046 precedent (implementer''s low-stakes call on exact fields/quantization). +- Client wire-decode IS in scope (one line): protocol.gd::atlas_response_from_raw raw.get("region_grid") passthrough, matching district_grid. The VISUAL overlay (atlas_viewer/marker_overlay/legend) is explicitly OUT of scope — small follow-up per D-226 amendment (a) incremental-overlay pattern. +- Edge-fuzz (D-243 §4) is consumer-side sampling behavior already implemented in region_baseline_at_district — not this ticket''s concern. +- Q-105 resolved into D-243; RegionClock tick-phase callbacks stay deferred — only the mean-state fields are served.', 'in_progress', 'medium', NULL, 'server', 'D-243', '2026-07-13 21:50:34.130', '2026-07-16 16:29:07.859', NULL, '6051dd64719856227b74735692044209', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXF0JB8E6PDQRASQ18E9ER', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Wire region climate stack into the cascade (CascadeLayer::Region + proxy exposure)', 'Si audit of T-960 (2026-07-13): region_profile.rs (T-1078 — RegionProfile, derive_regions_for_body, region_baseline_at_district) is implemented and unit-tested but never called from cascade.rs: no CascadeLayer::Region variant, nothing on BodyWorldState, nothing in the layer proxy. Prerequisite for any climate Atlas overlay (explicitly out of T-960 scope per 2026-07-13 ruling): add the cascade layer, populate BodyWorldState, expose via AtlasLayerResponse following the T-1046 district-grid precedent. The climate OVERLAY itself is a small follow-up once this serves data. + +--- +Refinement (2026-07-16, /whats-next Si review): READY, no gaps. + +Key implementation facts (Si-verified against post-PR#178 main): +- region_profile.rs (T-1078) exposes exactly what''s needed: RegionProfile{pos, clock: RegionClock{season, weather, mean_temp_c}, latitude_deg, moisture_q}, derive_regions_for_body(...) -> BTreeMap, region_baseline_at_district(...). Deterministic, unit-tested. +- CRITICAL: district_profile.rs::derive_all_districts (~1434-1509) ALREADY builds the region cache internally (incl. neighbours for edge-fuzz) and discards it — this ticket is retention, not new derivation. Chosen shape: option (a) — independent CascadeLayer::Region step in run_cascade_from_heightmap (one-layer-one-concern, mirrors existing layers; accept the cheap double-derive). +- CascadeLayer Ord today: Heightmap < Topography < Settlement < DistrictProfile < RoadGraph. Region slots as its own step. +- BodyWorldState: add pub regions: BTreeMap per the districts precedent (same determinism rationale, same empty-until-run convention). Footprint trivial (~195×98 max). +- layer_proxy.rs doc comment (76-79) already earmarks T-1113 as one of the two final layer fields. Mirror build_district_grid: RegionGridLayer + build_region_grid(state) -> Option<...>, called from handle_atlas_request cache-hit branch. Encoding: dense row-major grid per the T-1046 precedent (implementer''s low-stakes call on exact fields/quantization). +- Client wire-decode IS in scope (one line): protocol.gd::atlas_response_from_raw raw.get("region_grid") passthrough, matching district_grid. The VISUAL overlay (atlas_viewer/marker_overlay/legend) is explicitly OUT of scope — small follow-up per D-226 amendment (a) incremental-overlay pattern. +- Edge-fuzz (D-243 §4) is consumer-side sampling behavior already implemented in region_baseline_at_district — not this ticket''s concern. +- Q-105 resolved into D-243; RegionClock tick-phase callbacks stay deferred — only the mean-state fields are served.', 'in_progress', 'medium', 'dudley', 'server', 'D-243', '2026-07-13 21:50:34.130', '2026-07-16 16:29:14.520', NULL, 'ca5d25a0104dea15c652446bc7b2e59d', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXEM9NM5M5SX9WQAAA40SC', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Design: coarse quarter-footprint Atlas layer (L4 skeleton on the planetary map)', 'Si audit of T-960 (2026-07-13): L4 quarter/block skeletons (T-957/T-976) auto-generate server-side into BodyWorldState.quarters, but carry full per-block zoning/street/tag detail — too fine for a planetary map, and unlike the district grid there is no existing coarse shape to reuse. DESIGN ticket (Araminta encoding + Tyre data shape) before any wiring: define a QuarterFootprintLayer (city outline + aggregate stats?) for AtlasLayerResponse and its overlay encoding per the D-226 amended (2026-07-13) overlay pattern. Wiring is a follow-up once the design is recorded. + +--- +Refinement (2026-07-16, /whats-next Si review): READY, one scoping note made explicit. + +- DELIVERABLE FORMAT (was unpinned): record the design as a **D-226 amendment** — the established mechanism (the 2026-07-13 overlay pattern itself was recorded that way); no docs/design Atlas-overlay doc precedent exists (T-1046 shipped design-in-ticket+code-comments). The design pass ends at the recorded amendment; the wiring follow-up ticket is filed by the lead afterwards, not by the design pass. +- BINDING CONSTRAINT: D-226 amendment (d) is a hard ceiling — planetary Atlas tops out at settlement/quarter-skeleton granularity with AT MOST aggregate stats. No per-block zoning/street/tag detail at planetary scale. City outline + aggregate stats only. +- DATA SOURCE: BodyWorldState.quarters stores QuarterWorldState{skeleton: QuarterSkeleton, block_tags: BTreeMap<(u8,u8), Vec>}; QuarterSkeleton carries [[BlockSkeleton;4];4] with zoning/district_type/density_pct/landmark + reservations/corridors. All aggregatable (density avg, dominant zoning/district-type mix, landmark count, corridor count) without inventing new simulation truth — same derivation class as build_district_grid/build_settlement_layer. +- PRECEDENT TO IMITATE (five touch points, each with a working example): server AtlasLayerResponse field + build_quarter_footprint_layer() mirroring build_district_grid (keyed off non-empty state.quarters); client OVERLAY_DEFS gen_* id (atlas_viewer.gd), _draw_gen_* fn (atlas_marker_overlay.gd, imitate _draw_gen_district ~185-188), GENERATION_LEGEND entry (atlas_legend_panel.gd). These are named in the amendment for the wiring follow-up — not implemented in this ticket. +- PARTICIPANT SPLIT: Tyre owns the aggregate-stats data shape (fields, structure, D-010 integer discipline); Araminta owns the overlay encoding (outline vs filled block, color axis per the shape-vs-color convention in atlas_legend_panel.gd) — the same division D-226 originally used. Two coordinated agents, not a workshop round. +- pql metadata quirk noted: the ticket''s decision_ref D-226 resolves to a wrong title in show-summary; `pql decisions read D-226` returns the correct record.', 'in_progress', 'medium', 'tyre', 'client', 'D-226', '2026-07-13 21:50:30.989', '2026-07-16 16:29:22.162', NULL, 'c875a58d0f49225f768dd2e7efbee3e8', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);