chore(meta): T-960/T-970/T-949 to review — PR #176 up; T-1114 gdlint-debt filed
Atlas-viewer batch shipped through the gate (2946/2946 gdUnit, full cargo suite, golden untouched). T-1114: 39 pre-existing client gdlint warnings tracked under T-1037. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1271,3 +1271,9 @@ MANUAL-vs-AUTO PAUSE (the one gap — lead ruling: Option A): track WHETHER THE
|
||||
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 ('06FBRCMEKT72S0Q6NE68JH7EXC', 'description', 'Split from T-1071 (2026-06-12): converting the 4 legacy geometry-bearing GJ-0 markers.json (GJ0d, GJ0d-1, GJ0e, GJ0f-2) to the D-223 names-only schema is SAFE for generation (import_economics.py:1452 skips GJ 0 explicitly; all authored coordinates/populations verified present name-by-name in tooling/planet-gen/sol_markers/*.json + sol_name_fixes.py FIXES) but REGRESSES the client: atlas_viewer.gd:433 still loads markers.json per the legacy D-191 §8 geometry schema, so Sol bodies lose their city/river/mountain Atlas overlays. The conversion was implemented, verified, and then deliberately reverted to preserve working overlays. Land both halves together: (1) point the Sol overlay read at the proper Sol home (sol_markers/ or a baked path — Q-107 consolidation may decide this), (2) convert the 4 files, (3) also fix the residual debt: sol_import.py still WRITES legacy-schema markers and an unconditional heightmap link in its own _write_index_md, and import_economics.py:1485 carries a now-misleading comment about preserved geometry markers (editing it stales the systems.db stamp — bundle with a regen).', 'Split from T-1071 (2026-06-12): converting the 4 legacy geometry-bearing GJ-0 markers.json (GJ0d, GJ0d-1, GJ0e, GJ0f-2) to the D-223 names-only schema is SAFE for generation (import_economics.py:1452 skips GJ 0 explicitly; all authored coordinates/populations verified present name-by-name in tooling/planet-gen/sol_markers/*.json + sol_name_fixes.py FIXES) but REGRESSES the client: atlas_viewer.gd:433 still loads markers.json per the legacy D-191 §8 geometry schema, so Sol bodies lose their city/river/mountain Atlas overlays. The conversion was implemented, verified, and then deliberately reverted to preserve working overlays. Land both halves together: (1) point the Sol overlay read at the proper Sol home (sol_markers/ or a baked path — Q-107 consolidation may decide this), (2) convert the 4 files, (3) also fix the residual debt: sol_import.py still WRITES legacy-schema markers and an unconditional heightmap link in its own _write_index_md, and import_economics.py:1485 carries a now-misleading comment about preserved geometry markers (editing it stales the systems.db stamp — bundle with a regen).
|
||||
|
||||
D-236 amended 2026-07-13: player access lore-capped at the Oort-cloud gateway station; Sol permanently excluded from deterministic runs. T-949 (2026-07-13 scoping) explicitly excludes Sol and leaves the legacy markers read in place for this ticket to migrate once Q-107 resolves — Sol''s geometry needs a server-side AUTHORED home, never a cascade path.', NULL, '2026-07-13 21:53:26', '2026-07-13 21:53:26.940', '2026-07-13 21:53:26.940', NULL, '814a6aa15196b19ecc10be00c2b28c60', 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 ('06FB0TNSRZ8BFVNWDH17CMH1YM', 'status', 'backlog', 'in_progress', NULL, '2026-07-13 21:54:06', '2026-07-13 21:54:06.361', '2026-07-13 21:54:06.361', NULL, 'ea84832dad04aa38fbbc6993eae1094d', 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 ('06FB0TNSRYEJ0G4F0SBHG379YR', 'status', 'backlog', 'in_progress', NULL, '2026-07-13 21:54:06', '2026-07-13 21:54:06.378', '2026-07-13 21:54:06.378', NULL, '252b112df804eb3c43ad50177bc65e70', 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 ('06FB0TNSRW2ZSPJ3D9NEZ6JBW8', 'status', 'backlog', 'in_progress', NULL, '2026-07-13 21:54:06', '2026-07-13 21:54:06.379', '2026-07-13 21:54:06.379', NULL, 'e2cb8bfa8c9865802fa2fa35b135f35b', 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 ('06FB0TNSRZ8BFVNWDH17CMH1YM', 'status', 'in_progress', 'review', NULL, '2026-07-14 14:36:24', '2026-07-14 14:36:24.074', '2026-07-14 14:36:24.074', NULL, 'f610c47b468432be2311ffb750fda80a', 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 ('06FB0TNSRW2ZSPJ3D9NEZ6JBW8', 'status', 'in_progress', 'review', NULL, '2026-07-14 14:36:24', '2026-07-14 14:36:24.077', '2026-07-14 14:36:24.077', NULL, '38a216c974f2c48757c2c2d08a9d4d1d', 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 ('06FB0TNSRYEJ0G4F0SBHG379YR', 'status', 'in_progress', 'review', NULL, '2026-07-14 14:36:24', '2026-07-14 14:36:24.077', '2026-07-14 14:36:24.077', NULL, 'bdbd4faf5158ae520a7b6e02aa0f0871', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
|
||||
@@ -27,3 +27,4 @@ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3GYTN814QG6WWYNJH7QAR', 'T-1111', '2026-07-13 15:17:37.109', '2026-07-13 15:17:37.109', NULL, 'f15dfa7968abd2a39e12cbd319f8c716', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXEM9NM5M5SX9WQAAA40SC', 'T-1112', '2026-07-13 21:50:30.995', '2026-07-13 21:50:30.995', NULL, '10e2ac50b65fb7feb93b6da87fae19d1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTXF0JB8E6PDQRASQ18E9ER', 'T-1113', '2026-07-13 21:50:34.135', '2026-07-13 21:50:34.135', NULL, 'be82a59d9e38c465f41936e6ecb7e791', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FP1GTTEGD648NDDFCAYR6NR4', 'T-1114', '2026-07-14 13:14:03.254', '2026-07-14 13:14:03.254', NULL, '732e051076bfed3a3c3413f4910fac4a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
|
||||
|
||||
@@ -1302,3 +1302,142 @@ MANUAL-vs-AUTO PAUSE (the one gap — lead ruling: Option A): track WHETHER THE
|
||||
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 ('06FBRCMEKT72S0Q6NE68JH7EXC', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Sol markers → D-223 names-only, migrated together with the Atlas legacy-geometry read path', 'Split from T-1071 (2026-06-12): converting the 4 legacy geometry-bearing GJ-0 markers.json (GJ0d, GJ0d-1, GJ0e, GJ0f-2) to the D-223 names-only schema is SAFE for generation (import_economics.py:1452 skips GJ 0 explicitly; all authored coordinates/populations verified present name-by-name in tooling/planet-gen/sol_markers/*.json + sol_name_fixes.py FIXES) but REGRESSES the client: atlas_viewer.gd:433 still loads markers.json per the legacy D-191 §8 geometry schema, so Sol bodies lose their city/river/mountain Atlas overlays. The conversion was implemented, verified, and then deliberately reverted to preserve working overlays. Land both halves together: (1) point the Sol overlay read at the proper Sol home (sol_markers/ or a baked path — Q-107 consolidation may decide this), (2) convert the 4 files, (3) also fix the residual debt: sol_import.py still WRITES legacy-schema markers and an unconditional heightmap link in its own _write_index_md, and import_economics.py:1485 carries a now-misleading comment about preserved geometry markers (editing it stales the systems.db stamp — bundle with a regen).
|
||||
|
||||
D-236 amended 2026-07-13: player access lore-capped at the Oort-cloud gateway station; Sol permanently excluded from deterministic runs. T-949 (2026-07-13 scoping) explicitly excludes Sol and leaves the legacy markers read in place for this ticket to migrate once Q-107 resolves — Sol''s geometry needs a server-side AUTHORED home, never a cascade path.', 'backlog', 'low', NULL, 'client', NULL, '2026-06-12 14:18:10', '2026-07-13 21:53:26.940', NULL, 'c37ad072071989493bfd216ffbb66891', 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 ('06FB0TNSRZ8BFVNWDH17CMH1YM', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Per-layer Atlas map viewer (generation progress viewer)', 'Render each cascade layer as a MAP in the implant Atlas (D-191, the Phase 3 viewer — D-166 amendment): terrain → water → biome → settlements → political zones → quarter/block skeleton → tiles. This is the progress-viewer deliverable; NO in-world rendering. Grows as each layer lands.
|
||||
|
||||
---
|
||||
Refinement (2026-05-23, /whats-next):
|
||||
- DATA TRANSPORT (resolves Q-098): NO bake — baking derived layer data makes mods second-class. A server-side FILE STREAM PROXY: resolves a body source files across base + mod paths, runs the deterministic cascade on demand (run_cascade, LRU-cached per D-203, ~45ms), and streams serialized layer data to the Godot client over IPC. First-party and mod bodies use the identical path; no pre-baked derived artifacts. Protocol/stream spec designed with Tyre and recorded in a D-record resolving Q-098.
|
||||
- UI: layer selector in the existing regional Atlas view; layers are ADDITIVE overlays (toggle heightmap + rivers + attractors + sub-biome together and composite), not one-at-a-time — matching the existing overlay-bar model (D-191).
|
||||
- SCOPE NOW: only Layer 0 (heightmap) + Layer 1 (rivers/basins/attractors/sub-biome) exist; the viewer grows as layers land (D-166). Acceptance: Layer 0 + Layer 1 render as additive, toggleable overlays for a body, fed by the proxy.
|
||||
|
||||
---
|
||||
Design (D-226, Araminta, 2026-05-24) — human-visual layer of the inspection harness. Extend OVERLAY_DEFS / AtlasOverlayBar with a generation overlay group (second row) + a left-side legend panel; do NOT build a separate viewer. Encoding: relief base; rivers as blue polylines (mouths = double-circle markers, confluences where in-degree >= 3); basin fills very translucent + thin boundary polylines; attractors as markers where SHAPE encodes the 7 AttractorTypes (circle/half-circle/diamond/down-tri/up-tri/hollow-circle/square) and COLOR encodes sub-biome (shape carries identity in headless/monochrome; color is additive); size scales with strength, skip strength < 0.15. Stable button ids gen_l0_heightmap / gen_l1_rivers / gen_l1_basins / gen_l1_attractors; start pending/locked, unlock+activate via notify_gen_layer_ready(id) as data arrives (grows as layers land, D-166). Consumes the live proxy (#969); the agent channel (#971) drives this same UI.
|
||||
|
||||
Remaining to close (Si sweep 2026-06-07): add the gen_l0_heightmap overlay to OVERLAY_DEFS + render path in atlas_viewer.gd / atlas_marker_overlay.gd — required by the D-226/T-960 acceptance criteria but currently absent. Layer-1 overlays (rivers/basins/attractors) + proxy wire + pending indicator are already implemented; this Layer-0 overlay is the sole remaining piece.
|
||||
|
||||
---
|
||||
Refinement (2026-07-13, /whats-next Si audit + Jeroen rulings) — RESCOPE. The 2026-06-07 scope note is obsolete in both directions:
|
||||
|
||||
DONE ALREADY (record, don''t rebuild):
|
||||
- L1 overlays (gen_l1_rivers/basins/attractors) + proxy wire + pending indicator: shipped.
|
||||
- District-morphology overlay (gen_district "MRPH"): shipped under T-1046 via AtlasLayerResponse.district_grid — the wiring precedent for everything below.
|
||||
- gen_l0_heightmap: DROPPED — relief already renders via the always-on terrain overlay (D-191 §7). D-226 amended (2026-07-13) accordingly.
|
||||
|
||||
IN SCOPE NOW (this ticket):
|
||||
1. gen_l2_roads overlay — L2 road/rail graph (T-1038) is computed on every AnalyzeBody (gen_queue.rs runs up_to=RoadGraph) but never serialized: add RoadGraphLayer field to AtlasLayerResponse (layer_proxy.rs), protocol.gd decode, overlay rendering (edges colored by MaintenanceAuthority, junction markers).
|
||||
2. gen_l3_settlements overlay — wire T-955''s computed CityPlacement positions through the proxy (new SettlementLayer field, exact T-1046 precedent) so cities render on generated bodies for the first time (Jeroen ruling: wire positions now; T-949 stays boundary-cleanup).
|
||||
3. Left-side legend panel — D-226 item (3) deliverable, never built (shape/color key for attractor types + sub-biomes + the new overlays).
|
||||
4. Doc-comment fix: layer_proxy.rs:31-34 claims cascade runs "through CascadeLayer::Settlement" — actually RoadGraph (gen_queue.rs:416); client''s up_to field is ignored by the server. One-line correction.
|
||||
|
||||
OUT OF SCOPE (explicitly, per 2026-07-13 rulings):
|
||||
- L4 quarter footprints → design ticket T-1112 (needs coarse-shape design first).
|
||||
- Region climate → prerequisite wiring ticket T-1113 (not in cascade at all yet).
|
||||
- L5 chunk/tile fill → NEVER an Atlas map layer (D-191/D-226 amendments 2026-07-13; harness-verified, Phase-5 in-world).
|
||||
- markers.json migration / Sol → T-949 / T-1073 (D-236: Sol excluded from deterministic runs, access capped at Oort gateway).
|
||||
|
||||
Overlay mechanism: follow the shipped always-toggleable pattern (D-226 as amended), NOT the old lock/notify spec.', 'in_progress', 'high', NULL, 'client', 'D-191', '2026-05-22 17:42:34', '2026-07-13 21:54:06.361', NULL, '956b2a24c68b83bb2d4e9399f5c90478', 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 ('06FB0TNSRYEJ0G4F0SBHG379YR', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Auto-pause sim on implant-fullscreen (inspection substrate)', 'D-226 layer 1 (substrate). Auto-pause the sim when the client enters a fullscreen implant app (the Atlas). Freeze the world-advancing tick phases (Movement/Simulation/Economy/Storyteller/Knowledge/TickAdvance) via run-conditions keyed to a pause command, but KEEP PreInput (gen-drain), Input (receive resume), Snapshot, PostSnapshot (bridge) alive so the UI keeps fetching data while frozen. Reuse the existing TickRate::Paused + the input.rs paused-allowlist seam; trigger from HudGroups::gameplay_occluded (D-170) -> a pause/resume command over the bridge. For static geography pause is a compute-saver; for dynamic state (economics, later) it is essential. Confirm exactly what TickRate::Paused currently gates (whole loop vs sim-advance) and gate at the phase level.
|
||||
|
||||
---
|
||||
Refinement (2026-07-13, /whats-next Si audit + lead ruling):
|
||||
|
||||
CONFIRMED (the ticket''s own open question): TickRate::Paused today gates ONLY the clock — advance_tick (simulation/time.rs:100-110, in TickPhase::TickAdvance) no-ops when Paused. There are ZERO run_if/run-conditions anywhere in the server schedule; tick_phases.rs::configure() only chains ordering. input.rs''s paused-allowlist (input.rs:128,134-155) is an in-system dispatch filter, not a phase gate. So "gate at the phase level" is new plumbing: add .run_if(not paused) to the SystemSet configs for Movement/Simulation/Storyteller/Knowledge/TickAdvance in tick_phases.rs::configure().
|
||||
|
||||
ECONOMY SPLIT (must not miss): serve_econ_state_query — which services the paused-ALLOWED EconStateQuery — is registered in the same TickPhase::Economy set, .after(tick_economy_simulation) (economy_plugin.rs:27-35). A blanket set-level gate on Economy would break that paused guarantee. Gate tick_economy_simulation individually; leave serve_econ_state_query unconditioned (.after() ordering holds when the upstream system is skipped). All other allowlist entries verified to land on keep-alive phases.
|
||||
|
||||
BRIDGE: no new protocol needed — PlayerAction::Pause/Unpause work end-to-end (D-088 manual pause; input_mapper.gd:137-139 → sim_bridge.gd action_enum_to_wire:528-531 → receive_bridge_inputs → process_player_input). The ONLY missing piece is client wiring: connect HudGroups.gameplay_occluded (hud_groups.gd:33,63-88) to sending Pause/Unpause via sim_bridge.gd''s outbound queue. Today only implant/map (Atlas, default_mode=fullscreen) triggers occlusion.
|
||||
|
||||
GEN-DRAIN: confirmed still correct post-T-1046 — GenerationPlugin registers drain_generation_completions + serve_atlas_requests in TickPhase::PreInput (atlas/plugin.rs:52-62); cascade compute is on an independent Rayon pool, so generation keeps flowing while paused. PreInput/Input/Snapshot/PostSnapshot stay alive per the ticket.
|
||||
|
||||
MANUAL-vs-AUTO PAUSE (the one gap — lead ruling: Option A): track WHETHER THE AUTO-PAUSE CAUSED the pause (a flag distinct from TickRate itself, e.g. auto_pause_active). Auto-resume on implant-close fires Unpause ONLY if auto-pause was the trigger — a prior manual pause (or D-088 Half rate) survives implant close untouched. No previous-rate stack (that''s Option C, deferred).', 'in_progress', 'high', NULL, 'server', 'D-226', '2026-05-24 09:22:33', '2026-07-13 21:54:06.378', NULL, '7d7c2f702ed806428f939f2d0d0e04d3', 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 ('06FB0TNSRW2ZSPJ3D9NEZ6JBW8', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas data delivery — replace client-side file reads with server API calls', 'The client currently reads markers.json and star_map_data.json directly from the filesystem. This bypasses the server layer entirely — the client should request all game data through IPC calls to the Rust backend.
|
||||
|
||||
Implementation can be simple: the server exposes a query/proxy endpoint that reads the JSON file or runs a DB query and returns the result. The client asks, the server responds. No complex protocol needed — just the boundary enforcement that the client never reads files or DB directly.
|
||||
|
||||
Affects: atlas app (reach, system, planet, regional screens), economics monitor. The server-side handler can start as a thin proxy (read file, return contents) and evolve into perception-filtered queries (D-012) later.
|
||||
|
||||
Re-parented under Phase 4 epic per cascade refocus 2026-06-12 — atlas data delivery underpins viewing cascade layers through the implant Atlas.
|
||||
|
||||
---
|
||||
Refinement (2026-07-13, /whats-next Si audit + Jeroen rulings):
|
||||
|
||||
SCOPE: the ~2,398 generated (non-Sol) bodies + star_map_data.json only.
|
||||
- SOL EXCLUDED (Jeroen): Sol stays out of all deterministic runs; player access is lore-capped at the Oort-cloud gateway station — see D-236 as amended 2026-07-13. Sol''s client-side legacy markers.json read (atlas_viewer.gd::_load_markers) STAYS as the documented D-223/D-236 exception until T-1073 (gated on Q-107). Do not repeat T-1073''s implement→break→revert cycle.
|
||||
- CITATION FIX: the description''s "perception-filtered queries (D-012)" should read D-010 (information boundaries). D-012 is chunk-based map architecture — unrelated.
|
||||
|
||||
CURRENT READ INVENTORY (verified 2026-07-13):
|
||||
1. atlas_viewer.gd::_load_markers (~436-467) — markers.json via FileAccess. For non-Sol bodies this is names-only data (D-223); replace with a names request over the bridge (server already reads atlas_city_names via CityContextReader). Positions come from T-960''s SettlementLayer work (separate ticket, same branch).
|
||||
2. system_index.gd::get_sorted_systems — star_map_data.json, consumed by atlas_app.gd:150 (Reach screen) + overview_screen.gd:114 (economics monitor selector; its only direct read). star_map_data.json is a build-time bake (tooling/generate-star-map-data.py); the server has NO existing reader — a thin proxy (server reads the same JSON, returns it) is acceptable per the ticket.
|
||||
3. OUT OF SCOPE (deliberate, D-225): reliefmap.png / wiki globe image loads stay client-side.
|
||||
|
||||
PROTOCOL PATTERN: structural disambiguation on the existing IPC stream (Inbound enum: Inputs vs AtlasRequest). Reach-level star-map data is not per-body/cascade-shaped — add NEW request/response types (e.g. StarMapRequest → StarMapResponse), do not shoehorn into AtlasLayerResponse. Per-body names ride the atlas path.', 'in_progress', 'medium', NULL, 'client', NULL, '2026-05-03 14:14:23', '2026-07-13 21:54:06.379', NULL, 'd8effcc8e1310f4e9381698c28f2f8ea', 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 ('06FP1GTTEGD648NDDFCAYR6NR4', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Client gdlint debt — 39 pre-existing warnings (zero-warnings policy)', 'Full gdlint over client/scripts + client/ui + client/tests reports 39 pre-existing problems (class-definitions-order across sandbox/, input_mapper, atlas system_screen/marker_overlay; max-returns in _sub_biome_color; max-line-length atlas_app.gd:75; duplicated-load in test_free_camera; constant-name in test_greybox_store). Verified 2026-07-14 (atlas-layer-viewer batch): all pre-date the branch — identical findings on main. Zero-warnings policy says these should be fixed or suppressed with commented justification. Mechanical sweep, no behavior changes.', 'backlog', 'low', NULL, 'client', NULL, '2026-07-14 13:14:03.252', '2026-07-14 13:14:03.252', NULL, '81f7495cbe4d2273019aab1dc39f73d1', 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 ('06FB0TNSRZ8BFVNWDH17CMH1YM', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Per-layer Atlas map viewer (generation progress viewer)', 'Render each cascade layer as a MAP in the implant Atlas (D-191, the Phase 3 viewer — D-166 amendment): terrain → water → biome → settlements → political zones → quarter/block skeleton → tiles. This is the progress-viewer deliverable; NO in-world rendering. Grows as each layer lands.
|
||||
|
||||
---
|
||||
Refinement (2026-05-23, /whats-next):
|
||||
- DATA TRANSPORT (resolves Q-098): NO bake — baking derived layer data makes mods second-class. A server-side FILE STREAM PROXY: resolves a body source files across base + mod paths, runs the deterministic cascade on demand (run_cascade, LRU-cached per D-203, ~45ms), and streams serialized layer data to the Godot client over IPC. First-party and mod bodies use the identical path; no pre-baked derived artifacts. Protocol/stream spec designed with Tyre and recorded in a D-record resolving Q-098.
|
||||
- UI: layer selector in the existing regional Atlas view; layers are ADDITIVE overlays (toggle heightmap + rivers + attractors + sub-biome together and composite), not one-at-a-time — matching the existing overlay-bar model (D-191).
|
||||
- SCOPE NOW: only Layer 0 (heightmap) + Layer 1 (rivers/basins/attractors/sub-biome) exist; the viewer grows as layers land (D-166). Acceptance: Layer 0 + Layer 1 render as additive, toggleable overlays for a body, fed by the proxy.
|
||||
|
||||
---
|
||||
Design (D-226, Araminta, 2026-05-24) — human-visual layer of the inspection harness. Extend OVERLAY_DEFS / AtlasOverlayBar with a generation overlay group (second row) + a left-side legend panel; do NOT build a separate viewer. Encoding: relief base; rivers as blue polylines (mouths = double-circle markers, confluences where in-degree >= 3); basin fills very translucent + thin boundary polylines; attractors as markers where SHAPE encodes the 7 AttractorTypes (circle/half-circle/diamond/down-tri/up-tri/hollow-circle/square) and COLOR encodes sub-biome (shape carries identity in headless/monochrome; color is additive); size scales with strength, skip strength < 0.15. Stable button ids gen_l0_heightmap / gen_l1_rivers / gen_l1_basins / gen_l1_attractors; start pending/locked, unlock+activate via notify_gen_layer_ready(id) as data arrives (grows as layers land, D-166). Consumes the live proxy (#969); the agent channel (#971) drives this same UI.
|
||||
|
||||
Remaining to close (Si sweep 2026-06-07): add the gen_l0_heightmap overlay to OVERLAY_DEFS + render path in atlas_viewer.gd / atlas_marker_overlay.gd — required by the D-226/T-960 acceptance criteria but currently absent. Layer-1 overlays (rivers/basins/attractors) + proxy wire + pending indicator are already implemented; this Layer-0 overlay is the sole remaining piece.
|
||||
|
||||
---
|
||||
Refinement (2026-07-13, /whats-next Si audit + Jeroen rulings) — RESCOPE. The 2026-06-07 scope note is obsolete in both directions:
|
||||
|
||||
DONE ALREADY (record, don''t rebuild):
|
||||
- L1 overlays (gen_l1_rivers/basins/attractors) + proxy wire + pending indicator: shipped.
|
||||
- District-morphology overlay (gen_district "MRPH"): shipped under T-1046 via AtlasLayerResponse.district_grid — the wiring precedent for everything below.
|
||||
- gen_l0_heightmap: DROPPED — relief already renders via the always-on terrain overlay (D-191 §7). D-226 amended (2026-07-13) accordingly.
|
||||
|
||||
IN SCOPE NOW (this ticket):
|
||||
1. gen_l2_roads overlay — L2 road/rail graph (T-1038) is computed on every AnalyzeBody (gen_queue.rs runs up_to=RoadGraph) but never serialized: add RoadGraphLayer field to AtlasLayerResponse (layer_proxy.rs), protocol.gd decode, overlay rendering (edges colored by MaintenanceAuthority, junction markers).
|
||||
2. gen_l3_settlements overlay — wire T-955''s computed CityPlacement positions through the proxy (new SettlementLayer field, exact T-1046 precedent) so cities render on generated bodies for the first time (Jeroen ruling: wire positions now; T-949 stays boundary-cleanup).
|
||||
3. Left-side legend panel — D-226 item (3) deliverable, never built (shape/color key for attractor types + sub-biomes + the new overlays).
|
||||
4. Doc-comment fix: layer_proxy.rs:31-34 claims cascade runs "through CascadeLayer::Settlement" — actually RoadGraph (gen_queue.rs:416); client''s up_to field is ignored by the server. One-line correction.
|
||||
|
||||
OUT OF SCOPE (explicitly, per 2026-07-13 rulings):
|
||||
- L4 quarter footprints → design ticket T-1112 (needs coarse-shape design first).
|
||||
- Region climate → prerequisite wiring ticket T-1113 (not in cascade at all yet).
|
||||
- L5 chunk/tile fill → NEVER an Atlas map layer (D-191/D-226 amendments 2026-07-13; harness-verified, Phase-5 in-world).
|
||||
- markers.json migration / Sol → T-949 / T-1073 (D-236: Sol excluded from deterministic runs, access capped at Oort gateway).
|
||||
|
||||
Overlay mechanism: follow the shipped always-toggleable pattern (D-226 as amended), NOT the old lock/notify spec.', 'review', 'high', NULL, 'client', 'D-191', '2026-05-22 17:42:34', '2026-07-14 14:36:24.074', NULL, '1be7212c31111c592dfb9f5aa7014578', 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 ('06FB0TNSRYEJ0G4F0SBHG379YR', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Auto-pause sim on implant-fullscreen (inspection substrate)', 'D-226 layer 1 (substrate). Auto-pause the sim when the client enters a fullscreen implant app (the Atlas). Freeze the world-advancing tick phases (Movement/Simulation/Economy/Storyteller/Knowledge/TickAdvance) via run-conditions keyed to a pause command, but KEEP PreInput (gen-drain), Input (receive resume), Snapshot, PostSnapshot (bridge) alive so the UI keeps fetching data while frozen. Reuse the existing TickRate::Paused + the input.rs paused-allowlist seam; trigger from HudGroups::gameplay_occluded (D-170) -> a pause/resume command over the bridge. For static geography pause is a compute-saver; for dynamic state (economics, later) it is essential. Confirm exactly what TickRate::Paused currently gates (whole loop vs sim-advance) and gate at the phase level.
|
||||
|
||||
---
|
||||
Refinement (2026-07-13, /whats-next Si audit + lead ruling):
|
||||
|
||||
CONFIRMED (the ticket''s own open question): TickRate::Paused today gates ONLY the clock — advance_tick (simulation/time.rs:100-110, in TickPhase::TickAdvance) no-ops when Paused. There are ZERO run_if/run-conditions anywhere in the server schedule; tick_phases.rs::configure() only chains ordering. input.rs''s paused-allowlist (input.rs:128,134-155) is an in-system dispatch filter, not a phase gate. So "gate at the phase level" is new plumbing: add .run_if(not paused) to the SystemSet configs for Movement/Simulation/Storyteller/Knowledge/TickAdvance in tick_phases.rs::configure().
|
||||
|
||||
ECONOMY SPLIT (must not miss): serve_econ_state_query — which services the paused-ALLOWED EconStateQuery — is registered in the same TickPhase::Economy set, .after(tick_economy_simulation) (economy_plugin.rs:27-35). A blanket set-level gate on Economy would break that paused guarantee. Gate tick_economy_simulation individually; leave serve_econ_state_query unconditioned (.after() ordering holds when the upstream system is skipped). All other allowlist entries verified to land on keep-alive phases.
|
||||
|
||||
BRIDGE: no new protocol needed — PlayerAction::Pause/Unpause work end-to-end (D-088 manual pause; input_mapper.gd:137-139 → sim_bridge.gd action_enum_to_wire:528-531 → receive_bridge_inputs → process_player_input). The ONLY missing piece is client wiring: connect HudGroups.gameplay_occluded (hud_groups.gd:33,63-88) to sending Pause/Unpause via sim_bridge.gd''s outbound queue. Today only implant/map (Atlas, default_mode=fullscreen) triggers occlusion.
|
||||
|
||||
GEN-DRAIN: confirmed still correct post-T-1046 — GenerationPlugin registers drain_generation_completions + serve_atlas_requests in TickPhase::PreInput (atlas/plugin.rs:52-62); cascade compute is on an independent Rayon pool, so generation keeps flowing while paused. PreInput/Input/Snapshot/PostSnapshot stay alive per the ticket.
|
||||
|
||||
MANUAL-vs-AUTO PAUSE (the one gap — lead ruling: Option A): track WHETHER THE AUTO-PAUSE CAUSED the pause (a flag distinct from TickRate itself, e.g. auto_pause_active). Auto-resume on implant-close fires Unpause ONLY if auto-pause was the trigger — a prior manual pause (or D-088 Half rate) survives implant close untouched. No previous-rate stack (that''s Option C, deferred).', 'review', 'high', NULL, 'server', 'D-226', '2026-05-24 09:22:33', '2026-07-14 14:36:24.076', NULL, '2d011ca4ce4ba724166772120be881a8', 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 ('06FB0TNSRW2ZSPJ3D9NEZ6JBW8', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas data delivery — replace client-side file reads with server API calls', 'The client currently reads markers.json and star_map_data.json directly from the filesystem. This bypasses the server layer entirely — the client should request all game data through IPC calls to the Rust backend.
|
||||
|
||||
Implementation can be simple: the server exposes a query/proxy endpoint that reads the JSON file or runs a DB query and returns the result. The client asks, the server responds. No complex protocol needed — just the boundary enforcement that the client never reads files or DB directly.
|
||||
|
||||
Affects: atlas app (reach, system, planet, regional screens), economics monitor. The server-side handler can start as a thin proxy (read file, return contents) and evolve into perception-filtered queries (D-012) later.
|
||||
|
||||
Re-parented under Phase 4 epic per cascade refocus 2026-06-12 — atlas data delivery underpins viewing cascade layers through the implant Atlas.
|
||||
|
||||
---
|
||||
Refinement (2026-07-13, /whats-next Si audit + Jeroen rulings):
|
||||
|
||||
SCOPE: the ~2,398 generated (non-Sol) bodies + star_map_data.json only.
|
||||
- SOL EXCLUDED (Jeroen): Sol stays out of all deterministic runs; player access is lore-capped at the Oort-cloud gateway station — see D-236 as amended 2026-07-13. Sol''s client-side legacy markers.json read (atlas_viewer.gd::_load_markers) STAYS as the documented D-223/D-236 exception until T-1073 (gated on Q-107). Do not repeat T-1073''s implement→break→revert cycle.
|
||||
- CITATION FIX: the description''s "perception-filtered queries (D-012)" should read D-010 (information boundaries). D-012 is chunk-based map architecture — unrelated.
|
||||
|
||||
CURRENT READ INVENTORY (verified 2026-07-13):
|
||||
1. atlas_viewer.gd::_load_markers (~436-467) — markers.json via FileAccess. For non-Sol bodies this is names-only data (D-223); replace with a names request over the bridge (server already reads atlas_city_names via CityContextReader). Positions come from T-960''s SettlementLayer work (separate ticket, same branch).
|
||||
2. system_index.gd::get_sorted_systems — star_map_data.json, consumed by atlas_app.gd:150 (Reach screen) + overview_screen.gd:114 (economics monitor selector; its only direct read). star_map_data.json is a build-time bake (tooling/generate-star-map-data.py); the server has NO existing reader — a thin proxy (server reads the same JSON, returns it) is acceptable per the ticket.
|
||||
3. OUT OF SCOPE (deliberate, D-225): reliefmap.png / wiki globe image loads stay client-side.
|
||||
|
||||
PROTOCOL PATTERN: structural disambiguation on the existing IPC stream (Inbound enum: Inputs vs AtlasRequest). Reach-level star-map data is not per-body/cascade-shaped — add NEW request/response types (e.g. StarMapRequest → StarMapResponse), do not shoehorn into AtlasLayerResponse. Per-body names ride the atlas path.', 'review', 'medium', NULL, 'client', NULL, '2026-05-03 14:14:23', '2026-07-14 14:36:24.077', NULL, '44aa53dcae1945b971c673cf3124f7b1', 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