## T-1150 (PR #191 review, Hoshe 4): atlas_window_request.gd had NO test file ## at all before this — direct coverage of the granularity/min_wl_m staleness ## guard, the n-clamp mirror (Tyre C1), and the old-server-shape default ## disposition. Follows test_atlas_window_viewer.gd's own ## "AtlasWindowRequest — cache reuse" section conventions (same ## instantiation pattern: `AtlasWindowRequest.new(owner_stub)`, `add_child()` ## for the debounce Timer, hand-built response dicts) rather than ## re-inventing a shape. class_name TestAtlasWindowRequest extends GdUnitTestSuite # atlas_window_request.gd has no class_name (review #8 precedent throughout # this cluster) — preloaded once here, not re-load()ed per test (gdlint # duplicated-load). const AtlasWindowRequest := preload("res://ui/implant/apps/atlas/atlas_window_request.gd") ## Dudley's WINDOW_GRANULARITY_REGION_KEY (server/src/atlas/layer_proxy.rs) — ## `u32::MAX`, the RESERVED KEY-SPACE TAG a real server ALWAYS puts in the ## legacy `granularity` slot for every Region response (never a real ## multiplier — District=1/Quarter=4 are the only legal wire multipliers). ## Do NOT "fix" this to 1 — using a convenient value here is EXACTLY the gap ## the live round caught (a mock that diverges from the wire in the one ## field that matters silently un-repros the bug). See ## AtlasWindowRequest's `_echoed_granularity_matches()` doc for the full ## rationale. const SERVER_LEGACY_GRANULARITY_REGION_SENTINEL: int = 4294967295 ## Build a hand-authored DistrictWindowLayer dict, granularity-aware ## (T-1150, extended T-1152/T-1153 for granularity_v2) — mirrors ## test_atlas_window_viewer.gd's own _mock_window(), with ## granularity/min_wl_m/granularity_v2 added as optional params so callers ## can build any rung's echo shape with one helper. static func _mock_window( center: Vector2i, n: int = 2, granularity: int = 1, min_wl_m: int = 0, granularity_v2: String = "District" ) -> Dictionary: return { "center": [center.x, center.y], "n": n, "granularity": granularity, "min_wl_m": min_wl_m, "granularity_v2": granularity_v2, "morphology": PackedByteArray([8, 14, 0, 1]), "elev_q": PackedByteArray([40, 90, 5, 60]), "temp_dc": [120, 95, -32768, 60], "moisture_q": PackedByteArray([50, 30, 90, 20]), "vegetation": PackedByteArray([2, 1, 6, 3]), "glaciation": PackedByteArray([0, 0, 1, 2]), } static func _mock_response(body_id: String, window: Variant) -> Dictionary: return {"body_id": body_id, "status": "Ready", "district_window": window} func _make_request() -> Variant: var owner_stub := RefCounted.new() var req = auto_free(AtlasWindowRequest.new(owner_stub)) add_child(req) return req # ============================================================================= # (a) granularity mismatch on the echo -> dropped as stale # ============================================================================= ## The mandatory item-(a) case: request_now() asks at the default district ## granularity (1); a response echoing granularity=4 (quarter) for the SAME ## center/n must be dropped as stale, not accepted — a different rung's ## derive answering a request for a different rung is exactly as stale as a ## mismatched center (T-1150 extends §2's guard to this axis). ## ## **Live-round correction:** the mock MUST carry a mismatched ## `granularity_v2` too (explicit `"Quarter"`, not `_mock_window()`'s ## `"District"` default) — a real Quarter response ALWAYS carries ## `granularity_v2: "Quarter"` on the wire, never the District default this ## test's fixture used to leave implicit. Under the v2-authoritative-when- ## present precedence rule (see on_response()'s own doc), a v2-MATCHING ## response is accepted regardless of what the legacy int says — leaving ## granularity_v2 at its District default here would have made this test ## pass for the wrong reason (an accidentally-matching v2 field masking a ## genuinely mismatched legacy int), exactly the class of gap the live round ## caught in the oversized-orbital round-trip test. func test_on_response_with_mismatched_granularity_is_dropped_as_stale() -> void: var req = _make_request() req.request_now("GJ380c", Vector2i(2, 2), 2) assert_bool(req.is_pending()).is_true() var quarter_window: Dictionary = _mock_window(Vector2i(2, 2), 2, 4, 0, "Quarter") req.on_response(_mock_response("GJ380c", quarter_window)) assert_bool(req.is_pending()).override_failure_message( "a granularity-mismatched response must be dropped as stale, leaving the district request still pending" ).is_true() # ============================================================================= # (a2) granularity_v2 mismatch on the echo -> dropped as stale (T-1152/T-1153, # the axis the legacy int alone cannot express — Region has no legacy value) # ============================================================================= ## request_now() can now ask for Region explicitly (T-1153's rung-reselect ## caller) — a response echoing "District" for the SAME center/n must be ## dropped as stale, the granularity_v2 twin of test (a) above, and the ## ONLY guard that can catch this specific mismatch (the legacy int is ## DISTRICT_GRANULARITY=1 on BOTH sides here, since Region has no legacy ## representation — see WindowGranularity::legacy_u32()'s doc). func test_on_response_with_mismatched_granularity_v2_is_dropped_as_stale() -> void: var req = _make_request() req.request_now("GJ380c", Vector2i(0, 0), 6400, AtlasWindowRequest.GRANULARITY_V2_REGION) assert_bool(req.is_pending()).is_true() var district_window: Dictionary = _mock_window(Vector2i(0, 0), 6400, 1, 0, "District") req.on_response(_mock_response("GJ380c", district_window)) assert_bool(req.is_pending()).override_failure_message( "a granularity_v2-mismatched response (District answering a Region request)" + " must be dropped as stale, leaving the request still pending" ).is_true() ## The matching case: request_now() asking for Region, answered by a Region ## echo at the SAME (center, n) — must be ACCEPTED and cached under the ## Region key, retrievable on a follow-up request without a new network round ## trip. ## ## **Live-round correction:** the mock's legacy `granularity` field is now ## Dudley's ACTUAL wire sentinel (`WINDOW_GRANULARITY_REGION_KEY` = ## `u32::MAX` = 4294967295), not a convenient `1` — the original version of ## this test used `1`, which coincidentally matched the request's own ## pinned `_granularity` and therefore never exercised the real mismatch a ## live server actually produces. See _echoed_granularity_matches()'s own ## doc (atlas_window_request.gd) for why this is load-bearing: without the ## v2-authoritative-when-present fix, THIS test would have failed with the ## real sentinel — it only passed before because the mock was wrong. func test_on_response_matching_granularity_v2_region_is_accepted_and_cached() -> void: var req = _make_request() req.request_now("GJ380c", Vector2i(0, 0), 6400, AtlasWindowRequest.GRANULARITY_V2_REGION) assert_bool(req.is_pending()).is_true() var region_window: Dictionary = _mock_window( Vector2i(0, 0), 6400, SERVER_LEGACY_GRANULARITY_REGION_SENTINEL, 0, "Region" ) req.on_response(_mock_response("GJ380c", region_window)) assert_bool(req.is_pending()).override_failure_message( "a response carrying the REAL legacy sentinel (u32::MAX) in the old" + " granularity slot must still be accepted — v2 is authoritative" + " whenever present, the legacy field must not be compared at all" ).is_false() var received: Array = [] req.window_ready.connect(func(w: Dictionary) -> void: received.append(w)) req.request_now("GJ380c", Vector2i(0, 0), 6400, AtlasWindowRequest.GRANULARITY_V2_REGION) assert_int(received.size()).override_failure_message( "a second Region request at the same (center, n) must hit the cache" ).is_equal(1) assert_bool(req.is_pending()).is_false() ## **The direct precedence-rule proof (live-round finding #2, the sharpest ## case):** a response whose `granularity_v2` MATCHES the request but whose ## LEGACY `granularity` field could never possibly match (the Region ## sentinel) must still be ACCEPTED — proving the legacy comparison is ## SKIPPED entirely when v2 is present, not merely "also checked and ## happens to pass." This is the literal shape of the live bug: real server ## responses ALWAYS carry the Region sentinel in the legacy slot, so any ## code path that still consults the legacy field when v2 is already ## authoritative would drop every single one of these, forever. func test_on_response_v2_match_is_accepted_regardless_of_legacy_field_value() -> void: var req = _make_request() req.request_now("GJ380c", Vector2i(0, 0), 6400, AtlasWindowRequest.GRANULARITY_V2_REGION) var region_window: Dictionary = _mock_window( Vector2i(0, 0), 6400, SERVER_LEGACY_GRANULARITY_REGION_SENTINEL, 0, "Region" ) req.on_response(_mock_response("GJ380c", region_window)) assert_bool(req.is_pending()).override_failure_message( "v2 match must be sufficient on its own — the legacy sentinel value must" + " never be consulted once granularity_v2 is present on the response" ).is_false() # ============================================================================= # (b) old-server-shape response (no granularity/min_wl_m keys) -> defaults # ============================================================================= ## A response from a hypothetical pre-T-1150 server (or any response whose ## district_window dict simply omits the new keys) must decode granularity ## as district (1) and min_wl_m as 0 via the same defaulting on_response() ## already applies — and since request_now()'s own defaults are identical, ## the response is ACCEPTED, not treated as stale just because two keys are ## missing. func test_on_response_missing_granularity_and_min_wl_defaults_and_is_accepted() -> void: var req = _make_request() req.request_now("GJ380c", Vector2i(3, 3), 2) assert_bool(req.is_pending()).is_true() # Old-shape window: no "granularity"/"min_wl_m" keys at all. var old_shape_window := { "center": [3, 3], "n": 2, "morphology": PackedByteArray([8, 14, 0, 1]), "elev_q": PackedByteArray([40, 90, 5, 60]), "temp_dc": [120, 95, -32768, 60], "moisture_q": PackedByteArray([50, 30, 90, 20]), "vegetation": PackedByteArray([2, 1, 6, 3]), "glaciation": PackedByteArray([0, 0, 1, 2]), } req.on_response(_mock_response("GJ380c", old_shape_window)) assert_bool(req.is_pending()).override_failure_message( ( "an old-server-shape response (missing granularity/min_wl_m) must " + "default to district/0 and be ACCEPTED, not dropped as stale" ) ).is_false() var received: Array = [] req.window_ready.connect(func(w: Dictionary) -> void: received.append(w)) # Re-request the same (body, center, n) — must now be a cache hit, proving # on_response() actually stored the old-shape window under the # district/0 key, not silently discarding it. req.request_now("GJ380c", Vector2i(3, 3), 2) assert_int(received.size()).is_equal(1) assert_bool(req.is_pending()).is_false() ## **Live-round sibling test (instruction #2's "old-server path stays ## covered"):** a response that carries the LEGACY `granularity` key WITH AN ## EXPLICIT VALUE (1, i.e. genuinely present, not merely defaulted via ## absence — the case test_on_response_missing_granularity_and_min_wl_defaults_and_is_accepted ## above doesn't exercise, since it omits the key entirely) but has NO ## `granularity_v2` key at all — the true "hypothetically old, pre-T-1152 ## server" shape — must still be accepted for a plain District request via ## the legacy-comparison FALLBACK branch in `_echoed_granularity_matches()`. ## This is the other half of the v2-authoritative-when-present precedence ## rule: v2 present -> v2 alone decides; v2 ABSENT -> legacy alone decides ## (never both, never neither). func test_on_response_legacy_only_no_v2_key_still_accepted_for_district() -> void: var req = _make_request() req.request_now("GJ380c", Vector2i(4, 4), 2) # defaults to District granularity assert_bool(req.is_pending()).is_true() # Legacy-only shape: "granularity" IS present (district=1), "granularity_v2" # key is absent entirely — not present-with-a-District-value, ABSENT. var legacy_only_window := { "center": [4, 4], "n": 2, "granularity": AtlasWindowRequest.DEFAULT_GRANULARITY, "min_wl_m": 0, "morphology": PackedByteArray([8, 14, 0, 1]), "elev_q": PackedByteArray([40, 90, 5, 60]), "temp_dc": [120, 95, -32768, 60], "moisture_q": PackedByteArray([50, 30, 90, 20]), "vegetation": PackedByteArray([2, 1, 6, 3]), "glaciation": PackedByteArray([0, 0, 1, 2]), } assert_bool(legacy_only_window.has("granularity_v2")).override_failure_message( "sanity: this fixture must NOT carry granularity_v2 at all — that's the point" ).is_false() req.on_response(_mock_response("GJ380c", legacy_only_window)) assert_bool(req.is_pending()).override_failure_message( "a legacy-only response (granularity=1 present, granularity_v2 absent) must" + " still be accepted for a District request via the legacy-fallback branch" ).is_false() # ============================================================================= # (c) n-clamp mirror (Tyre C1) — quarter n=32 stores clamped n=16 # ============================================================================= ## **Item (c) as literally scoped by the ticket** ("the clamp-mirror from ## item 1"): `_clamp_window_n_mirror()` reproduces the server's ## `clamp_window_n(raw_n, granularity)` bit-for-bit, INCLUDING the quarter ## n=32 -> 16 case — pinned directly against the static helper, independent ## of the request/response plumbing (`request_now()` has no public ## "request quarter" entry point today; T-1150 is struct/key plumbing only, ## requesting quarter is T-1153's job — see the class-level docstring on ## `_clamp_window_n_mirror()` for why calling `request_now()` at district ## granularity can never itself exercise the quarter branch: it unconditionally ## resets `_granularity` to district BEFORE clamping, by design, since no ## caller can ask for quarter yet). func test_clamp_window_n_mirror_matches_server_formula_at_quarter_n32() -> void: assert_int(AtlasWindowRequest._clamp_window_n_mirror(32, 4)).is_equal(16) # District granularity: the per-axis cap (64) governs, matching the # server's clamp_window_n_district_granularity_uses_per_axis_cap test. assert_int(AtlasWindowRequest._clamp_window_n_mirror(640, 1)).is_equal(64) # Small n well under budget at quarter granularity stays unclamped, # matching clamp_window_n_quarter_granularity_leaves_small_n_unclamped. assert_int(AtlasWindowRequest._clamp_window_n_mirror(8, 4)).is_equal(8) ## **Item (c), the request/response half:** `request_now()` actually WIRES ## the mirror in (not just defines it) — a request for a district-legal but ## per-axis-oversized `n` (e.g. 640, mirroring the server's own ## `DISTRICT_WINDOW_MAX_N*10` oversized-request test) stores the CLAMPED ## `_n=64`, so a server response echoing the server's OWN clamped n=64 is ## ACCEPTED, not rejected as stale for "not matching" the raw 640 that was ## asked for. This is the exact n-clamp/echo/staleness triangle Tyre C1 ## flagged, exercised through the reachable (district) path today; the ## quarter-specific n=32->16 number is pinned by the formula test above since ## no public API can drive quarter through `request_now()` yet. func test_oversized_n_request_stores_clamped_n_and_accepts_matching_echo() -> void: var req = _make_request() req.request_now("GJ380c", Vector2i(4, 4), 640) assert_int(req._n).override_failure_message( ( "request_now() must mirror the server's clamp_window_n(640, granularity=1) " + "== 64 BEFORE storing _n, not store the raw requested 640" ) ).is_equal(64) assert_bool(req.is_pending()).is_true() # The server's real response for this request echoes n=64 (its own # clamp_window_n() result) — must be ACCEPTED, not stale. var clamped_echo: Dictionary = _mock_window(Vector2i(4, 4), 64, 1, 0) req.on_response(_mock_response("GJ380c", clamped_echo)) assert_bool(req.is_pending()).override_failure_message( ( "a response echoing the CLAMPED n=64 must be accepted, since _n was " + "already clamped to 64 before the request fired" ) ).is_false() # ============================================================================= # (d) Region clamp mirror (T-1152/T-1153) — mirrors # server/src/atlas/layer_proxy.rs's clamp_window_n_v2 EXACTLY, including the # Region branch's bounded halving loop (no closed form, per Dudley's own # doc — "replicate the loop exactly"). # ============================================================================= ## District/Quarter through the v2 mirror must be BYTE-IDENTICAL to the ## legacy mirror — the server's own ## `clamp_window_n_v2_matches_legacy_for_finer_than_district_rungs` ## guarantee, restated client-side. func test_clamp_window_n_mirror_v2_matches_legacy_for_district_and_quarter() -> void: assert_int( AtlasWindowRequest._clamp_window_n_mirror_v2(32, AtlasWindowRequest.GRANULARITY_V2_QUARTER) ).is_equal(AtlasWindowRequest._clamp_window_n_mirror(32, 4)) assert_int( AtlasWindowRequest._clamp_window_n_mirror_v2(640, AtlasWindowRequest.GRANULARITY_V2_DISTRICT) ).is_equal(AtlasWindowRequest._clamp_window_n_mirror(640, 1)) ## The clean Region boundary case: n=6,400 (DISTRICT_WINDOW_MAX_N_REGION, ## the per-axis cap exactly) derives cell_grid_side(6400) = round(6400/100) = ## 64, and 64² = 4,096 = WIRE_CAP_CELLS EXACTLY — the halving loop's `>` ## condition is false at the boundary, so this must clamp to EXACTLY 6,400, ## not halve further. This is the server's own ## `region_per_axis_cap_lands_exactly_on_wire_cap_when_uncontested`-shaped ## boundary (WIRE_CAP_CELLS_SQRT * DISTRICTS_PER_REGION is DERIVED to land ## here exactly, per that constant's own doc). func test_clamp_window_n_mirror_v2_region_boundary_is_exact() -> void: var n: int = AtlasWindowRequest._clamp_window_n_mirror_v2( AtlasWindowRequest.SERVER_DISTRICT_WINDOW_MAX_N_REGION, AtlasWindowRequest.GRANULARITY_V2_REGION ) assert_int(n).is_equal(AtlasWindowRequest.SERVER_DISTRICT_WINDOW_MAX_N_REGION) ## Region's per-axis cap: a raw `n` far over DISTRICT_WINDOW_MAX_N_REGION ## (mirroring the server's own `region_request_oversized_n_clamps_and_echoes_clamped_n` ## test's `DISTRICT_WINDOW_MAX_N_REGION * 10` shape) must clamp DOWN — never ## trust the wire — and the result must satisfy BOTH invariants the server's ## own test asserts: `n <= DISTRICT_WINDOW_MAX_N_REGION` AND ## `cell_grid_side(n)^2 <= WIRE_CAP_CELLS`. func test_clamp_window_n_mirror_v2_region_oversized_n_clamps_within_both_bounds() -> void: var oversized: int = AtlasWindowRequest.SERVER_DISTRICT_WINDOW_MAX_N_REGION * 10 var n: int = AtlasWindowRequest._clamp_window_n_mirror_v2( oversized, AtlasWindowRequest.GRANULARITY_V2_REGION ) assert_int(n).override_failure_message( "echoed n must be clamped to DISTRICT_WINDOW_MAX_N_REGION, not the raw oversized value" ).is_less_equal(AtlasWindowRequest.SERVER_DISTRICT_WINDOW_MAX_N_REGION) var side: int = AtlasWindowRequest._cell_grid_side_region_mirror(n) assert_int(side * side).override_failure_message( "clamped cell count must never exceed WIRE_CAP_CELLS at Region granularity either" ).is_less_equal(AtlasWindowRequest.SERVER_WIRE_CAP_CELLS) ## A REGION request whose derived grid would exceed WIRE_CAP_CELLS (n set so ## cell_grid_side(n) rounds to 65, just over the 64-per-axis wire-size ## ceiling) must actually HALVE — this is the case the boundary test above ## deliberately sits just below, so this one confirms the loop body actually ## fires, not just that its guard conditions are correct at the edges. func test_clamp_window_n_mirror_v2_region_halves_when_over_wire_cap() -> void: # n=6,450 -> cell_grid_side = round(64.5) = 65 (round-half-away-from-zero, # matching Rust's f64::round() and GDScript's roundi() for non-negative # inputs) -> 65² = 4,225 > WIRE_CAP_CELLS (4,096) -> must halve at least once. var n: int = AtlasWindowRequest._clamp_window_n_mirror_v2( 6450, AtlasWindowRequest.GRANULARITY_V2_REGION ) assert_int(n).override_failure_message( "a Region request whose grid exceeds WIRE_CAP_CELLS must be halved down, not left at 6,450" ).is_less(6450) var side: int = AtlasWindowRequest._cell_grid_side_region_mirror(n) assert_int(side * side).is_less_equal(AtlasWindowRequest.SERVER_WIRE_CAP_CELLS) ## n smaller than one region (n < 100) must clamp its cell-grid side to a ## minimum of 1 — cell_grid_side_for_window()'s own `.max(1)` — never a ## degenerate 0x0 grid, matching WindowGranularity::cell_grid_side's own ## documented minimum. func test_cell_grid_side_region_mirror_minimum_is_one() -> void: assert_int(AtlasWindowRequest._cell_grid_side_region_mirror(1)).is_equal(1) assert_int(AtlasWindowRequest._cell_grid_side_region_mirror(50)).is_equal(1)