diff --git a/.pql/changelog/ticket_deps/2026-07.sql b/.pql/changelog/ticket_deps/2026-07.sql index 8a2fd0f78..827d956e7 100644 --- a/.pql/changelog/ticket_deps/2026-07.sql +++ b/.pql/changelog/ticket_deps/2026-07.sql @@ -2,3 +2,7 @@ INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updat INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWYHR72SC80F5T0TBW', '06FB0TNSRWGDT3AJJE5QD0E3FR', '2026-07-07 16:57:31.296', '2026-07-07 16:57:31.296', NULL, 'e6784e95e525cb6458fe258ab4b6e4c2', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXQGAX5GT4PTTBQYGJCV4', '06FB0TNSRZKXHAYMT7Q6WW3XDC', '2026-07-08 15:53:21.023', '2026-07-08 15:53:21.023', NULL, '64d1cc675b69a17b5e1ec1f59710e9eb', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FPS6QD5FG9TC2WXTDVA44FPW', '06FPS6RRBF9HHAED5QKTKQCY1G', '2026-07-17 05:38:31.704', '2026-07-17 05:38:31.704', NULL, '2064c9c98f1ac17eb75a65adc6282ea9', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); +INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FPXAS26J3BS7ZJVRFT5JDXP8', '06FPXATGN8QJAJVR0WCRHJS2TG', '2026-07-17 06:04:01.563', '2026-07-17 06:04:01.563', NULL, 'ee3fa6747444971d1e58089b8ddba619', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); +INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FPXATGN8QJAJVR0WCRHJS2TG', '06FPXB28V72K8ZPE5WSNJS1SP8', '2026-07-17 06:04:10.480', '2026-07-17 06:04:10.480', NULL, 'ef6be166d0635e87fe5e2f3db6f93a75', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); +INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FPXAWGRH9QK5QKV7584Q92Z8', '06FPXB28V72K8ZPE5WSNJS1SP8', '2026-07-17 06:04:17.197', '2026-07-17 06:04:17.197', NULL, 'aa125f47573802dc7efaaab8d34e18ad', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); +INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FPXAWGRH9QK5QKV7584Q92Z8', '06FPXB41KV1J008A140B9CFD7M', '2026-07-17 06:04:24.496', '2026-07-17 06:04:24.496', NULL, '9a17059a1d0eb20c8b9b16d152fcbb74', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); diff --git a/.pql/changelog/ticket_history/2026-07.sql b/.pql/changelog/ticket_history/2026-07.sql index 947668214..484afbaec 100644 --- a/.pql/changelog/ticket_history/2026-07.sql +++ b/.pql/changelog/ticket_history/2026-07.sql @@ -1477,3 +1477,6 @@ 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 ('06FPS6TF9XDZPKZY8DHG1T0E2R', 'assigned_to', NULL, 'dudley', NULL, '2026-07-17 05:38:51', '2026-07-17 05:38:51.406', '2026-07-17 05:38:51.406', NULL, 'a61ffc1075244eda35e07b8037fc561a', 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 ('06FPS6RRBF9HHAED5QKTKQCY1G', 'assigned_to', NULL, 'dudley', NULL, '2026-07-17 05:38:51', '2026-07-17 05:38:51.406', '2026-07-17 05:38:51.406', NULL, 'de3fdd3e8ceac6cd698a2270b5997592', 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 ('06FPX7HZY1CK3VSTRXP1NP9VYW', 'status', 'backlog', 'in_progress', NULL, '2026-07-17 05:48:21', '2026-07-17 05:48:21.369', '2026-07-17 05:48:21.369', NULL, '117c6985291dd5894ce19995f11d8c00', 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 ('06FPXAWGRH9QK5QKV7584Q92Z8', 'description', 'D-254 SS1/SS3/SS5. client/scenes/atlas_standalone.tscn + atlas_standalone.gd (modeled on visual_capture.gd''s boot shape — NOT a flag on main.tscn, which is saturated with player-only paths): attach-mode = TCP connect SR_PORT-or-9876 with ~500ms timeout; ECONNREFUSED falls through to spawn-mode = own child server via the server_process.gd ownership pattern with --port 0 + LISTENING:{port} parse, REAL systems.db (no --test-mode); sends Reader-role StartupMessage; opens implant/map fullscreen (skips main menu/character creation); window title branding via DisplayServer.window_set_title; intercept atlas close-to-gameplay in atlas_standalone.gd (do not modify atlas_app.gd). Makefile: target = trivial build+launch (the scene owns the attach-or-spawn decision — no Makefile orchestration; and per Oscar''s flag this simplicity does NOT shrink the T-1130 server work). Exportable later as a Godot export preset, no architecture change. Blocked by T-1130 for real attach-mode testing (developable against spawn-mode before that). Blocks the browser-UI ticket (needs a shell to launch from).', 'D-254 SS1/SS3/SS5. client/scenes/atlas_standalone.tscn + atlas_standalone.gd (modeled on visual_capture.gd''s boot shape — NOT a flag on main.tscn, which is saturated with player-only paths): attach-mode = TCP connect SR_PORT-or-9876 with ~500ms timeout; ECONNREFUSED falls through to spawn-mode = own child server via the server_process.gd ownership pattern with --port 0 + LISTENING:{port} parse, REAL systems.db (no --test-mode); sends Reader-role StartupMessage; opens implant/map fullscreen (skips main menu/character creation); window title branding via DisplayServer.window_set_title; intercept atlas close-to-gameplay in atlas_standalone.gd (do not modify atlas_app.gd). Makefile: target = trivial build+launch (the scene owns the attach-or-spawn decision — no Makefile orchestration; and per Oscar''s flag this simplicity does NOT shrink the T-1130 server work). Exportable later as a Godot export preset, no architecture change. Blocked by T-1130 for real attach-mode testing (developable against spawn-mode before that). Blocks the browser-UI ticket (needs a shell to launch from). + +Correction: the Makefile target name in the line above is ''atlas'' (make atlas) — shell backticks ate the word during filing.', NULL, '2026-07-17 06:03:20', '2026-07-17 06:03:20.063', '2026-07-17 06:03:20.063', NULL, 'e6cbeaa35dd5d2b3382cea2581d589f7', 2) ON CONFLICT(hash) DO NOTHING; diff --git a/.pql/changelog/tickets/2026-07.sql b/.pql/changelog/tickets/2026-07.sql index fe89190a2..de8caa839 100644 --- a/.pql/changelog/tickets/2026-07.sql +++ b/.pql/changelog/tickets/2026-07.sql @@ -2059,3 +2059,11 @@ Refinement (2026-07-17, Si review): READY. Upstream verified HEALTHY — glaciat 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 ('06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'epic', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Standalone Atlas companion app — make atlas (read-only reader, future trading)', 'Jeroen (2026-07-17): the Atlas should run as a standalone desktop application/reader via make atlas, against the RUNNING game server or by starting its own (with a save/load interaction seam). Read-only for now; may later support market trading against the running game. Three stated purposes: (1) lightweight app to scan ALL database data (dev data-inspection surface over systems/bodies/corps/settlements/etc.); (2) remains available as a LEGITIMATE player-facing pattern post-release — a diegetic second-monitor companion; (3) attach-or-spawn with save/load interaction (saves are Phase 5+ — v1 designs the seam, offers world-seed selection). Read-only enforcement implies a reader/spectator connection class on the bridge that never spawns a character or sends inputs — likely the first true multi-connection work (Oscar''s remit). Design pass first (D-254 claimed for the record); implementation tickets follow the recorded design.', 'backlog', 'high', NULL, NULL, NULL, '2026-07-17 05:47:53.088', '2026-07-17 05:47:53.088', NULL, '15e4ee84818115da35db352275277b10', 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 ('06FPX7HZY1CK3VSTRXP1NP9VYW', 'task', '06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'Design pass: D-254 companion-app architecture — connection model, reader protocol, app shell, data browser, save/load seam', 'Produce and record D-254 (id claimed). Participants: Tyre (architecture lead, writes the record) + Oscar (protocol/connection model — his activation). Must pin: (1) CONNECTION MODEL — attach to the running game server vs spawn-own (--test-mode? which world?) incl. discovery (port/SR_ADDR), and the multi-connection reality of the bridge today (recon: almost certainly single-connection; a second reader connection is new protocol work); (2) READER CONNECTION CLASS — handshake variant that never spawns a character and cannot send inputs (read-only enforced SERVER-side, not client courtesy — future market trading would widen this deliberately per-verb, design the enum now); (3) APP SHELL — how make atlas launches the existing implant Atlas UI standalone (second main scene vs feature flag vs export preset; keep the implant aesthetic — the diegetic second-monitor pattern is a product goal); (4) DATA BROWSER — Jeroen wants to scan ALL database data: define the browse surface (entity list/detail screens from implant components: systems, bodies, corps, settlements, markets) and its data path (existing wire requests vs a generic read API vs local systems.db read for static data + wire for dynamic — mind the D-010 information-boundary rules for what a reader may see); (5) SAVE/LOAD SEAM — saves are Phase 5+; design the interaction now (attach = inherits the running world; spawn = pick seed today, pick save later), record the hook; (6) FUTURE TRADING note — what changes when the app gains write verbs (auth? per-verb allowlist on the reader class?). Deliverable: D-254 record written in governance/decisions/architecture.md + a proposed implementation ticket tree under T-1128. Wiring is NOT this ticket.', 'backlog', 'high', NULL, 'server', NULL, '2026-07-17 05:48:12.656', '2026-07-17 05:48:12.656', NULL, '293a6ca42749bbad299da7e217a8fcc6', 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 ('06FPX7HZY1CK3VSTRXP1NP9VYW', 'task', '06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'Design pass: D-254 companion-app architecture — connection model, reader protocol, app shell, data browser, save/load seam', 'Produce and record D-254 (id claimed). Participants: Tyre (architecture lead, writes the record) + Oscar (protocol/connection model — his activation). Must pin: (1) CONNECTION MODEL — attach to the running game server vs spawn-own (--test-mode? which world?) incl. discovery (port/SR_ADDR), and the multi-connection reality of the bridge today (recon: almost certainly single-connection; a second reader connection is new protocol work); (2) READER CONNECTION CLASS — handshake variant that never spawns a character and cannot send inputs (read-only enforced SERVER-side, not client courtesy — future market trading would widen this deliberately per-verb, design the enum now); (3) APP SHELL — how make atlas launches the existing implant Atlas UI standalone (second main scene vs feature flag vs export preset; keep the implant aesthetic — the diegetic second-monitor pattern is a product goal); (4) DATA BROWSER — Jeroen wants to scan ALL database data: define the browse surface (entity list/detail screens from implant components: systems, bodies, corps, settlements, markets) and its data path (existing wire requests vs a generic read API vs local systems.db read for static data + wire for dynamic — mind the D-010 information-boundary rules for what a reader may see); (5) SAVE/LOAD SEAM — saves are Phase 5+; design the interaction now (attach = inherits the running world; spawn = pick seed today, pick save later), record the hook; (6) FUTURE TRADING note — what changes when the app gains write verbs (auth? per-verb allowlist on the reader class?). Deliverable: D-254 record written in governance/decisions/architecture.md + a proposed implementation ticket tree under T-1128. Wiring is NOT this ticket.', 'in_progress', 'high', NULL, 'server', NULL, '2026-07-17 05:48:12.656', '2026-07-17 05:48:21.364', NULL, '42d787f064722c83d45529642ecc597c', 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 ('06FPXAS26J3BS7ZJVRFT5JDXP8', 'task', '06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'Reader connection: multi-connection bridge + ConnectionRole gate', 'D-254 SS1/SS2 (record on the atlas-companion-app branch; ref attaches after merge+sync). THE GATING TICKET — everything else in T-1128 needs a server that can hold a second connection without hanging it (today: main.rs single blocking accept at ~line 120; a second client hangs silently forever). Scope: ConnectionRole field on StartupMessage (Player | Reader, serde default Player for back-compat, enum shaped for future TradingReader); TcpListener blocking single-accept -> non-blocking per-tick accept loop; BridgeResource becomes 0-1 Player + 0-N Reader collection (NOT general N-player — D-009 scope stays separate); Reader never enters the character-spawn path and receives NO ObserverSnapshot (structural, not filtered); per-connection response tagging for atlas/starmap/citynames request-response buffers; Player-only whole-server-shutdown-on-disconnect (Reader disconnects must never affect the player session); permitted-message matrix enforcement server-side — violation = log + drop frame, repeated = disconnect the reader; lower per-reader inbound frame cap. Deterministic sim unaffected by reader presence. Oscar''s design, Oscar implements.', 'backlog', 'high', NULL, 'server', NULL, '2026-07-17 06:02:17.012', '2026-07-17 06:02:17.012', NULL, 'e1d09618c5db58eaef42b5cf6dd80869', 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 ('06FPXATGN8QJAJVR0WCRHJS2TG', 'task', '06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'Browse data proxy — six v1 entity read endpoints over the wire', 'D-254 SS4. BrowseRequest/Response per-entity-kind types (star systems, bodies, stations, corporations, commodities, trait templates) in server/src/atlas/, sibling to atlas_data_proxy.rs; rusqlite reads against systems.db via the CityContextReader::open() pattern (five-ish new read functions on a proven pattern); wired into the same inbound demux the reader connection uses. Wire-only by D-254 ruling (extends the T-949 precedent: the client never reads game data files directly; no SQLite GDExtension). Excluded from v1: cascade-derived atlas geometry tables (partially populated mid-Phase-4) and event-log tables (wrong UI shape) — exclusion list recorded in D-254. Blocked by the reader-connection ticket (needs the connection class to gate against).', 'backlog', 'high', NULL, 'server', NULL, '2026-07-17 06:02:28.906', '2026-07-17 06:02:28.906', NULL, 'a679c6b81981a1d3cd18a5bf4aaac757', 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 ('06FPXAWGRH9QK5QKV7584Q92Z8', 'task', '06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'Standalone entry scene + attach-or-spawn boot + make atlas target', 'D-254 SS1/SS3/SS5. client/scenes/atlas_standalone.tscn + atlas_standalone.gd (modeled on visual_capture.gd''s boot shape — NOT a flag on main.tscn, which is saturated with player-only paths): attach-mode = TCP connect SR_PORT-or-9876 with ~500ms timeout; ECONNREFUSED falls through to spawn-mode = own child server via the server_process.gd ownership pattern with --port 0 + LISTENING:{port} parse, REAL systems.db (no --test-mode); sends Reader-role StartupMessage; opens implant/map fullscreen (skips main menu/character creation); window title branding via DisplayServer.window_set_title; intercept atlas close-to-gameplay in atlas_standalone.gd (do not modify atlas_app.gd). Makefile: target = trivial build+launch (the scene owns the attach-or-spawn decision — no Makefile orchestration; and per Oscar''s flag this simplicity does NOT shrink the T-1130 server work). Exportable later as a Godot export preset, no architecture change. Blocked by T-1130 for real attach-mode testing (developable against spawn-mode before that). Blocks the browser-UI ticket (needs a shell to launch from).', 'backlog', 'high', NULL, 'client', NULL, '2026-07-17 06:02:45.316', '2026-07-17 06:02:45.316', NULL, '122d617d90df55dc685b1da0e0a62135', 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 ('06FPXAWGRH9QK5QKV7584Q92Z8', 'task', '06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'Standalone entry scene + attach-or-spawn boot + make atlas target', 'D-254 SS1/SS3/SS5. client/scenes/atlas_standalone.tscn + atlas_standalone.gd (modeled on visual_capture.gd''s boot shape — NOT a flag on main.tscn, which is saturated with player-only paths): attach-mode = TCP connect SR_PORT-or-9876 with ~500ms timeout; ECONNREFUSED falls through to spawn-mode = own child server via the server_process.gd ownership pattern with --port 0 + LISTENING:{port} parse, REAL systems.db (no --test-mode); sends Reader-role StartupMessage; opens implant/map fullscreen (skips main menu/character creation); window title branding via DisplayServer.window_set_title; intercept atlas close-to-gameplay in atlas_standalone.gd (do not modify atlas_app.gd). Makefile: target = trivial build+launch (the scene owns the attach-or-spawn decision — no Makefile orchestration; and per Oscar''s flag this simplicity does NOT shrink the T-1130 server work). Exportable later as a Godot export preset, no architecture change. Blocked by T-1130 for real attach-mode testing (developable against spawn-mode before that). Blocks the browser-UI ticket (needs a shell to launch from). + +Correction: the Makefile target name in the line above is ''atlas'' (make atlas) — shell backticks ate the word during filing.', 'backlog', 'high', NULL, 'client', NULL, '2026-07-17 06:02:45.316', '2026-07-17 06:03:20.063', NULL, '199d41e8b2cf05d2246531c3aa02cf89', 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 ('06FPXB28V72K8ZPE5WSNJS1SP8', 'task', '06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'Data browser UI — implant/browser app, six index+detail screens', 'D-254 SS4 + Jeroen''s IA ruling (2026-07-17): a SEPARATE implant app (implant/browser), sibling to the Atlas — the six registry entities do not share the Atlas''s geographic drill-down. ONE ticket for all six per Jeroen (single review sees the whole surface). Scope: new client/ui/implant/apps/browser/ app.tres + app.gd + index/detail screen pairs for star systems, bodies, stations, corporations, commodities, trait templates — composed ENTIRELY from D-169 implant components (ImplantPanel/ImplantHeader/ImplantDataRow/ImplantTextBlock; no new UI primitives); wired to the six BrowseRequest endpoints; reachable from the standalone shell (and by design also from the in-game implant later — it is a normal implant app). Blocked by the browse-proxy ticket (data source) and the standalone-shell ticket (launch surface).', 'backlog', 'high', NULL, 'client', NULL, '2026-07-17 06:03:32.441', '2026-07-17 06:03:32.441', NULL, 'a9e18307ecab0cc8cb83f9b3c2612553', 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 ('06FPXB41KV1J008A140B9CFD7M', 'task', '06FPX7FKG0Y6SYWEDPG4PJQHQ8', 'Spawn-mode startup screen — seed picker now, save picker slot (Phase 5+)', 'D-254 SS5. The pre-Atlas startup screen for spawn-mode: world-seed selection v1; the future save picker slots into this exact screen as a second choice (reusing main.gd''s LoadGame wire action verbatim once saves exist, Phase 5+ / T-888 lineage). Genuinely independent of the browser work; spawn-mode works with the server-default seed without it — UX polish on a working path. Blocked by the standalone-shell ticket.', 'backlog', 'low', NULL, 'client', NULL, '2026-07-17 06:03:46.974', '2026-07-17 06:03:46.974', NULL, 'd1cdfff623d6af935993c00ea39962de', 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);