feat(simulation): feature-name pipeline wired + legacy window_granularity u32 retired (T-1169, T-1159)

One commit for two tickets whose changes share the bridge/plugin
plumbing files. T-1169 connects the three dormant feature-name pieces:
atlas_feature_names populated at regen (17,891 rows — 15,190 mountain,
2,701 river — via populate_atlas_feature_names mirroring the city-names
importer; systems.db regenerated, stamp fresh), attach_feature_names
wired into the cascade's Topography block with name pools threaded
DB-free through AnalyzeBody (D-225 pattern) and assignments stored on
Layer1Output/BodyWorldState for future consumers, and a
FeatureNamesRequest/Response read proxy as the bridge's 7th tagged
envelope (D-236 pattern, both SimBridge impls). Client label DRAW is
deliberately NOT here — implementation proved both river and mountain
labels need a wire-carried position (the pool is position-free; course
polylines aren't correlated with the named attractors by construction) —
deferred to T-1195's single design pass. cascade_layer1 golden re-pinned
(additive feature_names field).

T-1159 retires the legacy u32 granularity field fully shadowed by
window_granularity_v2: AtlasLayerRequest.window_granularity,
DistrictWindowLayer.granularity echo, the u32::MAX sentinel, and
resolve_window_granularity are gone server-side; client encode paths and
the caller-less atlas_window_cache legacy key component dropped;
msgpack fixtures regenerated; the T-1150 aliasing regression test now
drives through the surviving enum field. The district_window carrier
itself survives byte-compatible per D-255(c).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 16:10:27 +02:00
co-authored by Claude Fable 5
parent befdb689c1
commit 8da9670e0f
28 changed files with 1244 additions and 467 deletions
Binary file not shown.
+21 -27
View File
@@ -214,35 +214,32 @@ func test_encode_atlas_layer_request_carries_window_params() -> void:
assert_that(decoded.value.get("window_n")).is_equal(32)
## T-1150: window_granularity/window_min_wl_m are OMITTED (not sent as 0)
## when at their default — a windowed request that doesn't pass them (every
## pre-T-1150 window caller) is byte-identical to pre-T-1150 wire traffic,
## same contract as window_center/window_n's own default-omission above.
func test_encode_atlas_layer_request_omits_granularity_and_min_wl_by_default() -> void:
## T-1150: window_min_wl_m is OMITTED (not sent as 0) when at its default —
## a windowed request that doesn't pass it (every pre-T-1150 window caller)
## is byte-identical to pre-T-1150 wire traffic, same contract as
## window_center/window_n's own default-omission above.
func test_encode_atlas_layer_request_omits_min_wl_by_default() -> void:
var bytes := Protocol.encode_atlas_layer_request(
"GJ1c", "Topography", Vector2i(140, 260), 32
)
var decoded = Messagepack.decode(bytes)
assert_bool(decoded.value.has("window_granularity")).is_false()
assert_bool(decoded.value.has("window_min_wl_m")).is_false()
## T-1150: a quarter-granularity request with an octave cutoff carries both
## new fields verbatim, unclamped (the server owns
## resolve_window_granularity()/clamp_window_n() — never trusted from the
## wire, same posture as window_n).
func test_encode_atlas_layer_request_carries_granularity_and_min_wl() -> void:
## T-1150: a request with an octave cutoff carries it verbatim, unclamped
## (the server owns quantize_min_wl_m() — never trusted from the wire, same
## posture as window_n).
func test_encode_atlas_layer_request_carries_min_wl() -> void:
var bytes := Protocol.encode_atlas_layer_request(
"GJ1c", "Topography", Vector2i(140, 260), 32, 4, 512
"GJ1c", "Topography", Vector2i(140, 260), 32, 512
)
var decoded = Messagepack.decode(bytes)
assert_that(decoded.value.get("window_granularity")).is_equal(4)
assert_that(decoded.value.get("window_min_wl_m")).is_equal(512)
## T-1152/T-1153: window_granularity_v2 is OMITTED (not sent as "") when at
## its empty-string default — same byte-compatibility contract as
## window_granularity/window_min_wl_m's own default-omission.
## window_min_wl_m's own default-omission.
func test_encode_atlas_layer_request_omits_granularity_v2_by_default() -> void:
var bytes := Protocol.encode_atlas_layer_request(
"GJ1c", "Topography", Vector2i(140, 260), 32
@@ -252,22 +249,20 @@ func test_encode_atlas_layer_request_omits_granularity_v2_by_default() -> void:
## T-1152/T-1153: a Region-rung request carries window_granularity_v2 as the
## bare string "Region" — the ONLY way to express the coarser-than-district
## rung (WindowGranularity's Rust doc: "the ONLY way to actually request
## Region is window_granularity_v2 = Some(WindowGranularity::Region)"), a
## plain rmp_serde variant-name encoding matching RoadNodeKind's existing
## wire precedent, NOT an integer discriminant.
## bare string "Region" — the way to express the coarser-than-district rung
## (WindowGranularity's Rust doc), a plain rmp_serde variant-name encoding
## matching RoadNodeKind's existing wire precedent, NOT an integer
## discriminant.
##
## T-1159: the legacy `window_granularity: int` param this call used to also
## pass positionally (between window_n and window_min_wl_m) is retired — see
## atlas_map_protocol.gd's encode_atlas_layer_request doc.
func test_encode_atlas_layer_request_carries_granularity_v2_region() -> void:
var bytes := Protocol.encode_atlas_layer_request(
"GJ1c", "Topography", Vector2i(0, 0), 6400, 0, 0, "Region"
"GJ1c", "Topography", Vector2i(0, 0), 6400, 0, "Region"
)
var decoded = Messagepack.decode(bytes)
assert_that(decoded.value.get("window_granularity_v2")).is_equal("Region")
# The legacy window_granularity field is independently omittable — a
# Region request sends ONLY the v2 tag, never a legacy value pretending
# to mean something for Region (WINDOW_GRANULARITY_REGION_KEY is a
# key-space tag the SERVER echoes, never a legal wire INPUT).
assert_bool(decoded.value.has("window_granularity")).is_false()
## §2: district_window is a distinct payload (echoes center/n for the
@@ -280,7 +275,7 @@ func test_atlas_response_district_window_passthrough() -> void:
var window := {
"center": [140, 260],
"n": 32,
"granularity": 4, # T-1150: quarter granularity, passed through same as every other field
"granularity_v2": "Quarter",
"min_wl_m": 512,
"morphology": PackedByteArray([8, 14, 0, 5]),
"elev_q": PackedByteArray([40, 62, 5, 88]),
@@ -307,7 +302,6 @@ func test_atlas_response_district_window_passthrough_region_rung() -> void:
var window := {
"center": [0, 0],
"n": 6400,
"granularity": 4294967295, # WINDOW_GRANULARITY_REGION_KEY (u32::MAX) — key-space tag, not a real multiplier
"granularity_v2": "Region",
"min_wl_m": 0,
"morphology": PackedByteArray([8, 14, 0, 5]),
+32 -84
View File
@@ -122,100 +122,58 @@ func test_clear_empties_the_cache() -> void:
# =============================================================================
# granularity / min_wl_m (T-1150, zoom ladder design doc §3 aliasing risk)
# min_wl_m (T-1150, zoom ladder design doc §3 aliasing risk)
# =============================================================================
## **MANDATORY aliasing regression (client half, T-1150):** a granularity-4
## (quarter) key and a granularity-1 (district) key at the IDENTICAL
## (body_id, center, n) must be DISTINCT cache keys — this is what prevents a
## quarter-spacing request from silently reading (or overwriting) a
## district-spacing window's cache entry, and vice versa.
func test_make_key_distinguishes_granularity_at_identical_body_center_n() -> void:
var k_district := AtlasWindowCache.make_key(
"GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY
)
var k_quarter := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32, 4)
assert_str(k_district).is_not_equal(k_quarter)
## Same aliasing risk, the other new axis: two requests identical except for
## `min_wl_m` (the octave cutoff) must not collide either — different cutoffs
## are different derived payloads (T-1149/T-1150).
func test_make_key_distinguishes_min_wl_m_at_identical_body_center_n_granularity() -> void:
var k_uncut := AtlasWindowCache.make_key(
"GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0
)
var k_cut := AtlasWindowCache.make_key(
"GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 512
)
## **MANDATORY aliasing regression (client half, T-1150):** two requests
## identical except for `min_wl_m` (the octave cutoff) must not collide —
## different cutoffs are different derived payloads (T-1149/T-1150).
func test_make_key_distinguishes_min_wl_m_at_identical_body_center_n() -> void:
var k_uncut := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32, 0)
var k_cut := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32, 512)
assert_str(k_uncut).is_not_equal(k_cut)
## Omitting granularity/min_wl_m (every pre-T-1150 call site) must produce the
## SAME key as passing the explicit district/no-cutoff defaults — byte/string
## compatibility for existing callers, not just "doesn't crash".
func test_omitted_granularity_and_min_wl_m_match_explicit_district_defaults() -> void:
## Omitting min_wl_m (every pre-T-1150 call site) must produce the SAME key
## as passing the explicit no-cutoff default — byte/string compatibility for
## existing callers, not just "doesn't crash".
func test_omitted_min_wl_m_matches_explicit_default() -> void:
var k_omitted := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32)
var k_explicit := AtlasWindowCache.make_key(
"GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0
)
var k_explicit := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32, 0)
assert_str(k_omitted).is_equal(k_explicit)
## End-to-end through put()/get_window()/has() (not just make_key() in
## isolation): a quarter-granularity window and a district-granularity window
## at the identical (body, center, n) must both be independently retrievable,
## neither one clobbering or masking the other.
func test_district_and_quarter_windows_coexist_at_identical_body_center_n() -> void:
var cache := AtlasWindowCache.new()
var district_window := {"granularity": AtlasWindowCache.DISTRICT_GRANULARITY, "id": "district"}
var quarter_window := {"granularity": 4, "id": "quarter"}
cache.put("GJ1c", Vector2i(10, 20), 32, district_window, AtlasWindowCache.DISTRICT_GRANULARITY)
cache.put("GJ1c", Vector2i(10, 20), 32, quarter_window, 4)
assert_int(cache.size()).is_equal(2)
assert_that(
cache.get_window("GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY)
).is_equal(district_window)
assert_that(cache.get_window("GJ1c", Vector2i(10, 20), 32, 4)).is_equal(quarter_window)
# =============================================================================
# granularity_v2 (T-1152/T-1153): the string-tag axis — the ONLY thing that
# distinguishes Region from District/Quarter, since Region has no legal
# legacy-int representation (WindowGranularity::legacy_u32() returns None for
# Region — see the server's own doc). This is the SAME mandatory-aliasing
# regression class as the granularity/min_wl_m tests above, extended to the
# new axis.
# distinguishes Region from District/Quarter (WindowGranularity has no
# integer representation at all — see the server's own doc). This is the
# SAME mandatory-aliasing regression class as the min_wl_m tests above,
# extended to the new axis.
#
# T-1159: these tests used to also carry a legacy int `granularity`
# positional argument (mirroring the server's now-retired
# `window_granularity: u32` wire field) — removed along with the cache's own
# legacy key component (see atlas_window_cache.gd's doc).
# =============================================================================
## **MANDATORY aliasing regression (T-1152/T-1153):** a Region-rung key and a
## District-rung key at the IDENTICAL (body_id, center, n, legacy
## granularity, min_wl_m) must be DISTINCT cache keys — the legacy int slot
## alone (both "District" and default-omitted callers pass
## DISTRICT_GRANULARITY=1) cannot tell them apart; granularity_v2 is what
## does.
## District-rung key at the IDENTICAL (body_id, center, n, min_wl_m) must be
## DISTINCT cache keys — granularity_v2 is the only axis that can tell them
## apart.
func test_make_key_distinguishes_granularity_v2_region_from_district() -> void:
var k_district := AtlasWindowCache.make_key(
"GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "District"
)
var k_region := AtlasWindowCache.make_key(
"GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "Region"
)
var k_district := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32, 0, "District")
var k_region := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32, 0, "Region")
assert_str(k_district).is_not_equal(k_region)
## Omitting granularity_v2 (every pre-T-1152 call site) must produce the SAME
## key as passing the explicit "District" default — byte/string
## compatibility, same contract as the legacy granularity/min_wl_m defaults.
## compatibility, same contract as the min_wl_m default above.
func test_omitted_granularity_v2_matches_explicit_district_default() -> void:
var k_omitted := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32)
var k_explicit := AtlasWindowCache.make_key(
"GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "District"
)
var k_explicit := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32, 0, "District")
assert_str(k_omitted).is_equal(k_explicit)
@@ -229,23 +187,13 @@ func test_region_and_district_windows_coexist_at_identical_body_center_n() -> vo
var district_window := {"granularity_v2": "District", "id": "district"}
var region_window := {"granularity_v2": "Region", "id": "region"}
cache.put(
"GJ1c", Vector2i(10, 20), 32, district_window, AtlasWindowCache.DISTRICT_GRANULARITY, 0,
"District"
)
cache.put(
"GJ1c", Vector2i(10, 20), 32, region_window, AtlasWindowCache.DISTRICT_GRANULARITY, 0,
"Region"
)
cache.put("GJ1c", Vector2i(10, 20), 32, district_window, 0, "District")
cache.put("GJ1c", Vector2i(10, 20), 32, region_window, 0, "Region")
assert_int(cache.size()).is_equal(2)
assert_that(
cache.get_window(
"GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "District"
)
cache.get_window("GJ1c", Vector2i(10, 20), 32, 0, "District")
).is_equal(district_window)
assert_that(
cache.get_window(
"GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "Region"
)
cache.get_window("GJ1c", Vector2i(10, 20), 32, 0, "Region")
).is_equal(region_window)
+11 -7
View File
@@ -512,13 +512,17 @@ func test_decode_atlas_response_not_found() -> void:
## PR #191 review, Hoshe 3: `atlas_response_ready_with_window.msgpack` had NO
## consumer anywhere in client/tests — regenerated by the T-1150 `granularity`/
## `min_wl_m` field additions but nothing decoded it through the real IPC path.
## This is that consumer, matching the sibling `test_decode_atlas_response_*`
## tests' style/fixture-dir convention above: full decode_atlas_layer_response()
## consumer anywhere in client/tests — regenerated by the T-1150 `min_wl_m`
## field addition but nothing decoded it through the real IPC path. This is
## that consumer, matching the sibling `test_decode_atlas_response_*` tests'
## style/fixture-dir convention above: full decode_atlas_layer_response()
## round trip (not a hand-built Dictionary like test_atlas_data_delivery.gd's
## passthrough tests), confirming `district_window.granularity`/`.min_wl_m`
## (T-1150's two new echo fields) survive the real client decode path.
## passthrough tests), confirming `district_window.granularity_v2`/`.min_wl_m`
## survive the real client decode path.
##
## T-1159: the legacy `district_window.granularity` int echo this test used
## to also assert is retired server-side — see
## server/src/atlas/layer_proxy.rs's `DistrictWindowLayer` doc.
func test_decode_atlas_response_ready_with_window() -> void:
var bytes := _load_fixture("atlas_response_ready_with_window")
var resp = Protocol.decode_atlas_layer_response(bytes)
@@ -528,7 +532,7 @@ func test_decode_atlas_response_ready_with_window() -> void:
var window: Dictionary = resp.district_window
assert_that(window.get("center")).is_equal([10, -5])
assert_that(int(window.get("n"))).is_equal(2)
assert_that(int(window.get("granularity"))).is_equal(1)
assert_that(str(window.get("granularity_v2"))).is_equal("District")
assert_that(int(window.get("min_wl_m"))).is_equal(0)