Commit Graph
2592 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Fable 5 132915a4e5 test(engine): browse-inclusive union-frame rejection cases (PR #184 review)
Hoshe's finding: the H1 union-rejection mechanism correctly counts the
new browse discriminator, but ambiguous_union_frame_is_rejected was
carried over from PR #176 without a browse-inclusive case — a future
demux/ShapeProbe refactor could drop the fifth shape from the union
check with nothing to catch it. Adds browse+star_map and
browse+city_names union frames, both asserting rejection.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 10:53:36 +02:00
jpmschweitzerandClaude Fable 5 7111cea549 fix(engine): clippy items_after_test_module — tests mod to end of main.rs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 10:42:06 +02:00
jpmschweitzerandClaude Fable 5 2509624577 fix(engine): resolve systems.db exe-anchored, not cwd-relative — spawn-mode DB access
PathBuf::from("data/systems.db") was cwd-relative, and a spawned
server inherits GODOT's cwd — which is client/ (Godot's --path client
chdirs), so CultureResolver, CityContextReader, BodySourceResolver and
BrowseReader all silently failed in every make atlas / make game
spawn. Wave 1 masked it: the star map serves from star_map_data.json,
so 'renders 301 systems' never touched the DB; T-1133's browser was
the first DB-backed consumer to hit it live (Stig, /proc/PID/cwd).

resolve_systems_db_path(): exe-anchored <exe_dir>/../../data/systems.db
first (cwd-independent — the actual fix), then cwd-relative
data/systems.db (cd server && cargo run), then server/data/systems.db
(repo-root invocations); first existing candidate wins, info-logged.
Pure systems_db_candidates() split out as the testable seam (5 unit
tests — incl. pinning Path::parent() of a bare filename = Some(""),
not None). world_root now derives from the resolved ABSOLUTE path so
its ancestors().nth(3) arithmetic holds unconditionally instead of
silently falling back to ".." when canonicalize failed.

Verified all three launch styles; make atlas spawn shows 5 reader fds
open on server/data/systems.db via /proc/PID/fd.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 10:37:15 +02:00
jpmschweitzerandClaude Fable 5 90c562a6a3 feat(ui): T-1133 data browser — implant/browser app, six index+detail screens (D-254 SS4)
New implant app (app_path implant/browser, key B, fullscreen), sibling
to the Atlas per Jeroen's IA ruling: kind picker -> generic filterable
index (live search-mode typing) -> generic detail, parameterized per
kind, composed entirely from D-169 components. available_in_companion
left unset (default true) — the app appears in the companion shell
automatically via the generic-host seam, zero companion-side wiring.

browser_adapter.gd is the sole home of literal wire field names: maps
Oscar's BrowseResponse contract ({id, primary, secondary} index rows;
BrowseDetail enum-as-single-key-map) to view models for all six kinds,
folding join partners (system economy/factions/culture, corporation
presence, commodity production chains with nested Leontief inputs).
browse_protocol.gd split out of protocol.gd (max-file-lines);
sim_bridge gains browse_response_received + request_browse_index/detail.

Live-data catch: a present-but-NULL key (unnamed asteroid belt
proper_name) bypasses Dictionary.get fallbacks and rendered '<null>' —
_display_or() null-vs-absent helper applied across all six detail
mappers, 4 regression tests distinct from the absent-key cases.

43 gdUnit adapter cases; full suite 3074 green. Live-verified against
a real server + real systems.db: all six kinds Ready with real row
counts (301/3240/466/165/36/28), detail drill-down, NotFound on bogus
ids. Spawn-mode DB resolution issue found during verification is
pre-existing (cwd-relative data/systems.db) — server-side fix follows
separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 10:24:39 +02:00
jpmschweitzerandClaude Fable 5 d48d72fd31 feat(engine): T-1131 browse data proxy — six entity kinds, index+detail, one wire envelope (D-254 SS4)
browse_reader.rs: BrowseReader on the CityContextReader::open() pattern
— six index + six detail reads against systems.db (bodies filterable by
containing system; system/corporation/commodity details fold their join
partners). browse_proxy.rs: BrowseRequest{browse, kind, query} /
BrowseResponse{kind, status, index, detail} wire types + dispatcher;
BrowseIndexRow{id, primary, secondary} generic across kinds;
BrowseDetail a per-kind enum of field-exhaustive structs.

