From 6d4e03ffd5c5f44ddf8037cbf1c5edffafe252e9 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Fri, 17 Jul 2026 09:11:20 +0200 Subject: [PATCH] =?UTF-8?q?chore(meta):=20file=20T-1136=20=E2=80=94=20spaw?= =?UTF-8?q?ned-server=20orphan=20watchdog=20(T-1132=20SIGTERM=20gap=20foll?= =?UTF-8?q?ow-up)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .pql/changelog/ticket_idmap/2026-07.sql | 1 + .pql/changelog/tickets/2026-07.sql | 1 + 2 files changed, 2 insertions(+) diff --git a/.pql/changelog/ticket_idmap/2026-07.sql b/.pql/changelog/ticket_idmap/2026-07.sql index 77f44c0ef..761447748 100644 --- a/.pql/changelog/ticket_idmap/2026-07.sql +++ b/.pql/changelog/ticket_idmap/2026-07.sql @@ -49,3 +49,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 ('06FPXB28V72K8ZPE5WSNJS1SP8', 'T-1133', '2026-07-17 06:03:32.441', '2026-07-17 06:03:32.441', NULL, '032b367fbbe155baa75568ca8a82b754', 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 ('06FPXB41KV1J008A140B9CFD7M', 'T-1134', '2026-07-17 06:03:46.974', '2026-07-17 06:03:46.974', NULL, '7c1ba6caa5e39e27a2dae1507a8adf9d', 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 ('06FPXHCT46V340D1AJZRKBHJN4', 'T-1135', '2026-07-17 06:31:11.655', '2026-07-17 06:31:11.655', NULL, '9c14910a4fb21b72b6ce4e3d99318617', 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 ('06FPXTD20GS2CSC10RCC53Q6V4', 'T-1136', '2026-07-17 07:10:32.965', '2026-07-17 07:10:32.965', NULL, '39cf12c1af9e1d7d195d119107724f40', 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); diff --git a/.pql/changelog/tickets/2026-07.sql b/.pql/changelog/tickets/2026-07.sql index a86ab4d96..2f54cf0a1 100644 --- a/.pql/changelog/tickets/2026-07.sql +++ b/.pql/changelog/tickets/2026-07.sql @@ -2140,3 +2140,4 @@ Gap resolution (2026-07-17, Si review + Jeroen): (1) GATE: morphology-derived 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 ('06FPS6TF9XDZPKZY8DHG1T0E2R', 'task', '06FGSJNP8YM537DJCC82ZD6544', 'Frozen bodies read temperate-green on district morphology maps — render glaciation_grade', 'T-1123 zoom-ladder finding: GJ244Ad (frozen planet_class, temp panel pegged at the -60C clamp floor, vegetation solid Barren) still renders temperate-green morphology — the 17-zone MorphologyZone vocabulary (T-1027, FROZEN per its own contract) has no ice/glacial zone, and glaciation_grade is a separate DistrictProfile field nothing renders. Do NOT reopen the frozen vocab by default: the likely fix is rendering glaciation_grade as a modifier/overlay on the morphology color (ice-tinting affected zones) in both the T-1123 probe renderer and the future T-1124 view — or, if the team decides an ice zone belongs in the vocabulary after all, that is a deliberate amendment to the freeze decision, not a drive-by. Images: .cache/screenshots/district-windows gj244ad_w256_morphology.png vs _temp.png. Refinement (2026-07-17, Si review): READY. Upstream verified HEALTHY — glaciation derivation (derive_glaciation_grade_from_climate, district_profile.rs:339-366) is correctly wired and even gates the Fjord family; GJ244Ad moisture clears the gate floor. This is purely a rendering gap: aliveness_probe render_window_panels computes the full DistrictProfile and discards .glaciation_grade (line ~458 reads only morphology_zone). SCOPE RULING (lead): probe-only THIS ticket — per-pixel ice tint blended on the morphology panel keyed on glaciation_grade (+ optionally a 6th dedicated glaciation panel; PANEL_NAMES/bufs are array-driven, cheap). The wire+client half (glaciation: Vec parallel array inside DistrictGridLayer + build_district_grid + protocol.gd + _draw_gen_district — governance-UNCONSTRAINED per the D-226 growth-ceiling reading: the cap governs new top-level Option layers, not per-cell fields inside a shipped layer; elev_q precedent) is DEFERRED to T-1124''s design pass, which owns the which-fields-ship-at-district-resolution question. Freeze contract confirmed: D-239 SS6 — tint is classifier-tuning territory, no MorphologyZone vocab reopen; an ice zone would need its own explicit D-amendment (not pursued).', 'done', 'medium', 'dudley', 'server', NULL, '2026-07-16 20:25:45.551', '2026-07-17 06:36:05.022', NULL, 'f4a9417688f87f17eef4d66b8a8bb266', 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 ('06FPXTD20GS2CSC10RCC53Q6V4', 'task', '06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'Spawned-server orphan watchdog — survive companion SIGTERM (parent-death signal or equivalent)', 'T-1132 known gap (Stig, live-verified): a raw SIGTERM to the companion process bypasses Godot''s entire notification system (_notification never fires, _exit_tree never runs — confirmed by isolated repro), so a spawn-mode companion killed that way orphans its owned server process. All WM close paths (X button, Alt+F4, wmctrl -c) are clean and verified. No GDScript fix exists — the mitigation is server-side: when spawned as a companion child (e.g. a --parent-watch flag or detecting the pipe), the server should exit when its parent dies — prctl(PR_SET_PDEATHSIG, SIGTERM) on Linux at minimum, or a portable stdin-EOF watchdog (the companion already holds the child''s stdio pipe via start_with_pipe, so stdin closing on parent death is a reliable cross-platform death signal). Keep it opt-in per spawn args so make game and test-harness spawns are unaffected.', 'backlog', 'low', NULL, 'server', NULL, '2026-07-17 07:10:32.964', '2026-07-17 07:10:32.964', NULL, 'ab6964ffc45341d3f5c0014f1bc0d01a', 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);