chore(meta): T-1124/T-1118/T-1119 to review — PR #185 up (Atlas depth batch)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1556,3 +1556,6 @@ Batch split (lead): points 1-2 (server) = Dudley, who also owns the gen_fixtures
|
||||
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 ('06FQ9B977KGH3BWP1YQTN32TYM', 'description', 'Implement the D-226 T-1124 amendment SS5 (client half). protocol.gd passthrough: encode_atlas_layer_request gains the window params (serde-default absent = whole-body); atlas_response_from_raw gains district_window passthrough (the doc comment near protocol.gd:801 names this the one client-side spot). New regional viewing mode per SS5: zoom-threshold LOD swap in the existing AtlasViewer (new DISTRICT_WINDOW_MIN_ZOOM past SETTLEMENT_LABEL_MIN_ZOOM — not a new screen, not a nav push); morphology base layer lightness-modulated by elev_q (probe MORPHOLOGY_RGB hues); gen_dw_temp/gen_dw_moisture/gen_dw_veg toggle overlays (temp reuses the T-1118 region-ramp colorizer EXACTLY — one colorizer across both zoom levels; Marine=6 renders transparent; glaciation is an always-on ice-tint modifier, not a toggle); GENERATION_LEGEND entries with the 17-zone base folded to ~5 family rows. Client window cache keyed (body_id, center, n), LRU-evict only (D-227 determinism — no freshness check). Re-request on PAN ONLY when the view passes the held window''s edge (zoom never refetches); 150ms post-drag-release debounce; windows float on the pan center (not grid-snapped). Implant chrome: ImplantHeader anchor name + extent subtitle; map palettes stay out of theme accent roles (ACCENT_ACTIVE gold is the settlement marker''s).', 'Implement the D-226 T-1124 amendment SS5 (client half). protocol.gd passthrough: encode_atlas_layer_request gains the window params (serde-default absent = whole-body); atlas_response_from_raw gains district_window passthrough (the doc comment near protocol.gd:801 names this the one client-side spot). New regional viewing mode per SS5: zoom-threshold LOD swap in the existing AtlasViewer (new DISTRICT_WINDOW_MIN_ZOOM past SETTLEMENT_LABEL_MIN_ZOOM — not a new screen, not a nav push); morphology base layer lightness-modulated by elev_q (probe MORPHOLOGY_RGB hues); gen_dw_temp/gen_dw_moisture/gen_dw_veg toggle overlays (temp reuses the T-1118 region-ramp colorizer EXACTLY — one colorizer across both zoom levels; Marine=6 renders transparent; glaciation is an always-on ice-tint modifier, not a toggle); GENERATION_LEGEND entries with the 17-zone base folded to ~5 family rows. Client window cache keyed (body_id, center, n), LRU-evict only (D-227 determinism — no freshness check). Re-request on PAN ONLY when the view passes the held window''s edge (zoom never refetches); 150ms post-drag-release debounce; windows float on the pan center (not grid-snapped). Implant chrome: ImplantHeader anchor name + extent subtitle; map palettes stay out of theme accent roles (ACCENT_ACTIVE gold is the settlement marker''s).
|
||||
|
||||
Implementation note (Tyre, T-1124 report): DISTRICT_WINDOW_MIN_ZOOM proposed at 6.0 but atlas_viewer.gd caps _view_zoom at MAX_ZOOM = 8.0 — only a 6.0-8.0 band for the whole in-window-zoom detail story the SS5 legibility argument depends on. Tunable client constant, not wire contract: either lower the swap threshold or raise MAX_ZOOM; decide with on-screen-scale math at implementation.', NULL, '2026-07-18 10:02:32', '2026-07-18 10:02:32.846', '2026-07-18 10:02:32.846', NULL, 'b7437067dede390cbbf5d5d758b3b1a7', 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 ('06FPRZZ0P42NHC1QR5S3737EV4', 'status', 'in_progress', 'review', NULL, '2026-07-18 10:30:08', '2026-07-18 10:30:08.113', '2026-07-18 10:30:08.113', NULL, '475845ef730811d0a00675fcffba98fe', 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 ('06FPQXHDSMSVD3VADV38NG9STW', 'status', 'in_progress', 'review', NULL, '2026-07-18 10:30:08', '2026-07-18 10:30:08.116', '2026-07-18 10:30:08.116', NULL, '4446cca99e042920271275c7e16b4934', 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 ('06FPQXFFHXEEDQEM7PGXAH3534', 'status', 'in_progress', 'review', NULL, '2026-07-18 10:30:08', '2026-07-18 10:30:08.116', '2026-07-18 10:30:08.116', NULL, '748ea7e1d521afc72a2f34adf71c4f50', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
|
||||
@@ -2218,3 +2218,41 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat
|
||||
|
||||
Implementation note (Tyre, T-1124 report): DISTRICT_WINDOW_MIN_ZOOM proposed at 6.0 but atlas_viewer.gd caps _view_zoom at MAX_ZOOM = 8.0 — only a 6.0-8.0 band for the whole in-window-zoom detail story the SS5 legibility argument depends on. Tunable client constant, not wire contract: either lower the swap threshold or raise MAX_ZOOM; decide with on-screen-scale math at implementation.', 'backlog', 'high', NULL, 'client', NULL, '2026-07-18 10:02:12.668', '2026-07-18 10:02:32.846', NULL, 'a62fcba50644d79ffb1a1950f2df8a32', 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 ('06FQ9GQDWFC5S4PK17NGX35RFG', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'msgpack Vec-u8 layer fields decode as generic Array, not PackedByteArray — add serde_bytes or client-side conversion', 'Found during T-1118/T-1119 (Stig, confirmed by Dudley): rmp_serde serializes plain Vec-u8 struct fields (RegionGridLayer season/weather/moisture_q, DistrictGridLayer morphology/elev_q, and now QuarterFootprintLayer-adjacent arrays) as generic msgpack arrays rather than bin format, so the pure-GDScript msgpack addon decodes them as generic Array, not PackedByteArray. The existing ''is PackedByteArray'' guards on the client are therefore untested dead branches against real wire data; per-element Variant overhead on dense grids is real but small at current sizes. Fix options: (a) serde_bytes annotations server-side (bin encoding — check the GDScript addon decodes bin to PackedByteArray), (b) drop the dead guards and standardize on generic-Array handling with defensive decode (what the new T-1118/T-1119 code does), (c) leave as-is documented. Decide once, apply consistently across all dense-grid layers. Pre-existing gap — predates this batch; district_grid shipped this way in T-1046.', 'backlog', 'low', NULL, 'client', NULL, '2026-07-18 10:25:59.779', '2026-07-18 10:25:59.779', NULL, '05cc3a346e0a920cf531becf89f42d11', 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 ('06FPRZZ0P42NHC1QR5S3737EV4', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Design: Atlas regional map view — windowed district-resolution biome/climate screen (D-226)', 'Jeroen (2026-07-16): the Atlas needs the jet-plane altitude — a windowed district-resolution (2km-cell) map screen bridging the planetary canvas and the (never-mapped, D-226(d)) chunk/voxel world. Today the viewer is one whole-body texture with client-side pan/zoom; AtlasLayerRequest is {body_id, up_to} whole-body only — no rect/window/LOD machinery exists anywhere (recon-verified). Design pass (Tyre data shape + Araminta encoding, the T-1112 pattern): (1) windowed request protocol — rect/center+radius params on a new or extended layer request, served by calling derive_district per cell (district_profile.rs:1256, pure/on-demand — NOT the coarse eager grid); (2) which fields ship at district resolution (morphology, elev_q, temperature, moisture, vegetation — wire-integer discipline per D-010); (3) the screen: entry from a planetary-map click/settlement, second canvas vs zoom-threshold LOD swap, overlay/legend reuse; (4) budget: window size caps, caching, re-request-on-pan. Record as a D-226 amendment. District resolution is ABOVE the D-226(d) quarter-skeleton floor — in remit. Wiring is a follow-up ticket once the design is recorded. Natural batch-mates: T-1118 (climate overlay) + T-1119 (quarter glyphs). T-1123 (server-side window renderer) is the data-side proof and shares the per-cell derive pattern.
|
||||
|
||||
---
|
||||
Refinement (2026-07-18, Si review + lead rulings — binding for the design pass):
|
||||
|
||||
CORRECTED ANCHORS (post PR #182 rewrite): derive_district is now district_profile.rs:1415 (signature gained climate: &ClimateConstants; delegates to the shared invent_primitives — still pure/on-demand, still NOT the coarse eager grid). AtlasLayerRequest is server/src/atlas/layer_proxy.rs:39 (not bridge/mod.rs); its up_to field is currently unwired (cascade always runs to Region). AtlasLayerResponse growth-ceiling doc at layer_proxy.rs:76-79. Five-shape demux cap at bridge/mod.rs:60-76.
|
||||
|
||||
RULING 1 — request side (closed, not open): the windowed request MUST be optional window fields ON AtlasLayerRequest (serde-default; absent = whole-body, wire back-compat) — a new top-level request shape is FORBIDDEN by the five-shape demux ceiling (PR #184 Tyre ruling: the sixth shape triggers the D-225 tagged-envelope migration; a window param does not justify paying that now). The ticket phrase ''a new or extended layer request'' is superseded: extended only.
|
||||
|
||||
RULING 2 — response side (mandatory explicit resolution IN the amendment): the AtlasLayerResponse one-Option-field-per-layer pattern tops out around six per its own doc; region_grid is the fifth and quarter_footprints (T-1119, THIS batch) consumes the sixth. The windowed district payload is therefore the SEVENTH — the design must explicitly choose and record its carrier: (a) a seventh Option field busting the soft response ceiling with rationale + a re-pinned ceiling, (b) a response-side tagged-envelope/second-response-shape migration, or (c) another mechanism (e.g. the window response as its own payload kind inside the existing atlas request/response buffers). Cite the T-1127 ruling (the ceiling governs NEW TOP-LEVEL Option layers, not per-cell fields inside a shipped layer) and keep the request-cap and response-budget questions explicitly distinct — they are different ceilings with different hardness.
|
||||
|
||||
FIELD LIST — two mandatory dispositions: (1) glaciation_grade — T-1127 explicitly deferred its wire+client half to this design pass (Vec of u8, elev_q precedent, probe ice-tint as the render pattern); accept or reject EXPLICITLY, lean accept. (2) vegetation now includes Marine at discriminant 6 (T-1126) — any palette/legend must be exhaustive (the probe palette match is a compile-time guard; the GDScript side needs the discipline manually).
|
||||
|
||||
Reusable precedents verified: aliveness_probe --render (T-1123) is the working per-cell derive_district-in-a-window loop + 17-entry MORPHOLOGY_RGB palette; RegionGridLayer (layer_proxy.rs:154-165) is the dense-grid wire-shape precedent (parallel Vec arrays, documented sentinels e.g. REGION_TEMP_NONE_DC); DistrictPos = (i32,i32) at scale.rs:75. Deliverable unchanged: D-226 amendment + proposed follow-up wiring ticket(s); no implementation in this ticket.', 'review', 'high', NULL, 'client', 'D-226', '2026-07-16 19:55:47.761', '2026-07-18 10:30:08.108', NULL, '55a8b7e057612d1b6f1d8bd41de74d3c', 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 ('06FPQXHDSMSVD3VADV38NG9STW', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Wire QuarterFootprintLayer per the D-226 T-1112 amendment (six touch points)', 'Implements the design recorded in the D-226 amendment (2026-07-16, T-1112, merged PR #179). Six touch points, each named in the amendment SS4: (1) ZoningType gains PartialOrd/Ord derives mirroring DistrictType''s T-994 precedent (enables the dominant_zoning declaration-order tie-break); (2) AtlasLayerResponse.quarter_footprints field + build_quarter_footprint_layer() mirroring build_district_grid, keyed off non-empty state.quarters, aggregates keyed by city_id (join via the same deterministic QuarterId derivation the dispatch uses); (3) protocol.gd passthrough; (4) OVERLAY_DEFS gen_* id (atlas_viewer.gd); (5) _draw_gen_* scaled-glyph renderer anchored on the L3 settlement dot — shape=dominant district type, color=density ramp on the settlement-gold family, zoom-gated at SETTLEMENT_LABEL_MIN_ZOOM (atlas_marker_overlay.gd); (6) GENERATION_LEGEND entry (atlas_legend_panel.gd). Five aggregate fields: density_avg_pct u8, dominant_district_type, dominant_zoning, landmark_count u8, corridor_count u8; landmark/corridor tooltip-only per the D-226(d) ceiling.
|
||||
|
||||
---
|
||||
Refinement (2026-07-18, Si review — READY, all anchors verified current): ZoningType at generator.rs:234-235 missing PartialOrd/Ord exactly as stated (DistrictType''s T-994 derive block at :207 is the mirror). build_district_grid mirror template at layer_proxy.rs:106-133 (None-on-empty-source pattern confirmed); AtlasLayerResponse currently 5 layer fields — quarter_footprints is the SIXTH and, per the struct''s own growth doc at :76-79, the final one the current pattern allows (T-1124''s design pass, same batch, resolves what carries any seventh — do not resolve it here, just implement the sixth cleanly).
|
||||
|
||||
QUARTERS ARE POPULATED TODAY (critical check passed): BodyWorldState.quarters (body_world_state.rs:98) is filled by plugin.rs:365-367 on GenCompletion::SkeletonGenerated, and the executor (gen_queue.rs:436-474 GenerateSkeleton arm) calls the real generate_quarter_skeleton() + assign_all_block_tags() — NOT a stub. The stale TODO(#957) comment at plugin.rs:361-363 predates T-957 landing; delete it in passing. QuarterId derivation: plugin.rs:430/:648 via SeedDomain::Layer4Quarter (seed.rs:301).
|
||||
|
||||
Client anchors: SETTLEMENT_LABEL_MIN_ZOOM = 2.0 at atlas_marker_overlay.gd:113; L3 settlement-dot anchor _draw_gen_settlements at :695; _draw_gen_district shape template at :477; GENERATION_LEGEND at atlas_legend_panel.gd:41 (pure additive table; legend rows are gate-enforced by test_atlas_overlays.gd:192-209); protocol.gd:821 region_grid passthrough is the freshest sibling to mirror.
|
||||
|
||||
IN-SCOPE boilerplate not named in the six points: the get/set_generation_quarter_footprints accessor pair on atlas_viewer.gd (folded into touch point 4, exactly as region_grid''s accessors ride its OVERLAY_DEFS entry; protocol dispatch calls the setter — see protocol.gd:436 pattern).
|
||||
|
||||
Batch split (lead): points 1-2 (server) = Dudley, who also owns the gen_fixtures.rs edits for this batch (consider adding a populated quarter_footprints literal alongside T-1118''s region_grid literal — reviewers will expect the new layer to have fixture coverage); points 3-6 (client) + T-1118 = Stig. Dudley pins the quarter_footprints wire field names/types FIRST and messages Stig the shape before Stig wires the client half.', 'review', 'medium', NULL, 'server', 'D-226', '2026-07-16 17:25:23.533', '2026-07-18 10:30:08.116', NULL, '5df4d43574cc60403e3bf1b649459786', 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 ('06FPQXFFHXEEDQEM7PGXAH3534', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas climate overlay — render region_grid (temp/season/weather/moisture) in the viewer', 'Follow-up to T-1113 (merged PR #179): the server now serves RegionGridLayer (dense row-major; season/weather repr(u8) discriminants, mean_temp deci-degC i16 with i16::MIN airless sentinel, moisture_q u8) through AtlasLayerResponse.region_grid, and protocol.gd passes it through. Build the client overlay per the D-226 incremental-overlay pattern: OVERLAY_DEFS gen_* id (atlas_viewer.gd), _draw_gen_* renderer (atlas_marker_overlay.gd — a region-grid fill analogous to _draw_gen_district but at region granularity), GENERATION_LEGEND entry (atlas_legend_panel.gd). Pick ONE visual channel (mean temp ramp is the obvious first; season/weather as tooltip or variant overlays). Also add a populated region_grid wire fixture (all three committed fixtures carry nil — noted in PR #179).
|
||||
|
||||
---
|
||||
Refinement (2026-07-18, Si review — verified anchors): protocol.gd = client/scripts/protocol/protocol.gd (passthrough already shipped at :821). Touch points with directly-copyable district_grid precedent: atlas_viewer.gd:149-153 (OVERLAY_DEFS pattern) + :376-385 (set/get_generation_district_grid accessor pair to mirror) + :436 (dispatch in _on_atlas_layers_received); atlas_marker_overlay.gd:477-494 (_draw_gen_district, dispatched :185-188); atlas_legend_panel.gd:82-88.
|
||||
|
||||
COORDINATE PATH (explicit, two patterns coexist in the same file): copy _draw_gen_district''s SELF-CONTAINED mapping — cols/rows come from the layer dict itself (server-computed extent), cw = tex_w/cols, ch = tex_h/rows, fills the whole heightmap texture. Do NOT use the _gen_pos/_gen_grid_w/_gen_grid_h path (that is for Layer1 point data like rivers).
|
||||
|
||||
Legend row is GATE-ENFORCED: test_atlas_overlays.gd:192-209 generically asserts every gen_* overlay id has a legend row — the legend entry is required for the suite to pass, not polish.
|
||||
|
||||
Fixtures: client/tests/fixtures/msgpack/atlas_response_{ready,pending,not_found}.msgpack, generated by server/tests/gen_fixtures.rs::generate_atlas_layer_response_fixtures (:627/:641/:655 currently hardcode region_grid: None). Regen = make fixtures (NOT make fixtures-gauntlet — separate live pipeline). Populated fixture = add a non-empty RegionGridLayer literal following the road_graph/settlements populated literals at :577-618, run make fixtures, extend the Tier-2 replay test at test_atlas_overlays.gd:149. The server-side literal edit lands via Dudley (batch-mate, owns server/tests in this batch) — coordinate the literal''s contents with him; the client-side replay-test extension is this ticket''s.
|
||||
|
||||
Channel ruling confirmed: mean-temp ramp first (i16 deci-degC, REGION_TEMP_NONE_DC = i16::MIN airless sentinel needs an explicit render disposition — distinct sentinel color or skip); season/weather/moisture as tooltip or later variant overlays, not this ticket.', 'review', 'medium', NULL, 'client', 'D-226', '2026-07-16 17:25:07.599', '2026-07-18 10:30:08.116', NULL, 'a018183b9ea2c1388fdc613cd72a3217', 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);
|
||||
|
||||
Reference in New Issue
Block a user