fix(simulation+ui): T-1142 descent bounds, fit, pole wall, east-west wrap — live-verified full chain #188

Closed
jpmschweitzer wants to merge 0 commits from atlas-descent-fixes into main
Owner

Summary

T-1142 — the fixes from Jeroen's first hands-on descent, plus his pan-topology rulings, live-verified end to end through the real input pipeline this time.

The bug he hit

Clicking the letterbox beside the fixed planetary map descended to DistrictPos (12276, 3021) — an impossible column (no terrain-bearing body exceeds valid col ~11,236). The descend gate never checked the cursor was on the heightmap texture; the server trusted the insane center, derived clamped garbage, and cached it; and the window opened at native 512px in a ~1900px viewport (no fit). Net experience: a flat green postage stamp.

Client (Stig)

  • Bounds gate: is_on_texture() — ONE helper feeding both the reticle guard and the click fall-through (affordance always matches the click); half-open boundary pinned at the exact edge. Letterbox: no reticle, no descent.
  • Fit-and-center: pure fit_window_view() on enter / first window arrival / resize, gated by a _user_adjusted flag so it never fights manual zoom/pan. (Own-bug caught en route: RESIZED can fire mid-_ready — null-guarded.)
  • Pole hard wall (Jeroen's ruling): clamp_pan_offset_to_pole_wall() clamps the window edge, not the center — the pole row can reach the top of the screen, never past; handles the tiny-body window-taller-than-planet case. Three numeric hand-traces preceded the code; a first-draft test that silently never exercised the clamp (huge real radius) was replaced with a synthetic one.
  • East/west wrap (Jeroen's ruling): canonicalize_district_center()posmod column wrap (verified bit-identical to Rust rem_euclid against a live Godot process), clamped row; applied only to the FINAL refetch center (the edge-crossing decision stays in absolute space — a first-pass error caught by hand-trace). Circumnavigation is seamless; a full lap hits cache.
  • Header body name: "Lendel — (9570, −208)" instead of bare coordinates (the cheap half of T-1141 pulled forward).
  • Drag-pan verified through the real DistrictScreen→viewer chain and pinned by test (it already worked).

Server (Dudley)

  • normalize_window_center() mirroring the forward map exactly (column rem_euclid on the body's district circumference, row clamped to ±half-meridian; constants from scale::DISTRICT_M) — applied BEFORE the window-cache and coalescing keys. End-to-end test: the literal bug values on a 500 km fixture share one cache entry with canonical (4, 383), byte-identical layer. Echo carries the normalized center — reconciled by construction with the client, which canonicalizes before sending (independently converged, bit-identical math).

Live full-chain verification (the gap that let this ship the first time)

A synthetic-input drive on a real display — real atlas_standalone boot, real spawned server, events through Viewport.push_input (the genuine input pipeline, not OS injection): connect → star map → navigate to GJ380c-adjacent regional view → hover open terrain (reticle arms) → hover letterbox (reticle hidden) → click letterbox (no descent) → click terrain (descends) → window derives → fit-on-entry zoom 1.90 → drag-pan moves the composite → Esc back. All PASS; screenshots preserved in .cache/screenshots/descent-verify/ — the fitted window shows the body name in the header and real terrain content (elevation mottling + a riparian feature), not a flat fill.

Tests

Client: 140 new/modified across three suites + 94 sibling re-runs, zero ripple; gdlint clean (atlas_viewer.gd at the 1000-line cap a second round — T-1144 filed for the structural extraction). Server: 6 new tests; atlas:: 570/570, lib 1784/1784. Full suites via the pre-push gate.

Tickets: T-1142 (+T-1144 filed; T-1143 holds the quiet-interior legibility question for Araminta)

## Summary T-1142 — the fixes from Jeroen's first hands-on descent, plus his pan-topology rulings, **live-verified end to end through the real input pipeline this time**. ### The bug he hit Clicking the letterbox beside the fixed planetary map descended to DistrictPos (12276, 3021) — an impossible column (no terrain-bearing body exceeds valid col ~11,236). The descend gate never checked the cursor was on the heightmap texture; the server trusted the insane center, derived clamped garbage, and cached it; and the window opened at native 512px in a ~1900px viewport (no fit). Net experience: a flat green postage stamp. ### Client (Stig) - **Bounds gate**: `is_on_texture()` — ONE helper feeding both the reticle guard and the click fall-through (affordance always matches the click); half-open boundary pinned at the exact edge. Letterbox: no reticle, no descent. - **Fit-and-center**: pure `fit_window_view()` on enter / first window arrival / resize, gated by a `_user_adjusted` flag so it never fights manual zoom/pan. (Own-bug caught en route: RESIZED can fire mid-`_ready` — null-guarded.) - **Pole hard wall** (Jeroen's ruling): `clamp_pan_offset_to_pole_wall()` clamps the *window edge*, not the center — the pole row can reach the top of the screen, never past; handles the tiny-body window-taller-than-planet case. Three numeric hand-traces preceded the code; a first-draft test that silently never exercised the clamp (huge real radius) was replaced with a synthetic one. - **East/west wrap** (Jeroen's ruling): `canonicalize_district_center()` — `posmod` column wrap (verified bit-identical to Rust `rem_euclid` against a live Godot process), clamped row; applied only to the FINAL refetch center (the edge-crossing decision stays in absolute space — a first-pass error caught by hand-trace). Circumnavigation is seamless; a full lap hits cache. - **Header body name**: "Lendel — (9570, −208)" instead of bare coordinates (the cheap half of T-1141 pulled forward). - Drag-pan verified through the real DistrictScreen→viewer chain and pinned by test (it already worked). ### Server (Dudley) - `normalize_window_center()` mirroring the forward map exactly (column `rem_euclid` on the body's district circumference, row clamped to ±half-meridian; constants from `scale::DISTRICT_M`) — applied BEFORE the window-cache and coalescing keys. End-to-end test: the literal bug values on a 500 km fixture share one cache entry with canonical (4, 383), byte-identical layer. Echo carries the normalized center — reconciled by construction with the client, which canonicalizes before sending (independently converged, bit-identical math). ### Live full-chain verification (the gap that let this ship the first time) A synthetic-input drive on a real display — real `atlas_standalone` boot, real spawned server, events through `Viewport.push_input` (the genuine input pipeline, not OS injection): connect → star map → navigate to GJ380c-adjacent regional view → **hover open terrain (reticle arms) → hover letterbox (reticle hidden) → click letterbox (no descent) → click terrain (descends) → window derives → fit-on-entry zoom 1.90 → drag-pan moves the composite → Esc back**. All PASS; screenshots preserved in `.cache/screenshots/descent-verify/` — the fitted window shows the body name in the header and real terrain content (elevation mottling + a riparian feature), not a flat fill. ### Tests Client: 140 new/modified across three suites + 94 sibling re-runs, zero ripple; gdlint clean (atlas_viewer.gd at the 1000-line cap a second round — T-1144 filed for the structural extraction). Server: 6 new tests; atlas:: 570/570, lib 1784/1784. Full suites via the pre-push gate. Tickets: T-1142 (+T-1144 filed; T-1143 holds the quiet-interior legibility question for Araminta)
jpmschweitzer added 3 commits 2026-07-21 15:11:43 +02:00
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The server clamped window_n but trusted window_center — the letterbox
bug's impossible (12276, 3021) was derived at clamped-garbage latitude
and CACHED under its raw key. normalize_window_center mirrors the
forward map exactly (column rem_euclid against the body's district
circumference, row clamped to +/-half-meridian; constants from
scale::DISTRICT_M, no new magic numbers; no-radius test bodies
identity). Applied in serve_district_window BEFORE the window-cache
key and the coalescing key, so an insane request and its sane twin
share one entry — proven end-to-end with the literal bug values on a
500km fixture body resolving to canonical (4, 383), byte-identical.

Echo contract: DistrictWindowLayer.center now carries the NORMALIZED
value. Reconciled by design with the client half in this same branch —
the client canonicalizes before sending (bit-identical math, posmod ==
rem_euclid verified), so request and echo agree from the first
round-trip; server normalization is defense-in-depth for buggy or
modified clients.

6 new tests incl. the twin-cache proof and the echo pin; atlas::
570/570, lib 1784/1784, timing-sensitive tests 3x stable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bounds gate: AtlasDescendGeometry.is_on_texture() — ONE helper feeding
both the reticle guard and the click fall-through (the T-1140 lesson:
the visible affordance always matches the click); half-open
[0,tex_w)x[0,tex_h) boundary pinned at the exact edge. Letterbox
clicks no longer show a reticle or descend.

Fit-and-center: pure fit_window_view() (new atlas_window_geometry.gd)
wired into enter(), the FIRST window arrival, and NOTIFICATION_RESIZED
— gated by a _user_adjusted flag so the fit never fights manual
zoom/pan (flag clears only on a fresh enter). Found-own-bug: RESIZED
can fire mid-_ready() before _canvas exists — null-guarded like the
sibling panels.

Pole wall (Jeroen's ruling): clamp_pan_offset_to_pole_wall() clamps
the WINDOW EDGE, not the center, in screen space from the fitted
transform — Y only; wired into the drag handler and every fit (a
fresh fit can itself need the wall on a tiny body — the
window-taller-than-planet case is handled and tested). Three numeric
hand-traces preceded the code; a first-draft test using GJ380c's huge
radius silently never exercised the clamp — replaced with a synthetic
small radius.

East-west wrap (Jeroen's ruling): canonicalize_district_center() —
posmod column wrap (verified against a live Godot process to match
Rust rem_euclid bit-for-bit), clamped row; district_extent() shares
the exact formula (incl. .max(1)) with the server's
normalize_window_center so echoes and cache keys agree on canonical
form. Canonicalization applies only to the FINAL refetch center — the
edge-crossing decision stays in absolute district space (first-pass
math error caught by hand-trace). Seam-adjacent cache-key sharing
tested. Pan offset itself has no x wall — circumnavigation is
seamless.

Header: body proper_name/body_id ahead of the coordinates (the cheap
half of T-1141, noted in code). Drag-pan verified through the REAL
DistrictScreen-to-viewer chain and pinned by test (no fix needed).

140 tests across three suites, 0 failures; 94 sibling tests no
ripple; gdlint clean (atlas_viewer.gd at the 1000-line cap a second
round — structural extraction flagged for maintenance).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
Owner

QA review — Hoshe

Verdict: REQUEST_CHANGES

Verified all six review items against source at 831625019/4a65bb210 (worktree HEAD == origin tip). The bounds gate, canonicalization convergence, pole wall, and server twin-cache/echo behavior all check out with real evidence — hand-traced the client/server canonicalization formulas term-for-term (including confirming posmod empirically matches Rust rem_euclid bit-for-bit in a headless Godot run, not just trusting the code comment) and independently reproduced the server test fixture's numbers. Ran the three named client suites plus two sibling spot-checks and the full server suite myself rather than relying on the commit message — all green, matching the claimed counts exactly (atlas:: 570/570, lib 1784/1784). One real gap in test coverage on the _user_adjusted flag stops this short of approval.

Comments

client/tests/test_atlas_window_viewer.gd (missing coverage) / client/ui/implant/apps/atlas/atlas_window_viewer.gd:582

_user_adjusted is the load-bearing guard this PR introduces to stop auto-fit from fighting a manually-adjusted view (if _canvas and not _user_adjusted: _fit_and_center(), wired into three call sites: enter(), first-window-arrival at line 302, and NOTIFICATION_RESIZED at line 582). It has zero test coverage — grepped the whole client/tests/ tree for user_adjusted and NOTIFICATION_RESIZED: no matches anywhere. The 24-test test_atlas_window_viewer.gd suite covers fit-on-entry, header, drag-pan wiring, pole-wall-wired-into-drag, and east-west canonicalization thoroughly, but never drives the one branch that makes "never fights manual zoom/pan" true. _notification is a plain virtual method, directly callable the same way this same file already drives _gui_input synthetically (e.g. test_drag_pan_moves_view_offset) — no engine-privilege blocker. A test setting _user_adjusted = true, changing v.size, calling v._notification(NOTIFICATION_RESIZED), and asserting zoom/offset unchanged would close this; the mirror case (first-window-arrival re-fit skipped when already user-adjusted, guard at line 302) is equally untested and equally cheap to add.

Notes (non-blocking, not requiring action)

  • Minor doc-precision nit in server/src/atlas/layer_proxy.rs:818-825: the docstring says normalization prevents the insane/sane twin from landing in different cache entries "or coalesce independently" — but GenWorkItem::window_supersede_key() (server/src/atlas/gen_queue.rs:223-232) is scoped to (ConnectionId, body_id) only, never center, so there was never a per-center coalescing axis to diverge on in the first place. The actual tested behavior (cache-entry sharing) is correct and well-proven by insane_and_sane_twin_requests_share_one_cache_entry; only the prose explaining the coalescing half is slightly off. Not raising as a blocking comment since the runtime behavior claimed is true.
  • Confirmed atlas_viewer.gd sits at exactly 1000 lines (the gdlint max-file-lines cap, inclusive) — gdlint passes clean. Already self-flagged for structural extraction in the commit message; no new action needed here.
## QA review — Hoshe **Verdict: REQUEST_CHANGES** Verified all six review items against source at `831625019`/`4a65bb210` (worktree HEAD == origin tip). The bounds gate, canonicalization convergence, pole wall, and server twin-cache/echo behavior all check out with real evidence — hand-traced the client/server canonicalization formulas term-for-term (including confirming `posmod` empirically matches Rust `rem_euclid` bit-for-bit in a headless Godot run, not just trusting the code comment) and independently reproduced the server test fixture's numbers. Ran the three named client suites plus two sibling spot-checks and the full server suite myself rather than relying on the commit message — all green, matching the claimed counts exactly (atlas:: 570/570, lib 1784/1784). One real gap in test coverage on the `_user_adjusted` flag stops this short of approval. ### Comments **`client/tests/test_atlas_window_viewer.gd`** (missing coverage) / **`client/ui/implant/apps/atlas/atlas_window_viewer.gd:582`** `_user_adjusted` is the load-bearing guard this PR introduces to stop auto-fit from fighting a manually-adjusted view (`if _canvas and not _user_adjusted: _fit_and_center()`, wired into three call sites: `enter()`, first-window-arrival at line 302, and `NOTIFICATION_RESIZED` at line 582). It has zero test coverage — grepped the whole `client/tests/` tree for `user_adjusted` and `NOTIFICATION_RESIZED`: no matches anywhere. The 24-test `test_atlas_window_viewer.gd` suite covers fit-on-entry, header, drag-pan wiring, pole-wall-wired-into-drag, and east-west canonicalization thoroughly, but never drives the one branch that makes "never fights manual zoom/pan" true. `_notification` is a plain virtual method, directly callable the same way this same file already drives `_gui_input` synthetically (e.g. `test_drag_pan_moves_view_offset`) — no engine-privilege blocker. A test setting `_user_adjusted = true`, changing `v.size`, calling `v._notification(NOTIFICATION_RESIZED)`, and asserting zoom/offset unchanged would close this; the mirror case (first-window-arrival re-fit skipped when already user-adjusted, guard at line 302) is equally untested and equally cheap to add. ### Notes (non-blocking, not requiring action) - Minor doc-precision nit in `server/src/atlas/layer_proxy.rs:818-825`: the docstring says normalization prevents the insane/sane twin from landing in different cache entries "or coalesce independently" — but `GenWorkItem::window_supersede_key()` (`server/src/atlas/gen_queue.rs:223-232`) is scoped to `(ConnectionId, body_id)` only, never `center`, so there was never a per-center coalescing axis to diverge on in the first place. The actual tested behavior (cache-entry sharing) is correct and well-proven by `insane_and_sane_twin_requests_share_one_cache_entry`; only the prose explaining the coalescing half is slightly off. Not raising as a blocking comment since the runtime behavior claimed is true. - Confirmed `atlas_viewer.gd` sits at exactly 1000 lines (the `gdlint` `max-file-lines` cap, inclusive) — `gdlint` passes clean. Already self-flagged for structural extraction in the commit message; no new action needed here.
Author
Owner

QA re-review — Hoshe

Verdict: APPROVE (was REQUEST_CHANGES)

Re-reviewed commit 7ce6cc08f against both findings from my prior pass. Both closed, verified independently rather than trusting the commit message.

_user_adjusted resize guardclient/tests/test_atlas_window_viewer.gd:462-495

test_resize_after_manual_drag_keeps_user_view and test_resize_without_user_adjustment_refits drive the real _gui_input production path via _drag_viewer() (mouse-down/motion/up) — traced this against atlas_window_viewer.gd:512-529 and confirmed it sets _dragging then _user_adjusted through the actual handler code, not by poking the flag directly. They call v.notification(Control.NOTIFICATION_RESIZED) (the public engine dispatcher — more faithful to a real resize than the direct _notification() call I'd originally suggested). Checked the fixture body radius (6238.4 km → rows_half=4785) against the held window's row span ([4, 36]) to confirm the pole wall is a genuine no-op here, so the resize assertions cleanly isolate the _user_adjusted guard with no confounding from the unrelated clamp. Pulled the raw gdUnit execution log (not just the summary) — both tests ran and PASSED. Ran the suite myself: 52/52. gdlint clean.

Doc sentenceserver/src/atlas/layer_proxy.rs:826-830

Now correctly states the coalescing key is (ConnectionId, body_id) and never carried center — matches what I verified independently against window_supersede_key() (gen_queue.rs:223-232) in the first pass. No new inaccuracy introduced. cargo fmt --check clean; normalize_window_center tests and the full atlas:: suite (570/570) still pass.

Both fixes correctly scoped — only the two files flagged, no scope creep. Approving.

## QA re-review — Hoshe **Verdict: APPROVE** (was REQUEST_CHANGES) Re-reviewed commit `7ce6cc08f` against both findings from my prior pass. Both closed, verified independently rather than trusting the commit message. **`_user_adjusted` resize guard** — `client/tests/test_atlas_window_viewer.gd:462-495` `test_resize_after_manual_drag_keeps_user_view` and `test_resize_without_user_adjustment_refits` drive the real `_gui_input` production path via `_drag_viewer()` (mouse-down/motion/up) — traced this against `atlas_window_viewer.gd:512-529` and confirmed it sets `_dragging` then `_user_adjusted` through the actual handler code, not by poking the flag directly. They call `v.notification(Control.NOTIFICATION_RESIZED)` (the public engine dispatcher — more faithful to a real resize than the direct `_notification()` call I'd originally suggested). Checked the fixture body radius (6238.4 km → `rows_half=4785`) against the held window's row span (`[4, 36]`) to confirm the pole wall is a genuine no-op here, so the resize assertions cleanly isolate the `_user_adjusted` guard with no confounding from the unrelated clamp. Pulled the raw gdUnit execution log (not just the summary) — both tests ran and PASSED. Ran the suite myself: 52/52. `gdlint` clean. **Doc sentence** — `server/src/atlas/layer_proxy.rs:826-830` Now correctly states the coalescing key is `(ConnectionId, body_id)` and never carried `center` — matches what I verified independently against `window_supersede_key()` (`gen_queue.rs:223-232`) in the first pass. No new inaccuracy introduced. `cargo fmt --check` clean; `normalize_window_center` tests and the full `atlas::` suite (570/570) still pass. Both fixes correctly scoped — only the two files flagged, no scope creep. Approving.
jpmschweitzer added 1 commit 2026-07-21 15:25:07 +02:00
Hoshe's finding: the flag introduced so auto-fit never fights a manual
view had zero coverage on exactly that branch. Two tests drive the
REAL _gui_input path (synthetic drag), then fire NOTIFICATION_RESIZED:
user-adjusted view survives a resize untouched (zoom AND offset);
an unadjusted view re-fits to the new viewport. 52/52.

Non-blocking doc note also taken: layer_proxy's normalization comment
claimed the twins would otherwise 'coalesce independently' — the
coalescing key is (ConnectionId, body_id) and never carried center;
rewritten to say what normalization actually buys on that path (the
work item derives and echoes the canonical center).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
Owner

Review: atlas-descent-fixes → main (type: code) — round 2 (fix round)

Single reviewer (proportionality: a bug-fix round implementing explicit prescriptions from Jeroen's hands-on + prior reviews, live-verified full-chain by the lead on a real display before the PR).

Hoshe (QA): APPROVE (round 1: REQUEST_CHANGES, 1 blocking + 1 doc note — both fixed and confirmed)

Round-1 verified clean with independent evidence: bounds gate is ONE helper feeding both the reticle guard and the click fall-through, half-open boundary pinned at exact edges; client/server canonicalization hand-traced term-for-term with posmod(-1,1534)=1533 empirically confirmed bit-identical to Rust rem_euclid in a headless run, and the server fixture's (12276,3021)→(4,383) reproduced independently; the pole-wall test's radius genuinely fires the clamp (unlike the earlier silent-no-op draft); fit math unit-tested at the MIN/MAX_ZOOM clamps; the twin-cache end-to-end test asserts one entry across three requests with byte-identical layers; all suites re-run personally, matching claimed counts exactly.

Round-1 finding (fixed in 7ce6cc08f): _user_adjusted — the flag introduced specifically so auto-fit never fights a manual view — had zero coverage on exactly that branch. Fix confirmed: two tests drive the REAL _gui_input path (synthetic drag sets the flag through the production handler, not by poking it), then fire NOTIFICATION_RESIZED via the public engine dispatcher; user-adjusted zoom AND offset survive a resize untouched, and the unadjusted counter-case re-fits. Verified the test radius makes the pole wall a no-op so the assertions cleanly isolate the guard. Raw gdUnit log pulled, 52/52. Doc note also fixed: the layer_proxy comment no longer overstates the coalescing key (it is (ConnectionId, body_id), never center); no new inaccuracy.

# Finding Status
1 _user_adjusted resize guard had zero test coverage on its purpose branch FIXED (7ce6cc08f) — two-direction pin via the real input path
2 (doc) coalescing-key overstatement in layer_proxy prose FIXED — states the real key + what normalization buys

Verdict: APPROVED

Runtime verification: lead-run synthetic-input full-chain drive on a real display against a real spawned server — reticle arms on terrain / hidden on letterbox / letterbox click inert / descend / derive / fit zoom 1.90 / drag-pan / Esc, all PASS; screenshots in .cache/screenshots/descent-verify/ (fitted window shows the body name and real terrain content). Full suites via the pre-push gate on every push.

## Review: atlas-descent-fixes → main (type: code) — round 2 (fix round) Single reviewer (proportionality: a bug-fix round implementing explicit prescriptions from Jeroen's hands-on + prior reviews, live-verified full-chain by the lead on a real display before the PR). ### Hoshe (QA): APPROVE (round 1: REQUEST_CHANGES, 1 blocking + 1 doc note — both fixed and confirmed) Round-1 verified clean with independent evidence: bounds gate is ONE helper feeding both the reticle guard and the click fall-through, half-open boundary pinned at exact edges; client/server canonicalization hand-traced term-for-term with `posmod(-1,1534)=1533` empirically confirmed bit-identical to Rust `rem_euclid` in a headless run, and the server fixture's (12276,3021)→(4,383) reproduced independently; the pole-wall test's radius genuinely fires the clamp (unlike the earlier silent-no-op draft); fit math unit-tested at the MIN/MAX_ZOOM clamps; the twin-cache end-to-end test asserts one entry across three requests with byte-identical layers; all suites re-run personally, matching claimed counts exactly. **Round-1 finding (fixed in 7ce6cc08f):** `_user_adjusted` — the flag introduced specifically so auto-fit never fights a manual view — had zero coverage on exactly that branch. Fix confirmed: two tests drive the REAL `_gui_input` path (synthetic drag sets the flag through the production handler, not by poking it), then fire `NOTIFICATION_RESIZED` via the public engine dispatcher; user-adjusted zoom AND offset survive a resize untouched, and the unadjusted counter-case re-fits. Verified the test radius makes the pole wall a no-op so the assertions cleanly isolate the guard. Raw gdUnit log pulled, 52/52. Doc note also fixed: the layer_proxy comment no longer overstates the coalescing key (it is `(ConnectionId, body_id)`, never center); no new inaccuracy. | # | Finding | Status | |---|---------|--------| | 1 | `_user_adjusted` resize guard had zero test coverage on its purpose branch | FIXED (7ce6cc08f) — two-direction pin via the real input path | | 2 | (doc) coalescing-key overstatement in layer_proxy prose | FIXED — states the real key + what normalization buys | ### Verdict: APPROVED Runtime verification: lead-run synthetic-input full-chain drive on a real display against a real spawned server — reticle arms on terrain / hidden on letterbox / letterbox click inert / descend / derive / fit zoom 1.90 / drag-pan / Esc, all PASS; screenshots in `.cache/screenshots/descent-verify/` (fitted window shows the body name and real terrain content). Full suites via the pre-push gate on every push.
jpmschweitzer closed this pull request 2026-07-21 15:26:14 +02:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jpmschweitzer/settled-reach#188