fix(client): Global rung derived its canvas from a pre-layout viewport
Eyeballed on Lendel: the Atlas opened on a Global map that was literally two cells — one green, one blue — stretched across the window, reporting 19,598.512 km/gridunit, which is exactly half the body's circumference. Two bugs, both of which the D-255 extent inversion turned from harmless into fatal. enter() fires its first request BEFORE this Control is laid out, and a not-yet-laid-out size is not always exactly Vector2.ZERO — a few stray pixels sailed past the `== Vector2.ZERO` guard, so the viewer asked for a 2x2 gridunit canvas and the server's 2:1 fit floored it to 2x1. That never mattered while Global discarded the requested extent and took its cell counts from the body's region grid; the moment the request became the canvas size, a transient layout artefact became the map. Any viewport below a plausible panel size is now treated as not-laid-out. And Global was excluded from the refetch settle entirely, so a canvas born at the wrong size could never heal however the window was resized. That exclusion was correct when no viewport could change Global's extent. Global now takes the SIZE refit like every other rung, but still never the pan re-float — its canvas is whole-body and origin-anchored, and the server ignores `center` for it. Both have regression tests. The second asserts on _world_center rather than _view_offset, because _recompute_canvas_transform() legitimately re-centres the offset on any canvas adoption and would have made the test pass for the wrong reason. Worth noting for the class: no test written today could have caught this. Every one supplies an explicit viewport. The bug lived entirely in the gap between "scene loads" and "layout completes" — a seam a live launch exercises and a unit test does not. Also stages governance/README.md's pql-maintained record index (D-258). Pair session with Jeroen, 2026-07-26. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -787,6 +787,57 @@ func test_resize_recenters_an_already_held_global_canvas() -> void:
|
||||
).is_not_equal(offset_before)
|
||||
|
||||
|
||||
## EYEBALL REGRESSION (pair session 2026-07-26, Lendel): the Atlas opened on a
|
||||
## Global map that was literally two cells — one green, one blue — stretched
|
||||
## across the window, reporting 19,598 km/gridunit, exactly half the body's
|
||||
## circumference. Cause: enter() fires its first request BEFORE this Control is
|
||||
## laid out, and the not-laid-out size is not always exactly ZERO, so a few
|
||||
## stray pixels sailed past the `== Vector2.ZERO` guard and asked for a 2x2
|
||||
## gridunit canvas. Harmless while Global ignored the requested extent and took
|
||||
## its cell counts from the body's region grid; load-bearing the moment the
|
||||
## D-255 extent inversion made the request the canvas size.
|
||||
func test_request_extent_ignores_a_not_yet_laid_out_viewport() -> void:
|
||||
var v: StepCanvasViewer = _make_viewer()
|
||||
add_child(v)
|
||||
v.enter({"body_id": "GJ380c", "body_radius_km": 6238.4}, {})
|
||||
for degenerate in [Vector2.ZERO, Vector2(4.0, 4.0), Vector2(1920.0, 2.0)]:
|
||||
v.size = degenerate
|
||||
var extent: Vector2i = v._request_extent()
|
||||
var expected: Vector2i = StepCanvasTransport.viewport_fit_extent(
|
||||
StepCanvasViewer.FALLBACK_VIEWPORT_PX, v.get_held_rung()
|
||||
)
|
||||
assert_that(extent).override_failure_message(
|
||||
"a %s viewport must fall back, not be taken literally — got %s" % [degenerate, extent]
|
||||
).is_equal(expected)
|
||||
|
||||
|
||||
## ...and the second half of the same bug: Global was excluded from the refetch
|
||||
## settle entirely, so a canvas born at the wrong size could never heal however
|
||||
## the window was resized. Global must take the SIZE refit (it is viewport-sized
|
||||
## like every rung now) but never the pan re-float (its canvas is whole-body and
|
||||
## origin-anchored — the server ignores `center` for Global), which _refloat_now()
|
||||
## would betray by zeroing _view_offset.
|
||||
func test_global_takes_the_size_refit_but_never_the_pan_refloat() -> void:
|
||||
var v: StepCanvasViewer = _make_viewer()
|
||||
add_child(v)
|
||||
v.size = Vector2(1920.0, 1080.0)
|
||||
v.enter({"body_id": "T1189_extent_letterbox_test_body", "body_radius_km": 6371.0}, {})
|
||||
TestStepCanvasViewer._land_global_canvas(v, GJ1C_GLOBAL_EXTENT.x, GJ1C_GLOBAL_EXTENT.y)
|
||||
|
||||
# Drift the view far enough that a fixed rung would hard re-float.
|
||||
v._view_offset = Vector2(-100_000.0, -100_000.0)
|
||||
v._on_refetch_settle()
|
||||
|
||||
# _refloat_now() would re-centre the request on whatever world point sits
|
||||
# under the viewport centre; Global's canvas is origin-anchored and the
|
||||
# server ignores `center` for it, so the world centre must not move.
|
||||
# (_view_offset is NOT the probe here — _recompute_canvas_transform()
|
||||
# legitimately re-centres it on any canvas adoption.)
|
||||
assert_that(v._world_center).override_failure_message(
|
||||
"Global has no centre to re-float to — _world_center must stay at the origin"
|
||||
).is_equal(Vector2.ZERO)
|
||||
|
||||
|
||||
## Hoshe (review round 2): a narrow viewport where GJ1c's canvas exceeds
|
||||
## the available width on the gridunit lattice itself (177 gridunits >
|
||||
## available px after the legend column is reserved) used to make the OLD
|
||||
|
||||
Reference in New Issue
Block a user