Demux: Inbound::BrowseRequest is the FIFTH map shape — deliberately the
last; the doc's four-shape ceiling is re-pinned at five with rationale
(six kinds x two forms folded into ONE envelope whose internal enums
pick sub-behavior, the AtlasLayerRequest.up_to precedent, instead of
twelve top-level shapes) and a hard rule that a sixth shape must
migrate to the D-225 tagged-envelope framing. Served for BOTH roles,
connection-tagged 1:1 in-order like atlas/starmap/citynames.
serve_browse_requests pub so integration tests drive the true
end-to-end pipeline. Wire-only per D-254 (T-949 precedent); v1
exclusions (cascade geometry, event logs) respected.

30 unit tests + 7 bridge_tcp integration tests (six-kind round-trip
over real TCP, reader-can-browse, no crossed responses between two
readers, unknown-id NotFound, empty-table Ready); 2 pre-existing tests
updated for the new receive_bridge_inputs parameter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 10:01:21 +02:00
jpmschweitzerandClaude Fable 5 edde411fb6 chore(meta): close companion wave 1 — T-1129/T-1130/T-1132 done (PR #183 merged); D-254 synced
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:33:54 +02:00
jpmschweitzer a334c7c237 Merge remote-tracking branch 'origin/atlas-companion-app' 2026-07-17 09:32:07 +02:00
jpmschweitzerandClaude Fable 5 9b5c113961 fix(client): defer companion close-interceptor re-open out of the app_changed emit (PR #183 review)
Tyre's finding: _on_hud_app_changed ran open_app synchronously from
INSIDE close_app's app_changed emit; close_app continues past the emit
and resets _active_app, clobbering the re-open — Atlas left visible
(z already raised) but is_app_active() false, so atlas_app's input
guard rejects every key: keyboard soft-lock after one M/Escape on the
reach screen. Fix: open_app.call_deferred, out of the signal frame.

Two regression tests pin the contract at the HudGroups level (no
server needed): the synchronous shape must keep getting clobbered and
the deferred shape must survive — if HudGroups emit semantics ever
change, both flag the contract shift for a deliberate look.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:29:29 +02:00
jpmschweitzerandClaude Fable 5 7baac29861 chore(meta): T-1129/T-1130/T-1132 to review — PR #183 up (companion wave 1)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:17:46 +02:00
jpmschweitzerandClaude Fable 5 061eb642c9 fix(engine): clippy doc_lazy_continuation — PendingPoll::Failed note is its own paragraph, not a list continuation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:13:59 +02:00
jpmschweitzerandClaude Fable 5 6d4e03ffd5 chore(meta): file T-1136 — spawned-server orphan watchdog (T-1132 SIGTERM gap follow-up)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:11:20 +02:00
jpmschweitzerandClaude Fable 5 cffe760d36 feat(client): T-1132 standalone Atlas companion shell + make atlas (D-254 SS3)
New atlas_standalone scene/script: attach-or-spawn boot (one REAL
connect_to_sim attempt at SR_PORT-or-9876 — a separate throwaway TCP
probe was proven by live run to kill a pre-accept-loop server via
broken handshake pipe; never abandon a connected socket), else spawn
--port 0 via new ServerProcess.start_with_pipe + LISTENING:{port}
stdout parse, retry against the resolved port. Reader role wired end
to end: protocol.encode_startup_message optional role param (empty
omits the wire key — byte-identical for all existing callers),
sim_bridge.connection_role suppresses the post-handshake
RequestAllSettings auto-send, hud_groups skips AutoPause/AutoResume
sends for readers (all three would otherwise burn Reader violation
strikes per the T-1130 matrix — endorsed by Oscar).

Generic implant host per D-254 SS3: the shell instantiates ALL
registered implant apps; implant_app_manifest gains
available_in_companion (opt-out, default true) and
implant_registry.instantiate_all a standalone filter param (default
preserves hud.gd behavior byte-identically). Boot order is
instantiate_all THEN open_app (reverse renders a permanently black
window — app_changed fires with no listener; matches hud.gd's order).
Owned-server lifecycle: _exit_tree stops a spawned child, attached
servers survive companion close. Known engine limitation documented:
raw SIGTERM bypasses all Godot notifications and orphans a spawned
server; WM close paths verified clean.

Live-verified: spawn-mode (301 systems rendered from systems.db over
the wire), attach-mode, two simultaneous readers, clean shutdown with
zero orphan processes. 14 new gdUnit tests (port/LISTENING parsing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:09:09 +02:00
jpmschweitzerandClaude Fable 5 92c455ef10 chore(meta): close seam batch — T-1125/T-1126/T-1127 done (PR #182 merged, both reviewers approved clean)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:36:36 +02:00
jpmschweitzer 370a34eb1f Merge remote-tracking branch 'origin/coastline-invention' 2026-07-17 08:33:28 +02:00
jpmschweitzerandClaude Fable 5 627e02f7ba chore(meta): file T-1135 — split character spawn out of world-setup (T-1130 follow-up)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:31:45 +02:00
jpmschweitzerandClaude Fable 5 ddc3d39d09 feat(engine): T-1130 reader connections — role-gated multi-connection bridge (D-254 SS1/SS2)
ConnectionRole (Player|Reader, serde-default Player for wire back-compat;
shaped for a future TradingReader) on StartupMessage. BridgeResource
rewritten as 0-1 Player + 0-N Readers with ConnectionId; per-tick
accept_new_connections loop replaces the single blocking accept (the
listener is cloned non-blocking into ConnectionListener). First
connection installs per startup.role — spawn-mode Readers are often the
only connection a server gets.

Permitted-message matrix: readers may handshake and issue
Atlas/StarMap/CityNames requests (responses connection-tagged, own
requests only); PlayerInput from a reader is dropped with a strike
(disconnect at 3); ObserverSnapshot has no reader-facing path at all.
Shutdown scope: only a PLAYER send failure flips ServerRunning —
reader-only servers idle with the snapshot queued; reader disconnects
never kill the session.

Deliberately out of scope, documented at the call site: character spawn
stays in monolithic world-setup (reader-first servers carry an inert
unpiloted PlayerCharacter); no total-reader-count cap (per-reader frame
cap only, loopback-only scope).

6 new bridge_tcp integration tests; layer3 subprocess test exercises the
accept-loop end to end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:30:56 +02:00
jpmschweitzerandClaude Fable 5 e6dff2c370 chore(meta): T-1125/T-1126/T-1127 to review — PR #182 up (coastline invention seam batch)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:25:48 +02:00
jpmschweitzerandClaude Fable 5 a86dab3756 docs(meta): D-227 T-1125 invention-character amendment + D-239 T-1126 Marine amendment
D-227: records the two-tier driver model (body envelope from authored
params only, D-240 tilt exclusion upheld; position tier with fjord/
latitude/wetness/heterogeneity), the shared invent_primitives path,
the scatter floor-vs-ceiling reading, shoreline carving, and the
one-step-stale circularity ruling. D-239: Marine appended at
discriminant 6, morphology-derived verdict, airless precedence,
non-semantic Ord position.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:22:20 +02:00
jpmschweitzerandClaude Fable 5 aa1471069b test(simulation): derivation-harness call sites + believability golden regen for coastline invention
Mechanical call-site updates (7) for the invent_primitives signature;
believability golden regenerated via UPDATE_GOLDEN=1. Deltas are
deliberate: slope_q/elev_q spreads widen, vegetation_classes +1
(Marine), water-districts-wet coherence reaches 46/46 and 19/19
(T-1082 class closed — classification and coastline are the same line).
Reductions (ocean_fraction distinct, morphology_zones on GJ244Ad)
are the eager pseudo-grid point-sampling coasts honestly instead of
area-averaging them into synthetic intermediates; believability
coast-sampling resolution is Q-123 calibration territory. All 37
derivation-harness law checks unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:21:57 +02:00
jpmschweitzerandClaude Fable 5 6aafa77583 feat(simulation): T-1127 glaciation ice tint + Marine color in zoom-ladder probe
aliveness_probe --render gains a 6th glaciation panel; glaciated
districts get an ice tint keyed on GlaciationGrade, and Marine
vegetation renders [0,96,172] — distinct from the morphology water
tones so district-carrier vs voxel-generator disagreement stays
visible in ladders.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:21:27 +02:00
jpmschweitzerandClaude Fable 5 fef422bf01 feat(simulation): T-1125/T-1126 coastline invention — two-tier character model, shared invent_primitives, Marine vegetation
T-1125: new atlas/coast_invention.rs — BodyCoastEnvelope (tier 1: erosion
maturity derived hydro×atmo, tectonic energy; D-240 stands, no orbital
inputs) + coast_character_at (tier 2: latitude, glaciation fjord response,
local wetness, seeded 100-400 km heterogeneity field). C1 multi-octave
warp ~16-262 km, sub-pixel cap 0.75 px, salted stream isolated from
terrain scatter and climate edge-fuzz.

district_profile: shared invent_primitives front-half (warped envelope
sampling + slope-independent scatter floor + shoreline carving) wired
into BOTH derive_district and derive_district_profile — the batch path's
scatter-free area-mean aggregate is replaced by an invented centre-point
sample of the same continuous field, making silent path divergence
structurally impossible.

T-1126: VegetationClass::Marine appended at discriminant 6, verdict
morphology-derived (open_water from OpenOcean|Lake — no fourth ocean
threshold); airless precedence preserved. voxel.rs exhaustive-match arm
documented unreachable (WaterBody owns ocean districts).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:21:07 +02:00
jpmschweitzer d42951d43a chore(meta): record Jeroen's generic-implant-host requirement on T-1132/T-1133 (D-254 SS3 addition) 2026-07-17 08:10:53 +02:00
jpmschweitzerandClaude Fable 5 d370ca6044 docs(meta): D-254 SS3 — companion is a generic implant host; available_in_companion opt-out flag (Jeroen, mid-implementation)
Future implant apps/screens automatically extend the external app; per-app manifest bool (default true) locks out gameplay-dependent apps; in-game implant ignores the flag. Jeroen's suggested name availableInAtlasApp recorded with the rename rationale.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:10:08 +02:00
jpmschweitzer 554bba67d9 chore(meta): activate T-1130 (oscar) + T-1132 (stig) — companion-app implementation wave 1 2026-07-17 08:06:47 +02:00
jpmschweitzerandClaude Fable 5 b57805d0c6 docs(meta): D-254 — standalone Atlas companion app (make atlas, dual-connection reader) (T-1129)
Six sections: connection model (attach SR_PORT/9876 ~500ms else spawn --port 0 + LISTENING parse, auto-attach-else-spawn); Reader connection class (ConnectionRole on StartupMessage, serde-default Player; no character spawn, NO ObserverSnapshot, permitted-message matrix, drop-not-disconnect, 0-1 Player + 0-N Readers, Player-only shutdown-on-disconnect); app shell (dedicated atlas_standalone.tscn, trivial make atlas target); data browser (separate implant/browser app per Jeroen, six registry entities v1, WIRE-ONLY extending the T-949 precedent — no client SQLite); save/load seam (seed picker now, save picker slot Phase 5+); trading seam (TradingReader superset, idempotency tokens, loopback-only auth assumption recorded). Tyre (lead) + Oscar (connection sections, his activation). Validate + sync clean (388 records, 0 broken).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:05:57 +02:00
jpmschweitzer 599024f590 chore(meta): file D-254 implementation tree — T-1130 reader connection (gates all), T-1131 browse proxy, T-1132 standalone shell, T-1133 browser UI, T-1134 seed picker; Jeroen's IA + granularity rulings 2026-07-17 08:04:46 +02:00
jpmschweitzer 38b989b226 chore(skills): raise kanban WIP soft-limit 5 -> 10 (Jeroen, 2026-07-17 — sidequest track alongside the active batch) 2026-07-17 07:53:04 +02:00
jpmschweitzer 749ba49181 chore(meta): sidequest — file T-1128 companion-app epic + T-1129 design pass (D-254 claimed); activate design 2026-07-17 07:48:35 +02:00
jpmschweitzer ee0dd6df25 chore(meta): activate seam batch T-1125/T-1126/T-1127 — Jeroen's crinkle-varies rulings + Si gap resolutions; T-1126 blocked by T-1125 2026-07-17 07:39:28 +02:00
jpmschweitzer 3d73a4d221 chore(meta): close district-window batch — T-1123 done (PR #181 merged); T-1125 seam story is the recommended next batch 2026-07-16 22:37:02 +02:00
jpmschweitzer fa7db681ea Merge remote-tracking branch 'origin/district-window-render' 2026-07-16 22:36:40 +02:00
jpmschweitzer c8adc17556 chore(meta): T-1123 to review — PR #181 up 2026-07-16 22:31:40 +02:00
jpmschweitzerandClaude Fable 5 5e48c85a9a fix(simulation): move probe tests module below Args — clippy items_after_test_module
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:30:10 +02:00
jpmschweitzerandClaude Fable 5 cf6ef2bc31 feat(simulation): district-window zoom-ladder renderer — aliveness_probe --render/--window/--anchor (T-1123)
Renders true-2km district maps (derive_district per cell, NOT the coarse eager grid) as PNGs: morphology (17-zone palette transliterated from atlas_marker_overlay.gd, sync-commented), elev/temp/moisture/vegetation panels, anchor crosshair, km-honest filenames + manifest. believability.rs gains cascade_snapshot_for_body (cascade_for_body now a thin wrapper); probe re-derives the D-203-freed TerrainAnalysis via run_layer1 only under --render. Determinism proven: 5/5 panels byte-identical across passes AND cross-process (md5s reproduced in a fresh run). ~8us/district debug. First-ever look at the district layer produced the T-1125/T-1126/T-1127 findings (D-227 seam ends at ~500km; ocean-blind vegetation; unrendered glaciation).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:26:57 +02:00
jpmschweitzer c824ca51a1 chore(meta): file T-1125/T-1126/T-1127 — zoom-ladder findings under T-1079 (D-227 seam, ocean-blind veg, glaciation rendering) 2026-07-16 22:26:13 +02:00
jpmschweitzer 96737756dd chore(meta): file T-1123 district-window renderer (activated, dudley) + T-1124 Atlas regional-map-view design — Jeroen's orbit-to-jet-plane bridge gap 2026-07-16 21:56:18 +02:00
jpmschweitzer 531041506d chore(meta): close screenshot-goldens batch — T-1120 done (PR #180 merged) 2026-07-16 21:44:11 +02:00
jpmschweitzer 414dbd2da9 Merge remote-tracking branch 'origin/atlas-screenshot-goldens' 2026-07-16 21:43:16 +02:00
jpmschweitzerandClaude Fable 5 fcf913a413 fix(client): move golden-provenance key out of scenarios{} — crashed visual_capture --list (PR #180 review, Hoshe)
The _comment_atlas_goldens key inside scenarios{} hit _print_list's .get() on a bare String (reproduced: Invalid call on String at visual_capture.gd:699). Moved to a top-level key alongside resolution/golden_dir; _print_list now also skips _-prefixed and non-Dictionary entries so future comment keys cannot crash it. Verified: --list runs clean, JSON valid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 21:40:03 +02:00
jpmschweitzer de25063e99 chore(meta): file T-1122 — shared live-server GdUnit helper (PR #180 root-cause fallout) 2026-07-16 21:31:31 +02:00
jpmschweitzerandClaude Fable 5 3819e65759 test(client): pace input-roundtrip moves past the D-053 stance cooldown (T-1068 fix ported)
Root-caused with server trace logs: Walk stance throttles 1 move per 2 ticks and SILENTLY discards early moves (movement.rs apply_move -> try_move, TRACE-only) — under load the test's MoveEast landed exactly 1 tick after MoveNorth and was consumed. Server behavior is correct, deliberate D-053, pinned by Rust tests; production clients re-send while keys are held. Fix: COOLDOWN_TICKS=3 post-ack spacing, same as test_sprint2_proof.gd (T-1068) whose fix never reached this file due to helper copy-paste. Pre-fix repro at run 17/30 under load; post-fix 30/30 stress green + full suite 2956/2956.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 21:30:52 +02:00
jpmschweitzerandClaude Fable 5 8d1121d13a test(client): wall-clock deadline + 10s ceiling for input-roundtrip response waits
Second distinct flake in this suite today (gate run: MoveEast observed mid-move at the 5s window). The old accounting accrued elapsed only on empty polls — load-dependent effective window. Wall-clock deadline via Time.get_ticks_msec; ceiling 5s->10s (exit-on-arrival, costs nothing when healthy). Targeted suite 6/6.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 20:47:12 +02:00
jpmschweitzerandClaude Fable 5 9427b165f0 docs(client): golden provenance notes — atlas_* goldens are machine-local until T-1121 (PR #180 review, Tyre T1)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 20:42:37 +02:00
jpmschweitzer 84cfb05eca chore(meta): T-1120 to review — PR #180 up 2026-07-16 20:36:47 +02:00
jpmschweitzerandClaude Fable 5 56b9f135d0 test(client): add_child AtlasViewer in view-api tests — bare .new() has nil _canvas
Three of the four new tests skipped scene-tree entry, so _ready() never resolved _canvas and set_view crashed _apply_transform. Mirrors the fourth (passing) test. Targeted suite green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 20:34:01 +02:00
jpmschweitzer d3384ab417 chore(meta): file T-1121 — visual golden baseline drift across machines (T-1120 finding) 2026-07-16 20:30:31 +02:00
jpmschweitzerandClaude Fable 5 2b2f4f8abb test(client): 12 Atlas golden screenshots — 7 bodies x 3 zooms x 3 overlay sets (T-1120)
Curated from the 42-shot matrix, one per body spanning all zoom levels and overlay sets; self-consistency verified 12/12 at exact pixel match on this box. .import sidecars force-added per the existing golden convention. Bodies: GJ380c, GJ144e, GJ338Bd, GJ820Bc (Metropolis + Cygni yard), GJ251c (T-1116 water/no-roads exhibit), GJ244Ad (frozen), GJ445c-m1 (moon).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 20:29:53 +02:00
jpmschweitzerandClaude Fable 5 799156b140 feat(client): Atlas screenshot capture matrix + set_view API (T-1120)
AtlasViewer gains public set_view(zoom, offset)/get_view_offset (clamped, review-flagged API gap) + gdUnit suite. visual_capture.gd gains an atlas_matrix scenario (one boot, tests/atlas_shots.json-driven: 7 verified bodies x zoom x overlay sets, signal-gated waits on atlas_layers_received/city_names_received with timeout fallback). 12 individually-addressable golden scenarios registered in tests/visual.json. Root-level settings.db* gitignored (capture-spawned servers write their settings store to cwd). Fixes found live: GDScript lambdas capture value-type locals BY VALUE (wait-flag moved to Array carrier); RegionalScreen.enter() no-ops when the screen id is unchanged (direct enter() per body after the first).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 20:29:14 +02:00
jpmschweitzer 17cad2bbf9 chore(meta): activate T-1120 — Atlas screenshot capture matrix + goldens (stig) 2026-07-16 19:31:40 +02:00
jpmschweitzer 9706eb9d0e chore(meta): close atlas-layer batch — T-1112/T-1113 done (PR #179 merged); file T-1118 climate overlay, T-1119 quarter-footprint wiring, T-1120 Atlas screenshot goldens 2026-07-16 19:25:54 +02:00