test(simulation): post-adversarial workshop benches — population survey, chunk rung, S2 density, global tier
hydrology_equilibrium_bench: bench_population_survey_all_committed_bodies (all 267 real heightmaps solved independently — zero carved cells population- wide, ~0.86s total, byte-exact determinism; closes Troblum B1) + bench_per_basin_size_distribution_real_population (22,270 basins: dense wins 100% for lake carriers). bmv_gridunit_bench: chunk-64m per-cell + deep-step canvas benches (1,838 ns/cell, ~1.7s full 4K; Option D's missing row) + S2 courses-density benches (+38-87% at chunk/block, mechanism traced to station spacing scaling with rung cutoff). bmv_global_tier_bench (new): real per-body radii from systems.db via BodyParamsReader — global tier ~8.85MB PNG across the population (supersedes the ~174MB mis-priced figure), rung-0 derive ~16-21ms/body measured. All #[ignore]d release tests, stability re-run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1779,3 +1779,37 @@ 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 ('06FRCF0CX1Y5DTD3ER2JCDT27G', 'status', 'review', 'done', NULL, '2026-07-23 18:06:12', '2026-07-23 18:06:12.146', '2026-07-23 18:06:12.146', NULL, 'b2f9dd6df75e6fc00da53a9d85582167', 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 ('06FRZKCN13EF5TD9EZTXMSJ7EG', 'status', 'review', 'done', NULL, '2026-07-23 18:06:12', '2026-07-23 18:06:12.147', '2026-07-23 18:06:12.147', NULL, '03911a8b5220fca15a57cac632fdeeea', 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 ('06FRZKDFB23YFACY2G4M6WRSXC', 'status', 'review', 'done', NULL, '2026-07-23 18:06:12', '2026-07-23 18:06:12.147', '2026-07-23 18:06:12.147', NULL, '9356438925d73d203f8201d9eebfbd09', 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 ('06FRXGSXBZKXTHR7MR5K9H2HRG', 'description', 'Pre-existing architectural quirk found by Dudley during T-1168 integration testing (2026-07-23, not introduced by that batch): derive_district_profile''s cell-aggregate-centre sampling and the window path''s district-origin sampling resolve to genuinely different world positions for ''the same DistrictPos'' — full DistrictProfile output legitimately differs between paths (morphology/elev/moisture) at the same nominal district. His integration test was redesigned to compare the riparian signal at a shared exact world position instead (the right test). Investigate whether any existing batch/window consumer pair assumes positional agreement (city placement vs window rendering?), decide the canonical sampling convention, and either unify or document the divergence as intentional with the reasoning.', 'Pre-existing architectural quirk found by Dudley during T-1168 integration testing (2026-07-23, not introduced by that batch): derive_district_profile''s cell-aggregate-centre sampling and the window path''s district-origin sampling resolve to genuinely different world positions for ''the same DistrictPos'' — full DistrictProfile output legitimately differs between paths (morphology/elev/moisture) at the same nominal district. His integration test was redesigned to compare the riparian signal at a shared exact world position instead (the right test). Investigate whether any existing batch/window consumer pair assumes positional agreement (city placement vs window rendering?), decide the canonical sampling convention, and either unify or document the divergence as intentional with the reasoning.
|
||||
|
||||
D-255 (2026-07-24): the tagged-envelope step-canvas serving (T-1181) depends on batch and window derive agreeing cell-for-cell — this bug now also blocks the step-canvas serving path, and priority is raised accordingly (Tyre disposition, body-map-viewer workshop). No supersession; intent unchanged.', NULL, '2026-07-24 07:12:48', '2026-07-24 07:12:48.893', '2026-07-24 07:12:48.893', NULL, '00522c2052d6e2ef32fc4d363ac60981', 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 ('06FRXKFEJMDEPQ0PZ5Q862DHKG', 'description', 'Jeroen, 2026-07-23, reviewing the T-1170 course captures: ''there are a bunch of graphical cleanups I would want to suggest around line thickness and tapering off to a point at the source to make the map read more fluent, but I feel map polish like that is better off as a single large pass later.'' This ticket is that pass''s collector — park presentation refinements here rather than folding them into feature batches. Seeded items: (1) river line thickness tuning across rungs (beyond the functional per-class defaults Araminta confirmed in T-1170); (2) SOURCE TAPERING — courses should taper to a point at their upstream source rather than starting at full class width (the classic cartographic river grammar; likely per-vertex width via Polygon2D strip or per-segment width ramp, since draw_polyline is single-width); (3) candidates declined-as-scope during T-1170 review: class-tinted color ramp (Araminta: width+opacity sufficient for now, hue is solvable-later). Accumulate further items via pql ticket append as they come up in captures/reviews. Scope discipline: correctness issues (ruled values not rendering, clip bugs) are NEVER parked here — they get fixed in their own batches; this pass is aesthetics only. Schedule: after the nature layer stands (post T-1156 wave 2 at the earliest), as one coherent Araminta-led pass.
|
||||
|
||||
REFERENCE (Jeroen, 2026-07-23): RimWorld''s world map as the fluency benchmark — ''the rimworld maps do roads, rivers, coasts and biomes quite well'' (hex substrate explicitly NOT us; the techniques transfer, the tiling doesn''t). Extracted techniques for this pass: (1) RIVERS AS NETWORKS — visible tributary-joins-trunk convergence, subtle width variation along the run, taper-to-source (his earlier item 2), thin/consistent/restrained overall; (2) ROADS VS RIVERS disambiguated by COLOR + STRAIGHTNESS (grey chord-like vs blue winding), not width — the wave-2 road-rendering rule; (3) COASTS as a shoreline GRADIENT — beach/transition band + subtle near-shore water shading (our coastal/transition morphology class already exists; presentation only); (4) BIOME/RELIEF TEXTURE — stipple/texture density carrying hills/mountains/forest on top of hue; strong fit for us since T-1162''s vegetation-patchiness and relief fields can DRIVE stipple density (texture as data, not decoration); (5) geographic LABELS do heavy fluency lifting — that half lives in T-1169, coordinate the passes. Screenshot reference in the session record 2026-07-23.
|
||||
|
||||
Reference screenshot saved in-repo: docs/design/references/rimworld-world-map-fluency.jpg (+ README note in that dir) — supersedes the ''session record'' pointer in the previous append.', 'Jeroen, 2026-07-23, reviewing the T-1170 course captures: ''there are a bunch of graphical cleanups I would want to suggest around line thickness and tapering off to a point at the source to make the map read more fluent, but I feel map polish like that is better off as a single large pass later.'' This ticket is that pass''s collector — park presentation refinements here rather than folding them into feature batches. Seeded items: (1) river line thickness tuning across rungs (beyond the functional per-class defaults Araminta confirmed in T-1170); (2) SOURCE TAPERING — courses should taper to a point at their upstream source rather than starting at full class width (the classic cartographic river grammar; likely per-vertex width via Polygon2D strip or per-segment width ramp, since draw_polyline is single-width); (3) candidates declined-as-scope during T-1170 review: class-tinted color ramp (Araminta: width+opacity sufficient for now, hue is solvable-later). Accumulate further items via pql ticket append as they come up in captures/reviews. Scope discipline: correctness issues (ruled values not rendering, clip bugs) are NEVER parked here — they get fixed in their own batches; this pass is aesthetics only. Schedule: after the nature layer stands (post T-1156 wave 2 at the earliest), as one coherent Araminta-led pass.
|
||||
|
||||
REFERENCE (Jeroen, 2026-07-23): RimWorld''s world map as the fluency benchmark — ''the rimworld maps do roads, rivers, coasts and biomes quite well'' (hex substrate explicitly NOT us; the techniques transfer, the tiling doesn''t). Extracted techniques for this pass: (1) RIVERS AS NETWORKS — visible tributary-joins-trunk convergence, subtle width variation along the run, taper-to-source (his earlier item 2), thin/consistent/restrained overall; (2) ROADS VS RIVERS disambiguated by COLOR + STRAIGHTNESS (grey chord-like vs blue winding), not width — the wave-2 road-rendering rule; (3) COASTS as a shoreline GRADIENT — beach/transition band + subtle near-shore water shading (our coastal/transition morphology class already exists; presentation only); (4) BIOME/RELIEF TEXTURE — stipple/texture density carrying hills/mountains/forest on top of hue; strong fit for us since T-1162''s vegetation-patchiness and relief fields can DRIVE stipple density (texture as data, not decoration); (5) geographic LABELS do heavy fluency lifting — that half lives in T-1169, coordinate the passes. Screenshot reference in the session record 2026-07-23.
|
||||
|
||||
Reference screenshot saved in-repo: docs/design/references/rimworld-world-map-fluency.jpg (+ README note in that dir) — supersedes the ''session record'' pointer in the previous append.
|
||||
|
||||
RE-SCOPED by D-255 (2026-07-24, body-map-viewer workshop): the per-vertex river tapering/width-grammar work lands on the NEW screen-space annotation layer (T-1182) via Polygon2D strips — draw_polyline cannot taper. The c1 styling-engine blocker is DISCHARGED: measurement ⑥ landed (Image.set_pixel 77.5 ns/cell flat) and the call resolved CPU-first; shaders deferred, not a precondition. This ticket now depends only on the annotation layer landing (blocked-by T-1182, edge added). Not cancelled — re-homed onto the new component, unblocked otherwise.', NULL, '2026-07-24 07:12:51', '2026-07-24 07:12:51.866', '2026-07-24 07:12:51.866', NULL, 'b6d9c3f3d348683b2d1bb07ddd075189', 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 ('06FRXGSXBZKXTHR7MR5K9H2HRG', 'priority', 'low', 'high', NULL, '2026-07-24 07:13:02', '2026-07-24 07:13:02.546', '2026-07-24 07:13:02.546', NULL, '573adb2f20e62cdd046ce932ecb561dd', 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 ('06FRJD6EKPBQE08NA8VHP692W8', 'description', 'T-1153 broke the T-1120/T-1121 golden capture harness: client/tests/visual_scenarios.gd and visual_capture.gd call app._regional_screen._viewer.get_heightmap_texture()/show_body() — both crash against AtlasWindowViewer (regional_screen now wraps the ladder viewer; AtlasViewer is unreachable from nav). Confirmed NOT wired into tests/run-godot or the pre-push hook (no reference in either), so nothing blocks, but the 12 curated atlas_* goldens and the --atlas-matrix capture path are dead until redesigned for the ladder (capture at defined rungs/zooms instead of the fixed heightmap frame; the new canonical orbital frame is the natural replacement for the old whole-body shot). Also decide the fate of the retired AtlasViewer code these harnesses were the last live consumers of — likely deletable once T-1156 (overlay port) settles what carries forward.
|
||||
|
||||
Live round 4 addendum: client/tests/test_atlas_window_overlay_draw_smoke.gd (3 scenarios -> now 2 after removing a flaky harness-sanity check: single-window draw + tile-mosaic draw, both asserting real composited pixels via SubViewport render) is a standalone gdUnit file with its own headless-skip guard, added because this redesign hadn''t landed yet. When this ticket lands, migrate its 2 scenarios into the redesigned tests/visual.json harness (folding the standalone file away) for consistency with the rest of the real-rendering test suite — see docs/DEVOPS.md''s ''Real-rendering test exception'' note for the interim rationale.', 'T-1153 broke the T-1120/T-1121 golden capture harness: client/tests/visual_scenarios.gd and visual_capture.gd call app._regional_screen._viewer.get_heightmap_texture()/show_body() — both crash against AtlasWindowViewer (regional_screen now wraps the ladder viewer; AtlasViewer is unreachable from nav). Confirmed NOT wired into tests/run-godot or the pre-push hook (no reference in either), so nothing blocks, but the 12 curated atlas_* goldens and the --atlas-matrix capture path are dead until redesigned for the ladder (capture at defined rungs/zooms instead of the fixed heightmap frame; the new canonical orbital frame is the natural replacement for the old whole-body shot). Also decide the fate of the retired AtlasViewer code these harnesses were the last live consumers of — likely deletable once T-1156 (overlay port) settles what carries forward.
|
||||
|
||||
Live round 4 addendum: client/tests/test_atlas_window_overlay_draw_smoke.gd (3 scenarios -> now 2 after removing a flaky harness-sanity check: single-window draw + tile-mosaic draw, both asserting real composited pixels via SubViewport render) is a standalone gdUnit file with its own headless-skip guard, added because this redesign hadn''t landed yet. When this ticket lands, migrate its 2 scenarios into the redesigned tests/visual.json harness (folding the standalone file away) for consistency with the rest of the real-rendering test suite — see docs/DEVOPS.md''s ''Real-rendering test exception'' note for the interim rationale.
|
||||
|
||||
RE-SCOPED by D-255 (2026-07-24, body-map-viewer workshop): this becomes the capture harness for the STEPPED render architecture — goldens key on (body, step) canvases, not the retired continuous-zoom frames. The T-1152/T-1153 test suites (coverage-walk, continuous-zoom seams, compute_tile_grid mosaic) retire with their code in T-1182''s change; this re-scoped harness is their replacement and the eyeball-check substrate for every step canvas. More needed than ever — keep, don''t cancel.', NULL, '2026-07-24 07:13:05', '2026-07-24 07:13:05.192', '2026-07-24 07:13:05.192', NULL, 'bedc693c890c890566674646daebd3f7', 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 ('06FRMPSM9GSWK586N5GBP2N22G', 'description', 'PR #192 review (Tyre): the viewer sits at exactly gdlint''s 1000-line cap, twice trimmed to fit, and fuses three separable responsibilities: (a) input handling (_gui_input/_process/_apply_pan_delta/edge-scroll), (b) request orchestration + rung reselection (_maybe_reselect_rung/_maybe_refloat_window), (c) the canonical-frame state machine (_zoom_at zoom floor/_is_at_canonical_frame/_maybe_reset_to_canonical_frame/_canonical_fit_zoom). All six live fix rounds of the T-1152/T-1153 batch traced to held-state/transform/lifetime coupling in this file — extract cluster (c) (+ likely (b)) into its own class BEFORE the next change breaches the cap and forces either a deadline extraction or comment-gutting that loses the hard-won live-round rationale comments. The tile-set (atlas_window_tile_set.gd) and geometry (atlas_window_geometry.gd) extractions are the precedent. Behavior-preserving refactor: the zoom-ladder suites (44+122+20 tests) are the safety net.', 'PR #192 review (Tyre): the viewer sits at exactly gdlint''s 1000-line cap, twice trimmed to fit, and fuses three separable responsibilities: (a) input handling (_gui_input/_process/_apply_pan_delta/edge-scroll), (b) request orchestration + rung reselection (_maybe_reselect_rung/_maybe_refloat_window), (c) the canonical-frame state machine (_zoom_at zoom floor/_is_at_canonical_frame/_maybe_reset_to_canonical_frame/_canonical_fit_zoom). All six live fix rounds of the T-1152/T-1153 batch traced to held-state/transform/lifetime coupling in this file — extract cluster (c) (+ likely (b)) into its own class BEFORE the next change breaches the cap and forces either a deadline extraction or comment-gutting that loses the hard-won live-round rationale comments. The tile-set (atlas_window_tile_set.gd) and geometry (atlas_window_geometry.gd) extractions are the precedent. Behavior-preserving refactor: the zoom-ladder suites (44+122+20 tests) are the safety net.
|
||||
|
||||
SUPERSEDED by the body-map-viewer render architecture (D-255, 2026-07-24): the canonical-frame + rung-reselection state machine this ticket would extract is exactly what changes shape under stepped zoom (no continuous zoom floor, no _canonical_fit_zoom, select_rung retired). Extracting code about to be deleted is waste (Stig''s round-1 call, confirmed by the workshop). The new component''s decomposition (input/pan, step-cross orchestration, two draw layers) is decided fresh in T-1182, not by reviving this ticket. Cancelled.', NULL, '2026-07-24 07:13:14', '2026-07-24 07:13:14.172', '2026-07-24 07:13:14.172', NULL, 'f23e0d9981db5d6f939140cc8545d9d0', 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 ('06FRMPSM9GSWK586N5GBP2N22G', 'status', 'backlog', 'cancelled', NULL, '2026-07-24 07:13:18', '2026-07-24 07:13:18.469', '2026-07-24 07:13:18.469', NULL, '71fa27b107e5220c44fe22feda2b5c2a', 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 ('06FRY9W24PV55Z6FMW8TEM7XER', 'description', 'Jeroen, 2026-07-23, during the T-1170 live rounds: ''I want to discuss and maybe revise the pixel scan/output mechanism for drawing the map. I feel we can be smarter about this and bypass an entire class of errors we are seeing as well as probably improve performance.'' DISCUSSION FIRST — this is a design conversation with Jeroen (pair/workshop mode), not autonomous work; scheduled after the T-1170/T-1168 cycle closes. The error class in evidence, all descending from immediate-mode draw calls inside a zoom-scaled canvas (_canvas.scale = view_zoom): the per-call-site zoom compensation discipline (_zs/_zs_stroke, silently degrading when one site is missed — PR #195 I1, PR #197 stroke sites), Godot''s line-rasterizer width floor (sub-1.0-canvas-unit strokes collapse to hairline — the T-1170 width bug), the radius-smaller-than-stroke draw_arc regime (the mouth-ring investigation), and arguably the wrap-image resolution family. Candidate directions to bring to the discussion: (a) Tyre''s unscaled screen-space sibling layer (positions transformed, sizes literal — already noted on T-1156 wave 2/T-1158); (b) render-to-texture per window/tile at native resolution, composited as textures (sizes become texel-exact, zoom becomes pure texture transform); (c) shader-side composition of the per-cell data (morphology/courses as data textures, coloring+features in fragment shader — likely the performance win); (d) hybrid. Inputs to gather before the discussion: current draw-call counts/frame costs per rung, the T-1175 polish requirements (per-vertex tapering wants Polygon2D strips or shaders anyway), and the wave-2 marker volume. Relates: T-1158 (viewer decomposition), T-1175 (polish pass), Tyre''s PR #197 Q5 note.
|
||||
|
||||
PREP SESSION COMPLETE + BRIEF SIGNED OFF (2026-07-25, Jeroen + lead + Tyre). Jeroen''s design outline captured and clarified over two AskUserQuestion rounds; Tyre delivered governance-delta/implications pass and ratified the brief (zero misrepresentations, zero blocking gaps). Signed-off workshop brief: docs/workshops/body-map-viewer/body-map-viewer-workshop-brief.md (session artifacts: jeroen-outline.md, clarifications.md, tyre-implications.md, prep-grounding.md in the same dir). Settled premises: server-side content determination per zoom step; client map-art function; RTT terrain + screen-space vector annotations baseline (locks T-1176 candidates b+a; c1 styling open); GPU presentation-only; stepped zoom (supersedes continuous — recorded at workshop filing); tile=1m only, ''gridunit (at zoom level)'' coined; data resolution tunable (1px ideal, 5x5 fallback); hydrology = deterministic equilibrium; client-primary cache (store shape open: server-side SQLite cache / godot-sqlite / file cache — SQLite ships in the Rust server, NOT the Godot client). Workshop: 5 seats (Dudley/Araminta/Stig/Tyre + Troblum r2), 2 rounds + lead interview, extendable at Jeroen''s call, round 1 GATED on measurements — see blocker edges. Expected Output 2 mandates an explicit deprecation sweep (Clerk audit) of all conflicting DQR records/tickets at filing.', 'Jeroen, 2026-07-23, during the T-1170 live rounds: ''I want to discuss and maybe revise the pixel scan/output mechanism for drawing the map. I feel we can be smarter about this and bypass an entire class of errors we are seeing as well as probably improve performance.'' DISCUSSION FIRST — this is a design conversation with Jeroen (pair/workshop mode), not autonomous work; scheduled after the T-1170/T-1168 cycle closes. The error class in evidence, all descending from immediate-mode draw calls inside a zoom-scaled canvas (_canvas.scale = view_zoom): the per-call-site zoom compensation discipline (_zs/_zs_stroke, silently degrading when one site is missed — PR #195 I1, PR #197 stroke sites), Godot''s line-rasterizer width floor (sub-1.0-canvas-unit strokes collapse to hairline — the T-1170 width bug), the radius-smaller-than-stroke draw_arc regime (the mouth-ring investigation), and arguably the wrap-image resolution family. Candidate directions to bring to the discussion: (a) Tyre''s unscaled screen-space sibling layer (positions transformed, sizes literal — already noted on T-1156 wave 2/T-1158); (b) render-to-texture per window/tile at native resolution, composited as textures (sizes become texel-exact, zoom becomes pure texture transform); (c) shader-side composition of the per-cell data (morphology/courses as data textures, coloring+features in fragment shader — likely the performance win); (d) hybrid. Inputs to gather before the discussion: current draw-call counts/frame costs per rung, the T-1175 polish requirements (per-vertex tapering wants Polygon2D strips or shaders anyway), and the wave-2 marker volume. Relates: T-1158 (viewer decomposition), T-1175 (polish pass), Tyre''s PR #197 Q5 note.
|
||||
|
||||
PREP SESSION COMPLETE + BRIEF SIGNED OFF (2026-07-25, Jeroen + lead + Tyre). Jeroen''s design outline captured and clarified over two AskUserQuestion rounds; Tyre delivered governance-delta/implications pass and ratified the brief (zero misrepresentations, zero blocking gaps). Signed-off workshop brief: docs/workshops/body-map-viewer/body-map-viewer-workshop-brief.md (session artifacts: jeroen-outline.md, clarifications.md, tyre-implications.md, prep-grounding.md in the same dir). Settled premises: server-side content determination per zoom step; client map-art function; RTT terrain + screen-space vector annotations baseline (locks T-1176 candidates b+a; c1 styling open); GPU presentation-only; stepped zoom (supersedes continuous — recorded at workshop filing); tile=1m only, ''gridunit (at zoom level)'' coined; data resolution tunable (1px ideal, 5x5 fallback); hydrology = deterministic equilibrium; client-primary cache (store shape open: server-side SQLite cache / godot-sqlite / file cache — SQLite ships in the Rust server, NOT the Godot client). Workshop: 5 seats (Dudley/Araminta/Stig/Tyre + Troblum r2), 2 rounds + lead interview, extendable at Jeroen''s call, round 1 GATED on measurements — see blocker edges. Expected Output 2 mandates an explicit deprecation sweep (Clerk audit) of all conflicting DQR records/tickets at filing.
|
||||
|
||||
DELIVERED (2026-07-24): the body-map-viewer workshop is this ticket''s output. D-255 filed (stepped Atlas render architecture: server-determines-content, client map-art function, six-level ladder Global+Region→Chunk, tagged-envelope wire, three-tier cache, cache-accelerated-pure-function seed-chaining, lakes from settled hydrology) + 12 in-place amendments (D-166/D-192/D-225/D-226/D-227/D-243 + river-courses-t1170 gloss) + Clerk audit clean (2 unswept conflicts found and fixed: t1143 doc superseded banner, CLAUDE.md Phase-4 row) + measurements ①–⑥ and the population survey all MEASURED + implementation chain T-1181–T-1185 with reconciliations (T-1158 cancelled, T-1175/T-1157 re-scoped, T-1174 raised). Full record: docs/workshops/body-map-viewer/ (workshop-outcomes.md; architecture-briefing-final.md is the plain-language companion).', NULL, '2026-07-24 07:13:23', '2026-07-24 07:13:23.420', '2026-07-24 07:13:23.420', NULL, 'e4ef9dbd48334f1181f494730f0a09f3', 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 ('06FRY9W24PV55Z6FMW8TEM7XER', 'status', 'in_progress', 'done', NULL, '2026-07-24 07:13:28', '2026-07-24 07:13:28.217', '2026-07-24 07:13:28.217', NULL, '53966f3039143c089e5941fec3db1c86', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
|
||||
@@ -2619,3 +2619,42 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat
|
||||
REPURPOSED as body-map-viewer workshop gate measurement ③ (2026-07-25, brief appendix ③: docs/workshops/body-map-viewer/body-map-viewer-workshop-brief.md). Unblocked since T-1162 shipped the octave-cutoff plumbing this was blocked on. Scope unchanged (block/tile rung per-cell costs + wire at those granularities); its numbers now price the bottom of the stepped gridunit ladder (~10px per 1m tile bottom-out). Round 1 of the workshop is gated on this landing alongside T-1177/T-1178/T-1179.', 'done', 'medium', NULL, 'server', 'D-226', '2026-07-21 19:51:50.248', '2026-07-23 18:06:12.146', NULL, 'c248f2785286f98c3d60982bcfb9fd85', 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 ('06FRZKDFB23YFACY2G4M6WRSXC', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Measurement ⑤: Godot ImageTexture upload cost per step-cross (330K–8.3M px)', 'Workshop measurement for body-map-viewer (brief appendix ⑤; tyre-implications.md §3.5). Measure ImageTexture.create_from_image (and update paths) for 330K–8.3M px images on step-cross — client-side stutter risk for the RTT terrain layer''s hold-fetch-swap. NOT a round-1 gate (may land during round 1), but a real interactive-latency input for Stig Q2. Owner: Stig. Effort est 0.25 day.', 'done', 'medium', NULL, 'client', 'D-226', '2026-07-23 16:27:29.496', '2026-07-23 18:06:12.147', NULL, '149c633463919bfebfbea2bebb8dc566', 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 ('06FRZKCN13EF5TD9EZTXMSJ7EG', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Measurement ④: wire-size table for step-canvas encodings (raw/bit-packed/RLE/PNG + MessagePack round-trip)', 'Workshop gate measurement for body-map-viewer (brief appendix ④; tyre-implications.md §3.3). For a ~330K-gridunit step canvas: dense classification arrays ≈ 4–5 bytes/gridunit ≈ 1.3–1.6 MB/step raw. Produce the comparison table: raw dense vs bit-packed vs run-length vs PNG-encoded raster, with an actual MessagePack round-trip on one real canvas (not arithmetic only). Directly informs the named-feature encoding decision (Araminta Q1) and whether the tagged-envelope migration (D-225 deferral) is forced. Owners: Araminta (encoding) + Dudley (real canvas + numbers). Effort est 0.5 day.', 'done', 'high', NULL, 'server', 'D-225', '2026-07-23 16:27:22.760', '2026-07-23 18:06:12.147', NULL, '47f5693da9e161d70c3389969ff6d051', 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 ('06FS5XQW73B1P8WKR2BCZBFXZW', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Step-canvas serving: StepCanvasRequest/Response tagged envelope (D-255 wire migration)', 'The D-225-discharging migration per D-255(c): one new Inbound variant (StepCanvasRequest, required marker field step_canvas, extending the proven star_map/city_names/browse ShapeProbe pattern in server/src/bridge/mod.rs) + a dedicated StepCanvasResponse (NOT a field on AtlasLayerResponse — the D-226 §2 ceiling is re-scoped to the legacy carrier). Serves all six rungs of the D-255(a) ladder — rung-0 Global variable-extent is a field value, not a different shape; fixed rungs viewport-sized per D-255(b). Encoding: PNG-per-field dense (8 fields: 6 static + glaciation/flooded sim-state L8 planes) + MessagePack-native sparse (courses, cliffs) per the T-1179 measured table. SERVER CACHE TIERS ARE THIS TICKET''S SCOPE TOO (SI gap 3): the D-203-shaped resident global tier (~8.85MB population-wide, measured) + TTL(detail, time, distance) for finer rungs + SIM_STATE_TTL[field] = 1x the field''s own fastest driving clock-bucket per body class (flooded: tidal bucket moon-bearing / seasonal moonless; glaciation: seasonal — D-227 amendment (1), Dudley+Araminta joint formula). ACCEPTANCE GATE (SI gap 2, mandatory per D-227 amendment (3)): byte-identical output test — cache-hit derive path == cache-miss derive path for every rung; the seed-chaining cache-accelerated-pure-function correctness gate, same shape as T-1170''s window-independence invariant. Implementation note carried from measurement S2: courses cost +38-87% at chunk/block spacing (station count scales inversely with rung spacing — 1,732 vs 867 points/course measured); a station-spacing cap independent of rung spacing is a named candidate optimization, decision at implementation. Design sources: dudley-round2.md §(a), tyre-round2.md §(b), D-255(c)(d)(f). Legacy district_window survives byte-unchanged until its consumer is replaced.', 'backlog', 'high', NULL, 'server', 'D-255', '2026-07-24 07:11:27.800', '2026-07-24 07:11:27.800', NULL, 'd6a9e1781177ade8a4dfadb912ad5e6a', 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 ('06FS5XT949C8D2JZRWDX2CRZN8', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Client map component: RTT terrain + screen-space annotations + stepped transport (D-255)', 'The two-layer client rebuild per D-255(a)(b)(e): a render-to-texture terrain layer (per-step data canvas colorized CPU-side — c1 ruling: Image.set_pixel, measured 77.5 ns/cell flat, NOT a hand-rolled buffer write which measured 2x slower; L8 planes where single-channel per measurement ⑤; texture.update reuse on step-cross) + an unscaled screen-space annotation sibling (names, glyphs, course polylines, markers — literal px sizes, positions world→screen). Stepped transport: discrete rung index 0-5, scroll steps, cursor-anchored, edge-scroll pan, full-zoom-out reset to the rung-0 Global frame; hold-fetch-swap on step-cross (morph/tween optional cosmetic follow-on, never re-derivation); step-dependent display ratio (1x1 deep/mid, ~5x5 shallow — presentation only, never spacing/cache-key). EXECUTES THE FULL _canvas.scale RETIREMENT PATH in the same change (tyre-round2.md ~line 1074): (1) _canvas.scale/_canvas.position/_apply_transform continuous-scale model; (2) the _zs/_zs_stroke/_zs_ring_radius compensation family in atlas_window_geometry_nature.gd — deleted wholesale; (3) select_rung + MAX_COVERAGE_M + compute_tile_grid (T-1152/T-1153 code); (4) the AtlasViewer/orbital-mosaic-vs-window two-code-path split (collapses to ''Global opener is rung 0, one viewer one path''); (5) _view_zoom float + _canonical_fit_zoom. Their test suites (coverage-walk unit tests, continuous-zoom seam tests, compute_tile_grid mosaic tests) are DELETED in the same change — never leave old goldens asserting against retired frames (the T-1157 dead-goldens rule); replacement coverage lands under re-scoped T-1157. SURVIVING SURFACES — do not delete (SI gap 1): atlas_window_tile_set.gd''s LRU SHAPE survives as the skeleton for the client cache-store ticket (adapt it, do not delete it — it is not on the retirement path); _filter_for_granularity_v2 (NEAREST/LINEAR per rung is still a real RTT draw-time question); compositing/legend/overlay-bar chrome (call-site updates only). Determinism boundary per D-255(e): client interpolates only within the closed server-supplied input set. Design sources: stig-round1.md, stig-round2.md, D-255(a)(b)(e).', 'backlog', 'high', NULL, 'client', 'D-255', '2026-07-24 07:11:47.490', '2026-07-24 07:11:47.490', NULL, '8c2daef21d9f83357442fcf9301da982', 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 ('06FS5XW0ZMPVYA2CPBBTP88TQC', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Client cache store: FileAccess dir, two-axis eviction, version tag, retention cap (D-255)', 'The client-side cache tiers per D-255(d) and Stig''s three-tier spec (stig-round2.md (c)): in-memory LRU (adapting atlas_window_tile_set.gd''s surviving LRU skeleton from the map-component ticket) + disk-backed FileAccess cache dir with index. Two-axis eviction per D-227 amendment (1) — staleness and storage are DISTINCT: geometry entries never go stale (determinism; byte-valid forever) and are evicted only by (2a) time-since-last-visit (Jeroen''s storage-thrift ruling) and (2b) LRU capacity budget, two independent sweeps kept separate; sim-state entries (frozen/flooded planes) carry the real staleness TTL (SIM_STATE_TTL formula — served/invalidated per the serving ticket''s server-side formula). Rung-0 Global entries: retention floor, never swept. HARDENING REQUIREMENTS from D-255(d), both mandatory: (i) per-body deep-rung retention cap (max resident chunk/block-spacing tile count or disk quota per body, independent of the rung-0 floor — the structural closure of the D-226(d) accumulation gap; the AtlasAgentInterface QA channel inherits the same cap); (ii) every persistent entry carries a schema/version tag (project version or generator stamp) — read-time mismatch = cache miss + re-fetch, NEVER decode (the D-192 co-ship boundary; a disk cache survives game updates). Index-entry schema sketch in stig-round2.md (key/file_path/tier/written_at/last_read_at/size_bytes/sim_ttl/retention_floor); sweep triggers on body-open + coarse background timer, never per-frame. Explicitly rejected by the workshop: SQLite in any shape (server-side relocation, godot-sqlite addon) — plain FileAccess + index won on both agents'' independent analyses. Design sources: stig-round2.md (c), dudley-round2.md (d), D-255(d), D-227 amendments (1)(2).', 'backlog', 'high', NULL, 'client', 'D-255', '2026-07-24 07:12:01.789', '2026-07-24 07:12:01.789', NULL, '671ce378f0b2adbde098e4ef64cc8ea7', 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 ('06FS5XXY5GNCQEXYAYQEQD0CHM', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Hydrology into the pipeline: productionize the T-1177 solver + lake morphology sourcing (D-255)', 'Two halves, one ticket (the D-227 lakes amendment''s implementation; converged in araminta-round2.md §(e) + dudley-interview2-response.md CORRECTED section). HALF 1 — productionize: wire server/src/atlas/hydrology_equilibrium.rs (currently an inert workshop prototype, zero non-test callers) into the derive pipeline: solve once per body at rung-0 Global populate (measured ~24ms/body at 512x256; population survey: all 267 bodies ~0.86s), result held with the global tier (D-203-shaped, keep-always). HALF 2 — lake sourcing: MorphologyZone::Lake (discriminant 1 — ALREADY in the frozen D-239 17-zone vocabulary, no widening) becomes sourced from the settled solver: at derive time a gridunit is Lake when bilinear-sampled HydrologyResult.filled_scaled exceeds bilinear-sampled original elevation (the continuous filled-surface comparison — lake edges refine with rung like coastlines, per D-166; NEVER project basin-cell membership as a discrete lookup, which gives blocky non-refining edges), with today''s ocean_fraction_q>=60 heuristic as fallback where no solve exists. This is seed-chaining mechanism B (coarse continuous primitive sampled fresh per rung — D-255(f)). STATIC classification — distinct from the sim-state flooded plane; a lake''s existence must never flicker on a TTL. NO endorheic bit anywhere (ruled: the cue is outflow-course presence, delivered by the separate outlet-wiring ticket; until that lands the map shows lakes without the drains-vs-closed distinction — honest sequencing per D-227 amendment (4)). Byte cost: zero new wire bytes (existing field). Uniform moisture_q=55 scope limit from the survey noted: affects endorheic/overflow split only, never lake extent.', 'backlog', 'medium', NULL, 'server', 'D-227', '2026-07-24 07:12:17.452', '2026-07-24 07:12:17.452', NULL, '3dafd698cf9833cf55198d56384eb275', 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 ('06FS5XZF4A978WS1J66Q2JBK8C', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Basin-outlet → course-network wiring: the endorheic cue deliverable (D-255)', 'Thread HydrologyResult overflow basins'' resolved outlet_path/spill points into RiverNetwork/courses as D8 downstream continuations, so an overflow lake''s exit river appears in the served courses and an endorheic basin''s absence of one reads as ''no course leaves this lake''. THE RULED ENDORHEIC CUE (D-227 amendment (4), converged Dudley+Araminta): outflow-course PRESENCE — no wire bit, no 18th zone (proportionality: 1,030/22,270 = 4.63% endorheic doesn''t justify widening the frozen vocabulary; the inference is definitionally sound with no misfire case — every Overflow basin has a guaranteed non-empty outlet_path (tested: overflowing_basin_has_nonempty_outlet_path), every Endorheic none). Pre-cleared ADDITIVE by T-1170 Ruling 7b: the RIVER_DOWNSTREAM_TERMINAL sentinel was reserved exactly for endorheic interior sinks, and river_course::build_edges is already no-op-safe on TERMINAL (verified) — not a wire migration. Required regardless of the cue: overflow lakes must show their exit rivers to be hydrologically honest on the map (a lake that drains but shows no outlet river is simply wrong). Until this lands, the map shows lakes (via the lake-sourcing ticket) but not the drains-vs-closed distinction — the recorded honest sequencing. Endorheic basins map to TERMINAL; overflow outlets extend the D8 network from the spill cell along outlet_path. Design sources: dudley-interview2-response.md CORRECTED section, araminta-round2.md §(e), t1177-hydrology.md, D-227 amendment (4).', 'backlog', 'medium', NULL, 'server', 'D-227', '2026-07-24 07:12:29.986', '2026-07-24 07:12:29.986', NULL, 'c328c9c06c251f04977ce9350dc13df8', 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 ('06FRXGSXBZKXTHR7MR5K9H2HRG', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Batch vs window derive paths sample different world positions for the same DistrictPos', 'Pre-existing architectural quirk found by Dudley during T-1168 integration testing (2026-07-23, not introduced by that batch): derive_district_profile''s cell-aggregate-centre sampling and the window path''s district-origin sampling resolve to genuinely different world positions for ''the same DistrictPos'' — full DistrictProfile output legitimately differs between paths (morphology/elev/moisture) at the same nominal district. His integration test was redesigned to compare the riparian signal at a shared exact world position instead (the right test). Investigate whether any existing batch/window consumer pair assumes positional agreement (city placement vs window rendering?), decide the canonical sampling convention, and either unify or document the divergence as intentional with the reasoning.
|
||||
|
||||
D-255 (2026-07-24): the tagged-envelope step-canvas serving (T-1181) depends on batch and window derive agreeing cell-for-cell — this bug now also blocks the step-canvas serving path, and priority is raised accordingly (Tyre disposition, body-map-viewer workshop). No supersession; intent unchanged.', 'backlog', 'low', NULL, 'server', NULL, '2026-07-23 11:36:27.743', '2026-07-24 07:12:48.892', NULL, '2150cc98e2294ca1d408a8aa18db92b1', 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 ('06FRXKFEJMDEPQ0PZ5Q862DHKG', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas map-reading polish pass — river/nature presentation refinements (single large pass)', 'Jeroen, 2026-07-23, reviewing the T-1170 course captures: ''there are a bunch of graphical cleanups I would want to suggest around line thickness and tapering off to a point at the source to make the map read more fluent, but I feel map polish like that is better off as a single large pass later.'' This ticket is that pass''s collector — park presentation refinements here rather than folding them into feature batches. Seeded items: (1) river line thickness tuning across rungs (beyond the functional per-class defaults Araminta confirmed in T-1170); (2) SOURCE TAPERING — courses should taper to a point at their upstream source rather than starting at full class width (the classic cartographic river grammar; likely per-vertex width via Polygon2D strip or per-segment width ramp, since draw_polyline is single-width); (3) candidates declined-as-scope during T-1170 review: class-tinted color ramp (Araminta: width+opacity sufficient for now, hue is solvable-later). Accumulate further items via pql ticket append as they come up in captures/reviews. Scope discipline: correctness issues (ruled values not rendering, clip bugs) are NEVER parked here — they get fixed in their own batches; this pass is aesthetics only. Schedule: after the nature layer stands (post T-1156 wave 2 at the earliest), as one coherent Araminta-led pass.
|
||||
|
||||
REFERENCE (Jeroen, 2026-07-23): RimWorld''s world map as the fluency benchmark — ''the rimworld maps do roads, rivers, coasts and biomes quite well'' (hex substrate explicitly NOT us; the techniques transfer, the tiling doesn''t). Extracted techniques for this pass: (1) RIVERS AS NETWORKS — visible tributary-joins-trunk convergence, subtle width variation along the run, taper-to-source (his earlier item 2), thin/consistent/restrained overall; (2) ROADS VS RIVERS disambiguated by COLOR + STRAIGHTNESS (grey chord-like vs blue winding), not width — the wave-2 road-rendering rule; (3) COASTS as a shoreline GRADIENT — beach/transition band + subtle near-shore water shading (our coastal/transition morphology class already exists; presentation only); (4) BIOME/RELIEF TEXTURE — stipple/texture density carrying hills/mountains/forest on top of hue; strong fit for us since T-1162''s vegetation-patchiness and relief fields can DRIVE stipple density (texture as data, not decoration); (5) geographic LABELS do heavy fluency lifting — that half lives in T-1169, coordinate the passes. Screenshot reference in the session record 2026-07-23.
|
||||
|
||||
Reference screenshot saved in-repo: docs/design/references/rimworld-world-map-fluency.jpg (+ README note in that dir) — supersedes the ''session record'' pointer in the previous append.
|
||||
|
||||
RE-SCOPED by D-255 (2026-07-24, body-map-viewer workshop): the per-vertex river tapering/width-grammar work lands on the NEW screen-space annotation layer (T-1182) via Polygon2D strips — draw_polyline cannot taper. The c1 styling-engine blocker is DISCHARGED: measurement ⑥ landed (Image.set_pixel 77.5 ns/cell flat) and the call resolved CPU-first; shaders deferred, not a precondition. This ticket now depends only on the annotation layer landing (blocked-by T-1182, edge added). Not cancelled — re-homed onto the new component, unblocked otherwise.', 'backlog', 'low', NULL, 'client', 'D-226', '2026-07-23 11:48:08.469', '2026-07-24 07:12:51.865', NULL, '150a69959f11e86bd0d84d33977254dc', 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 ('06FRXGSXBZKXTHR7MR5K9H2HRG', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Batch vs window derive paths sample different world positions for the same DistrictPos', 'Pre-existing architectural quirk found by Dudley during T-1168 integration testing (2026-07-23, not introduced by that batch): derive_district_profile''s cell-aggregate-centre sampling and the window path''s district-origin sampling resolve to genuinely different world positions for ''the same DistrictPos'' — full DistrictProfile output legitimately differs between paths (morphology/elev/moisture) at the same nominal district. His integration test was redesigned to compare the riparian signal at a shared exact world position instead (the right test). Investigate whether any existing batch/window consumer pair assumes positional agreement (city placement vs window rendering?), decide the canonical sampling convention, and either unify or document the divergence as intentional with the reasoning.
|
||||
|
||||
D-255 (2026-07-24): the tagged-envelope step-canvas serving (T-1181) depends on batch and window derive agreeing cell-for-cell — this bug now also blocks the step-canvas serving path, and priority is raised accordingly (Tyre disposition, body-map-viewer workshop). No supersession; intent unchanged.', 'backlog', 'high', NULL, 'server', NULL, '2026-07-23 11:36:27.743', '2026-07-24 07:13:02.546', NULL, '2750e1728d81d27338e4795b9ab238d6', 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 ('06FRJD6EKPBQE08NA8VHP692W8', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Redesign the atlas visual-capture goldens for the zoom ladder (visual_scenarios/visual_capture)', 'T-1153 broke the T-1120/T-1121 golden capture harness: client/tests/visual_scenarios.gd and visual_capture.gd call app._regional_screen._viewer.get_heightmap_texture()/show_body() — both crash against AtlasWindowViewer (regional_screen now wraps the ladder viewer; AtlasViewer is unreachable from nav). Confirmed NOT wired into tests/run-godot or the pre-push hook (no reference in either), so nothing blocks, but the 12 curated atlas_* goldens and the --atlas-matrix capture path are dead until redesigned for the ladder (capture at defined rungs/zooms instead of the fixed heightmap frame; the new canonical orbital frame is the natural replacement for the old whole-body shot). Also decide the fate of the retired AtlasViewer code these harnesses were the last live consumers of — likely deletable once T-1156 (overlay port) settles what carries forward.
|
||||
|
||||
Live round 4 addendum: client/tests/test_atlas_window_overlay_draw_smoke.gd (3 scenarios -> now 2 after removing a flaky harness-sanity check: single-window draw + tile-mosaic draw, both asserting real composited pixels via SubViewport render) is a standalone gdUnit file with its own headless-skip guard, added because this redesign hadn''t landed yet. When this ticket lands, migrate its 2 scenarios into the redesigned tests/visual.json harness (folding the standalone file away) for consistency with the rest of the real-rendering test suite — see docs/DEVOPS.md''s ''Real-rendering test exception'' note for the interim rationale.
|
||||
|
||||
RE-SCOPED by D-255 (2026-07-24, body-map-viewer workshop): this becomes the capture harness for the STEPPED render architecture — goldens key on (body, step) canvases, not the retired continuous-zoom frames. The T-1152/T-1153 test suites (coverage-walk, continuous-zoom seams, compute_tile_grid mosaic) retire with their code in T-1182''s change; this re-scoped harness is their replacement and the eyeball-check substrate for every step canvas. More needed than ever — keep, don''t cancel.', 'backlog', 'medium', NULL, 'client', NULL, '2026-07-22 09:42:47.197', '2026-07-24 07:13:05.192', NULL, 'dd52cedc5657190dc60033ffdca63451', 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 ('06FRMPSM9GSWK586N5GBP2N22G', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Decompose atlas_window_viewer.gd — extract the canonical-frame + rung-reselection cluster', 'PR #192 review (Tyre): the viewer sits at exactly gdlint''s 1000-line cap, twice trimmed to fit, and fuses three separable responsibilities: (a) input handling (_gui_input/_process/_apply_pan_delta/edge-scroll), (b) request orchestration + rung reselection (_maybe_reselect_rung/_maybe_refloat_window), (c) the canonical-frame state machine (_zoom_at zoom floor/_is_at_canonical_frame/_maybe_reset_to_canonical_frame/_canonical_fit_zoom). All six live fix rounds of the T-1152/T-1153 batch traced to held-state/transform/lifetime coupling in this file — extract cluster (c) (+ likely (b)) into its own class BEFORE the next change breaches the cap and forces either a deadline extraction or comment-gutting that loses the hard-won live-round rationale comments. The tile-set (atlas_window_tile_set.gd) and geometry (atlas_window_geometry.gd) extractions are the precedent. Behavior-preserving refactor: the zoom-ladder suites (44+122+20 tests) are the safety net.
|
||||
|
||||
SUPERSEDED by the body-map-viewer render architecture (D-255, 2026-07-24): the canonical-frame + rung-reselection state machine this ticket would extract is exactly what changes shape under stepped zoom (no continuous zoom floor, no _canonical_fit_zoom, select_rung retired). Extracting code about to be deleted is waste (Stig''s round-1 call, confirmed by the workshop). The new component''s decomposition (input/pan, step-cross orchestration, two draw layers) is decided fresh in T-1182, not by reviving this ticket. Cancelled.', 'backlog', 'medium', NULL, 'client', NULL, '2026-07-22 15:04:20.812', '2026-07-24 07:13:14.171', NULL, 'b70e9d80468ec0f8295b561f99c98b2e', 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 ('06FRMPSM9GSWK586N5GBP2N22G', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Decompose atlas_window_viewer.gd — extract the canonical-frame + rung-reselection cluster', 'PR #192 review (Tyre): the viewer sits at exactly gdlint''s 1000-line cap, twice trimmed to fit, and fuses three separable responsibilities: (a) input handling (_gui_input/_process/_apply_pan_delta/edge-scroll), (b) request orchestration + rung reselection (_maybe_reselect_rung/_maybe_refloat_window), (c) the canonical-frame state machine (_zoom_at zoom floor/_is_at_canonical_frame/_maybe_reset_to_canonical_frame/_canonical_fit_zoom). All six live fix rounds of the T-1152/T-1153 batch traced to held-state/transform/lifetime coupling in this file — extract cluster (c) (+ likely (b)) into its own class BEFORE the next change breaches the cap and forces either a deadline extraction or comment-gutting that loses the hard-won live-round rationale comments. The tile-set (atlas_window_tile_set.gd) and geometry (atlas_window_geometry.gd) extractions are the precedent. Behavior-preserving refactor: the zoom-ladder suites (44+122+20 tests) are the safety net.
|
||||
|
||||
SUPERSEDED by the body-map-viewer render architecture (D-255, 2026-07-24): the canonical-frame + rung-reselection state machine this ticket would extract is exactly what changes shape under stepped zoom (no continuous zoom floor, no _canonical_fit_zoom, select_rung retired). Extracting code about to be deleted is waste (Stig''s round-1 call, confirmed by the workshop). The new component''s decomposition (input/pan, step-cross orchestration, two draw layers) is decided fresh in T-1182, not by reviving this ticket. Cancelled.', 'cancelled', 'medium', NULL, 'client', NULL, '2026-07-22 15:04:20.812', '2026-07-24 07:13:18.468', NULL, '955c12d603c68fda38f74a92ab6b942b', 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 ('06FRY9W24PV55Z6FMW8TEM7XER', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Design discussion: revise the Atlas map render mechanism (bypass the zoom-scaled-canvas error class)', 'Jeroen, 2026-07-23, during the T-1170 live rounds: ''I want to discuss and maybe revise the pixel scan/output mechanism for drawing the map. I feel we can be smarter about this and bypass an entire class of errors we are seeing as well as probably improve performance.'' DISCUSSION FIRST — this is a design conversation with Jeroen (pair/workshop mode), not autonomous work; scheduled after the T-1170/T-1168 cycle closes. The error class in evidence, all descending from immediate-mode draw calls inside a zoom-scaled canvas (_canvas.scale = view_zoom): the per-call-site zoom compensation discipline (_zs/_zs_stroke, silently degrading when one site is missed — PR #195 I1, PR #197 stroke sites), Godot''s line-rasterizer width floor (sub-1.0-canvas-unit strokes collapse to hairline — the T-1170 width bug), the radius-smaller-than-stroke draw_arc regime (the mouth-ring investigation), and arguably the wrap-image resolution family. Candidate directions to bring to the discussion: (a) Tyre''s unscaled screen-space sibling layer (positions transformed, sizes literal — already noted on T-1156 wave 2/T-1158); (b) render-to-texture per window/tile at native resolution, composited as textures (sizes become texel-exact, zoom becomes pure texture transform); (c) shader-side composition of the per-cell data (morphology/courses as data textures, coloring+features in fragment shader — likely the performance win); (d) hybrid. Inputs to gather before the discussion: current draw-call counts/frame costs per rung, the T-1175 polish requirements (per-vertex tapering wants Polygon2D strips or shaders anyway), and the wave-2 marker volume. Relates: T-1158 (viewer decomposition), T-1175 (polish pass), Tyre''s PR #197 Q5 note.
|
||||
|
||||
PREP SESSION COMPLETE + BRIEF SIGNED OFF (2026-07-25, Jeroen + lead + Tyre). Jeroen''s design outline captured and clarified over two AskUserQuestion rounds; Tyre delivered governance-delta/implications pass and ratified the brief (zero misrepresentations, zero blocking gaps). Signed-off workshop brief: docs/workshops/body-map-viewer/body-map-viewer-workshop-brief.md (session artifacts: jeroen-outline.md, clarifications.md, tyre-implications.md, prep-grounding.md in the same dir). Settled premises: server-side content determination per zoom step; client map-art function; RTT terrain + screen-space vector annotations baseline (locks T-1176 candidates b+a; c1 styling open); GPU presentation-only; stepped zoom (supersedes continuous — recorded at workshop filing); tile=1m only, ''gridunit (at zoom level)'' coined; data resolution tunable (1px ideal, 5x5 fallback); hydrology = deterministic equilibrium; client-primary cache (store shape open: server-side SQLite cache / godot-sqlite / file cache — SQLite ships in the Rust server, NOT the Godot client). Workshop: 5 seats (Dudley/Araminta/Stig/Tyre + Troblum r2), 2 rounds + lead interview, extendable at Jeroen''s call, round 1 GATED on measurements — see blocker edges. Expected Output 2 mandates an explicit deprecation sweep (Clerk audit) of all conflicting DQR records/tickets at filing.
|
||||
|
||||
DELIVERED (2026-07-24): the body-map-viewer workshop is this ticket''s output. D-255 filed (stepped Atlas render architecture: server-determines-content, client map-art function, six-level ladder Global+Region→Chunk, tagged-envelope wire, three-tier cache, cache-accelerated-pure-function seed-chaining, lakes from settled hydrology) + 12 in-place amendments (D-166/D-192/D-225/D-226/D-227/D-243 + river-courses-t1170 gloss) + Clerk audit clean (2 unswept conflicts found and fixed: t1143 doc superseded banner, CLAUDE.md Phase-4 row) + measurements ①–⑥ and the population survey all MEASURED + implementation chain T-1181–T-1185 with reconciliations (T-1158 cancelled, T-1175/T-1157 re-scoped, T-1174 raised). Full record: docs/workshops/body-map-viewer/ (workshop-outcomes.md; architecture-briefing-final.md is the plain-language companion).', 'in_progress', 'high', NULL, 'client', 'D-226', '2026-07-23 13:25:58.949', '2026-07-24 07:13:23.420', NULL, '5e902693de50646d79225005c3c2875d', 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 ('06FRY9W24PV55Z6FMW8TEM7XER', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Design discussion: revise the Atlas map render mechanism (bypass the zoom-scaled-canvas error class)', 'Jeroen, 2026-07-23, during the T-1170 live rounds: ''I want to discuss and maybe revise the pixel scan/output mechanism for drawing the map. I feel we can be smarter about this and bypass an entire class of errors we are seeing as well as probably improve performance.'' DISCUSSION FIRST — this is a design conversation with Jeroen (pair/workshop mode), not autonomous work; scheduled after the T-1170/T-1168 cycle closes. The error class in evidence, all descending from immediate-mode draw calls inside a zoom-scaled canvas (_canvas.scale = view_zoom): the per-call-site zoom compensation discipline (_zs/_zs_stroke, silently degrading when one site is missed — PR #195 I1, PR #197 stroke sites), Godot''s line-rasterizer width floor (sub-1.0-canvas-unit strokes collapse to hairline — the T-1170 width bug), the radius-smaller-than-stroke draw_arc regime (the mouth-ring investigation), and arguably the wrap-image resolution family. Candidate directions to bring to the discussion: (a) Tyre''s unscaled screen-space sibling layer (positions transformed, sizes literal — already noted on T-1156 wave 2/T-1158); (b) render-to-texture per window/tile at native resolution, composited as textures (sizes become texel-exact, zoom becomes pure texture transform); (c) shader-side composition of the per-cell data (morphology/courses as data textures, coloring+features in fragment shader — likely the performance win); (d) hybrid. Inputs to gather before the discussion: current draw-call counts/frame costs per rung, the T-1175 polish requirements (per-vertex tapering wants Polygon2D strips or shaders anyway), and the wave-2 marker volume. Relates: T-1158 (viewer decomposition), T-1175 (polish pass), Tyre''s PR #197 Q5 note.
|
||||
|
||||
PREP SESSION COMPLETE + BRIEF SIGNED OFF (2026-07-25, Jeroen + lead + Tyre). Jeroen''s design outline captured and clarified over two AskUserQuestion rounds; Tyre delivered governance-delta/implications pass and ratified the brief (zero misrepresentations, zero blocking gaps). Signed-off workshop brief: docs/workshops/body-map-viewer/body-map-viewer-workshop-brief.md (session artifacts: jeroen-outline.md, clarifications.md, tyre-implications.md, prep-grounding.md in the same dir). Settled premises: server-side content determination per zoom step; client map-art function; RTT terrain + screen-space vector annotations baseline (locks T-1176 candidates b+a; c1 styling open); GPU presentation-only; stepped zoom (supersedes continuous — recorded at workshop filing); tile=1m only, ''gridunit (at zoom level)'' coined; data resolution tunable (1px ideal, 5x5 fallback); hydrology = deterministic equilibrium; client-primary cache (store shape open: server-side SQLite cache / godot-sqlite / file cache — SQLite ships in the Rust server, NOT the Godot client). Workshop: 5 seats (Dudley/Araminta/Stig/Tyre + Troblum r2), 2 rounds + lead interview, extendable at Jeroen''s call, round 1 GATED on measurements — see blocker edges. Expected Output 2 mandates an explicit deprecation sweep (Clerk audit) of all conflicting DQR records/tickets at filing.
|
||||
|
||||
DELIVERED (2026-07-24): the body-map-viewer workshop is this ticket''s output. D-255 filed (stepped Atlas render architecture: server-determines-content, client map-art function, six-level ladder Global+Region→Chunk, tagged-envelope wire, three-tier cache, cache-accelerated-pure-function seed-chaining, lakes from settled hydrology) + 12 in-place amendments (D-166/D-192/D-225/D-226/D-227/D-243 + river-courses-t1170 gloss) + Clerk audit clean (2 unswept conflicts found and fixed: t1143 doc superseded banner, CLAUDE.md Phase-4 row) + measurements ①–⑥ and the population survey all MEASURED + implementation chain T-1181–T-1185 with reconciliations (T-1158 cancelled, T-1175/T-1157 re-scoped, T-1174 raised). Full record: docs/workshops/body-map-viewer/ (workshop-outcomes.md; architecture-briefing-final.md is the plain-language companion).', 'done', 'high', NULL, 'client', 'D-226', '2026-07-23 13:25:58.949', '2026-07-24 07:13:28.217', NULL, '0d5ca1f2955ad2d785d4dacda92a26f1', 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