chore(meta): close T-1163 — PR #193 merged (cold-launch starvation fix); review captures T-1164/T-1165/T-1166 filed

Tyre + Hoshe both APPROVE at 8bb09abad (one Hoshe fix round: wrong-body
Pending regression + comment dedupe, both revert-verified independently).
Cold acceptance re-verified on MERGED main: fresh release server, first
connection, Lendel converged mosaic inside 2s, stable while unattended,
legend one-legend-tall (.cache/screenshots/cold-start-main/). Review
tickets: T-1164 tiled terminal-recovery, T-1165 repaint-edge root-cause,
T-1166 scripted cold-launch test tier (both under T-1037 where noted).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 21:30:03 +02:00
co-authored by Claude Fable 5
parent 6d80936b65
commit bbe9099e22
3 changed files with 8 additions and 0 deletions
@@ -1681,3 +1681,4 @@ INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, chang
RE-SCOPED (Jeroen, 2026-07-22): ''we are aiming for not coloring in the cities at the moment the nature layer (geo and wild growth) first,'' matching D-166''s outside-in order. SPLIT this ticket''s overlay set into two waves. WAVE 1 (this ticket, promoted): the NATURE overlays gen_l1_rivers/basins/attractors onto the ladder (rivers as per-rung refining features: trunk rivers at Region, tributaries at District, streams at Quarter the wire/derivation question of serving river skeletons windowed is the real work), plus named natural features (rivers/oceans/ranges labels) if cheap. WAVE 2 (deferred until the nature layer stands, per Jeroen): everything civilizational city markers + sidebar, settlements/quarters footprints, roads/rail, POL/POP/CRP/gate markers. Do not port wave 2 with wave 1.', NULL, '2026-07-22 16:32:58', '2026-07-22 16:32:58.189', '2026-07-22 16:32:58.189', NULL, '9eb8e20a198920c024087e6153d4806b', 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 ('06FRPCJ4KD6SB9TB8TH9SJH1E0', 'status', 'backlog', 'review', NULL, '2026-07-22 18:59:22', '2026-07-22 18:59:22.418', '2026-07-22 18:59:22.418', NULL, 'ec51e983461658e7857f3c04a1ff73e5', 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 ('06FRPCJ4KD6SB9TB8TH9SJH1E0', 'status', 'review', 'done', NULL, '2026-07-22 19:29:52', '2026-07-22 19:29:52.281', '2026-07-22 19:29:52.281', NULL, 'd56f979255d7655437b286362d412900', 2) ON CONFLICT(hash) DO NOTHING;
+3
View File
@@ -77,3 +77,6 @@ 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 ('06FRMPY76TYY76FSBV2Y5P8QHM', 'T-1161', '2026-07-22 15:04:58.422', '2026-07-22 15:04:58.422', NULL, '57dc57abf66f677ff9014a71f7e42135', 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 ('06FRNAHD35YPZHJWMJCRZK62Z4', 'T-1162', '2026-07-22 16:30:36.394', '2026-07-22 16:30:36.394', NULL, 'ae1e4ce6b54ab340579241e6ac250865', 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 ('06FRPCJ4KD6SB9TB8TH9SJH1E0', 'T-1163', '2026-07-22 18:59:15.230', '2026-07-22 18:59:15.230', NULL, '0da68cd5428c1d43b8f1c542d1cc3506', 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 ('06FRPEGNSG7VVR602MTT4VDCEW', 'T-1164', '2026-07-22 19:07:47.535', '2026-07-22 19:07:47.535', NULL, 'a6f29e587f56a6cbc822281a6ee56d92', 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 ('06FRPEJ6TVFXRBEZPSP40677G4', 'T-1165', '2026-07-22 19:08:00.091', '2026-07-22 19:08:00.091', NULL, '864a7d91fd2fbc7ca277a1ae9fc8c833', 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 ('06FRPF77A790HCWZH78AVZ7T8M', 'T-1166', '2026-07-22 19:10:52.247', '2026-07-22 19:10:52.247', NULL, '78091c0dc323d292ca54c95963de61e6', 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);
+4
View File
@@ -2465,3 +2465,7 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat
RE-SCOPED (Jeroen, 2026-07-22): ''we are aiming for not coloring in the cities at the moment the nature layer (geo and wild growth) first,'' matching D-166''s outside-in order. SPLIT this ticket''s overlay set into two waves. WAVE 1 (this ticket, promoted): the NATURE overlays gen_l1_rivers/basins/attractors onto the ladder (rivers as per-rung refining features: trunk rivers at Region, tributaries at District, streams at Quarter the wire/derivation question of serving river skeletons windowed is the real work), plus named natural features (rivers/oceans/ranges labels) if cheap. WAVE 2 (deferred until the nature layer stands, per Jeroen): everything civilizational city markers + sidebar, settlements/quarters footprints, roads/rail, POL/POP/CRP/gate markers. Do not port wave 2 with wave 1.', 'backlog', 'high', NULL, 'client', 'D-226', '2026-07-22 09:42:37.105', '2026-07-22 16:32:58.189', NULL, '0e72ac69b0183e078d966b92aa6cf5be', 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 ('06FRPCJ4KD6SB9TB8TH9SJH1E0', 'bug', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Cold first launch starves: whole-response Pending never reaches the retry path', 'Jeroen''s make atlas launch showed a black map zooming into any body. Root cause (after four disproven theories, each killed by verification): a stone-cold body answers the first window request with whole-response status Pending (only the whole-body cache-hit branch sets Ready — layer_proxy.rs serve path), and atlas_window_request.gd on_response()''s first check (status != Ready -> return) swallowed it before the retry machinery could run — retries frozen at 0 forever, DERIVING state never resolves. Second connections worked by luck (first connection''s request warms the whole-body cache -> Ready -> healthy path), which also masked the bug in every warm-server verification drive. Affected BOTH tile-mosaic and single-window first descents. Fix (branch ladder-cold-start): status-first branching per the atlas_generation_proxy reference shape (Pending -> retry; NotFound/Error -> immediate give-up, replacing the elapsed-retries ceiling), deterministic exponential backoff + per-tile stagger, wire-accurate regressions through the real fan-out plus single-window mirrors, Dudley''s connection-zero bridge_tcp pin, self-healing tile repaint, ImplantApp re-entry guard + immediate-free panel clears, legend re-fit, visible DERIVING TERRAIN state, and make atlas moving to a RELEASE server via SR_SERVER_BIN. Cold acceptance verified live: first connection, fresh release server — DERIVING at 2s, terrain painting tile-by-tile by 5s, all six tiles converged, legend one-legend-tall.', 'backlog', 'critical', NULL, 'client', 'D-226', '2026-07-22 18:59:15.227', '2026-07-22 18:59:15.227', NULL, '413332e77799ba02262b7f18849d4add', 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 ('06FRPCJ4KD6SB9TB8TH9SJH1E0', 'bug', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Cold first launch starves: whole-response Pending never reaches the retry path', 'Jeroen''s make atlas launch showed a black map zooming into any body. Root cause (after four disproven theories, each killed by verification): a stone-cold body answers the first window request with whole-response status Pending (only the whole-body cache-hit branch sets Ready — layer_proxy.rs serve path), and atlas_window_request.gd on_response()''s first check (status != Ready -> return) swallowed it before the retry machinery could run — retries frozen at 0 forever, DERIVING state never resolves. Second connections worked by luck (first connection''s request warms the whole-body cache -> Ready -> healthy path), which also masked the bug in every warm-server verification drive. Affected BOTH tile-mosaic and single-window first descents. Fix (branch ladder-cold-start): status-first branching per the atlas_generation_proxy reference shape (Pending -> retry; NotFound/Error -> immediate give-up, replacing the elapsed-retries ceiling), deterministic exponential backoff + per-tile stagger, wire-accurate regressions through the real fan-out plus single-window mirrors, Dudley''s connection-zero bridge_tcp pin, self-healing tile repaint, ImplantApp re-entry guard + immediate-free panel clears, legend re-fit, visible DERIVING TERRAIN state, and make atlas moving to a RELEASE server via SR_SERVER_BIN. Cold acceptance verified live: first connection, fresh release server — DERIVING at 2s, terrain painting tile-by-tile by 5s, all six tiles converged, legend one-legend-tall.', 'review', 'critical', NULL, 'client', 'D-226', '2026-07-22 18:59:15.227', '2026-07-22 18:59:22.418', NULL, '624cfd2b92d5dfdaf4626b47b160525e', 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 ('06FRPEGNSG7VVR602MTT4VDCEW', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Tiled orbital terminal-recovery — exhausted DERIVING state has no retry path', 'PR #193 review (Tyre, finding 2): after MAX_RETRIES(30)/~110s of genuine unbroken Pending in the tiled orbital rest state, the player is permanently stuck at DERIVING TERRAIN: pan is a no-op while tiled (_maybe_refloat_window early-returns), zoom-out is floored at the canonical frame (edge-triggered reset never re-fires), and regional_screen.enter() no-ops same-body re-entry — recovery only via zooming IN across the Region boundary or visiting a different body. Pathological trigger (110s of continuous Pending) and the release-server make-atlas change makes it near-impossible on the sanctioned path, but it is a real dead-end. Fix options per the review: a manual retry affordance on the DERIVING state, or same-body re-entry re-issues tile requests when has_pending_tiles() and every tile request is exhausted-non-pending. Single-window is already fully recoverable (any pan/zoom resets the retry state) — this is tile-mode only.', 'backlog', 'medium', NULL, 'client', 'D-226', '2026-07-22 19:07:47.532', '2026-07-22 19:07:47.532', NULL, '92b47ce81c968400b47583826c7505b4', 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 ('06FRPEJ6TVFXRBEZPSP40677G4', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Root-cause the dropped tile-arrival repaint edge (self-heal poll is compensating)', 'PR #193 review (Tyre, finding 3): the cold-start fix ships a bounded self-healing _process redraw (atlas_window_viewer.gd ~887: redraw viewer+overlay every frame while _tile_mode and has_pending_tiles()) — architecturally acceptable (goes quiet the instant tiles complete, spy-tested) but honestly a poll compensating for a signal-driven repaint contract the team could not fully trust under cold-server timing: some queue_redraw edge was observed dropped in live rounds (black mosaic with correct data/geometry/textures) and was never exactly pinned. Root-cause the dropped edge (candidates from the live dossier: tile_ready ordering vs draw scheduling, overlay-vs-viewer redraw routing under deferred frees, RenderingServer timing on texture upload) so the poll can be retired and so other renderers do not copy the poll pattern as gospel. Keep the self-heal until the edge is pinned AND a regression exists.', 'backlog', 'low', NULL, 'client', NULL, '2026-07-22 19:08:00.086', '2026-07-22 19:08:00.086', NULL, 'a7911cd3eedb2d309d5f128e8c108754', 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 ('06FRPF77A790HCWZH78AVZ7T8M', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Scripted cold-launch integration test tier (fresh server, connection zero, tiles arrive, non-black frame)', 'PR #193 review (Tyre, finding 1): T-1163 (every cold first launch black) was only findable by a human launching the real stack cold — ~3500 unit tests were green with the bug live, and every scripted verification drive used a warm server (second connection), the exact luck that masked the bug. File the missing test tier: a scripted cold-launch integration test that (1) spawns a FRESH release server process (never pre-warmed — build via make build-server-release, SR_SERVER_BIN override), (2) drives the first-ever client connection through the real Atlas descent into a body (SceneTree -s script, atlas_standalone.tscn, nav.push + _on_body_selected — the live-drive harness shape in tooling/, untyped autoload refs per the harness conventions), (3) asserts all tiles arrive within a deadline (tile_set.is_fully_arrived() or per-tile window non-null), and (4) asserts a non-black rendered frame (capture via root.get_texture().get_image(), assert mean luminance above a floor). Compose from existing pieces: the visual_capture/server_process helpers and the run-visual entry. This is the tier that would have caught T-1163 on day one; it also becomes the permanent home for the cold acceptance run /pr-review now performs by hand. Not a gate hook initially — a make target (make test-cold-launch) runnable on demand and in review.', 'backlog', 'medium', NULL, 'client', NULL, '2026-07-22 19:10:52.241', '2026-07-22 19:10:52.241', NULL, '0ad401e6728e37e8f499bc04b32cba9d', 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 ('06FRPCJ4KD6SB9TB8TH9SJH1E0', 'bug', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Cold first launch starves: whole-response Pending never reaches the retry path', 'Jeroen''s make atlas launch showed a black map zooming into any body. Root cause (after four disproven theories, each killed by verification): a stone-cold body answers the first window request with whole-response status Pending (only the whole-body cache-hit branch sets Ready — layer_proxy.rs serve path), and atlas_window_request.gd on_response()''s first check (status != Ready -> return) swallowed it before the retry machinery could run — retries frozen at 0 forever, DERIVING state never resolves. Second connections worked by luck (first connection''s request warms the whole-body cache -> Ready -> healthy path), which also masked the bug in every warm-server verification drive. Affected BOTH tile-mosaic and single-window first descents. Fix (branch ladder-cold-start): status-first branching per the atlas_generation_proxy reference shape (Pending -> retry; NotFound/Error -> immediate give-up, replacing the elapsed-retries ceiling), deterministic exponential backoff + per-tile stagger, wire-accurate regressions through the real fan-out plus single-window mirrors, Dudley''s connection-zero bridge_tcp pin, self-healing tile repaint, ImplantApp re-entry guard + immediate-free panel clears, legend re-fit, visible DERIVING TERRAIN state, and make atlas moving to a RELEASE server via SR_SERVER_BIN. Cold acceptance verified live: first connection, fresh release server — DERIVING at 2s, terrain painting tile-by-tile by 5s, all six tiles converged, legend one-legend-tall.', 'done', 'critical', NULL, 'client', 'D-226', '2026-07-22 18:59:15.227', '2026-07-22 19:29:52.281', NULL, 'a106f9a9ccd78c7ccecc1e98e5e45862', 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);