The complete workshop record: four round-1 positions, five round-2 syntheses (incl. Troblum's adversarial pass with addendum + final scorecard — all seven findings resolved), both lead interviews, Qatux's round notes and the 8-section workshop-outcomes.md (the lakes message-crossing documented as process history), measurement ⑥ (set_pixel/c1) + the population-survey and chunk/S2 addenda in the measurement docs, the brief's appendix updated through ⑥, and architecture-briefing-final.md — Jeroen's outline written back as-built (six-level ladder, lakes, ~9MB resident global tier). README row: Complete. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1234 lines
90 KiB
Markdown
1234 lines
90 KiB
Markdown
---
|
||
title: "Body Map Viewer — Tyre's Round 2 Synthesis"
|
||
description: "Final amendment texts (record-ready), tagged-envelope governance disposition, step-ladder tables, and the deprecation-sweep draft (Expected Output 2)"
|
||
type: workshop
|
||
status: active
|
||
workshop: body-map-viewer
|
||
created: 2026-07-25
|
||
---
|
||
|
||
# Tyre — Round 2 Synthesis
|
||
|
||
*cracks knuckles* — interview 1 upheld both my load-bearing round-1 calls
|
||
(gridunit snaps to D-243; cliffs Phase-4) and added two rulings I now fold in:
|
||
the **map-time TTL-split with the storage/staleness axes distinction** (Jeroen's
|
||
new eviction amendment), and **cliffs as a sparse `CliffSegment` feature list**
|
||
(aligning my round-1 "new fields, not stolen bits" text with Araminta's sparse
|
||
shape and Jeroen's ruling). This document is the filing package: paste §(a) into
|
||
`governance/decisions/architecture.md` with only ID-claiming left, run the §(d)
|
||
sweep at wrap-up.
|
||
|
||
Four sections, in the coordinator's order: (a) final amendment texts, (b)
|
||
envelope mechanics + the ceiling-rule disposition (with Dudley on wire/serving),
|
||
(c) step-ladder tables (with Dudley on costs), (d) deprecation-sweep draft.
|
||
|
||
---
|
||
|
||
## (a) AMENDMENT TEXTS — FINAL, record-ready
|
||
|
||
These incorporate every interview-1 ruling. Each is written to paste directly
|
||
into the named record. **A new D-record** (the body-map-viewer render
|
||
architecture) is claimed separately at filing — these are the *amendments to
|
||
existing records*; the new-record text lives at the end of this section as
|
||
§(a.0) so the whole package is in one place.
|
||
|
||
### (a.0) NEW RECORD — body-map-viewer render architecture (claim a D-id at filing)
|
||
|
||
> **D-NNN — Body-map-viewer stepped render architecture (supersedes the
|
||
> T-1143 continuous-ladder mechanism).** *Claimed [date]. Domain:
|
||
> architecture.*
|
||
>
|
||
> - **Decision:** The Atlas map handler is rebuilt on three locked premises:
|
||
> **(1) content determination is server-side** — the CPU/Rust server answers
|
||
> "what is at this world coordinate at this zoom step" as a per-step data
|
||
> canvas; the client never invents geometry. **(2) The client is a map-art
|
||
> function** — it colorizes, styles, and annotates the server's canvas via a
|
||
> render-to-texture terrain layer (texel-exact, drawn at the display ratio) +
|
||
> an unscaled screen-space sibling layer for vector annotations. **(3) Zoom is
|
||
> stepped** — discrete gridunit-spacing levels, one server-canvas fetch per
|
||
> crossed step boundary, cursor-anchored, with edge-scroll pan and a hard
|
||
> full-zoom-out reset to the canonical Global (rung-0) body-surface frame.
|
||
> - **The step ladder** is **six levels** — the **Global** map opener (rung 0)
|
||
> plus **five fixed metre rungs** (Dudley's Option D, every fixed rung
|
||
> measured): **Global (rung 0, body-surface view) → Region (204.8 km, rung 1)
|
||
> → District (2,048 m, rung 2) → Quarter (512 m, rung 3) → Block (128 m,
|
||
> rung 4) → Chunk (64 m, rung 5, deepest)**. **Rung 0 (Global) is the map
|
||
> opener and is *variable*-extent, not a fixed metre rung** (Jeroen, interview
|
||
> 2 correction): it is the whole body surface at **one gridunit per region**,
|
||
> so its canvas *is* the body's region grid — variable per body (~19K gridunits
|
||
> on an Earth-class body; the D-243 elastic seam made visible, since region
|
||
> count floats per `body_radius_km`). **Region (rung 1) is the largest
|
||
> *fixed*-size rung** — viewport-sized like every fixed rung below it, *not*
|
||
> the always-kept tier (that is Global). Tile/voxel (1 m)
|
||
> is **dropped from the Atlas ladder** (Jeroen, interview 2: *"the actual tile
|
||
> level rung seems unusable, maybe replace with 64"* — a 10-px-per-tile
|
||
> full-screen view is ~192×108 m of ground, which is in-world viewport content,
|
||
> Phase-5's scope, not an Atlas map); voxel is reserved for Phase-5 in-world
|
||
> rendering. Every fixed rung's **gridunit spacing is one of D-243's
|
||
> absolute-metre rungs** — never a viewport-derived spacing (see the D-243
|
||
> gridunit amendment, §(a.4)). **Deepest bottom-out rule: 1 screen px per 64 m gridunit, no
|
||
> magnification margin** — the old "10 px per tile" margin does *not* carry
|
||
> over (it existed because a 1 m unit is sub-readable at 1×1; a 64 m gridunit
|
||
> is already a legible map feature — a city block / short street — so chunk
|
||
> uses the plain fixed-canvas budget with no display-ratio-sized exception,
|
||
> §(c)).
|
||
> - **Canvas policy:** **rung 0 (Global) is the sole canonical, always-keep
|
||
> tier** — the body-surface region-grid canvas, one gridunit per region,
|
||
> variable-extent per body. D-226(d)-legal by construction: at one gridunit per
|
||
> region it is *coarser* than the region grid, never a sub-region
|
||
> metre-resolution whole-body derivation. **Every fixed rung — Region (rung 1)
|
||
> through Chunk (rung 5) — is viewport-sized and evictable** (Region included:
|
||
> it is the largest fixed rung, not the canonical tier), bounded to a fixed
|
||
> canvas-pixel budget (not a per-monitor echo), which keeps the deep
|
||
> ladder legal under D-226(d) **per request** by construction (a viewport-sized
|
||
> chunk-spacing canvas is never a whole-body metre-resolution derivation on any
|
||
> single request). **The D-226(d) prohibition is stated as a per-request /
|
||
> per-derivation constraint, not an aggregate-storage constraint** (§(a.8),
|
||
> Troblum S3) — the letter and the purpose are both held server-side; the
|
||
> client-cache *accumulation* path is closed by the deep-rung retention cap in
|
||
> the Cache bullet, not left to practical improbability.
|
||
> - **Wire:** the per-step canvas rides a **tagged-envelope** carrier (§(a.5),
|
||
> §(b)) — the ceiling-forcing payload D-225 deferred, now built. Dense
|
||
> classification fields ship PNG-per-field (measurement ④'s winner on size and
|
||
> speed); sparse feature lists (`courses`, `cliffs`) stay MessagePack-native.
|
||
> - **Cache:** three tiers, cheapest-first — client in-memory LRU → client
|
||
> disk-backed `FileAccess` store (self-cleaning TTL for sim-state entries) →
|
||
> server (D-203-shaped resident global tier + TTL(detail, time, distance) for
|
||
> finer rungs). Determinism (D-227) makes every geometry tier a pure cache,
|
||
> never a source of truth. **Staleness and storage are distinct eviction
|
||
> axes** (§(a.6)). **The server global (rung-0) tier is the body-surface
|
||
> region-grid canvas — one gridunit per region, ~19K gridunits on an
|
||
> Earth-class body — and costs ~8.85 MB PNG-encoded (27.61 MB raw) across the
|
||
> entire real ~267-body population** (Dudley, measured: 4,825,615 total cells,
|
||
> avg 18,073/body; largest GJ325Ac at 25,200 cells/47.4 KB, smallest a moon at
|
||
> 253 cells; Earth-class reference 195×97 = 18,915, matching the ~19K framing).
|
||
> This supersedes the earlier ~174 MB figure (which mis-priced a fixed 4K-class
|
||
> Region-*spacing* canvas per body, ~440× too many cells). At ~8.85 MB the
|
||
> keep-always tier is **trivially process-resident, not merely disk-safe** —
|
||
> the "always keep global" policy gets *easier*, not harder, under the
|
||
> rung-identity correction. Convention stated: **SI decimal MB**, so the figure
|
||
> isn't "corrected" against a `du`-reported MiB number later (Troblum N1).
|
||
> **Derive cost — the "snappy after first calc" number (Dudley, measured on
|
||
> real per-body extents, not extrapolated):** ~16–21 ms single-thread per body
|
||
> (~830–910 ns/cell over ~18K cells) — trivially interactive on a fresh
|
||
> Atlas-open. The tier **populates lazily, once per body, on first Atlas-open**
|
||
> via the D-206 background queue (the same pattern every other cached layer
|
||
> uses), so the ~4.0 s all-267-summed single-thread figure is a sanity ceiling
|
||
> only, never paid synchronously in one batch (same shape as T-1177's
|
||
> per-body-vs-summed hydrology framing). **Two client-cache hardening requirements, both
|
||
> stated in the record, both implemented in Stig's `FileAccess` spec:** (i) a
|
||
> **per-body deep-rung retention cap** (a maximum resident chunk/block-spacing
|
||
> tile count or disk quota per body, independent of the rung-0 retention floor)
|
||
> — this is the structural ceiling that closes the D-226(d) accumulation gap
|
||
> (§(a.8)); (ii)
|
||
> every persistent cache entry carries a **schema/version tag** (the game's
|
||
> `project.yaml` version string or a `generator_sha`-style stamp), checked at
|
||
> read time — a mismatch is treated as a cache miss and re-fetched, never
|
||
> decoded (§(a.9), Troblum S5).
|
||
> - **Rationale:** the T-1143 error class (client compensating for a
|
||
> zoom-scaled canvas — `_canvas.scale`, `_zs`/`_zs_stroke`/`_zs_ring_radius`,
|
||
> the line-rasterizer floor) is dissolved at the root: there is no
|
||
> zoom-scaled canvas anymore, so per-call compensation cannot occur. Every
|
||
> pre-workshop cost gate (①–⑤) came back GO with no extrapolation.
|
||
> - **Cross-reference:** D-166 (cascade + the amended zoom-ladder corollary),
|
||
> D-226 (the ceiling this migrates past; D-226(d) the deep-step boundary),
|
||
> D-227 (derive-don't-store — the cache's discipline), D-243 (the rung ladder
|
||
> gridunit snaps to), D-225 (the tagged-envelope migration this executes),
|
||
> D-010 (determinism — server-owns-derivation, client-art-function).
|
||
> - **Dissent:** None.
|
||
|
||
### (a.1) D-166 corollary — repoint (owns between-step magnification)
|
||
|
||
Paste as an amendment on D-166, after the 2026-07-21 amendment:
|
||
|
||
> **Amendment (2026-07-25, body-map-viewer workshop — stepped ladder
|
||
> supersedes continuous).** The 2026-07-21 corollary sentence — *"Display at
|
||
> every rung samples the derivation at canvas resolution (the ladder is a
|
||
> continuous field, not a stack of fixed display rasters)"* — is **repointed,
|
||
> not deleted.** The zoom mechanism is now **stepped**: the server generates
|
||
> one data canvas per discrete zoom step, sampled at that step's native D-243
|
||
> gridunit spacing. The corollary's *guarantee* survives, re-expressed
|
||
> per-step: **a gridunit is never derived coarser than its step's own rung
|
||
> floor, and never displayed finer than the display-ratio tunable** (1×1 ideal,
|
||
> ≥5×5 px/gridunit acceptable — measurement ④). The "continuous field" framing
|
||
> is retired as literally false (it never was continuous once server-side
|
||
> per-step canvases replaced the client `_canvas.scale` model). The corollary
|
||
> now reads: *"each zoom step's data canvas is a derivation sampled at that
|
||
> step's native gridunit spacing; display within a step holds that canvas at a
|
||
> fixed, texel-exact ratio; between-step magnification of the held canvas is
|
||
> bounded to one step interval and is the ladder's only sanctioned display-time
|
||
> scaling."* **This amendment owns the one honest new gap it creates:** in the
|
||
> interval just before a step-cross, the held (coarser or adjacent) canvas is
|
||
> magnified to fill the new step's viewport for the fetch duration — the exact
|
||
> operation the original corollary was written against, now a **named, bounded
|
||
> exception** rather than a silent violation. The bound is joint in two knobs:
|
||
> step count (more steps → smaller per-step magnification factor) and the
|
||
> display ratio. The fetch interval is short — measurement ⑤ shows step-canvas
|
||
> texture upload at 0.03–4.6 ms across every size, never a frame-budget risk,
|
||
> and measurement ④ shows an uncached 330K-gridunit step derives + encodes
|
||
> server-side in ~80 ms — so the magnified hold is a double-digit-millisecond
|
||
> transient, not a resting display state. **Ladder extent (interview 2,
|
||
> §(a.8b)):** the 2026-07-21 amendment's *"down to tile scale"* phrasing is
|
||
> narrowed — the Atlas ladder bottoms out at **chunk (64 m)**, not tile (1 m);
|
||
> tile/voxel is Phase-5 in-world content, not an Atlas rung. The per-step
|
||
> derivation guarantee above applies to every rung from region down to chunk.
|
||
|
||
### (a.2) T-1143 ruling 3 — superseded for zoom transport
|
||
|
||
Paste as an amendment on the D-226 record's T-1143 ruling block (or on D-166,
|
||
wherever the T-1143 rulings are anchored — they live in the D-226 amendment
|
||
chain):
|
||
|
||
> **Superseded 2026-07-25 (body-map-viewer workshop).** T-1143 ruling 3
|
||
> ("continuous cursor-anchored zoom... wheel-zoom carries the view from the
|
||
> orbital frame down through regional granularities continuously") is
|
||
> superseded for the **transport mechanism**: zoom is **stepped** — scroll
|
||
> clicks through discrete D-243-rung gridunit-spacing levels, one server-canvas
|
||
> fetch per crossed step boundary. **Survives unchanged:** (a) cursor-anchored
|
||
> centering, (b) edge-scroll pan, (c) the [HARD] condition that a full
|
||
> zoom-out resets to the canonical Global (rung-0) body-surface frame and
|
||
> location. A
|
||
> client-side morph/tween between held step canvases is an **investigation
|
||
> item** (cosmetic interpolation of already-arrived textures while the next
|
||
> step's canvas is in flight — never re-derivation, never a second positional
|
||
> truth; see the determinism-boundary ruling, §(a.7)). **T-1143 ruling 2**
|
||
> ("progressive capped-density tiling riding the generalized `district_window`
|
||
> carrier — no forced tagged-envelope migration") is **also superseded**: the
|
||
> tagged-envelope migration is now triggered (§(a.5)) — measurement ④ shows the
|
||
> step-canvas payload at 21×–563× the windowed ceiling across the three
|
||
> measured sizes, off by two to three orders of magnitude before encoding is
|
||
> even considered, which no additive-param reuse of `district_window` can
|
||
> carry.
|
||
|
||
### (a.3) `select_rung` / rung-model — replaced by the step index
|
||
|
||
Paste as an amendment note (on the same T-1143-rulings block):
|
||
|
||
> **Superseded 2026-07-25.** The shipped rung selector — `select_rung()`'s
|
||
> unified per-rung coverage-ceiling walk keyed on `MAX_COVERAGE_M` (Quarter →
|
||
> District → Region → tile-mode mosaic; `atlas-zoom-ladder-t1143.md` §6 "Final
|
||
> model, round 3") — is **replaced by a discrete step index** into the stepped
|
||
> gridunit ladder. Rungs-as-derivation-granularity survive conceptually (every
|
||
> step still names an absolute-metre D-243 rung), but the *selector* is no
|
||
> longer a coverage walk over viewport extent — it is "which step the viewport
|
||
> is currently on," advanced/retreated one notch per scroll. `select_rung`,
|
||
> `MAX_COVERAGE_M`, the coverage-ceiling walk, and the `compute_tile_grid()`
|
||
> whole-body Region-tile mosaic that composed the beyond-Region extent are
|
||
> retired. The whitelist-validation *discipline* from `resolve_window_granularity`
|
||
> (T-1150: finer-than-district integer multiples only, unknown values fall back,
|
||
> never trusted from the wire) is the correct shape for the **step index's own
|
||
> validation** and should be reused, not reinvented.
|
||
|
||
### (a.4) D-243 — gridunit vocabulary entry (additive)
|
||
|
||
Paste into D-243's item (5) vocabulary block, or as a labelled amendment:
|
||
|
||
> **Amendment (2026-07-25, body-map-viewer workshop) — `gridunit` added to the
|
||
> locked vocabulary (additive; no rung changes).** **gridunit (at zoom step):**
|
||
> the per-step data-canvas cell. **Not a new spatial rung** — a *role* name for
|
||
> whichever D-243 absolute-metre rung the Atlas ladder pins a given zoom step
|
||
> to. **At every *fixed* rung, gridunit spacing equals one of the ladder's fixed
|
||
> metre values and never floats with viewport size or display resolution** — a
|
||
> fixed step's gridunit is a D-243 metre rung, full stop. **The Atlas ladder's
|
||
> fixed rungs run from Region (~205 km, rung 1) down to chunk (64 m, rung 5, the
|
||
> deepest Atlas rung); tile/voxel (1 m) is NOT an Atlas gridunit** — it is
|
||
> dropped from the ladder (§(a.8b), Jeroen interview 2) and reserved for Phase-5
|
||
> in-world rendering. **The one exception to fixed-metre snapping is rung 0
|
||
> (Global)**: it is the *variable* map-opener, one gridunit per region, so its
|
||
> gridunit is a whole region (~205 km) but its *canvas extent* floats with the
|
||
> body's region count (the D-243 elastic seam). Global's gridunit is still not
|
||
> viewport-derived — it is the region grid, a fixed property of the body — so the
|
||
> "never floats with viewport/display" discipline holds; only the body's own
|
||
> region count varies. So
|
||
> the outline's *"10 px per tile"* bottom-out is **superseded** by **"1 screen
|
||
> px per 64 m gridunit, no magnification margin"** (Dudley's chunk bench): the
|
||
> Atlas bottoms out at the chunk rung at the workshop's own 1×1 ideal ratio,
|
||
> with *no* extra magnification, because a 64 m gridunit is already a legible
|
||
> map feature (city block / short street) — unlike a 1 m unit, which needed the
|
||
> 10× margin only to be readable at all (which is exactly the in-world-viewport
|
||
> problem chunk is defined to sit above). The **display ratio** (screen-px per
|
||
> gridunit — 1×1 ideal, ≥5×5 acceptable) is the free,
|
||
> client-side, viewport-dependent parameter, kept terminologically and
|
||
> architecturally separate from gridunit spacing: two monitors at different
|
||
> resolutions requesting the same step receive the **same** absolute-metre
|
||
> canvas (same rung, same derived content, same cache entry — shareable) and
|
||
> merely display it at different px-per-gridunit ratios (a GPU
|
||
> texture-to-viewport resize, never a re-derivation). This is what keeps the
|
||
> derivation cache key free of any presentation parameter (D-227: "a canvas for
|
||
> a fixed seed never changes" stays true). **The display ratio is
|
||
> step-dependent, not flat across the ladder** (Stig, measurement ⑥ —
|
||
> `Image.set_pixel` 77.5 ns/cell flat, so coloring cost is driven by cell count,
|
||
> never display density): **1×1 at the deepest steps** (Block/chunk — full
|
||
> fidelity where the player is closest to visible detail; chunk-64 m is now the
|
||
> deepest Atlas rung, §(a.8b)), **1×1 preferred at the mid steps**
|
||
> (Quarter/District) while the realistic canvas stays under ~2M cells, and
|
||
> **~5×5 reserved for the shallow rungs** (Region/rung 1 — and the Global/rung-0
|
||
> opener, whose region-grid canvas is tiny in cell count regardless of ratio)
|
||
> where the metre *extent* grows large. There is no measured reason to sacrifice
|
||
> fidelity where the player is nearest the detail; the ~5×5 fallback is a
|
||
> cost-relief valve for the coarse steps only. This changes *nothing* about the
|
||
> snap rule or the cache key — the ratio still governs only presentation (canvas
|
||
> *extent* sizing + on-screen scale), and per-step ratio selection is a
|
||
> client-side policy, never a spacing or derivation input.
|
||
|
||
### (a.5) D-226 T-1124 §2 windowed-family ceiling — tagged-envelope migration triggered
|
||
|
||
Paste as an amendment on D-226 (extends the amendment chain that already holds
|
||
the T-1156/T-1170 carrier notes):
|
||
|
||
> **Amended 2026-07-25 (body-map-viewer workshop — tagged-envelope migration
|
||
> triggered, superseding T-1143 ruling 2's "no forced migration").** The
|
||
> windowed-family ceiling's **purpose survives untouched**: prevent
|
||
> uncorrelated concurrent windowed *queries* needing per-field request
|
||
> correlation. Its **current mechanism** — "exactly one windowed-query field on
|
||
> `AtlasLayerResponse` (`district_window`), sized for a ≤4,096-cell served
|
||
> window" — **cannot carry a step canvas**: measurement ④ (T-1179) shows the
|
||
> best available encoding (PNG-per-field) at 21×–563× the ~30 KB reference
|
||
> across the three measured canvas sizes (330K/2.07M/8.3M gridunits), with no
|
||
> encoding in the measured set closing that gap (it is a cell-count gap of two
|
||
> to three orders of magnitude, not a codec gap). The **tagged-envelope
|
||
> migration D-225 deferred** (2026-06-12 constraint: *"the next inbound message
|
||
> type must introduce a tagged envelope"*) is hereby the sanctioned path and is
|
||
> executed: the step-canvas payload becomes its own **tagged message type on
|
||
> the existing IPC stream** (not a second socket, not a `district_window`
|
||
> growth) — the exact shape §(b) fixes. **The ceiling rule is re-scoped, not
|
||
> lifted:** "exactly one windowed-query field" now governs the **legacy
|
||
> `district_window` carrier only**; the tagged step-canvas envelope is a
|
||
> **separate carrier the ceiling rule does not apply to by construction** — it
|
||
> is not a second windowed field on the old shape, it is the new shape. The
|
||
> ceiling's original job (no uncorrelated concurrent windowed queries) is
|
||
> preserved *within* the envelope by the same echo-key/staleness discipline
|
||
> `district_window` uses today (`(body, step, center, granularity)` echoed on
|
||
> every response, latest-wins, stale-discardable). Framed as **expected scope,
|
||
> executing a planned deferral** — tier: challenging but doable, not a risk.
|
||
> **Concrete shape (Dudley, §(b)):** inbound is a discriminator-field
|
||
> `StepCanvasRequest { step_canvas: bool, body_id, step_index, center, extent,
|
||
> min_wl_m }` — a sixth `Inbound` variant extending the existing
|
||
> `star_map`/`city_names`/`browse` `ShapeProbe` pattern (the required-marker
|
||
> form D-225's 2026-06-12 amendment named); outbound is a **dedicated
|
||
> `StepCanvasResponse` message** (not a field on `AtlasLayerResponse`) +
|
||
> `SimBridge::send_step_canvas_response`. The legacy `district_window` carrier
|
||
> survives **byte-unchanged** — the envelope carries only new step-canvas
|
||
> traffic; `district_window` goes cold when its only client (the retired
|
||
> `AtlasWindowViewer`) is deleted, then is removed in a follow-up cleanup
|
||
> ticket (D-005/D-192 co-ship — no old-client/new-server window). **The ceiling
|
||
> rule is therefore RE-SCOPED, not retired:** it keeps governing the live legacy
|
||
> carrier verbatim.
|
||
|
||
### (a.6) Map-time axis + storage/staleness eviction split (Jeroen's interview-1 amendment)
|
||
|
||
New — records interview-1 ruling 2 verbatim-grounded. Paste as an amendment on
|
||
D-227 (the derive-don't-store record whose cache discipline this instantiates)
|
||
and cross-reference from the new render-architecture record:
|
||
|
||
> **Amendment (2026-07-25, body-map-viewer workshop — map time axis; and
|
||
> staleness vs storage as distinct cache axes).** The Atlas map shows **current
|
||
> state via a TTL-split**: **static geometry** (morphology/elevation/moisture/
|
||
> vegetation/glaciation/height — everything derive-don't-store covers) is
|
||
> **cached indefinitely-fresh** (determinism: re-derivation is byte-identical,
|
||
> so "stale" is not a concept that applies to geometry); **sim-state planes**
|
||
> (frozen/flooded, and any future climate-sim-driven field) are carried as
|
||
> **separately-cached short-TTL planes**, re-requested as sim time advances.
|
||
> **Two distinct eviction axes (Jeroen, interview 1, verbatim: *"we still may
|
||
> also want to evict non global level geometry based on time to save storage
|
||
> for planets the player visits but never goes back to"*):** **(1)
|
||
> staleness-eviction** applies only to sim-state planes (they genuinely go
|
||
> stale as sim time moves); geometry never goes stale. **(2)
|
||
> storage-eviction** applies to *all* sub-global cache entries including
|
||
> geometry — **every fixed rung, Region (rung 1) through Chunk (rung 5),
|
||
> included** — evicted on time-since-last-visit purely as a **storage-budget
|
||
> policy**, not because the data is wrong (a re-derive on next visit is
|
||
> byte-identical and cheap — measurement ②/③, ~190–220 ns/cell parallel flat at
|
||
> every rung). **The global tier — rung 0 (Global, the body-surface region-grid
|
||
> canvas), NOT Region — alone is keep-always** — exempt from both axes, the
|
||
> resident tier that makes "atlas navigation snappy after first calc" true.
|
||
> (Region is rung 1, the largest *fixed* rung; it is viewport-sized and
|
||
> storage-evictable like every rung below it — the always-kept tier is the
|
||
> variable Global opener above it.) This makes Dudley's `TTL(detail, time, distance)`
|
||
> formula precise: the `time` term is *storage-eviction* for geometry (evict a
|
||
> long-unvisited body's fine-rung canvases to reclaim disk) and *staleness*
|
||
> for sim-state planes (re-fetch a flooded/frozen plane whose sim-time TTL
|
||
> expired) — two different reasons an entry leaves the cache, never conflated.
|
||
|
||
### (a.7) river-courses-t1170.md carrier rule + cliff sparse-list — terminology repoint + cliff addition
|
||
|
||
Paste as a note at the top of `docs/architecture/river-courses-t1170.md` and as
|
||
a one-line D-227 cross-reference update:
|
||
|
||
> **Note (2026-07-25, body-map-viewer workshop).** The carrier three-way rule
|
||
> (Ruling 1c) survives unchanged in substance; "the windowed payload" is
|
||
> repointed terminologically to "the per-step data-canvas payload — formerly
|
||
> the `district_window` field, now the tagged step-canvas envelope (D-226
|
||
> 2026-07-25 amendment, §(a.5))." Rule (iii) — *rung-indexed invented detail
|
||
> rides the windowed payload regardless of geometric kind* — now has a **second
|
||
> vector member alongside `courses`: `cliffs: Vec<CliffSegment>`.** Carved-gorge
|
||
> geometry (dominant `elevation` unchanged + per-segment `channel_depth` +
|
||
> `cliff_edge`, T-1177's direct solver-output carry) is **rung-indexed invented
|
||
> detail** exactly as course geometry is (hydrology settles once per body, but
|
||
> the *carved representation drawn at a step* is a windowed-rung concern the
|
||
> same way course geometry is), so it rides the step-canvas envelope as a
|
||
> **sparse feature list — zero-length when nothing is carved** (measurement ①:
|
||
> gorge carving is structurally rare, zero carved cells across all three
|
||
> production-scale benches), `#[serde(default)]`, parallel to `courses`. It is
|
||
> **not** a dense per-gridunit array and **not** a stolen bit of an existing
|
||
> classification byte. **Scope: Phase-4 Atlas** (Jeroen, interview 1, ruling 3
|
||
> — a map showing a smooth shoreline where the settled solver computed a carved
|
||
> channel would misrepresent the "settled hydrology" the workshop premised;
|
||
> including it is nearly free given the direct-carry representation). **The
|
||
> sparse-list encoding's "near-zero occupancy" cost is SURVEY-CONFIRMED
|
||
> population-wide (Troblum B1, resolved strong):** the pre-filing population
|
||
> survey ran all **267 committed real heightmaps** independently (each body's
|
||
> own PNG-embedded sea level, real 512×256 working grid, ~0.86 s total,
|
||
> byte-exact determinism across two runs) and found **zero carved-outlet
|
||
> basins, zero `cliff_edge` cells, 0/267 bodies with any carving** — across
|
||
> genuinely varied terrain (31–187 basins/body), not a flat population. The
|
||
> `cliffs` field ships **empty on every currently-committed body**; the
|
||
> "near-free" claim is now population-backed, not one-body-backed. **Framing
|
||
> held deliberately at "not observed yet ≠ cannot occur":** the carving
|
||
> arithmetic (`channel_depth = original − spill_level`, the `cliff_edge` flag)
|
||
> stays unit-proven in isolation for any future body whose terrain does produce
|
||
> the narrow two-independently-sealed-basins-plus-single-cell-corridor geometry
|
||
> carving requires — the field-set and Phase-4 scope stand because the model
|
||
> must represent what the solver *can* produce, and the sparse-list is the
|
||
> right shape at zero occupancy (empty vec, `#[serde(default)]`) and remains a
|
||
> correct shape at any future nonzero occupancy. **Survey scope limit to carry
|
||
> into the filed record:** the survey used uniform `moisture_q = 55` (per-body
|
||
> climate wiring is out of scope) — this affects only the endorheic/overflow
|
||
> *split*, never carving (carving is elevation-gated, never moisture-gated), so
|
||
> the zero-carving finding is independent of the climate simplification. Full
|
||
> addendum: `measurements/t1177-hydrology.md` "POPULATION SURVEY" section.
|
||
|
||
### (a.8) D-226(d) whole-body prohibition — per-request framing + client-cache accumulation cap (Troblum S3)
|
||
|
||
Paste as an amendment on D-226 (the item-(d) prohibition), alongside the ceiling
|
||
amendment §(a.5):
|
||
|
||
> **Amended 2026-07-25 (body-map-viewer workshop — accumulation gap closed,
|
||
> Troblum adversarial pass S3).** The item-(d) whole-body prohibition ("chunk/
|
||
> tile/voxel output never appears as a whole-body planetary map layer") is
|
||
> **stated explicitly as a per-request / per-derivation constraint, not an
|
||
> aggregate-storage constraint.** The stepped ladder's viewport-sizing policy
|
||
> holds it **by construction server-side**: no single `StepCanvasRequest` ever
|
||
> derives whole-body coverage at sub-Region spacing (the deepest step is a
|
||
> chunk-64 m viewport canvas — see §(a.8b) for the tile/voxel-drop narrowing).
|
||
> But the client-side persistent cache (Stig's `FileAccess` store) introduces an
|
||
> *accumulation* path the letter of the rule does not cover: a systematic
|
||
> exhaustive pan at the deepest (chunk) spacing — most plausibly the **D-226
|
||
> item-(4) `AtlasAgentInterface` automated QA sweep**, not normal play — could
|
||
> assemble a near-whole-body chunk-resolution artifact as N discrete cached
|
||
> files over wall-clock time (the tile-spacing case that produced the ~985 GB /
|
||
> 6.6M-tile figure is now moot at the Atlas ladder — tile is dropped, §(a.8b) —
|
||
> but the *accumulation principle* still applies at chunk/block spacing, just at
|
||
> a coarser resolution and a proportionally smaller aggregate; impossible by
|
||
> accident, but not *structurally* prevented). The rule's purpose is about
|
||
> information content, not file count, so packaging it as N files does not
|
||
> exempt it. **Closed structurally, not by improbability:** a **per-body
|
||
> deep-rung client-cache retention cap** (a maximum resident chunk/block-spacing
|
||
> tile count or disk quota per body, independent of the rung-0/Global retention
|
||
> floor) bounds sub-global accumulation so the aggregate can never approach whole-body
|
||
> metre-resolution coverage. The automated QA channel inherits the same cap —
|
||
> an agent sweep's client cache is bounded identically, so a QA run cannot
|
||
> silently deposit the forbidden artifact in `user://atlas_cache/`. The exact
|
||
> cap value is a tuning constant sized in Stig's cache spec at implementation;
|
||
> the *requirement that a cap exist* is record-level.
|
||
|
||
### (a.8b) D-226(d) floor — partial restore at chunk (Jeroen's interview-2 narrowing of his own interview-1 opening)
|
||
|
||
Paste as an amendment on D-226, immediately after the T-1143 ruling 1 block
|
||
(which opened item-(d)'s floor for the ladder) — this narrows that opening:
|
||
|
||
> **Amended 2026-07-25 (body-map-viewer workshop, interview 2 — the opened
|
||
> floor lands at chunk; tile/voxel re-close for the Atlas).** T-1143 ruling 1
|
||
> (2026-07-21) opened item-(d)'s floor "toward block/tile granularity" for the
|
||
> Atlas ladder, on the BHAG that *"we set a new BHAG so old restrictions are up
|
||
> for debate."* Interview 2 **scopes that opening — it does not reverse it.**
|
||
> Jeroen (verbatim): *"the actual tile level rung seems unusable. maybe replace
|
||
> with 64?"* Reasoning (matching the workshop's own seam logic): a 10-px-per-tile
|
||
> full-screen Atlas view is ~192×108 m of ground — that is **in-world viewport
|
||
> content (Phase-5 scope)**, not a map. The Atlas zoom ladder therefore bottoms
|
||
> out at **chunk (64 m)**, and **tile/voxel (1 m) output returns to
|
||
> never-Atlas-mapped** — exactly item-(d)'s original prohibition, now restored
|
||
> for the tile/voxel tier specifically. **Precise post-interview-2 state of the
|
||
> floor:** the opening is *used* down to chunk (64 m) — block (128 m) and chunk
|
||
> (64 m) are legal Atlas rungs, riding the viewport-sized windowed carve-out
|
||
> (§(a.8) per-request framing) — and *re-closed* below chunk: tile (1 m) and
|
||
> voxel/subvoxel output are Atlas-invisible, verified by the
|
||
> believability/derivation harnesses and shown **in-world in Phase 5**, exactly
|
||
> as item (d) originally required. This is a **deliberate narrowing of the
|
||
> BHAG's scope, not a walk-back of the BHAG** ("a Reach a character can travel
|
||
> through" is unchanged; what changed is that the *Atlas map* stops one rung
|
||
> above the in-world viewport, because that's where a map stops being a map).
|
||
> The harness-verification path for tile/voxel L5 fill remains primary, as it
|
||
> was before the opening — the opening's practical effect is now limited to the
|
||
> block and chunk rungs, which is the range where a whole-viewport canvas still
|
||
> reads as a *map* rather than a *scene*.
|
||
|
||
### (a.9) Client-cache schema/version tag — the one D-192 gap (Troblum S5)
|
||
|
||
Paste as an amendment on D-227 (the cache-discipline record) and cross-reference
|
||
from D-192:
|
||
|
||
> **Amendment (2026-07-25, body-map-viewer workshop — persistent-cache version
|
||
> discipline, Troblum adversarial pass S5).** D-192 drops the client/server
|
||
> protocol version handshake on the subprocess-co-ship rationale ("the Godot
|
||
> client launches the Rust server it was built with — always in sync at
|
||
> runtime"). That holds for the **live** wire, and for the tagged-envelope
|
||
> migration itself (no live network deployment where an old client meets a new
|
||
> server). It does **not** hold for a **disk-backed persistent cache** (Stig's
|
||
> `user://atlas_cache/` store, premise 9): a cache file written by game version
|
||
> N and read back by version N+1 **survives a game update by construction** —
|
||
> exactly the version boundary D-192 assumes away everywhere else. A patch that
|
||
> changes the step-canvas payload shape (adds a field — e.g. this workshop's own
|
||
> `cliffs` list — or shifts an enum discriminant range per T-1150's "unknown
|
||
> values fall back, never trusted from the wire") would have an N-schema cache
|
||
> decoded as N+1-schema: a hard decode error at best, a silent
|
||
> misinterpretation of old bytes as new fields at worst (the exact class D-225's
|
||
> 2026-06-12 tagged-envelope constraint prevents for the *live* wire, now
|
||
> extended to the *disk* format). **Requirement (record-level):** every
|
||
> persistent client-cache entry carries a **schema/version tag** at write time
|
||
> (the game's `project.yaml` version string, or a `generator_sha`-style stamp),
|
||
> and a **read-time check**: a tag mismatch is treated as a **cache miss —
|
||
> re-fetch, never decode.** This extends the existing cache-index shape
|
||
> (`{written_at, last_read_at, kind, size_bytes}` + `schema_version`) by one
|
||
> field; it lands in Stig's `FileAccess` spec at implementation, but the
|
||
> *requirement* is stated here so it is not discovered as a stale-cache decode
|
||
> bug in the wild. Consistent with D-227's "cache never truth, evict → recompute
|
||
> always valid" — a version-mismatched entry is just another eviction case.
|
||
|
||
### (a.10) Seed-chaining — the "cache-accelerated pure function" model (Jeroen interview-2: he meant consuming coarser output)
|
||
|
||
Paste as an amendment on D-227 (this is the one place derive-don't-store meets
|
||
"a finer step reads a coarser step's output") — **for Jeroen's final
|
||
ratification against his phrase "serves as seed information for the deeper
|
||
cascade."** Governance framing is mine; the cost/impl side is
|
||
**Dudley-confirmed** (`dudley-interview2-response.md` §2) — his A/B mechanism
|
||
distinction is folded in, and the `[DUDLEY]` bracket is resolved.
|
||
|
||
> **Amendment (2026-07-25, body-map-viewer workshop, interview 2 — seed-chaining
|
||
> resolved as a cache-accelerated pure function).** Jeroen's outline —
|
||
> *"[the step canvas] at the same time serves as seed information for the deeper
|
||
> cascade"* — is ruled at interview 2 to mean the finer step **consumes the
|
||
> coarser step's resolved output** (not merely that the coarser rung is
|
||
> independently re-derivable). This is reconciled with D-227 derive-don't-store
|
||
> **without weakening it**, via the **cache-accelerated pure function** model:
|
||
>
|
||
> - **What "consuming coarser output" means precisely — mechanism B, not
|
||
> mechanism A** (Dudley §2, load-bearing to prevent a subtle violation).
|
||
> **(A) Reading the coarser step's RESOLVED CLASSIFICATION** (e.g. taking a
|
||
> District-spacing `morphology_zone` as a shortcut for a Chunk cell's zone)
|
||
> is **ruled OUT** — it violates Araminta's categorical-field re-derivation
|
||
> rule (§(a.6)/round-1: coarser steps re-derive morphology/vegetation/
|
||
> glaciation as a fresh dominant-mode pick at their own spacing, never inherit
|
||
> a different spacing's classification — the same-vocabulary/different-meaning-
|
||
> per-scale contradiction). **(B) Reading the coarser step's underlying
|
||
> CONTINUOUS PRIMITIVE** (the region/district *baseline blend* at a world
|
||
> position) as an input to the finer step's OWN fresh classification is what
|
||
> "seed information for the deeper cascade" means — and it is **already the
|
||
> shipped pattern** (`invent_primitives`'s district call reads a region
|
||
> baseline today). The cache-accelerated model applies to (B): cache the
|
||
> continuous baseline blend, not the resolved classification.
|
||
> - **The DEFINITION stays pure.** Every gridunit value remains
|
||
> `derive(seed, position)` — a pure function of fixed inputs, byte-identical
|
||
> on every evaluation (D-010/D-227 unchanged). "Consuming the coarser output"
|
||
> does not make the finer step a function of *mutable state*; the coarser
|
||
> baseline it consumes is itself `derive(seed, position)` at the coarser rung —
|
||
> a pure value, not a stored fact.
|
||
> - **The IMPLEMENTATION may read a resident coarser canvas as an
|
||
> ACCELERATION,** with a **derive-fresh fallback** when that canvas isn't
|
||
> resident. Reading the cached coarser canvas is faster than recomputing it;
|
||
> not having it costs a fresh derive of exactly the shape Dudley already
|
||
> benched.
|
||
> - **This is an OPTIMIZATION, not a SEMANTIC DEPENDENCY — the load-bearing
|
||
> governance distinction.** The coarser canvas being read is *itself evictable
|
||
> derived data* (a pure function of the same seed). So correctness never
|
||
> depends on the cache being warm: if the coarser entry is evicted, the finer
|
||
> step derives it fresh and gets **byte-identical** input, producing the same
|
||
> output. That is precisely D-227's own standing test — *"eviction →
|
||
> recompute, always valid."* A semantic dependency would mean "the finer step
|
||
> is *wrong* without the coarser cache" — never true here, because the coarser
|
||
> value is re-derivable to the same bytes. The cache is still **never truth,
|
||
> only an accelerator**: derive-don't-store holds intact.
|
||
> - **Mandatory determinism test (the proof that makes this airtight):** the
|
||
> cache-hit path (read resident coarser canvas) and the cache-miss path
|
||
> (derive the coarser input fresh) **must produce byte-identical finer-step
|
||
> output** — both are the same pure function of the same seed. This is a
|
||
> required test, the same shape as T-1170's window-independence invariant. If
|
||
> it passes, the two paths are indistinguishable except in speed, which is the
|
||
> definition of "optimization, not dependency." If it ever failed, that would
|
||
> be a determinism bug (a non-pure derivation), caught here rather than
|
||
> corrupting a save (D-227's determinism-is-save-critical clause).
|
||
> - **Benched numbers survive as worst-case ceilings (Dudley-confirmed).** Every
|
||
> ①②③ cost number measured the *independent re-derivation* path — which is
|
||
> exactly the cache-miss fallback. So the measured costs are the **cache-cold
|
||
> ceiling**: the shipped system is never slower than the appendix, and is
|
||
> faster whenever the coarser baseline is resident. This closes Troblum B2's
|
||
> "every cost number prices the wrong architecture" worry — the numbers price
|
||
> the *fallback*, and the fallback is the worst case, so they remain
|
||
> authoritative as an upper bound.
|
||
> - **No chain-reaction on eviction (Dudley-confirmed).** A deep-step (chunk)
|
||
> cache miss does **not** walk backward through evicted District/Region cache
|
||
> state — each rung's fresh-derive fallback is fully self-contained
|
||
> (`derive(seed, position)` takes nothing but those two inputs, by
|
||
> construction), so a miss costs *one* fresh derive at that rung's own inputs,
|
||
> never a cascade through every evicted ancestor. Troblum B2's chain-reaction
|
||
> worry **dissolves** — there is no dependency to chain, because the fallback
|
||
> was never built to depend on any other rung's cache state.
|
||
> - **Acceleration magnitude is unquantified but not architecture-gating
|
||
> (Dudley-confirmed honest caveat).** The saving from reading a cached
|
||
> continuous baseline vs. recomputing it (mechanism B) is *very likely real
|
||
> but modest* — no bench isolates the region-baseline-blend sub-cost from the
|
||
> full `derive_at_metres` call (most of the per-cell cost is the octave-sum
|
||
> detail-scatter work mechanism B does *not* propose caching). This is a
|
||
> **future implementation-time measurement**, not a gate on the architecture
|
||
> ruling: the ①②③ ceiling numbers already answer the load-bearing yes/no, and
|
||
> the "expected" (as opposed to worst-case) latency is sized later.
|
||
> - **Cross-reference:** supersedes Dudley's round-2 §(b) "independent
|
||
> re-derivation, never reads a cached response" *as the exclusive rule* — that
|
||
> ruling survives as the **fallback path's** description (function-composition
|
||
> on a cache miss); interview 2 adds the cache-read **fast path** (mechanism B)
|
||
> on top, governed by the byte-identical-paths test above.
|
||
|
||
### (a.11) Lakes — settled-hydrology sourcing of the existing `MorphologyZone::Lake`; endorheic cue via outflow-course presence (FINAL, converged)
|
||
|
||
**FINAL — fully converged on both sides.** The endorheic-cue residual is closed:
|
||
Dudley picked Araminta's **outflow-course presence** (his doc updated with proper
|
||
supersession — the stale 4-state-`water` sections, a crossed-in-flight reply to
|
||
Araminta's *original* questions, are marked SUPERSEDED-BY-CROSSING and traceable,
|
||
not deleted; his corrected section carries her 8-dense + 2-sparse struct with a
|
||
no-dissent confirm). No open clauses remain in this amendment.
|
||
|
||
Paste as an amendment on D-227 (the derive-pipeline record — the fill is a
|
||
data-source fix, not a wire change) with a D-239 §6 cross-reference. Converged
|
||
sources: Araminta's encoding ruling (`araminta-round2.md` §(e), where she verified
|
||
Dudley's code-read at source — `district_profile.rs:556-565`,
|
||
`generator.rs:1198-1223`, `features.rs:104-105` — and withdrew her earlier
|
||
new-field proposal) + Dudley's pipeline ruling + endorheic-cue pick
|
||
(`dudley-interview2-response.md`, "LAKES CONVERGENCE", corrected section).
|
||
|
||
> **Amendment (2026-07-23, body-map-viewer workshop — lakes sourced from settled
|
||
> hydrology; endorheic cue via outflow-course presence).** The outline's lake
|
||
> behaviour (settled fill, overflow, endorheic sinks — measurement ①/T-1177)
|
||
> reaches the Atlas map with **no new wire field and no vocabulary change**:
|
||
>
|
||
> - **Lakes ride the EXISTING `MorphologyZone::Lake`** (discriminant 1, already
|
||
> in the frozen 17-zone D-239 §6 vocabulary — *not* a new zone; **no new wire
|
||
> field for the fill itself**). The gap was never a missing vocabulary entry; it
|
||
> was a missing **data source**. Today `derive_morphology_zone` emits `Lake`
|
||
> from a crude heightmap threshold (`ocean_fraction_q >= 60`, a bilinear sample
|
||
> of `elev < sea_level`), with **zero connection to `HydrologyResult`'s
|
||
> settled-equilibrium basins** (the code's own comment already flags this as a
|
||
> known gap). **The fix:** `derive_morphology_zone` sources the `Lake` emission
|
||
> from settled hydrology instead of the heightmap heuristic, **falling through
|
||
> to today's `ocean_fraction_q` heuristic where no basin exists.**
|
||
> - **Pipeline sourcing — sample the continuous `filled_scaled` field, NOT
|
||
> projected basin-cell membership (Dudley's ruling, adopted).** Water derives
|
||
> from `HydrologyResult`'s continuous `filled_scaled` field **sampled bilinearly
|
||
> at each gridunit's world position** (the same mechanism `ocean_fraction_q`/
|
||
> `sea_level` already use) — *not* from basin-cell membership projected as a
|
||
> discrete 512×256 lookup, which would produce a **blocky, non-refining lake
|
||
> edge — exactly the magnified-coarser-composite artifact D-166's corollary
|
||
> forbids** (§(a.1)). This is **seed-chaining mechanism B (§(a.10)) applied to
|
||
> hydrology exactly as it already applies to `sea_level`**: sample a coarser
|
||
> rung's continuous primitive fresh per rung, never re-solve — so the lake edge
|
||
> *refines* with zoom (a genuine finer curve at each rung), not a coarse grid
|
||
> magnified. Sea vs. Lake is unchanged (both already-existing discriminants; the
|
||
> `OpenOcean` tier is untouched).
|
||
> - **Static, distinct from the sim-state flooded plane.** Lake basin geometry is
|
||
> a settled equilibrium — a pure function of seed + terrain (D-227), cached
|
||
> indefinitely-fresh like all geometry. It is **not** the short-TTL
|
||
> frozen/flooded sim-state plane (§(a.6)); a lake's *existence and extent* are
|
||
> static, while the flooded plane is the sim-time-varying water-height overlay.
|
||
> The two do not conflate.
|
||
> - **Endorheic-vs-overflow cue = OUTFLOW-COURSE PRESENCE. No wire bit, no new
|
||
> zone (FINAL).** The distinction (a lake that drains vs. a closed sink) ships
|
||
> as a **client-side read of whether a lake has a river course exiting it**: an
|
||
> overflow basin's outlet edge appears in `courses` (T-1170); an endorheic
|
||
> basin's does not. **Three reasons this is the right carrier, not a dense
|
||
> marker:**
|
||
> - **Proportionality.** Endorheic is **1,030 of 22,270 basins = 4.63%** in the
|
||
> real population. A per-cell bit under morphology-fold would force either an
|
||
> 18th `MorphologyZone` arm — a **D-239 frozen-vocabulary change every consumer
|
||
> inherits forever** (including the one-colorizer-family guarantee) — or a new
|
||
> wire field, for a **fewer-than-1-in-20 distinction**, when a zero-marginal-
|
||
> cost alternative exists.
|
||
> - **The work is required regardless.** Overflow lakes **must** show their exit
|
||
> rivers to be hydrologically honest (a lake that drains but shows no outlet
|
||
> river is simply wrong on the map) — so the basin-outlet→course wiring is
|
||
> built no matter what. The endorheic cue is a **side effect of that required
|
||
> work, not a feature it pays for.**
|
||
> - **Definitionally sound, no misfire case.** Every `Overflow` basin has a
|
||
> guaranteed non-empty `outlet_path` (tested:
|
||
> `overflowing_basin_has_nonempty_outlet_path`); every `Endorheic` basin has
|
||
> none. The presence/absence read is exact — there is no basin class that
|
||
> drains-but-shows-no-course or is-closed-but-shows-a-course.
|
||
> The **cliffs list is NOT the cue** (T-1177's survey: zero carved cells across
|
||
> all 267 real bodies — a cliff-wired cue would fire nowhere).
|
||
> - **Honest scope — until the outlet-wiring ticket ships, there is NO visible
|
||
> endorheic cue.** `HydrologyResult`'s basin `outlet_path`/`BasinOutcome` is
|
||
> **not currently threaded into `RiverNetwork`/`courses`** (D8-network-derived, a
|
||
> different computation; T-1177's own scope note confirms `HydrologyResult` is
|
||
> prototype-only, unwired to any payload). So the two deliverables are distinct:
|
||
> the `Lake` **sourcing fix** (self-contained — the map shows lakes as water) and
|
||
> the **outlet-wiring** (the exit-river distinction). **Between them, the map
|
||
> shows lakes but not the drains-vs-closed distinction** — state this plainly;
|
||
> it is not a gap in the design, it is the honest sequencing. The outlet-wiring
|
||
> is a **real, small, additive follow-up ticket** (§(d)), **pre-cleared by
|
||
> T-1170 Ruling 7b** (the reserved `TERMINAL` downstream sentinel: *"an interior
|
||
> sink becomes an additive drainage-extraction change, not a wire migration...
|
||
> the work is in D8 sink retention and lake morphology, and every piece this
|
||
> batch builds consumes them without modification"*), and
|
||
> `river_course::build_edges` is already **no-op-safe on `TERMINAL`** (Dudley's
|
||
> confirm) — additive, not a migration.
|
||
> - **Visual treatment:** lakes draw as water at every rung, same colorizer family
|
||
> as sea/ocean (one-colorizer-family guarantee, Araminta round-1 §3 — a `Lake`
|
||
> discriminant colours identically whether sourced by heuristic or basin);
|
||
> endorheic-vs-overflow reads via **outlet-course presence** at the lake shore
|
||
> (no distinct fill/texture on the lake body, no new styling rule for Stig — the
|
||
> present-or-absent exit river *is* the visual difference).
|
||
|
||
---
|
||
|
||
## (b) TAGGED-ENVELOPE MECHANICS — governance disposition (with Dudley on wire/serving)
|
||
|
||
**Division of labor:** I own the record framing + the D-225/D-226 §2 disposition
|
||
(what happens to the ceiling rule). Dudley owns the wire/serving design (message
|
||
shape, demux, legacy coexistence). **Dudley has ruled** (`dudley-round2.md` §(a),
|
||
grounded in a direct read of `server/src/bridge/mod.rs`); his three answers are
|
||
folded in below and §(a.5)'s bracketed clause is now resolved.
|
||
|
||
### The ceiling-rule disposition (mine, final)
|
||
|
||
The windowed-family ceiling (D-226 T-1124 §2, [HARD]) has two separable parts,
|
||
and only one moves:
|
||
|
||
- **Its purpose — "no uncorrelated concurrent windowed queries needing
|
||
per-field request correlation" — is preserved in full.** This is why the rule
|
||
existed: two independently-in-flight windowed queries would each need their
|
||
own request→response correlation, and the hand-rolled shape-demux couldn't
|
||
carry that. The tagged envelope *strengthens* this: a tagged message has an
|
||
explicit correlation handle by construction (the tag + echo key), which is
|
||
strictly better than the shape-demux the ceiling was protecting.
|
||
- **Its mechanism — "exactly one windowed field on `AtlasLayerResponse`" — is
|
||
re-scoped to the legacy carrier only.** The rule was a *fence around a
|
||
hand-rolled demux*, not a first-principles limit on windowed data. Once a
|
||
proper tagged envelope exists, the fence is obsolete for anything inside the
|
||
envelope: the envelope can carry as many correlated fields as its schema
|
||
declares, because the tag makes correlation explicit rather than structural.
|
||
|
||
**So the disposition is: the ceiling rule keeps governing `district_window`
|
||
(the legacy shape-demuxed carrier) verbatim, and does not extend to the tagged
|
||
step-canvas envelope, which is a new carrier with its own explicit correlation
|
||
discipline.** This is the same move T-1156 and T-1170 made in miniature (both
|
||
kept traffic *off* the ceiling by choosing the right carrier) — the difference
|
||
is those two stayed inside the one-field shape because they *could* (skeleton is
|
||
whole-body; courses are content of the existing field), whereas the step canvas
|
||
*cannot* (cell count alone forces a new carrier), so this one builds the
|
||
envelope the others didn't need.
|
||
|
||
**D-225's constraint is landed on its intended target.** D-225's 2026-06-12
|
||
amendment said the *next* inbound message type must introduce a tagged envelope
|
||
rather than extend shape-based detection. Every carrier since (T-1124's window
|
||
params, T-1131's BrowseRequest — "the fifth and last map-shape probe") deferred
|
||
it by riding existing shapes. The step canvas is the one that can't ride an
|
||
existing shape, so it is correctly the one that pays the deferred cost. This is
|
||
a *planned* migration executing on schedule, not an emergency.
|
||
|
||
### Three slots — Dudley's rulings, folded in
|
||
|
||
Dudley read the actual `decode_inbound`/`Inbound` code and found the
|
||
"tagged-marker" pattern D-225 asked for is **already implemented five times**
|
||
(each newer inbound shape — `StarMapRequest`/`CityNamesRequest`/`BrowseRequest`
|
||
— carries a mandatory boolean discriminator, and `ShapeProbe` already enforces
|
||
at-most-one-discriminator). So the migration extends a proven pattern rather
|
||
than inventing a new envelope format — which sharpens my governance framing: at
|
||
the *code* level this is "doable," and the "challenging" part lives in the
|
||
client rebuild (Stig) and the cache/ladder work, not the demux.
|
||
|
||
1. **Message shape → discriminator field on the existing stream.** Inbound: a
|
||
new `StepCanvasRequest { step_canvas: bool, body_id, step_index, center,
|
||
extent, min_wl_m }` as a sixth `Inbound` variant, extending the existing
|
||
`ShapeProbe` mutual-exclusivity chain. Outbound: a **dedicated
|
||
`StepCanvasResponse` message** (not a field on `AtlasLayerResponse` — D-226
|
||
T-1124 §2 names this exact "dedicated response message by rule" case) +
|
||
`SimBridge::send_step_canvas_response`. **My §(a.5) text stands verbatim** —
|
||
"its own tagged message type on the existing IPC stream" is exactly a
|
||
discriminated inbound variant + dedicated response message; D-225's language
|
||
was "a tagged envelope *(or a required marker field)*", and the required
|
||
marker field is what ships. The ceiling disposition is identical to what I
|
||
drafted.
|
||
|
||
2. **Legacy coexistence → `district_window` survives unchanged; the envelope
|
||
carries only the new step-canvas traffic.** Dudley's call matches my lean:
|
||
no retirement message, no dual-write, no migration of existing windowed
|
||
traffic. The legacy carrier keeps working byte-for-byte until Stig's stepped
|
||
viewer replaces its only client, at which point it goes cold and gets deleted
|
||
in a follow-up cleanup ticket (D-005/D-192 co-ship guarantee means no
|
||
old-client/new-server window). **Therefore the ceiling rule is RE-SCOPED (my
|
||
§(a.5) primary text), not fully retired** — it keeps governing the live
|
||
legacy `district_window` carrier verbatim; the envelope is the new carrier
|
||
outside it. The §(d) deprecation table's parenthetical "(if Dudley rules
|
||
one-carrier-subsumes-all → SUPERSEDE)" branch does **not** fire — re-scope is
|
||
final.
|
||
|
||
3. **Rung-0 (Global) and rung-1 (Region) both ride the NEW envelope** — at
|
||
`step_index: 0` (Global, the variable body-surface region-grid canvas) and
|
||
`step_index: 1` (Region, 204.8 km fixed), **not** the legacy whole-body
|
||
`region_grid`/`district_grid` `Option` fields. Dudley's reasoning is the one
|
||
I'd have given: putting the opener on the legacy family would force the new
|
||
stepped client to speak two response protocols (envelope for the deeper rungs,
|
||
old family for the opener) for zero architectural gain — one request shape,
|
||
one response shape across the whole ladder is simpler on both sides and is
|
||
what premise 8 ("step boundaries = compute-chunk boundaries") implies
|
||
uniformly. The only per-rung difference is that rung 0's canvas *extent* is
|
||
variable (the region grid) rather than a fixed pixel budget — a field value on
|
||
`StepCanvasRequest`, not a different message shape. **Render-architecture
|
||
record "Wire" bullet updated accordingly** (§(a.0): the envelope carries every
|
||
rung including the Global opener; the legacy whole-body layers keep serving
|
||
whatever non-stepped consumers survive the cutover, if any).
|
||
|
||
**Response framing (Araminta's relayed dense/sparse question, Dudley answered):**
|
||
one flat tagged `StepCanvasResponse` carrying all fields together (six dense
|
||
PNG-per-field + `settlement_id` dense + `courses`/`cliffs` sparse
|
||
MessagePack-native), **not** a dense/sparse split into separately-tagged
|
||
sub-messages. The progressive-paint UX case (terrain first, annotations after)
|
||
is real but belongs client-side (paint the RTT layer on decode, defer the
|
||
annotation draw a frame) — no wire-protocol complexity for a cost split the
|
||
measurements don't show (courses +0.09–0.21 ms, negligible). This matches the
|
||
whole-payload-together precedent D-225 set for `Layer1Output`.
|
||
|
||
*Filing note: §(a.5) and §(a.0) are now final — no bracketed clauses remain.*
|
||
|
||
---
|
||
|
||
## (c) STEP-LADDER TABLES — snap-rule constraints (mine) + costs (Dudley's)
|
||
|
||
**INTERVIEW-2 UPDATE — tile/voxel dropped, chunk-64 m is the new deepest rung,
|
||
and Dudley's Option D is DELIVERED (every row measured).** Jeroen ruled the tile
|
||
rung "unusable" (§(a.8b)); chunk (64 m) is the deepest Atlas rung. Dudley
|
||
benched the never-measured chunk rung (`dudley-interview2-response.md` §1) and
|
||
built Option D — **this is now the live ladder table** (below). Options A/B/C
|
||
are superseded and retained only for the carried-forward reasoning.
|
||
|
||
### Option D — the adopted ladder (six levels: Global opener + 5 fixed rungs; chunk-64 m deepest, every fixed rung measured)
|
||
|
||
**Six levels after Jeroen's interview-2 rung-identity correction: rung 0 =
|
||
Global (the variable body-surface region-grid map opener, always-kept), then five
|
||
fixed metre rungs Region→Chunk.**
|
||
|
||
| Rung | Level | Spacing | Factor (from prev) | Canvas | Cells | World extent | Derive cost (parallel) |
|
||
|---:|---|---:|---:|---|---:|---|---:|
|
||
| 0 | **Global** (opener) | 1 gridunit / region (~205 km) | — | **variable — the body's region grid** | ~18K (avg/body; ~19K Earth-class) | whole body | **~16–21 ms/body single-thread** (Earth-class 18,915 cells = 15.9–16.2 ms; largest 25,200 = 20.9–21.3 ms; ~830–910 ns/cell); **~8.85 MB PNG all 267 bodies** |
|
||
| 1 | Region | 204.8 km | — (variable→fixed seam) | 3840×2160 | 8.3M | whole body (capped mosaic) | 1,827 ms |
|
||
| 2 | District | 2,048 m | 100× | 3840×2160 | 8.3M | 7,864 × 4,424 km | 1,827 ms |
|
||
| 3 | Quarter | 512 m | 4× | 3840×2160 | 8.3M | 1,966 × 1,106 km | ~1,827 ms (same-band) |
|
||
| 4 | Block | 128 m | 4× | 3840×2160 | 8.3M | 491 × 276 km | ~1,827 ms (measured) |
|
||
| 5 (deepest) | **Chunk** | **64 m** | **2×** | 3840×2160 | 8.3M | **245.8 × 138.2 km** | **1,724–1,733 ms (measured)** |
|
||
|
||
**Rung 0 (Global) is categorically different from the fixed rungs:** its canvas
|
||
is the body's region grid (one gridunit per region), so its *extent* is variable
|
||
per body (the D-243 elastic seam — region count floats per `body_radius_km`,
|
||
~19K gridunits Earth-class, far smaller than a fixed 4K canvas) and it is the
|
||
sole always-kept tier. Rung 1 (Region) is the largest *fixed* rung — 204.8 km
|
||
spacing, a fixed 3840×2160 viewport canvas, evictable like every rung below. The
|
||
**Global→Region transition (rung 0→1) is the variable→fixed seam**, not a metre
|
||
factor; the first metre factor is Region→District (rung 1→2, ÷100).
|
||
|
||
**Every fixed row (1–5) is directly measured or in a directly-measured band —
|
||
the "zero asterisks" property the old Option B earned by *skipping* chunk, now
|
||
earned by *measuring* it.** (Rung 0 is Dudley-measured too: ~16–21 ms/body
|
||
single-thread over ~18K region-grid gridunits, ~8.85 MB PNG across all 267
|
||
bodies — trivially cheap to derive and store.) Two things Option D settles that
|
||
the old tables couldn't:
|
||
- **The deepest-step canvas-sizing special case is GONE.** The old voxel/tile
|
||
deepest step needed a display-ratio-sized canvas (216×384 m at 10 px/tile,
|
||
*not* the fixed-budget convention every other step used, because the two were
|
||
incompatible at 1 m spacing). **Chunk has no such incompatibility** — at 1×1
|
||
px/gridunit the fixed 3840×2160 budget and the "no magnification margin"
|
||
bottom-out rule are the *same* rule, so chunk uses the plain fixed-canvas
|
||
convention like every other rung. Dropping the special case is a genuine
|
||
simplification, a free consequence of Jeroen's own ruling.
|
||
- **Deepest-step derive cost rose two orders of magnitude in absolute terms
|
||
(17 ms → ~1.7 s) — and that is correct, not a regression.** Chunk's canvas
|
||
covers a vastly larger world area (216×384 m → 245.8×138.2 km) at the *same
|
||
cell count*, so it costs the same as every other rung's full canvas
|
||
(1.7–1.8 s parallel band) — which is exactly what "no special case" means.
|
||
1.7 s parallel is comfortably inside the step-cross tolerance every number in
|
||
this workshop uses. Cost still does not gate this rung.
|
||
|
||
**Bottom-out rule (record-level, §(a.0)/§(a.4)):** *1 screen px per 64 m
|
||
gridunit, no additional magnification margin.* The old 10×-per-tile rule was a
|
||
legibility margin for a sub-readable 1 m unit; a 64 m gridunit is already a
|
||
legible map feature, so it does not carry over — applying it would needlessly
|
||
shrink coverage 10× for no legibility gain.
|
||
|
||
**My snap constraints (hard, from the snap rule + interviews 1 & 2, corrected for
|
||
the Global/Region rung-identity fix):**
|
||
- **Every *fixed* rung's gridunit spacing = one of D-243's metre rungs.** The
|
||
Atlas ladder's fixed rungs are region ~205 km (rung 1), district 2,048 m,
|
||
quarter 512 m, block 128 m, chunk 64 m (rung 5) — tile/voxel (1 m) is NOT an
|
||
Atlas rung (§(a.8b), Phase-5 in-world content).
|
||
- **Rung 0 = Global** — the *variable* map opener (one gridunit per region, the
|
||
body's region grid; D-243 elastic seam), the whole-body canonical / always-keep
|
||
tier. This is the ONE variable-extent level; it is not viewport-derived (its
|
||
gridunit is a whole region, a fixed property of the body).
|
||
- **Rung 1 = Region** (~205 km) — the largest *fixed* rung, viewport-sized and
|
||
evictable like every rung below it; **not** the always-kept tier (that is
|
||
Global).
|
||
- **Deepest rung (5) bottoms at chunk (64 m)**, at 1×1 px/gridunit, no margin —
|
||
fixed 3840×2160 canvas like every other fixed rung (no display-ratio-sized
|
||
exception; that oddity died with the tile rung).
|
||
- No fixed rung invents a spacing D-243 doesn't name.
|
||
- Display ratio (px/gridunit, 1×1 → 5×5) is the free client knob, decoupled
|
||
from spacing — it sizes the canvas *extent* and the on-screen scale, never
|
||
the spacing.
|
||
|
||
---
|
||
|
||
**The material below (Options A/B/C + convention notes) is pre-interview-2
|
||
(voxel-deepest) reasoning, superseded by Option D above.** Retained for the
|
||
carried-forward logic (factor-unevenness analysis, the zero-asterisk argument)
|
||
— every "voxel 1 m / 216×384 m / 10 px/tile" row is void.
|
||
|
||
> **The tables and convention notes below are pre-interview-2 (voxel-deepest)
|
||
> reasoning, retained for the carried-forward logic (canvas convention, factor
|
||
> analysis, zero-asterisk argument). Options A/B/C and every "voxel 1 m / 216×384
|
||
> m / 10 px/tile" row are SUPERSEDED by Dudley's Option D (chunk-64 m deepest).
|
||
> The display-ratio-split *logic* below still holds — it just now lands the
|
||
> "display-ratio-sized deepest step" at the chunk rung, with Dudley's chunk
|
||
> bench supplying the deepest-row numbers that replace 216×384 m / 17 ms.**
|
||
|
||
**Canvas convention (Dudley's correction, adopted — reads at chunk now, not
|
||
voxel):** the fixed 3840×2160 canvas-pixel budget holds at every step **except
|
||
the deepest** — at the deepest rung the fixed-px-budget convention and the
|
||
display-ratio contract are mutually incompatible (a fixed 3840×2160 canvas at
|
||
metre-scale spacing covers little ground yet holds many cells, oversized for the
|
||
bottom-out display density), so the deepest step is **display-ratio-sized
|
||
instead**. *(Pre-interview-2 this was voxel 1 m → 216 × 384 m / 82,944 cells,
|
||
measurement ③; post-interview-2 the deepest rung is chunk 64 m and the extent is
|
||
Dudley's Option-D chunk display band.)* This is a convention-level split
|
||
(fixed-budget shallow, display-ratio deep), not a skeleton-specific one.
|
||
|
||
**Per-step display ratio (Stig, measurement ⑥):** the px-per-gridunit ratio is
|
||
step-dependent, not flat — **1×1 at Block/chunk** (full fidelity where the
|
||
player is nearest visible detail; ⑥ confirms `set_pixel` at 77.5 ns/cell flat,
|
||
so cost is cell-count-bound, not display-density-bound), **1×1 preferred at
|
||
Quarter/District** while the realistic canvas stays under ~2M cells, **~5×5 at
|
||
the shallow rungs (Region and the Global opener)** where extent grows. This
|
||
tightens the extent column above: at
|
||
the shallow steps the ~5×5 ratio means a coarser realistic canvas than the
|
||
fixed 3840×2160 worst-case (fewer cells, cheaper), so the 8.3M/1,827 ms figures
|
||
in the tables are the *fidelity-ceiling* cost, not the typical one — the actual
|
||
shallow-step canvas at ~5×5 is proportionally smaller. The deep steps stay at
|
||
1×1 (the 17 ms/83K deep-step number is already at full 1×1 fidelity). Cost only
|
||
*improves* against the table where the ratio relaxes; nowhere does it worsen.
|
||
|
||
**Three candidate ladders — Dudley's cost fills folded in** (all costs
|
||
MEASURED or same-band-confirmed against ①–④; the one honest gap, chunk at 64 m,
|
||
is flagged not guessed):
|
||
|
||
### Option A — one-rung-per-step (6 steps, clean 1:1 to D-243)
|
||
|
||
| Step | Gridunit rung | Spacing | Factor | Viewport extent | Cells | Derive cost (parallel) |
|
||
|---|---|---:|---:|---|---:|---|
|
||
| 0 | region | 204.8 km | — (canonical) | whole body (capped-tile mosaic) | 8.3M | 1,827 ms MEASURED |
|
||
| 1 | district | 2,048 m | ÷100 | 7,864 × 4,424 km | 8.3M | 1,827 ms MEASURED |
|
||
| 2 | quarter | 512 m | ÷4 | 1,966 × 1,106 km | 8.3M | ~1,827 ms same-band (T-1154) |
|
||
| 3 | block | 128 m | ÷4 | 491 × 276 km | 8.3M | ~1,827 ms MEASURED (T-1154) |
|
||
| 4 | chunk | 64 m | ÷2 | 246 × 138 km | 8.3M | **UNMEASURED** — never benched; cutoff-mechanism reasoning strongly implies same-band, but Dudley refuses to report a number he didn't run |
|
||
| 5 | voxel | 1 m | ÷64 | 216 × 384 m (display-ratio) | 83K | 17 ms MEASURED (③) |
|
||
|
||
*My concern with A, now confirmed by cost:* chunk (64 m) is the one rung nobody
|
||
measured, and it's D-243's *stream/derive unit*, not a natural display rung —
|
||
its ÷2 factor is a barely-perceptible zoom notch that adds a fetch and an
|
||
asterisk for no visual gain.
|
||
|
||
### Option B — skip-chunk (5 steps) — the joint recommendation
|
||
|
||
| Step | Gridunit rung | Spacing | Factor | Viewport extent | Cells | Derive cost (parallel) |
|
||
|---|---|---:|---:|---|---:|---|
|
||
| 0 | region | 204.8 km | — (canonical) | whole body | 8.3M | 1,827 ms MEASURED |
|
||
| 1 | district | 2,048 m | ÷100 | 7,864 × 4,424 km | 8.3M | 1,827 ms MEASURED |
|
||
| 2 | quarter | 512 m | ÷4 | 1,966 × 1,106 km | 8.3M | ~1,827 ms same-band |
|
||
| 3 | block | 128 m | ÷4 | 491 × 276 km | 8.3M | ~1,827 ms MEASURED |
|
||
| 4 (deepest) | voxel | 1 m | ÷128 | 216 × 384 m (display-ratio) | 83K | **17 ms MEASURED (③)** |
|
||
|
||
*Why B wins, and it's an evidence argument, not a taste one (Dudley + me
|
||
converge here independently):* **every row is directly measured or same-band-
|
||
confirmed — zero asterisks.** That's a direct consequence of chunk never having
|
||
been benched: B is the only one of the three skeletons that doesn't lean on the
|
||
unmeasured rung. The one genuinely large factor (block→voxel ÷128) lands at the
|
||
*deepest* step where between-step magnification matters *least* (max detail
|
||
already; no finer step to under-serve). The ÷100 Region→District factor at
|
||
0→1 is the one that maps onto a real seam — see the factor note below.
|
||
|
||
### Option C — coarse-doubled (4 steps, skip District too)
|
||
|
||
| Step | Gridunit rung | Spacing | Factor | Viewport extent | Cells | Derive cost |
|
||
|---|---|---:|---:|---|---:|---|
|
||
| 0 | region | 204.8 km | — (canonical) | whole body | 8.3M | 1,827 ms MEASURED |
|
||
| 1 | quarter | 512 m | ÷400 | 1,966 × 1,106 km | 8.3M | ~1,827 ms same-band |
|
||
| 2 | block | 128 m | ÷4 | 491 × 276 km | 8.3M | ~1,827 ms MEASURED |
|
||
| 3 (deepest) | voxel | 1 m | ÷128 | 216 × 384 m (display-ratio) | 83K | 17 ms MEASURED |
|
||
|
||
*Why I list but don't recommend C:* **it costs identically to B row-for-row**
|
||
(same rungs, same measured rates — District's absence is not a cost saving,
|
||
it's purely a pacing choice, Dudley confirms). Its distinguishing feature is the
|
||
÷400 Region→Quarter jump at 0→1 — a brutal between-step magnification interval
|
||
(the held Region canvas magnified ~400× to approximate a Quarter view before the
|
||
fetch lands is the D-166-corollary artifact at its worst). Only viable if fetch
|
||
latency makes that magnified hold imperceptible — and since costs don't separate
|
||
B from C at all, this is a pure UX-pacing call for Jeroen, not a cost tradeoff.
|
||
|
||
### The factor-unevenness note (Dudley's serving answer, folded in)
|
||
|
||
**The rung-identity correction makes the serving-seam story *cleaner*, not
|
||
messier** — the architectural boundary now lines up with a genuine rung boundary
|
||
instead of being buried inside a metre factor. The two seams that matter are now
|
||
*distinct*:
|
||
- **The variable→fixed / global→sub-global seam is rung 0→1 (Global→Region).**
|
||
This is the one real serving-side boundary: Global (rung 0) is variable-extent
|
||
and always-kept; Region (rung 1) is the first fixed, viewport-sized, evictable
|
||
rung. The cache-tier split (keep-always vs. storage-evictable, Dudley's §(d))
|
||
falls exactly on this seam — cleaner than the old framing, which had the cache
|
||
boundary and the ÷100 metre factor collapsed onto one "step 0→1" edge.
|
||
- **The metre factors (÷100, ÷4, ÷4, ÷2) are all *within* the sub-global fixed
|
||
ladder** (Region→District ÷100, then ÷4/÷4/÷2). None crosses a serving seam —
|
||
Region, District, Quarter, Block, chunk are all sub-global geometry, same
|
||
eviction policy, same derive path, same flat per-cell cost. The ÷100
|
||
Region→District jump is the largest metre factor but it is *pure UX pacing*
|
||
now that it no longer coincides with the cache boundary (which moved up to
|
||
rung 0→1). Option D's gentle bottom factors (largest sub-global jump ÷4, deepest
|
||
transition a barely-perceptible ÷2) are *strictly better* for the between-step
|
||
magnification red flag than any prior option.
|
||
|
||
### Recommendation — Option D (adopted)
|
||
|
||
The Option D table at the top of §(c) is the adopted ladder: **six levels**
|
||
(Global opener + 5 fixed rungs: Region→District→Quarter→Block→Chunk), every fixed
|
||
rung measured, no unmeasured rung, no deepest-step canvas-sizing special case,
|
||
and the gentlest factor profile of any candidate. It inherits everything the old
|
||
Option B earned (measured-not-inferred rows) and removes Option B's one remaining
|
||
awkwardness (the voxel deepest-step special case) for free, as a consequence of
|
||
Jeroen's own
|
||
tile-drop ruling. *(The old A/B/C ranking below is superseded — Option D is what
|
||
the chunk-deepest ruling produces, and it dominates all three.)* **The one call
|
||
left for Jeroen is confirming the six-level shape** (Global opener + 5 fixed
|
||
rungs) — Option D is Dudley's and my joint recommendation, no B-vs-C fork
|
||
survives the tile drop.
|
||
|
||
---
|
||
|
||
## (d) DEPRECATION-SWEEP DRAFT (Expected Output 2)
|
||
|
||
Every DQR record and ticket that conflicts with the decided setup, each with a
|
||
disposition one-liner — **ready for the Clerk consistency audit at wrap-up.**
|
||
The audit's job is to catch conflicts this list *didn't* name; this list is the
|
||
known-conflicts starting set (the governance delta's named items + the round-1
|
||
ticket reconciliations the brief called out).
|
||
|
||
### DQR records — amend / supersede
|
||
|
||
| Record | Disposition |
|
||
|---|---|
|
||
| **D-166 corollary (2026-07-21)** | AMEND — repoint the "continuous field, not fixed display rasters" sentence to per-step (§(a.1)); it now owns between-step magnification as a bounded exception. Not deleted. |
|
||
| **D-226 T-1124 §2 windowed-family ceiling** | AMEND — re-scope "exactly one windowed field" to the legacy `district_window` carrier only; the tagged step-canvas envelope is a new carrier outside the rule (§(a.5)). Purpose preserved, mechanism narrowed. (Re-scope is **final** — Dudley ruled `district_window` survives, envelope carries only new traffic, §(b); the SUPERSEDE branch does not fire.) |
|
||
| **D-226 T-1143 ruling 2** ("no forced tagged-envelope migration") | SUPERSEDE — migration now triggered (§(a.2), §(a.5)). |
|
||
| **D-226 T-1143 ruling 3** (continuous cursor-anchored zoom) | SUPERSEDE for transport (stepped); cursor-centering/edge-scroll/full-reset survive (§(a.2)). |
|
||
| **D-226 T-1143 §6 `select_rung` / `MAX_COVERAGE_M` coverage-walk model** | SUPERSEDE — replaced by the discrete step index (§(a.3)). |
|
||
| **D-226 T-1143 ruling 1** (item-(d) floor opened "toward block/tile") | AMEND / NARROW (interview 2, §(a.8b)) — the opening now lands at **chunk (64 m)**; tile/voxel (1 m) re-closes for the Atlas (Phase-5 in-world content). A deliberate scoping of the BHAG, not a reversal. |
|
||
| **D-243 item (5) vocabulary** | AMEND (additive) — add `gridunit` as a role name for a rung; add the display-ratio-vs-spacing distinction; **the Atlas ladder bottoms at chunk (64 m), tile/voxel not an Atlas rung** (§(a.4), interview 2). No D-243 rung *definitions* change — the metre ladder is intact; only which rungs the *Atlas* uses is narrowed. |
|
||
| **D-225 (2026-06-12 tagged-envelope-deferral constraint)** | SATISFY (note, not supersede) — the deferred constraint is now executed by this workshop's envelope; annotate D-225 that its "next inbound message type must be a tagged envelope" constraint is discharged here (§(a.5)). |
|
||
| **D-226 item (d) whole-body prohibition** | AMEND (Troblum S3 + interview 2) — state the prohibition as a **per-request / per-derivation** constraint, not aggregate-storage; add the per-body deep-rung client-cache retention cap (§(a.8)); and record the floor's partial-restore at chunk (§(a.8b) — the accumulation case is now chunk/block spacing, tile/voxel Atlas-invisible again). The prohibition's *substance* survives; this hardens it and re-narrows its floor. |
|
||
| **D-227 (derive-don't-store)** | AMEND (additive) — (1) the map-time TTL-split + staleness-vs-storage eviction-axes distinction (§(a.6)); (2) the persistent-cache schema/version-tag requirement (§(a.9), Troblum S5); (3) **the seed-chaining "cache-accelerated pure function" model** (§(a.10), interview 2) — a finer step may read a resident coarser canvas as an *optimization* with derive-fresh fallback, staying inside derive-don't-store because the coarser value is itself re-derivable to identical bytes (optimization, not semantic dependency); (4) **the lake sourcing fix** (§(a.11)) — `MorphologyZone::Lake` sourced from `HydrologyResult`'s continuous `filled_scaled` (mechanism B), a derive-pipeline data-source change, **not** a D-239 vocabulary change (the frozen 17-zone set is reused verbatim — see the D-239 note below). All four are additive; derive-don't-store's core is unchanged and, for (3), *reinforced* (the byte-identical-paths determinism test is D-227's own eviction-validity property applied to a fast path). |
|
||
| **D-192 (no client/server version handshake)** | CROSS-REF note (Troblum S5) — annotate that the co-ship "always in sync" guarantee does not extend to the persistent disk cache; the schema/version tag (§(a.9)) is where that boundary is handled. Not a change to D-192's live-wire reasoning, which stands. |
|
||
| **river-courses-t1170.md carrier rule (Ruling 1c)** | AMEND (note) — terminology repoint ("windowed payload" → step-canvas envelope) + add `cliffs` as rule (iii)'s second vector member (§(a.7)). Substance unchanged. |
|
||
|
||
**Records confirmed SURVIVING UNTOUCHED** (state explicitly so the Clerk audit
|
||
doesn't over-rewrite): D-010 (four principles — the server relocation
|
||
*reinforces* principle 4); D-166 cascade + phase gating (still Phase-4 Atlas);
|
||
D-169/D-170 (implant UI — the map component still lives in the implant Atlas
|
||
app, occludes gameplay via HudGroups); D-223 (`atlas_city_names` — Araminta's
|
||
settlement-name lookup rides it unchanged); D-239 (the 17-zone morphology +
|
||
vegetation/glaciation vocabulary — frozen across every step per Araminta's
|
||
one-colorizer-family ruling; **the §(a.11) lake fix explicitly does NOT touch it
|
||
— it reuses the existing `MorphologyZone::Lake` discriminant, changing only its
|
||
data source, and the endorheic cue rides `courses` precisely to avoid an 18th
|
||
zone**). *(D-226 item (d) moved out of this list — it is
|
||
now AMENDED per Troblum S3, above.)*
|
||
|
||
### Tickets — cancel / re-scope / repurpose
|
||
|
||
| Ticket | Current status | Disposition |
|
||
|---|---|---|
|
||
| **T-1176** (design discussion: revise the Atlas map render mechanism) | in_progress | CLOSE as delivered — this workshop *is* its output; the render-architecture D-record + amendments are the deliverable. Mark done at filing, referencing the new D-record. |
|
||
| **T-1158** (decompose `atlas_window_viewer.gd` — canonical-frame + rung-reselection cluster) | backlog | CANCEL with supersession note (Stig's round-1 call, confirmed): the canonical-frame state machine T-1158 wanted to extract is exactly what changes shape under stepped zoom (no continuous zoom floor, no `_canonical_fit_zoom()`); extracting code about to be deleted is waste. The new component's three-piece decomposition (input/pan, step-cross orchestration, two draw layers) is decided fresh in the implementation ticket, not by reviving T-1158. Note: "superseded by body-map-viewer render architecture (D-NNN); decomposition folded into the new component's implementation." |
|
||
| **T-1175** (Atlas map-reading polish — river/nature presentation, single large pass) | backlog | RE-SCOPE + note the styling-engine dependency: T-1175's per-vertex river tapering/width-grammar work lands on the **screen-space annotation layer** (§ Stig round-1) via a Polygon2D-strip mechanism (`draw_polyline` can't taper). **The c1 blocker is now cleared** — measurement ⑥ landed (Stig: `Image.set_pixel` 77.5 ns/cell flat) and the c1 call resolved **CPU-first** (terrain raster colorized CPU-side; shaders deferred, not a ladder precondition). T-1175's tapering is a screen-space-annotation-layer concern independent of the terrain c1 call, so it depends only on **(a) the new annotation layer landing** — the ⑥-gated dependency is discharged. Not cancelled; re-homed onto the new component, unblocked. |
|
||
| **T-1157** (redesign atlas visual-capture goldens for the zoom ladder) | backlog | RE-SCOPE as the new mechanism's verification story: the dead-goldens problem T-1157 targets is a direct consequence of the `AtlasViewer`/orbital-mosaic split that the stepped model *collapses* (global zoom = step 0, not a separate code path — Stig round-1). Re-scope to "capture harness for the stepped render architecture" — goldens key on (body, step) canvases, not the retired continuous-zoom frames. Keep, don't cancel: the capture harness is more needed than ever (it's the eyeball-check substrate for every step canvas). |
|
||
| **T-1174** (batch vs window derive paths sample different world positions for the same DistrictPos) | backlog | KEEP, unchanged in intent — this is a *derivation-correctness* bug (two derive paths disagreeing on the same position) that is **orthogonal to the render pivot** and survives it: the tagged envelope still needs batch and window derive to agree cell-for-cell (it's the same `derive_at_metres` correctness both carriers depend on). If anything the stepped model *raises* its priority (more derive paths sharing the same position math). No supersession; note only that it now blocks the step-canvas serving path too. |
|
||
| **T-1153** (continuous cursor-anchored zoom ladder in the client) | done | Its shipped CODE is superseded (the continuous zoom transport, `_view_zoom` float, progressive cross-rung refinement machinery) — the ticket stays `done` (it delivered what it was scoped for), but its *code* is on the `_canvas.scale` retirement path (below). No ticket action; flag its shipped surfaces in the retirement-path note so the implementation ticket knows what it's replacing. |
|
||
| **T-1152** (derived planetary rung — progressive capped-density tiling; AtlasViewer heightmap texture retires) | done | Its `compute_tile_grid()` whole-body Region-tile mosaic is superseded by the **rung-0 Global canvas** (the body-surface region grid, one gridunit per region — the map opener; there is no beyond-Region mosaic, and Region itself is now rung 1, a viewport-sized fixed rung, not the top). Ticket stays `done`; its mosaic code is on the retirement path. The heightmap-texture retirement it *did* land (the `reliefmap.png` display path) stays retired — that survives the pivot (heightmaps were already demoted to derivation input by the D-166 corollary). |
|
||
| **T-1153/T-1152 test suites** | — | The zoom-ladder goldens and rung-selection tests those two stories shipped are **retired with their code** (they test continuous zoom + coverage-walk selection + the Region-tile mosaic — all superseded). T-1157's re-scoped capture harness (above) is their replacement. Concretely: the `select_rung`/coverage-walk unit tests, the continuous-zoom seam tests, and the `compute_tile_grid` mosaic tests are deleted in the same change that deletes the code they cover; new step-index + step-canvas tests land under the re-scoped T-1157. Do NOT leave the old goldens asserting against retired frames (the T-1157 dead-goldens problem, repeated). |
|
||
| **NEW — lake morphology sourcing** (§(a.11) converged core) | new | CREATE — source the existing `MorphologyZone::Lake` emission from `HydrologyResult`'s continuous `filled_scaled` field (bilinear per-rung sampling, seed-chaining mechanism B), replacing the `ocean_fraction_q >= 60` heightmap heuristic as the authoritative `Lake` trigger with heuristic fallback. Self-contained; no wire change, no vocabulary change. Blocks nothing; consumes T-1177's `HydrologyResult` (currently prototype-only). |
|
||
| **NEW — hydrology basin-outlet → D8 wiring** (§(a.11) endorheic follow-up) | new | CREATE — thread a `HydrologyResult` overflow basin's resolved `outlet_path`/spill point into `RiverNetwork`/`courses` as a D8 downstream continuation (so an overflow lake's outlet edge appears in `courses`, an endorheic basin's absence reads as "no course"). **Pre-cleared additive by T-1170 Ruling 7b** (reserved `TERMINAL` sentinel; `river_course::build_edges` already no-op-safe on `TERMINAL`) — not a wire migration. This is the deliverable the endorheic-vs-overflow distinction ships on: the cue is **outflow-course presence** (§(a.11) FINAL — no bit, no zone), so until this ticket lands the map shows lakes but not the drains-vs-closed distinction. Required regardless (overflow lakes must show exit rivers to be hydrologically honest); the endorheic cue is a side effect of that work. |
|
||
|
||
### The `_canvas.scale` retirement path (explicit, for the implementation ticket)
|
||
|
||
Retired **in the same change** that lands the new two-layer component (Stig
|
||
round-1 §1; sequenced so close inspection is never stranded, the T-1138
|
||
discipline):
|
||
- `_canvas.scale` / `_canvas.position` transform model + `_apply_transform()`
|
||
(continuous scale) — replaced by the step-canvas anchor (a fixed per-step
|
||
texture draw, not a continuous scale node).
|
||
- `_zs()` / `_zs_stroke()` / `_zs_ring_radius()` compensation family in
|
||
`atlas_window_geometry_nature.gd` — deleted wholesale; the unscaled
|
||
screen-space annotation layer makes them structurally impossible to need.
|
||
- `select_rung()` + `MAX_COVERAGE_M` + `compute_tile_grid()` (T-1152/T-1153
|
||
code) — replaced by the step index.
|
||
- The `AtlasViewer`/orbital-mosaic-vs-window two-code-path split — collapses to
|
||
"the Global opener is rung 0" (one viewer, one path; global zoom is the rung-0
|
||
body-surface canvas, not a separate code path).
|
||
- `_view_zoom` float + `_canonical_fit_zoom()` continuous fit — replaced by the
|
||
discrete rung index + the rung-0 (Global) canonical frame.
|
||
|
||
**Surviving client surfaces** (Stig round-1, not on the retirement path):
|
||
`_filter_for_granularity_v2()` (NEAREST/LINEAR per rung still a real RTT
|
||
draw-time question), `atlas_window_tile_set.gd`'s LRU *shape* (right skeleton
|
||
for the new client cache, plus the two-tier eviction), and the
|
||
compositing/legend/overlay-bar chrome (call-site updates only, no structural
|
||
rewrite).
|
||
|
||
---
|
||
|
||
## Summary — 100% COMPLETE, Clerk-audit-ready
|
||
|
||
All governance calls are decided and Jeroen-ratifiable, and every cross-agent
|
||
input is folded in — Dudley's interview-2 response (chunk-64 m display band +
|
||
Option D + seed-chaining confirm + S2/S4) and his corrected global-tier byte
|
||
number (**~8.85 MB PNG all-bodies**), Jeroen's **Global/Region rung-identity
|
||
correction** (below), on top of round 2's Dudley/Araminta/Stig/Troblum inputs.
|
||
**No `[DUDLEY]` brackets and no held clauses remain.** **§(a.11) (lakes) is
|
||
FINAL** — both parts converged on both sides: (1) the **core** — lakes reuse the
|
||
existing `MorphologyZone::Lake` (no new field/zone, a data-source fix) sourced
|
||
from `HydrologyResult`'s continuous `filled_scaled` field sampled bilinearly per
|
||
rung (lake edges *refine* with zoom, not blocky-magnified — seed-chaining
|
||
mechanism B); and (2) the **endorheic-vs-overflow cue = outflow-course
|
||
presence** (Dudley picked Araminta's (i); no wire bit, no 18th zone). Rationale
|
||
recorded: proportionality (4.63% endorheic doesn't justify permanently widening
|
||
the D-239-frozen vocabulary), the outlet-wiring is required regardless (overflow
|
||
lakes must show exit rivers to be honest — the cue is a side effect), and the
|
||
inference is definitionally sound with no misfire (every Overflow basin has a
|
||
non-empty `outlet_path`, every Endorheic none). Honest sequencing stated: until
|
||
the outlet-wiring ticket ships, the map shows lakes but not the drains-vs-closed
|
||
distinction. The stale "4-state water field" crossing is documented (superseded
|
||
by Araminta's withdrawal, Dudley's doc marked SUPERSEDED-BY-CROSSING) — never
|
||
adopted.
|
||
|
||
**Jeroen's rung-identity correction (post-briefing-back) — folded in
|
||
throughout.** Round 2 conflated the map opener's *spacing* with its *rung
|
||
identity*: it called Region "step 0 / the canonical tier." Corrected to **six
|
||
levels**: **rung 0 = Global** (the body-surface map opener — *variable* extent,
|
||
one gridunit per region, the D-243 elastic seam made visible; **this** is the
|
||
canonical always-kept tier), **rung 1 = Region** (the largest *fixed*-size rung,
|
||
viewport-sized and evictable like every rung below it), then District (2),
|
||
Quarter (3), Block (4), Chunk (5). Corrected everywhere: §(a.0) ladder/canvas/
|
||
cache bullets, §(a.1)/§(a.2) full-zoom-out reset (→ Global frame), §(a.4)
|
||
gridunit entry (Global is the one variable-extent level, fixed rungs snap to
|
||
metres), §(a.6) keep-always tier (→ rung 0, not Region), §(a.8) retention floor
|
||
(→ rung 0), §(b) envelope carriers (both Global and Region ride it), §(c) Option
|
||
D table + snap constraints + factor note, and the T-1152 disposition. **The
|
||
correction makes the serving-seam story cleaner:** the global/sub-global cache
|
||
boundary now falls on a real rung edge (rung 0→1, the variable→fixed seam)
|
||
instead of being buried in the ÷100 Region→District metre factor. **Byte-math
|
||
consequence (Dudley, measured):** the always-kept global tier is the tiny
|
||
variable region-grid canvas — **~8.85 MB PNG-encoded across all ~267 bodies**
|
||
(27.61 MB raw; avg ~18K cells/body), not a fixed 4K-class canvas. This supersedes
|
||
the ~174 MB figure (~440× too many cells) and makes the tier **trivially
|
||
process-resident, not merely disk-safe** — "always keep global" gets *easier*
|
||
under the correction. Sub-global (Tier 2) is unchanged: disk + storage-eviction.
|
||
|
||
**Interview-2 reworks are folded in (two changes, two ratifications):**
|
||
- **RATIFIED as-is:** the ceiling re-scope (§(a.5)/§(b), files as drafted) and
|
||
everything in the package not touched by the two reworks below.
|
||
- **REWORK 1 — ladder bottom → chunk (64 m), Option D delivered:** tile/voxel
|
||
dropped (Jeroen: "the actual tile level rung seems unusable, maybe replace
|
||
with 64"). New amendment §(a.8b) records this as a **deliberate interview-2
|
||
narrowing** of his interview-1 floor opening — used to chunk, tile/voxel
|
||
*re-closes* for the Atlas (Phase-5 in-world content). Updated consistently
|
||
across §(a.0), §(a.4) (the "10 px per tile" bottom-out superseded by **"1 px
|
||
per 64 m gridunit, no magnification margin"** — Dudley's chunk bench), §(a.1),
|
||
§(a.8), and §(c). **Option D is the adopted ladder** (six levels: Global opener
|
||
+ 5 fixed rungs Region→District→Quarter→Block→Chunk; every fixed rung measured
|
||
— chunk deepest = 245.8×138.2 km / ~1.7 s parallel). Its bonus: the
|
||
deepest-step canvas-sizing *special case is gone* — chunk uses the plain
|
||
fixed-3840×2160 budget like every fixed rung (a free simplification), and its
|
||
factor profile (÷100/÷4/÷4/÷2, all within the sub-global fixed ladder) is the
|
||
gentlest of any candidate, strictly best for the between-step magnification
|
||
flag.
|
||
- **REWORK 2 — seed-chaining → "cache-accelerated pure function":** Jeroen
|
||
ruled he meant *consuming* the coarser output, not independent re-derivation.
|
||
New amendment §(a.10) reconciles this with D-227 **without weakening it**: the
|
||
definition stays pure (`derive(seed, position)`), the implementation may read
|
||
a resident coarser canvas as an **optimization** with derive-fresh fallback,
|
||
and it stays inside derive-don't-store because the coarser value is itself
|
||
re-derivable to identical bytes (optimization, not semantic dependency —
|
||
proven by a mandatory byte-identical-paths determinism test). Dudley's §(b)
|
||
independent-re-derivation ruling survives as the *fallback path*; the benched
|
||
numbers survive as the **cache-cold worst-case ceiling**, which closes Troblum
|
||
B2. **Dudley-confirmed** (`dudley-interview2-response.md` §2): the model is
|
||
D-227-sound, no chain-reaction on eviction (each rung's fallback is
|
||
self-contained), and his **A/B mechanism distinction** is folded into §(a.10)
|
||
— "consuming coarser output" means reading the coarser **continuous primitive
|
||
baseline** (mechanism B, the shipped district-reads-region pattern) as input
|
||
to a *fresh* classification, **not** reading the coarser *resolved
|
||
classification* (mechanism A, ruled out — it would violate Araminta's
|
||
categorical re-derivation rule). Acceleration magnitude is unquantified but
|
||
not architecture-gating (a future impl-time measurement).
|
||
|
||
**Final and record-ready (§a, §b, §c, §d) — 1 new-record draft (§(a.0)) + twelve
|
||
amendment texts (§(a.1)–§(a.11), including §(a.8b)):** §(a.1) D-166 corollary;
|
||
§(a.2) T-1143 rulings 2/3 supersession; §(a.3) select_rung→step-index; §(a.4)
|
||
D-243 gridunit; §(a.5) D-226 §2 ceiling→envelope; §(a.6) D-227 TTL-split; §(a.7)
|
||
T-1170 carrier + cliff; §(a.8) D-226(d) per-request+cap; §(a.8b) D-226(d)
|
||
floor→chunk (interview 2); §(a.9) D-227/D-192 cache schema-tag; §(a.10)
|
||
seed-chaining (interview 2); §(a.11) lakes — FINAL (morphology-fold +
|
||
`filled_scaled` sourcing + endorheic cue via outflow-course presence, interview
|
||
2). §(a.7) cliff cost is survey-confirmed (0/267 carve).
|
||
§(c) carries the adopted **Option D** ladder (six levels: Global opener + 5 fixed
|
||
rungs, chunk-deepest, every fixed rung measured). Deprecation sweep: **12 DQR
|
||
dispositions** (adds D-226 T-1143-ruling-1 narrow + the D-227 seed-chaining line)
|
||
+ 10 ticket dispositions (adds the two lake tickets — morphology-sourcing +
|
||
basin-outlet D8 wiring) + the `_canvas.scale` retirement path. **No `[DUDLEY]`
|
||
brackets, no held clauses, no open items remain** — the global-tier byte total
|
||
is in (~8.85 MB PNG all-bodies, Dudley measured; supersedes the ~174 MB figure,
|
||
tier now trivially process-resident) and §(a.11)'s endorheic cue is finalized
|
||
(outflow-course presence). **The package is 100% complete and Clerk-audit-ready.**
|
||
|
||
**For Jeroen's final ratification** (governance calls, decided text ready):
|
||
(1) **§(a.10) seed-chaining** against his phrase "serves as seed information for
|
||
the deeper cascade" — the cache-accelerated-pure-function model (mechanism B) is
|
||
the reconciliation of his "consuming coarser output" intent with D-227;
|
||
(2) **Option D's six-level shape** (Global opener + Region→District→Quarter→Block
|
||
→Chunk) — the tile-drop removed the old B-vs-C fork, so this is a single confirm,
|
||
not a choice.
|
||
The migration is the one real chunk of new work; Dudley's code read puts it at
|
||
"doable" (one `Inbound` variant + one `SimBridge` method on a pattern proven five
|
||
times), with the "challenging" part in Stig's client rebuild.
|
||
|
||
*Troblum's adversarial pass is now **fully dispositioned**: B1 (cliff survey)
|
||
resolved 0/267 → §(a.7) survey-confirmed; B2 (seed-chaining) resolved by §(a.10);
|
||
**S2 (deep-step course density) run by Dudley** — a real finding (+38%–87% cost
|
||
at chunk/block vs. District's <5%, traced to course point-count scaling inversely
|
||
with rung spacing; still affordable in absolute terms, flagged as an
|
||
implementation consideration — a possible rung-independent station-spacing cap —
|
||
for the ticket plan; the measurement is filed as the "S2 ADDENDUM" in
|
||
`measurements/t1178-t1154-derive-bench.md`, alongside the chunk-64 m
|
||
"INTERVIEW-2 ADDENDUM" — both already written by Dudley); **S4 (sim-state phase
|
||
cadence) resolved** by a Dudley+Araminta joint formula (`SIM_STATE_TTL` bound to
|
||
1× the field's own driving sim bucket — tidal-or-seasonal for flooded, seasonal
|
||
for glaciation; 1× confirmed cost-affordable). S1 (evict-then-revisit costing)
|
||
remains a Dudley cache-spec tuning number, not a governance-text change — my
|
||
§(a.6) TTL amendment already separates the two eviction axes it probes. S2's
|
||
finding may warrant a one-line note in the §(a.7)/render-record wire discussion
|
||
if course rendering at chunk needs the station-cap; flagging for the Clerk audit.
|
||
Full adversarial-pass disposition is visible for the audit.*
|