diff --git a/.pql/changelog/ticket_history/2026-07.sql b/.pql/changelog/ticket_history/2026-07.sql index e1aecaf3c..3ae7582e8 100644 --- a/.pql/changelog/ticket_history/2026-07.sql +++ b/.pql/changelog/ticket_history/2026-07.sql @@ -1999,3 +1999,55 @@ 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 ('06FRMPWFRCD3M8282XJ01YWGX0', 'status', 'review', 'done', NULL, '2026-07-25 16:20:22', '2026-07-25 16:20:22.122', '2026-07-25 16:20:22.122', NULL, '8535ec9c01bcf0887849790d05bab399', 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 ('06FRV2EV5QK4BCZ1P9H85JH2YM', 'status', 'review', 'done', NULL, '2026-07-25 16:20:22', '2026-07-25 16:20:22.129', '2026-07-25 16:20:22.129', NULL, '8ed7643be68460f63e0d3555d9502718', 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 ('06FRMPTY517G7ZBMPAPMMCCMK8', 'status', 'review', 'done', NULL, '2026-07-25 16:20:22', '2026-07-25 16:20:22.131', '2026-07-25 16:20:22.131', NULL, 'cd5e54f6e1f1066e344ca2ab6740fade', 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 ('06FB0TNSRZ9Q7NHVDRT6ARMCWW', 'description', 'D-210 defines SubBiomeVariant for fine-grained biome classification within SettingType::Wilderness districts. Currently deferred — SettingType::Wilderness carries a plain String biome field. Implement SubBiomeVariant enum and wire it into the atlas skeleton generator when the biome taxonomy is finalized.', 'D-210 defines SubBiomeVariant for fine-grained biome classification within SettingType::Wilderness districts. Currently deferred — SettingType::Wilderness carries a plain String biome field. Implement SubBiomeVariant enum and wire it into the atlas skeleton generator when the biome taxonomy is finalized. + +Refinement review (2026-07-25, Si): OBSOLETE — D-210''s design was fully implemented and merged in PR #953/#963 (commit d418eba8b, 2026-06-03), a month after this ticket was filed, and the ticket was never closed out. Evidence: server/src/atlas/subbiome.rs (classify/classify_variant/base_cost, all 11 variants + terrain_modification_cost from the four D-210 signals, unit-tested); SubBiomeVariant enum + GeographicAttractor.sub_biome (generator.rs:539/:567); wired into the Layer-1 orchestrator (layer1.rs:209-215, Alpine branch tested); consumed downstream (attractor_matching.rs, cascade.rs); client overlay live (atlas_overlay_colors.gd:203 sub_biome_color). The only literal residue — SettingType::Wilderness carrying the cosmetic `Biome = String` alias — is unrelated to D-210''s classification/cost system; tighten it via a separate small ticket if ever wanted. Closing as delivered-by-#953.', NULL, '2026-07-25 16:25:46', '2026-07-25 16:25:46.604', '2026-07-25 16:25:46.604', NULL, '93092399b4a74d80678fc0b0d3d82bd7', 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 ('06FB0TNSRZ9Q7NHVDRT6ARMCWW', 'status', 'backlog', 'done', NULL, '2026-07-25 16:25:46', '2026-07-25 16:25:46.760', '2026-07-25 16:25:46.760', NULL, 'c269eb7751dfb286413b3a4d826889e4', 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 ('06FB0TNSRZZ5XKET93HPHKQHKW', 'description', 'Follow-ups from the Hoshe/Tyre pre-bake review (the BLOCKER/MAJOR items were fixed inline; these are the deferred MINOR/coverage items): + +TESTS: +- features.rs: full per-type attractor reachability fixtures — craft heightmaps that guarantee LakeShore (enclosed depression), PassEntrance (saddle), PlainCenter (flat), RiverCrossing (confluence). Currently only RiverMouth/CoastalAccess/ValleyFloor are exercised on the slope/sine fixtures. +- heightmap.rs: 8-bit grayscale decode path; sea_level passthrough assertion; downsample identity/upsample early-return. +- drainage.rs: basin area_pct bit-for-bit determinism (only river_cells + basin count checked today). +- layer1.rs: attach_feature_names mountain branch with a non-empty mountain pool + ≥1 Alpine attractor. +- features.rs: thin_by_spacing behavior (spacing collisions, equirectangular column wrap). +- import_economics.py: automated idempotency test — two runs on a scratch DB yield identical atlas_city_names count (not doubled), and 0 rows for system ''GJ 0'' (Sol exemption). Wire alongside check-systems-db / pre-push. +- Wire test_sim_determinism.py into pre-push or a make target. + +MINOR CODE NITS: +- drainage.rs ~480-488: comment the intentional isolated-basin fallback divergence from the old merge-to-basin-0 behavior (Tyre N1). +- planet_simulation.py ~787-788: oasis_water binary_dilation iterations are fixed-pixel — scale by GRID_W/512 for biome-display consistency at 1024 (cosmetic, Atlas only, not cascade; Tyre N2). + +D-256/T-1174 finding (2026-07-25): the believability harness golden is INSENSITIVE to a total basin_direction regression — an all-North basin collapse (every survey cell defaulting) produced a byte-identical believability.json at current sample density (64/2048 districts; basin only reaches voxel meander phase/channel width, too localized for the coarse aggregate stats). The cross-namespace keying seam is now covered by the restored derive_all_districts_threads_supplied_basin_directions test (production-shaped survey keys), but the harness itself has no basin-sensitive metric. Candidate hardening: a basin-direction distribution stat (distinct directions >= 2 on a drained body) or a voxel-transect metric that moves with meander phase.', 'Follow-ups from the Hoshe/Tyre pre-bake review (the BLOCKER/MAJOR items were fixed inline; these are the deferred MINOR/coverage items): + +TESTS: +- features.rs: full per-type attractor reachability fixtures — craft heightmaps that guarantee LakeShore (enclosed depression), PassEntrance (saddle), PlainCenter (flat), RiverCrossing (confluence). Currently only RiverMouth/CoastalAccess/ValleyFloor are exercised on the slope/sine fixtures. +- heightmap.rs: 8-bit grayscale decode path; sea_level passthrough assertion; downsample identity/upsample early-return. +- drainage.rs: basin area_pct bit-for-bit determinism (only river_cells + basin count checked today). +- layer1.rs: attach_feature_names mountain branch with a non-empty mountain pool + ≥1 Alpine attractor. +- features.rs: thin_by_spacing behavior (spacing collisions, equirectangular column wrap). +- import_economics.py: automated idempotency test — two runs on a scratch DB yield identical atlas_city_names count (not doubled), and 0 rows for system ''GJ 0'' (Sol exemption). Wire alongside check-systems-db / pre-push. +- Wire test_sim_determinism.py into pre-push or a make target. + +MINOR CODE NITS: +- drainage.rs ~480-488: comment the intentional isolated-basin fallback divergence from the old merge-to-basin-0 behavior (Tyre N1). +- planet_simulation.py ~787-788: oasis_water binary_dilation iterations are fixed-pixel — scale by GRID_W/512 for biome-display consistency at 1024 (cosmetic, Atlas only, not cascade; Tyre N2). + +D-256/T-1174 finding (2026-07-25): the believability harness golden is INSENSITIVE to a total basin_direction regression — an all-North basin collapse (every survey cell defaulting) produced a byte-identical believability.json at current sample density (64/2048 districts; basin only reaches voxel meander phase/channel width, too localized for the coarse aggregate stats). The cross-namespace keying seam is now covered by the restored derive_all_districts_threads_supplied_basin_directions test (production-shaped survey keys), but the harness itself has no basin-sensitive metric. Candidate hardening: a basin-direction distribution stat (distinct directions >= 2 on a drained body) or a voxel-transect metric that moves with meander phase. + +Refinement trim (2026-07-25, Si — every listed gap re-verified against current code before this batch): (1) DROP the test_sim_determinism.py wiring item — already done, Makefile:256 wires it into make test-tooling which the push gate runs on tooling changes. (2) The drainage.rs isolated-basin comment nit moved to ~line 654 (file grew; the old ~480-488 cite is stale) — still open, just relocate. (3) The layer1.rs attach_feature_names mountain-branch item: implicit coverage may already exist via run_layer1_* tests — check before adding a redundant test. (4) The D-256/T-1174 addendum''s "basin-direction distribution stat" candidate hardening is a genuine open design question (which stat, what threshold) — PROPOSE the stat to the lead before coding it, don''t invent silently. All other items (features.rs per-type reachability fixtures + thin_by_spacing, heightmap.rs 8-bit/sea-level-passthrough/upsample-identity, drainage.rs area_pct bit-determinism, import_economics.py idempotency test, oasis_water binary_dilation nit at planet_simulation.py:784-788) verified still open as written.', NULL, '2026-07-25 16:25:56', '2026-07-25 16:25:56.990', '2026-07-25 16:25:56.990', NULL, '99464deb0f973bb04ffdc943badd4d10', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'description', 'D-226 layer 4 (apex). A client-side AtlasAgentInterface exposing a JSON control channel so an automated agent (terminal/curl, headless Godot) can navigate the REAL Atlas UI: observe -> JSON of (a) current data state shown and (b) a walkable UI affordance tree (toggle controls: id/label/state/locked); act -> named SEMANTIC intents (select_system/open_system/select_body/open_regional/select_city/set_overlay/reset_view/back/close_atlas) backed by the same handlers a click calls (the map uses _gui_input, NOT pixel-clicks), plus get_layer_data_summary (attractor/river/basin counts as JSON without rendering). Single AtlasAgentInterface autoload/static class for a stable contract; generic Control-tree walk so economics/saves plug in later. Turns human-eyeball review into an agent QA sweep. Depends on #960 (the viewer) + the auto-pause substrate. Screenshot capture is a separate ticket (kept off the critical path).', 'D-226 layer 4 (apex). A client-side AtlasAgentInterface exposing a JSON control channel so an automated agent (terminal/curl, headless Godot) can navigate the REAL Atlas UI: observe -> JSON of (a) current data state shown and (b) a walkable UI affordance tree (toggle controls: id/label/state/locked); act -> named SEMANTIC intents (select_system/open_system/select_body/open_regional/select_city/set_overlay/reset_view/back/close_atlas) backed by the same handlers a click calls (the map uses _gui_input, NOT pixel-clicks), plus get_layer_data_summary (attractor/river/basin counts as JSON without rendering). Single AtlasAgentInterface autoload/static class for a stable contract; generic Control-tree walk so economics/saves plug in later. Turns human-eyeball review into an agent QA sweep. Depends on #960 (the viewer) + the auto-pause substrate. Screenshot capture is a separate ticket (kept off the critical path). + +Re-scope (2026-07-25, Si refinement + lead ruling): both cited blockers are satisfied (T-960, T-970 done) and the D-255(d) deep-rung cache cap is already built defensively for this exact consumer (step_canvas_disk_cache.gd:61 names the AtlasAgentInterface QA sweep). But D-226''s named-intent list was designed against the retired pre-D-255 continuous-zoom Atlas — the ticket''s intent surface is STALE. Implementer instruction: derive the actual intent list from the CURRENT stepped-rung API before building the wrapper, and post the derived list to the team lead for confirmation before implementation. Known mapping start (verify, don''t trust): select_system → atlas_app._on_system_selected(system_id); select_body → _on_body_selected(body); reset_view → StepCanvasViewer._reset_to_global(); set_overlay → set_overlay_visible(); back → _on_regional_back(); zoom step → _scroll_rung(direction, cursor_local); open_regional/select_city/open_system need tracing through screens/regional_screen.gd, district_screen.gd, system_screen.gd. SEQUENCING: T-1157 (stepped capture-harness redesign) needs the same walk-the-Atlas-headlessly primitive — its harness-techniques inventory (appended 2026-07-25) documents five proven eyeball-driver patterns (InputSwallower, in-process viewer-method navigation, fixed-center revisit, view-transform logging) that are the PROTOTYPE for this channel; build the T-971 intent layer as the productionization of that pattern so T-1157''s harness can consume it rather than the two designing overlapping scaffolding independently.', NULL, '2026-07-25 16:26:05', '2026-07-25 16:26:05.492', '2026-07-25 16:26:05.492', NULL, 'f7eb781029e013fcecfceffbf28932d8', 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 ('06FB0TNSRZZ5XKET93HPHKQHKW', 'status', 'backlog', 'in_progress', NULL, '2026-07-25 16:26:10', '2026-07-25 16:26:10.181', '2026-07-25 16:26:10.181', NULL, 'f352b98435a6a00018e45a8e2dd46675', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'status', 'backlog', 'in_progress', NULL, '2026-07-25 16:26:10', '2026-07-25 16:26:10.188', '2026-07-25 16:26:10.188', NULL, '27e775276ffa828ab316d2f4e3034c1e', 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 ('06FB0TNSRZZ5XKET93HPHKQHKW', 'assigned_to', NULL, 'dudley', NULL, '2026-07-25 16:26:11', '2026-07-25 16:26:11.164', '2026-07-25 16:26:11.164', NULL, '63073f8ecec393e1eefde9b98ea63e1c', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'assigned_to', NULL, 'stig', NULL, '2026-07-25 16:26:11', '2026-07-25 16:26:11.308', '2026-07-25 16:26:11.308', NULL, 'd0016aa197af14b8daab5e496d884b9b', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'description', 'D-226 layer 4 (apex). A client-side AtlasAgentInterface exposing a JSON control channel so an automated agent (terminal/curl, headless Godot) can navigate the REAL Atlas UI: observe -> JSON of (a) current data state shown and (b) a walkable UI affordance tree (toggle controls: id/label/state/locked); act -> named SEMANTIC intents (select_system/open_system/select_body/open_regional/select_city/set_overlay/reset_view/back/close_atlas) backed by the same handlers a click calls (the map uses _gui_input, NOT pixel-clicks), plus get_layer_data_summary (attractor/river/basin counts as JSON without rendering). Single AtlasAgentInterface autoload/static class for a stable contract; generic Control-tree walk so economics/saves plug in later. Turns human-eyeball review into an agent QA sweep. Depends on #960 (the viewer) + the auto-pause substrate. Screenshot capture is a separate ticket (kept off the critical path). + +Re-scope (2026-07-25, Si refinement + lead ruling): both cited blockers are satisfied (T-960, T-970 done) and the D-255(d) deep-rung cache cap is already built defensively for this exact consumer (step_canvas_disk_cache.gd:61 names the AtlasAgentInterface QA sweep). But D-226''s named-intent list was designed against the retired pre-D-255 continuous-zoom Atlas — the ticket''s intent surface is STALE. Implementer instruction: derive the actual intent list from the CURRENT stepped-rung API before building the wrapper, and post the derived list to the team lead for confirmation before implementation. Known mapping start (verify, don''t trust): select_system → atlas_app._on_system_selected(system_id); select_body → _on_body_selected(body); reset_view → StepCanvasViewer._reset_to_global(); set_overlay → set_overlay_visible(); back → _on_regional_back(); zoom step → _scroll_rung(direction, cursor_local); open_regional/select_city/open_system need tracing through screens/regional_screen.gd, district_screen.gd, system_screen.gd. SEQUENCING: T-1157 (stepped capture-harness redesign) needs the same walk-the-Atlas-headlessly primitive — its harness-techniques inventory (appended 2026-07-25) documents five proven eyeball-driver patterns (InputSwallower, in-process viewer-method navigation, fixed-center revisit, view-transform logging) that are the PROTOTYPE for this channel; build the T-971 intent layer as the productionization of that pattern so T-1157''s harness can consume it rather than the two designing overlapping scaffolding independently.', 'D-226 layer 4 (apex). A client-side AtlasAgentInterface exposing a JSON control channel so an automated agent (terminal/curl, headless Godot) can navigate the REAL Atlas UI: observe -> JSON of (a) current data state shown and (b) a walkable UI affordance tree (toggle controls: id/label/state/locked); act -> named SEMANTIC intents (select_system/open_system/select_body/open_regional/select_city/set_overlay/reset_view/back/close_atlas) backed by the same handlers a click calls (the map uses _gui_input, NOT pixel-clicks), plus get_layer_data_summary (attractor/river/basin counts as JSON without rendering). Single AtlasAgentInterface autoload/static class for a stable contract; generic Control-tree walk so economics/saves plug in later. Turns human-eyeball review into an agent QA sweep. Depends on #960 (the viewer) + the auto-pause substrate. Screenshot capture is a separate ticket (kept off the critical path). + +Re-scope (2026-07-25, Si refinement + lead ruling): both cited blockers are satisfied (T-960, T-970 done) and the D-255(d) deep-rung cache cap is already built defensively for this exact consumer (step_canvas_disk_cache.gd:61 names the AtlasAgentInterface QA sweep). But D-226''s named-intent list was designed against the retired pre-D-255 continuous-zoom Atlas — the ticket''s intent surface is STALE. Implementer instruction: derive the actual intent list from the CURRENT stepped-rung API before building the wrapper, and post the derived list to the team lead for confirmation before implementation. Known mapping start (verify, don''t trust): select_system → atlas_app._on_system_selected(system_id); select_body → _on_body_selected(body); reset_view → StepCanvasViewer._reset_to_global(); set_overlay → set_overlay_visible(); back → _on_regional_back(); zoom step → _scroll_rung(direction, cursor_local); open_regional/select_city/open_system need tracing through screens/regional_screen.gd, district_screen.gd, system_screen.gd. SEQUENCING: T-1157 (stepped capture-harness redesign) needs the same walk-the-Atlas-headlessly primitive — its harness-techniques inventory (appended 2026-07-25) documents five proven eyeball-driver patterns (InputSwallower, in-process viewer-method navigation, fixed-center revisit, view-transform logging) that are the PROTOTYPE for this channel; build the T-971 intent layer as the productionization of that pattern so T-1157''s harness can consume it rather than the two designing overlapping scaffolding independently. + +Intent-vocabulary diff vs D-226''s original list (recorded at implementation, 2026-07-25): select_city and open_regional DROPPED — post-D-255, settlements are settlement_id canvas cell values with no hit-test affordance (StepCanvasAnnotationLayer._draw_settlements() draws markers from cell data; no server get-settlement-by-id affordance, no client hit-test). A settlement-hit-test intent becomes its own ticket when a real consumer needs it — not filed speculatively. ADDED beyond D-226: open_atlas (a driver must be able to start a session), jump_to_center (the fixed-center revisit pattern proven by five T-1157-inventory eyeball drivers, now first-class via the new StepCanvasViewer.jump_to seam), and open_body replacing open_regional (Region..Chunk is one screen; descent is scroll_rung, not screen pushes). get_layer_data_summary reports the real EncodedStepCanvas fields (courses/cliffs/settlements) — D-226''s attractor/river/basin-count phrasing was retired-AtlasViewer vocabulary. Transport: in-process only this ticket; remote JSON transport is a follow-up when a remote consumer exists.', NULL, '2026-07-25 16:50:40', '2026-07-25 16:50:40.290', '2026-07-25 16:50:40.290', NULL, 'e6dfa5f5986853952eef1eac98269926', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'status', 'in_progress', 'review', NULL, '2026-07-25 16:57:34', '2026-07-25 16:57:34.623', '2026-07-25 16:57:34.623', NULL, '7b2b60bf4e2ba234c7fbf9fc2fafecc9', 2) ON CONFLICT(hash) DO NOTHING; diff --git a/.pql/changelog/tickets/2026-07.sql b/.pql/changelog/tickets/2026-07.sql index 13b0d4782..997931f21 100644 --- a/.pql/changelog/tickets/2026-07.sql +++ b/.pql/changelog/tickets/2026-07.sql @@ -2880,3 +2880,82 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat Scope adjudication (2026-07-25, PR round, lead ruling): the "client label draw" clause is RE-SCOPED OUT of this ticket into T-1195, for rivers as well as mountains. Implementation found the ticket''s cheap-anchor premise false: the FeatureNamesRequest pool proxy is position-free (correctly mirroring CityNamesRequest per this ticket''s own instruction), and the client''s course polylines (river_course::InventedCourse) are not correlated with layer1::GeographicAttractor positions by construction — so anchoring a pool name at a mouth ring has no matching basis without a wire-carried position, the identical dependency mountains have. Rather than two ad-hoc wire changes, the one design decision (name rides the course array vs a separate sparse feature-position list mirroring courses/cliffs) lands once in T-1195 for both feature types. This ticket''s delivered scope: atlas_feature_names populated at regen (17,891 rows), the FeatureNamesRequest/Response proxy end-to-end, attach_feature_names wired into the cascade with assignments stored on Layer1Output/BodyWorldState — the three dormant pieces connected.', 'done', 'low', 'dudley', 'server', 'D-226', '2026-07-23 05:54:09.837', '2026-07-25 16:20:22.129', NULL, '9c327527100e094d1a6e34180ffec6e6', 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 ('06FRMPTY517G7ZBMPAPMMCCMK8', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Retire the legacy window_granularity u32 wire field', 'PR #192 review (Tyre): window_granularity_v2 (the WindowGranularity enum) fully shadows the legacy u32 field — the server always echoes both, and the only conceivable legacy readers are pre-T-1152 clients, which do not exist (single-repo client/server pair, no external clients). Retire the u32 field + the WINDOW_GRANULARITY_REGION_KEY sentinel machinery from AtlasLayerRequest/DistrictWindowLayer once confirmed nothing reads it: server resolve_window_granularity legacy path, client encode path, the sentinel echo, and the five-touch-point key components that still carry the legacy value alongside the enum. Scheduled in the D-226 amendment refinement-semantics note (PR #192). Do AFTER T-1153''s follow-ups settle — no urgency, the dual-echo is cheap; the win is contract simplicity.', 'done', 'low', 'dudley', 'server', NULL, '2026-07-22 15:04:31.528', '2026-07-25 16:20:22.131', NULL, 'f6bfff77f8268ad8002aad9f799493f0', 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 ('06FB0TNSRZ9Q7NHVDRT6ARMCWW', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'D-210 SubBiomeVariant implementation', 'D-210 defines SubBiomeVariant for fine-grained biome classification within SettingType::Wilderness districts. Currently deferred — SettingType::Wilderness carries a plain String biome field. Implement SubBiomeVariant enum and wire it into the atlas skeleton generator when the biome taxonomy is finalized. + +Refinement review (2026-07-25, Si): OBSOLETE — D-210''s design was fully implemented and merged in PR #953/#963 (commit d418eba8b, 2026-06-03), a month after this ticket was filed, and the ticket was never closed out. Evidence: server/src/atlas/subbiome.rs (classify/classify_variant/base_cost, all 11 variants + terrain_modification_cost from the four D-210 signals, unit-tested); SubBiomeVariant enum + GeographicAttractor.sub_biome (generator.rs:539/:567); wired into the Layer-1 orchestrator (layer1.rs:209-215, Alpine branch tested); consumed downstream (attractor_matching.rs, cascade.rs); client overlay live (atlas_overlay_colors.gd:203 sub_biome_color). The only literal residue — SettingType::Wilderness carrying the cosmetic `Biome = String` alias — is unrelated to D-210''s classification/cost system; tighten it via a separate small ticket if ever wanted. Closing as delivered-by-#953.', 'backlog', 'low', NULL, 'server', NULL, '2026-05-03 10:30:14', '2026-07-25 16:25:46.604', NULL, 'b7a8c5833ac90ea380b52b32d48580b1', 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 ('06FB0TNSRZ9Q7NHVDRT6ARMCWW', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'D-210 SubBiomeVariant implementation', 'D-210 defines SubBiomeVariant for fine-grained biome classification within SettingType::Wilderness districts. Currently deferred — SettingType::Wilderness carries a plain String biome field. Implement SubBiomeVariant enum and wire it into the atlas skeleton generator when the biome taxonomy is finalized. + +Refinement review (2026-07-25, Si): OBSOLETE — D-210''s design was fully implemented and merged in PR #953/#963 (commit d418eba8b, 2026-06-03), a month after this ticket was filed, and the ticket was never closed out. Evidence: server/src/atlas/subbiome.rs (classify/classify_variant/base_cost, all 11 variants + terrain_modification_cost from the four D-210 signals, unit-tested); SubBiomeVariant enum + GeographicAttractor.sub_biome (generator.rs:539/:567); wired into the Layer-1 orchestrator (layer1.rs:209-215, Alpine branch tested); consumed downstream (attractor_matching.rs, cascade.rs); client overlay live (atlas_overlay_colors.gd:203 sub_biome_color). The only literal residue — SettingType::Wilderness carrying the cosmetic `Biome = String` alias — is unrelated to D-210''s classification/cost system; tighten it via a separate small ticket if ever wanted. Closing as delivered-by-#953.', 'done', 'low', NULL, 'server', NULL, '2026-05-03 10:30:14', '2026-07-25 16:25:46.760', NULL, 'e6aa010c5e0067704611e73147fbffed', 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 ('06FB0TNSRZZ5XKET93HPHKQHKW', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Phase-4 test hardening — deferred review gaps (#953/#963 review)', 'Follow-ups from the Hoshe/Tyre pre-bake review (the BLOCKER/MAJOR items were fixed inline; these are the deferred MINOR/coverage items): + +TESTS: +- features.rs: full per-type attractor reachability fixtures — craft heightmaps that guarantee LakeShore (enclosed depression), PassEntrance (saddle), PlainCenter (flat), RiverCrossing (confluence). Currently only RiverMouth/CoastalAccess/ValleyFloor are exercised on the slope/sine fixtures. +- heightmap.rs: 8-bit grayscale decode path; sea_level passthrough assertion; downsample identity/upsample early-return. +- drainage.rs: basin area_pct bit-for-bit determinism (only river_cells + basin count checked today). +- layer1.rs: attach_feature_names mountain branch with a non-empty mountain pool + ≥1 Alpine attractor. +- features.rs: thin_by_spacing behavior (spacing collisions, equirectangular column wrap). +- import_economics.py: automated idempotency test — two runs on a scratch DB yield identical atlas_city_names count (not doubled), and 0 rows for system ''GJ 0'' (Sol exemption). Wire alongside check-systems-db / pre-push. +- Wire test_sim_determinism.py into pre-push or a make target. + +MINOR CODE NITS: +- drainage.rs ~480-488: comment the intentional isolated-basin fallback divergence from the old merge-to-basin-0 behavior (Tyre N1). +- planet_simulation.py ~787-788: oasis_water binary_dilation iterations are fixed-pixel — scale by GRID_W/512 for biome-display consistency at 1024 (cosmetic, Atlas only, not cascade; Tyre N2). + +D-256/T-1174 finding (2026-07-25): the believability harness golden is INSENSITIVE to a total basin_direction regression — an all-North basin collapse (every survey cell defaulting) produced a byte-identical believability.json at current sample density (64/2048 districts; basin only reaches voxel meander phase/channel width, too localized for the coarse aggregate stats). The cross-namespace keying seam is now covered by the restored derive_all_districts_threads_supplied_basin_directions test (production-shaped survey keys), but the harness itself has no basin-sensitive metric. Candidate hardening: a basin-direction distribution stat (distinct directions >= 2 on a drained body) or a voxel-transect metric that moves with meander phase. + +Refinement trim (2026-07-25, Si — every listed gap re-verified against current code before this batch): (1) DROP the test_sim_determinism.py wiring item — already done, Makefile:256 wires it into make test-tooling which the push gate runs on tooling changes. (2) The drainage.rs isolated-basin comment nit moved to ~line 654 (file grew; the old ~480-488 cite is stale) — still open, just relocate. (3) The layer1.rs attach_feature_names mountain-branch item: implicit coverage may already exist via run_layer1_* tests — check before adding a redundant test. (4) The D-256/T-1174 addendum''s "basin-direction distribution stat" candidate hardening is a genuine open design question (which stat, what threshold) — PROPOSE the stat to the lead before coding it, don''t invent silently. All other items (features.rs per-type reachability fixtures + thin_by_spacing, heightmap.rs 8-bit/sea-level-passthrough/upsample-identity, drainage.rs area_pct bit-determinism, import_economics.py idempotency test, oasis_water binary_dilation nit at planet_simulation.py:784-788) verified still open as written.', 'backlog', 'medium', NULL, 'server', NULL, '2026-05-23 06:09:45', '2026-07-25 16:25:56.990', NULL, 'e89f228c33aefc802abd1b95dabe078e', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas agent control channel — observe/act named-intent navigation (D-226)', 'D-226 layer 4 (apex). A client-side AtlasAgentInterface exposing a JSON control channel so an automated agent (terminal/curl, headless Godot) can navigate the REAL Atlas UI: observe -> JSON of (a) current data state shown and (b) a walkable UI affordance tree (toggle controls: id/label/state/locked); act -> named SEMANTIC intents (select_system/open_system/select_body/open_regional/select_city/set_overlay/reset_view/back/close_atlas) backed by the same handlers a click calls (the map uses _gui_input, NOT pixel-clicks), plus get_layer_data_summary (attractor/river/basin counts as JSON without rendering). Single AtlasAgentInterface autoload/static class for a stable contract; generic Control-tree walk so economics/saves plug in later. Turns human-eyeball review into an agent QA sweep. Depends on #960 (the viewer) + the auto-pause substrate. Screenshot capture is a separate ticket (kept off the critical path). + +Re-scope (2026-07-25, Si refinement + lead ruling): both cited blockers are satisfied (T-960, T-970 done) and the D-255(d) deep-rung cache cap is already built defensively for this exact consumer (step_canvas_disk_cache.gd:61 names the AtlasAgentInterface QA sweep). But D-226''s named-intent list was designed against the retired pre-D-255 continuous-zoom Atlas — the ticket''s intent surface is STALE. Implementer instruction: derive the actual intent list from the CURRENT stepped-rung API before building the wrapper, and post the derived list to the team lead for confirmation before implementation. Known mapping start (verify, don''t trust): select_system → atlas_app._on_system_selected(system_id); select_body → _on_body_selected(body); reset_view → StepCanvasViewer._reset_to_global(); set_overlay → set_overlay_visible(); back → _on_regional_back(); zoom step → _scroll_rung(direction, cursor_local); open_regional/select_city/open_system need tracing through screens/regional_screen.gd, district_screen.gd, system_screen.gd. SEQUENCING: T-1157 (stepped capture-harness redesign) needs the same walk-the-Atlas-headlessly primitive — its harness-techniques inventory (appended 2026-07-25) documents five proven eyeball-driver patterns (InputSwallower, in-process viewer-method navigation, fixed-center revisit, view-transform logging) that are the PROTOTYPE for this channel; build the T-971 intent layer as the productionization of that pattern so T-1157''s harness can consume it rather than the two designing overlapping scaffolding independently.', 'backlog', 'medium', NULL, 'client', 'D-226', '2026-05-24 09:22:38', '2026-07-25 16:26:05.492', NULL, 'ebc75290cb615984581a87c04a0d88b5', 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 ('06FB0TNSRZZ5XKET93HPHKQHKW', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Phase-4 test hardening — deferred review gaps (#953/#963 review)', 'Follow-ups from the Hoshe/Tyre pre-bake review (the BLOCKER/MAJOR items were fixed inline; these are the deferred MINOR/coverage items): + +TESTS: +- features.rs: full per-type attractor reachability fixtures — craft heightmaps that guarantee LakeShore (enclosed depression), PassEntrance (saddle), PlainCenter (flat), RiverCrossing (confluence). Currently only RiverMouth/CoastalAccess/ValleyFloor are exercised on the slope/sine fixtures. +- heightmap.rs: 8-bit grayscale decode path; sea_level passthrough assertion; downsample identity/upsample early-return. +- drainage.rs: basin area_pct bit-for-bit determinism (only river_cells + basin count checked today). +- layer1.rs: attach_feature_names mountain branch with a non-empty mountain pool + ≥1 Alpine attractor. +- features.rs: thin_by_spacing behavior (spacing collisions, equirectangular column wrap). +- import_economics.py: automated idempotency test — two runs on a scratch DB yield identical atlas_city_names count (not doubled), and 0 rows for system ''GJ 0'' (Sol exemption). Wire alongside check-systems-db / pre-push. +- Wire test_sim_determinism.py into pre-push or a make target. + +MINOR CODE NITS: +- drainage.rs ~480-488: comment the intentional isolated-basin fallback divergence from the old merge-to-basin-0 behavior (Tyre N1). +- planet_simulation.py ~787-788: oasis_water binary_dilation iterations are fixed-pixel — scale by GRID_W/512 for biome-display consistency at 1024 (cosmetic, Atlas only, not cascade; Tyre N2). + +D-256/T-1174 finding (2026-07-25): the believability harness golden is INSENSITIVE to a total basin_direction regression — an all-North basin collapse (every survey cell defaulting) produced a byte-identical believability.json at current sample density (64/2048 districts; basin only reaches voxel meander phase/channel width, too localized for the coarse aggregate stats). The cross-namespace keying seam is now covered by the restored derive_all_districts_threads_supplied_basin_directions test (production-shaped survey keys), but the harness itself has no basin-sensitive metric. Candidate hardening: a basin-direction distribution stat (distinct directions >= 2 on a drained body) or a voxel-transect metric that moves with meander phase. + +Refinement trim (2026-07-25, Si — every listed gap re-verified against current code before this batch): (1) DROP the test_sim_determinism.py wiring item — already done, Makefile:256 wires it into make test-tooling which the push gate runs on tooling changes. (2) The drainage.rs isolated-basin comment nit moved to ~line 654 (file grew; the old ~480-488 cite is stale) — still open, just relocate. (3) The layer1.rs attach_feature_names mountain-branch item: implicit coverage may already exist via run_layer1_* tests — check before adding a redundant test. (4) The D-256/T-1174 addendum''s "basin-direction distribution stat" candidate hardening is a genuine open design question (which stat, what threshold) — PROPOSE the stat to the lead before coding it, don''t invent silently. All other items (features.rs per-type reachability fixtures + thin_by_spacing, heightmap.rs 8-bit/sea-level-passthrough/upsample-identity, drainage.rs area_pct bit-determinism, import_economics.py idempotency test, oasis_water binary_dilation nit at planet_simulation.py:784-788) verified still open as written.', 'in_progress', 'medium', NULL, 'server', NULL, '2026-05-23 06:09:45', '2026-07-25 16:26:10.181', NULL, '1330970c9d7ec160af9d9b6f116152a4', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas agent control channel — observe/act named-intent navigation (D-226)', 'D-226 layer 4 (apex). A client-side AtlasAgentInterface exposing a JSON control channel so an automated agent (terminal/curl, headless Godot) can navigate the REAL Atlas UI: observe -> JSON of (a) current data state shown and (b) a walkable UI affordance tree (toggle controls: id/label/state/locked); act -> named SEMANTIC intents (select_system/open_system/select_body/open_regional/select_city/set_overlay/reset_view/back/close_atlas) backed by the same handlers a click calls (the map uses _gui_input, NOT pixel-clicks), plus get_layer_data_summary (attractor/river/basin counts as JSON without rendering). Single AtlasAgentInterface autoload/static class for a stable contract; generic Control-tree walk so economics/saves plug in later. Turns human-eyeball review into an agent QA sweep. Depends on #960 (the viewer) + the auto-pause substrate. Screenshot capture is a separate ticket (kept off the critical path). + +Re-scope (2026-07-25, Si refinement + lead ruling): both cited blockers are satisfied (T-960, T-970 done) and the D-255(d) deep-rung cache cap is already built defensively for this exact consumer (step_canvas_disk_cache.gd:61 names the AtlasAgentInterface QA sweep). But D-226''s named-intent list was designed against the retired pre-D-255 continuous-zoom Atlas — the ticket''s intent surface is STALE. Implementer instruction: derive the actual intent list from the CURRENT stepped-rung API before building the wrapper, and post the derived list to the team lead for confirmation before implementation. Known mapping start (verify, don''t trust): select_system → atlas_app._on_system_selected(system_id); select_body → _on_body_selected(body); reset_view → StepCanvasViewer._reset_to_global(); set_overlay → set_overlay_visible(); back → _on_regional_back(); zoom step → _scroll_rung(direction, cursor_local); open_regional/select_city/open_system need tracing through screens/regional_screen.gd, district_screen.gd, system_screen.gd. SEQUENCING: T-1157 (stepped capture-harness redesign) needs the same walk-the-Atlas-headlessly primitive — its harness-techniques inventory (appended 2026-07-25) documents five proven eyeball-driver patterns (InputSwallower, in-process viewer-method navigation, fixed-center revisit, view-transform logging) that are the PROTOTYPE for this channel; build the T-971 intent layer as the productionization of that pattern so T-1157''s harness can consume it rather than the two designing overlapping scaffolding independently.', 'in_progress', 'medium', NULL, 'client', 'D-226', '2026-05-24 09:22:38', '2026-07-25 16:26:10.188', NULL, 'e6121a05892f9e4e72c7974d4b0faf96', 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 ('06FB0TNSRZZ5XKET93HPHKQHKW', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Phase-4 test hardening — deferred review gaps (#953/#963 review)', 'Follow-ups from the Hoshe/Tyre pre-bake review (the BLOCKER/MAJOR items were fixed inline; these are the deferred MINOR/coverage items): + +TESTS: +- features.rs: full per-type attractor reachability fixtures — craft heightmaps that guarantee LakeShore (enclosed depression), PassEntrance (saddle), PlainCenter (flat), RiverCrossing (confluence). Currently only RiverMouth/CoastalAccess/ValleyFloor are exercised on the slope/sine fixtures. +- heightmap.rs: 8-bit grayscale decode path; sea_level passthrough assertion; downsample identity/upsample early-return. +- drainage.rs: basin area_pct bit-for-bit determinism (only river_cells + basin count checked today). +- layer1.rs: attach_feature_names mountain branch with a non-empty mountain pool + ≥1 Alpine attractor. +- features.rs: thin_by_spacing behavior (spacing collisions, equirectangular column wrap). +- import_economics.py: automated idempotency test — two runs on a scratch DB yield identical atlas_city_names count (not doubled), and 0 rows for system ''GJ 0'' (Sol exemption). Wire alongside check-systems-db / pre-push. +- Wire test_sim_determinism.py into pre-push or a make target. + +MINOR CODE NITS: +- drainage.rs ~480-488: comment the intentional isolated-basin fallback divergence from the old merge-to-basin-0 behavior (Tyre N1). +- planet_simulation.py ~787-788: oasis_water binary_dilation iterations are fixed-pixel — scale by GRID_W/512 for biome-display consistency at 1024 (cosmetic, Atlas only, not cascade; Tyre N2). + +D-256/T-1174 finding (2026-07-25): the believability harness golden is INSENSITIVE to a total basin_direction regression — an all-North basin collapse (every survey cell defaulting) produced a byte-identical believability.json at current sample density (64/2048 districts; basin only reaches voxel meander phase/channel width, too localized for the coarse aggregate stats). The cross-namespace keying seam is now covered by the restored derive_all_districts_threads_supplied_basin_directions test (production-shaped survey keys), but the harness itself has no basin-sensitive metric. Candidate hardening: a basin-direction distribution stat (distinct directions >= 2 on a drained body) or a voxel-transect metric that moves with meander phase. + +Refinement trim (2026-07-25, Si — every listed gap re-verified against current code before this batch): (1) DROP the test_sim_determinism.py wiring item — already done, Makefile:256 wires it into make test-tooling which the push gate runs on tooling changes. (2) The drainage.rs isolated-basin comment nit moved to ~line 654 (file grew; the old ~480-488 cite is stale) — still open, just relocate. (3) The layer1.rs attach_feature_names mountain-branch item: implicit coverage may already exist via run_layer1_* tests — check before adding a redundant test. (4) The D-256/T-1174 addendum''s "basin-direction distribution stat" candidate hardening is a genuine open design question (which stat, what threshold) — PROPOSE the stat to the lead before coding it, don''t invent silently. All other items (features.rs per-type reachability fixtures + thin_by_spacing, heightmap.rs 8-bit/sea-level-passthrough/upsample-identity, drainage.rs area_pct bit-determinism, import_economics.py idempotency test, oasis_water binary_dilation nit at planet_simulation.py:784-788) verified still open as written.', 'in_progress', 'medium', 'dudley', 'server', NULL, '2026-05-23 06:09:45', '2026-07-25 16:26:11.159', NULL, 'd2bc3750b255e45527ac695220f93c8d', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas agent control channel — observe/act named-intent navigation (D-226)', 'D-226 layer 4 (apex). A client-side AtlasAgentInterface exposing a JSON control channel so an automated agent (terminal/curl, headless Godot) can navigate the REAL Atlas UI: observe -> JSON of (a) current data state shown and (b) a walkable UI affordance tree (toggle controls: id/label/state/locked); act -> named SEMANTIC intents (select_system/open_system/select_body/open_regional/select_city/set_overlay/reset_view/back/close_atlas) backed by the same handlers a click calls (the map uses _gui_input, NOT pixel-clicks), plus get_layer_data_summary (attractor/river/basin counts as JSON without rendering). Single AtlasAgentInterface autoload/static class for a stable contract; generic Control-tree walk so economics/saves plug in later. Turns human-eyeball review into an agent QA sweep. Depends on #960 (the viewer) + the auto-pause substrate. Screenshot capture is a separate ticket (kept off the critical path). + +Re-scope (2026-07-25, Si refinement + lead ruling): both cited blockers are satisfied (T-960, T-970 done) and the D-255(d) deep-rung cache cap is already built defensively for this exact consumer (step_canvas_disk_cache.gd:61 names the AtlasAgentInterface QA sweep). But D-226''s named-intent list was designed against the retired pre-D-255 continuous-zoom Atlas — the ticket''s intent surface is STALE. Implementer instruction: derive the actual intent list from the CURRENT stepped-rung API before building the wrapper, and post the derived list to the team lead for confirmation before implementation. Known mapping start (verify, don''t trust): select_system → atlas_app._on_system_selected(system_id); select_body → _on_body_selected(body); reset_view → StepCanvasViewer._reset_to_global(); set_overlay → set_overlay_visible(); back → _on_regional_back(); zoom step → _scroll_rung(direction, cursor_local); open_regional/select_city/open_system need tracing through screens/regional_screen.gd, district_screen.gd, system_screen.gd. SEQUENCING: T-1157 (stepped capture-harness redesign) needs the same walk-the-Atlas-headlessly primitive — its harness-techniques inventory (appended 2026-07-25) documents five proven eyeball-driver patterns (InputSwallower, in-process viewer-method navigation, fixed-center revisit, view-transform logging) that are the PROTOTYPE for this channel; build the T-971 intent layer as the productionization of that pattern so T-1157''s harness can consume it rather than the two designing overlapping scaffolding independently.', 'in_progress', 'medium', 'stig', 'client', 'D-226', '2026-05-24 09:22:38', '2026-07-25 16:26:11.308', NULL, 'c61776c96a1110fae0686f2eb4927fcd', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas agent control channel — observe/act named-intent navigation (D-226)', 'D-226 layer 4 (apex). A client-side AtlasAgentInterface exposing a JSON control channel so an automated agent (terminal/curl, headless Godot) can navigate the REAL Atlas UI: observe -> JSON of (a) current data state shown and (b) a walkable UI affordance tree (toggle controls: id/label/state/locked); act -> named SEMANTIC intents (select_system/open_system/select_body/open_regional/select_city/set_overlay/reset_view/back/close_atlas) backed by the same handlers a click calls (the map uses _gui_input, NOT pixel-clicks), plus get_layer_data_summary (attractor/river/basin counts as JSON without rendering). Single AtlasAgentInterface autoload/static class for a stable contract; generic Control-tree walk so economics/saves plug in later. Turns human-eyeball review into an agent QA sweep. Depends on #960 (the viewer) + the auto-pause substrate. Screenshot capture is a separate ticket (kept off the critical path). + +Re-scope (2026-07-25, Si refinement + lead ruling): both cited blockers are satisfied (T-960, T-970 done) and the D-255(d) deep-rung cache cap is already built defensively for this exact consumer (step_canvas_disk_cache.gd:61 names the AtlasAgentInterface QA sweep). But D-226''s named-intent list was designed against the retired pre-D-255 continuous-zoom Atlas — the ticket''s intent surface is STALE. Implementer instruction: derive the actual intent list from the CURRENT stepped-rung API before building the wrapper, and post the derived list to the team lead for confirmation before implementation. Known mapping start (verify, don''t trust): select_system → atlas_app._on_system_selected(system_id); select_body → _on_body_selected(body); reset_view → StepCanvasViewer._reset_to_global(); set_overlay → set_overlay_visible(); back → _on_regional_back(); zoom step → _scroll_rung(direction, cursor_local); open_regional/select_city/open_system need tracing through screens/regional_screen.gd, district_screen.gd, system_screen.gd. SEQUENCING: T-1157 (stepped capture-harness redesign) needs the same walk-the-Atlas-headlessly primitive — its harness-techniques inventory (appended 2026-07-25) documents five proven eyeball-driver patterns (InputSwallower, in-process viewer-method navigation, fixed-center revisit, view-transform logging) that are the PROTOTYPE for this channel; build the T-971 intent layer as the productionization of that pattern so T-1157''s harness can consume it rather than the two designing overlapping scaffolding independently. + +Intent-vocabulary diff vs D-226''s original list (recorded at implementation, 2026-07-25): select_city and open_regional DROPPED — post-D-255, settlements are settlement_id canvas cell values with no hit-test affordance (StepCanvasAnnotationLayer._draw_settlements() draws markers from cell data; no server get-settlement-by-id affordance, no client hit-test). A settlement-hit-test intent becomes its own ticket when a real consumer needs it — not filed speculatively. ADDED beyond D-226: open_atlas (a driver must be able to start a session), jump_to_center (the fixed-center revisit pattern proven by five T-1157-inventory eyeball drivers, now first-class via the new StepCanvasViewer.jump_to seam), and open_body replacing open_regional (Region..Chunk is one screen; descent is scroll_rung, not screen pushes). get_layer_data_summary reports the real EncodedStepCanvas fields (courses/cliffs/settlements) — D-226''s attractor/river/basin-count phrasing was retired-AtlasViewer vocabulary. Transport: in-process only this ticket; remote JSON transport is a follow-up when a remote consumer exists.', 'in_progress', 'medium', 'stig', 'client', 'D-226', '2026-05-24 09:22:38', '2026-07-25 16:50:40.290', NULL, '5889e54d53d1d2a8f1457cfb56c2f699', 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 ('06FB0TNSRWTP633SM8XB302MBM', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas agent control channel — observe/act named-intent navigation (D-226)', 'D-226 layer 4 (apex). A client-side AtlasAgentInterface exposing a JSON control channel so an automated agent (terminal/curl, headless Godot) can navigate the REAL Atlas UI: observe -> JSON of (a) current data state shown and (b) a walkable UI affordance tree (toggle controls: id/label/state/locked); act -> named SEMANTIC intents (select_system/open_system/select_body/open_regional/select_city/set_overlay/reset_view/back/close_atlas) backed by the same handlers a click calls (the map uses _gui_input, NOT pixel-clicks), plus get_layer_data_summary (attractor/river/basin counts as JSON without rendering). Single AtlasAgentInterface autoload/static class for a stable contract; generic Control-tree walk so economics/saves plug in later. Turns human-eyeball review into an agent QA sweep. Depends on #960 (the viewer) + the auto-pause substrate. Screenshot capture is a separate ticket (kept off the critical path). + +Re-scope (2026-07-25, Si refinement + lead ruling): both cited blockers are satisfied (T-960, T-970 done) and the D-255(d) deep-rung cache cap is already built defensively for this exact consumer (step_canvas_disk_cache.gd:61 names the AtlasAgentInterface QA sweep). But D-226''s named-intent list was designed against the retired pre-D-255 continuous-zoom Atlas — the ticket''s intent surface is STALE. Implementer instruction: derive the actual intent list from the CURRENT stepped-rung API before building the wrapper, and post the derived list to the team lead for confirmation before implementation. Known mapping start (verify, don''t trust): select_system → atlas_app._on_system_selected(system_id); select_body → _on_body_selected(body); reset_view → StepCanvasViewer._reset_to_global(); set_overlay → set_overlay_visible(); back → _on_regional_back(); zoom step → _scroll_rung(direction, cursor_local); open_regional/select_city/open_system need tracing through screens/regional_screen.gd, district_screen.gd, system_screen.gd. SEQUENCING: T-1157 (stepped capture-harness redesign) needs the same walk-the-Atlas-headlessly primitive — its harness-techniques inventory (appended 2026-07-25) documents five proven eyeball-driver patterns (InputSwallower, in-process viewer-method navigation, fixed-center revisit, view-transform logging) that are the PROTOTYPE for this channel; build the T-971 intent layer as the productionization of that pattern so T-1157''s harness can consume it rather than the two designing overlapping scaffolding independently. + +Intent-vocabulary diff vs D-226''s original list (recorded at implementation, 2026-07-25): select_city and open_regional DROPPED — post-D-255, settlements are settlement_id canvas cell values with no hit-test affordance (StepCanvasAnnotationLayer._draw_settlements() draws markers from cell data; no server get-settlement-by-id affordance, no client hit-test). A settlement-hit-test intent becomes its own ticket when a real consumer needs it — not filed speculatively. ADDED beyond D-226: open_atlas (a driver must be able to start a session), jump_to_center (the fixed-center revisit pattern proven by five T-1157-inventory eyeball drivers, now first-class via the new StepCanvasViewer.jump_to seam), and open_body replacing open_regional (Region..Chunk is one screen; descent is scroll_rung, not screen pushes). get_layer_data_summary reports the real EncodedStepCanvas fields (courses/cliffs/settlements) — D-226''s attractor/river/basin-count phrasing was retired-AtlasViewer vocabulary. Transport: in-process only this ticket; remote JSON transport is a follow-up when a remote consumer exists.', 'review', 'medium', 'stig', 'client', 'D-226', '2026-05-24 09:22:38', '2026-07-25 16:57:34.622', NULL, 'e938b340830f851c004b4271226430ec', 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);