docs(docs): §5 erratum superseded — unified coverage-ceiling rung model + tile mode as merged (T-1153 round 3)

This commit is contained in:
2026-07-22 13:04:07 +02:00
parent 6195fd28b3
commit 9ffda88e57
+3 -1
View File
@@ -108,7 +108,9 @@ Confirmed by direct code inspection (not aspirational): `value_noise`, `terrain_
**Split:** rungs govern *what classification granularity is available and legal to request* (a policy/cost question, §2/§10); canvas-resolution sampling governs *what density the client actually asks for*, tracking the viewport continuously. The rung-selection rule (§2) is the join: pick the coarsest legal rung whose spacing is ≤2× the current screen sample spacing.
> **Erratum (2026-07-22, T-1153 implementation — Stig):** the single-table-scan reading of the rule above is unsatisfiable for the District rung at any real viewport: with `CELL_PIXEL_SIZE = 16` and the server's `DISTRICT_WINDOW_MAX_N = 64` per-axis cap, the ≤2× visual-tolerance band and the window-coverage ceiling never overlap (boundary zooms at 1600×900: coverage releases Region at `_view_zoom ≈ 1.5625`, the 2× band hands District→Quarter at `≈ 0.125` — pinned by executable tests in `client/tests/test_atlas_window_geometry.gd`). As implemented, `AtlasWindowGeometry.select_rung()` splits the rule into two independent gates: a **coverage ceiling** (can a District-extent window span the requested world extent at all — decides Region) checked first, then the **2× visual tolerance** (decides District vs Quarter) on the remainder. Net effect at real viewports: the ladder steps Region → Quarter directly; District has no felt band. Pacing knobs if that's undesirable: `CELL_PIXEL_SIZE` shifts both crossings but cannot open a District band; the `2.0` multiplier in `select_rung()` is the client-only lever (at the cost of loosening the one-tier-finer-than-a-pixel guarantee); a real District band needs `DISTRICT_WINDOW_MAX_N ≥ ~canvas_px/2` — a server wire-budget change requiring re-measurement.
> **Erratum (2026-07-22, T-1153 implementation — Stig; superseded same day by the round-3 model below):** the single-table-scan reading of the rule above is unsatisfiable for the District rung at any real viewport: with `CELL_PIXEL_SIZE = 16` and the server's `DISTRICT_WINDOW_MAX_N = 64` per-axis cap, the ≤2× visual-tolerance band and the window-coverage ceiling never overlap. An interim two-gate split (coverage ceiling → 2× tolerance) shipped briefly but left District structurally unreachable and Region held indefinitely during pure zoom (caught in the live eyeball rounds, never merged).
>
> **Final model (round 3, as merged):** `AtlasWindowGeometry.select_rung()` is a **unified per-rung coverage-ceiling walk** — `MAX_COVERAGE_M` maps each rung to the maximum world extent its wire-capped window can span (Quarter ≈ 32.8 km, District ≈ 131 km, Region ≈ 13,107 km); selection walks finest-first and returns the first rung whose ceiling covers the current extent. The 2× visual-tolerance clause is retired: coverage, not tolerance, is the selector, which restores District as a real rung (the 33131 km extent band) and makes the ladder Quarter → District → Region → **tile mode** (extents beyond Region's single-window ceiling compose a whole-body mosaic of capped Region tiles — the ruling's progressive capped-density tiling; `compute_tile_grid()`, Lendel = 3×2). The one-tier-finer-than-a-pixel guarantee is preserved by construction at Quarter/District scales and bounded at Region scale by the wire cap — the felt-pacing knob is `CELL_PIXEL_SIZE`; widening a rung's band is a `WIRE_CAP_CELLS`/`MAX_N` budget change requiring re-measurement.
**Bounded key space, not unbounded.** A continuous field sampled at arbitrary density would give the cache an unbounded key space (client obstacle flagged in the grounding: the 24-entry exact-match LRU would thrash to ~0% hit rate). This is avoided because **requests snap to quantized rung tiers** (granularity ∈ {1, 4, …}) and integer district-aligned centers — only *display* is continuous; every *request* the wire actually carries is one of a small number of discrete shapes. **Gap flagged by critique:** as specified, `window_min_wl_m` is viewport-continuous (`E/C`) while the cache key/echo tuple is `(body, center, n, granularity)` — same key, different `min_wl`, would silently collide. Fix: **quantize `min_wl_m` to a small fixed set of bands per rung** (matching the rung's own octave bands) rather than passing a raw continuous value, and add the quantized band to both the echo and the cache key. This closes the gap without reopening the unbounded-key problem.