chore(meta): record the atlas shutdown leak as intermittent, not constant

Observed twice today with different outcomes. The crash is deterministic —
every shutdown logs the null-instance error at server_process.gd:87 via
_stop_spawned_server. The orphaned server is NOT: one run leaked a process
that had to be killed by hand, the next reaped cleanly with the same error in
the log.

That combination is the awkward one. A fix verified by a single clean
shutdown proves nothing, so T-1224 now says to reproduce by repeated
launch/close while watching for surviving processes, rather than by reading
one log.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-27 09:05:40 +02:00
co-authored by Claude
parent 363574d687
commit 58cd87d48c
2 changed files with 12 additions and 0 deletions
@@ -3232,3 +3232,10 @@ Atmosphere keeps its full expressive range for the SURFACE-EXPEDITION layer (Jer
Also record that Sol bodies carry dangling terrain_reference rows pointing at heightmaps deliberately never baked (import_heightmaps.py explicitly excludes Sol), so a real Earth or Mars DEM dropped at that exact path would silently start generating a procedural homeworld with no gate to stop it.
Claim ids with ''pql decisions claim D architecture ...'' before writing.', NULL, '2026-07-26 23:13:40', '2026-07-26 23:13:40.114', '2026-07-26 23:13:40.114', NULL, '7c7563a0fa9899b39ec05877ab33b0cb', 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 ('06FT0VAZ0RV0FQZMSTB13QP56M', 'description', 'Found during the 2026-07-26 pair session while verifying the D-255 extent-inversion work in the make atlas companion shell (D-254). server_process.gd:87''s _stop_spawned_server crashes on a null instance when called via atlas_standalone.gd:292 -- reproduced during this session''s shutdown and had to be killed by hand (orphaned process left running after the client exited). Separately, but likely related root cause: every cold make atlas launch also logs ''TCP connection failed after 20 retries'' as an ERROR for what is actually an expected attach-probe path (the client probing for an already-running server before deciding to spawn its own) -- this should not log at ERROR severity since failure is the expected/normal outcome on a cold launch.
Context: make atlas (the D-254 companion shell) was never verified post-D-255 landing before this session -- last touched 2026-07-22, viewer replaced 2026-07-24/25, so this is likely the first real shutdown exercise since the stepped-Atlas rebuild. Fix both: (1) null-check server_process instance before calling stop on it, or guard the call site in atlas_standalone.gd:292; (2) downgrade or restructure the attach-probe''s expected-failure log to not read as an ERROR. Verify with a full cold-launch-then-quit cycle leaving no orphaned server process.', 'Found during the 2026-07-26 pair session while verifying the D-255 extent-inversion work in the make atlas companion shell (D-254). server_process.gd:87''s _stop_spawned_server crashes on a null instance when called via atlas_standalone.gd:292 -- reproduced during this session''s shutdown and had to be killed by hand (orphaned process left running after the client exited). Separately, but likely related root cause: every cold make atlas launch also logs ''TCP connection failed after 20 retries'' as an ERROR for what is actually an expected attach-probe path (the client probing for an already-running server before deciding to spawn its own) -- this should not log at ERROR severity since failure is the expected/normal outcome on a cold launch.
Context: make atlas (the D-254 companion shell) was never verified post-D-255 landing before this session -- last touched 2026-07-22, viewer replaced 2026-07-24/25, so this is likely the first real shutdown exercise since the stepped-Atlas rebuild. Fix both: (1) null-check server_process instance before calling stop on it, or guard the call site in atlas_standalone.gd:292; (2) downgrade or restructure the attach-probe''s expected-failure log to not read as an ERROR. Verify with a full cold-launch-then-quit cycle leaving no orphaned server process.
OBSERVED TWICE 2026-07-27, and the two runs differed worth knowing before someone tries to reproduce. The crash itself is DETERMINISTIC: every Atlas shutdown logs ''Attempt to call function stop in base null instance'' at server_process.gd:87, reached via atlas_standalone.gd:292 (_stop_spawned_server) from _exit_tree. The ORPHANED SERVER is INTERMITTENT: on the first run the spawned settled-reach-server survived the Godot exit and had to be killed by hand (PID 1917179, found ~40min later); on the second run, same crash in the log, but the child was reaped correctly and no stray remained. So this is a race on the shutdown path, not a straight always-leaks bug which means a fix verified by a single clean shutdown proves nothing. Reproduce by launching and closing repeatedly and checking for surviving ''settled-reach-server --port 0'' processes, not by reading one log. Note the null instance is reached during _notification, so the reap may be racing Godot''s own teardown of the ServerProcess node.', NULL, '2026-07-27 07:05:31', '2026-07-27 07:05:31.990', '2026-07-27 07:05:31.990', NULL, '9cc5b0e2a196151d167cb1608a90146a', 2) ON CONFLICT(hash) DO NOTHING;
+5
View File
@@ -5524,3 +5524,8 @@ Also record that Sol bodies carry dangling terrain_reference rows pointing at he
Claim ids with ''pql decisions claim D architecture ...'' before writing.', 'backlog', 'high', NULL, 'server', NULL, '2026-07-26 23:12:57.206', '2026-07-26 23:13:40.114', NULL, '53a08ddb97ea73677337c7a50dd1cc05', 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 ('06FT1D64MS28Z2BGV4Z771JRQG', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'client/tests/util/scene_helper.gd has no importers -- dead test utility', 'Found by the new parse sweep on 2026-07-27. This helper had not PARSED since 2026-02-25 -- five months -- because a lambda used ''func(a := null, ...)'', and := cannot infer a type from null. Fixed in commit a005e4840 with explicit '': Variant'' params. But the reason it went unnoticed for five months is that NOTHING IMPORTS IT: a grep across client/tests/ returns zero consumers. So the blast radius of the breakage was zero, and the file is dead code. Decide: delete it, or adopt it (it wraps signal-emission monitoring for scene tests, which several suites currently hand-roll). Not deleted unilaterally -- deleting code is the user''s call. Low priority; it is inert either way now that it parses.', 'backlog', 'low', NULL, 'client', NULL, '2026-07-26 23:13:49.222', '2026-07-26 23:13:49.222', NULL, '336371298ea7b847684b5e093ef1b299', 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 ('06FT0VAZ0RV0FQZMSTB13QP56M', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'make atlas: _stop_spawned_server crashes on null instance, leaves orphaned server process', 'Found during the 2026-07-26 pair session while verifying the D-255 extent-inversion work in the make atlas companion shell (D-254). server_process.gd:87''s _stop_spawned_server crashes on a null instance when called via atlas_standalone.gd:292 -- reproduced during this session''s shutdown and had to be killed by hand (orphaned process left running after the client exited). Separately, but likely related root cause: every cold make atlas launch also logs ''TCP connection failed after 20 retries'' as an ERROR for what is actually an expected attach-probe path (the client probing for an already-running server before deciding to spawn its own) -- this should not log at ERROR severity since failure is the expected/normal outcome on a cold launch.
Context: make atlas (the D-254 companion shell) was never verified post-D-255 landing before this session -- last touched 2026-07-22, viewer replaced 2026-07-24/25, so this is likely the first real shutdown exercise since the stepped-Atlas rebuild. Fix both: (1) null-check server_process instance before calling stop on it, or guard the call site in atlas_standalone.gd:292; (2) downgrade or restructure the attach-probe''s expected-failure log to not read as an ERROR. Verify with a full cold-launch-then-quit cycle leaving no orphaned server process.
OBSERVED TWICE 2026-07-27, and the two runs differed worth knowing before someone tries to reproduce. The crash itself is DETERMINISTIC: every Atlas shutdown logs ''Attempt to call function stop in base null instance'' at server_process.gd:87, reached via atlas_standalone.gd:292 (_stop_spawned_server) from _exit_tree. The ORPHANED SERVER is INTERMITTENT: on the first run the spawned settled-reach-server survived the Godot exit and had to be killed by hand (PID 1917179, found ~40min later); on the second run, same crash in the log, but the child was reaped correctly and no stray remained. So this is a race on the shutdown path, not a straight always-leaks bug which means a fix verified by a single clean shutdown proves nothing. Reproduce by launching and closing repeatedly and checking for surviving ''settled-reach-server --port 0'' processes, not by reading one log. Note the null instance is reached during _notification, so the reap may be racing Godot''s own teardown of the ServerProcess node.', 'backlog', 'medium', NULL, NULL, NULL, '2026-07-26 21:55:50.150', '2026-07-27 07:05:31.990', NULL, 'c254af187f565cdfae408d04a65f2ac2', 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);