Commit Graph
2706 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Fable 5 365b044e79 docs(meta): D-226 wave-1 nature-overlay carrier note (T-1156 — Tyre's ruling)
Rivers/basins/attractors ride the existing whole-body layer1 field —
neither AtlasLayerResponse ceiling touched, no tagged-envelope
migration. Per-rung refinement is client-side class filtering on the
additive river_class (distinct from T-1162's server-side Nyquist
cutoff: a fixed finite graph has nothing to truncate). General rule:
discrete map features ride the whole-body overlay family filtered
client-side; continuous per-metre fields ride the windowed per-cell
arrays — wave 2's roads/settlements inherit this unchanged. Riparian
vegetation response is the named T-1168 forward contract, deferred.

Tickets: T-1156

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 08:04:12 +02:00
jpmschweitzerandClaude Fable 5 825ea9749f chore(meta): close nature-first batch — T-1162/T-1161 done (PR #194 merged, triple review), T-1155 cancelled as superseded
Tyre APPROVE after one fix round (I1 rung-floor dependency direction
implemented as his stronger ask + drift guard; I2 comment cites; I3
governance captures in his exact text; I4 golden body coverage; all
non-blocking follow-ups swept, none parked). Hoshe APPROVE (empirical
revert checks; his one nit refuted with the diff hunk and formally
retracted). Araminta APPROVED the T-1161 acceptance captures. Cold
eyeball re-verified on MERGED main (.cache/screenshots/nature-octaves-
main/): Region NEAREST crisp, Quarter coast crinkle intact, filters
runtime-verified. T-1155 cancelled: superseded by T-1161's two-axes
outcome per Tyre's Q4 ruling.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:39:37 +02:00
jpmschweitzer 153b4113b5 Merge remote-tracking branch 'origin/nature-octaves' 2026-07-22 23:37:30 +02:00
jpmschweitzerandClaude Fable 5 972842c320 style(simulation): cargo fmt — const assert line wrap
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:36:11 +02:00
jpmschweitzerandClaude Fable 5 e5a68f4445 docs(simulation): sweep the last pre-I1 floor-framing comment (Tyre's non-blocking follow-up)
DISTRICT_MIN_WL_M's doc in window_derivation_golden.rs still carried
the 'NOT 2×DISTRICT_M by coincidence alone' framing the I1 fix
inverted everywhere else — now states the rung authors the floor and
the terrain-octave coincidence is guard-pinned, matching the rewritten
MIN_WL_BANDS_M and coast_invention docs.

Tickets: T-1162

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:34:53 +02:00
jpmschweitzerandClaude Fable 5 f50c93b2c8 docs(meta): PR #194 I3 — §8 step 6 erratum + D-226 filter-axis note (T-1161 two-axes supersedes COMPOSITE_SMOOTH retirement)
Tyre's exact capture: the design pass's 'retire COMPOSITE_SMOOTH /
crisp draw_rect as the only path' is superseded — the const survives
as the compile-time pipeline axis, the crisp path stays as debug/
compare, and crispness-at-sparse-rungs is delivered by the per-rung
sampling-filter policy instead. T-1155's retirement framing is
cancelled (ticket closes on merge). Also records the R2 softening:
the T-1162 relief band adds sub-district elevation variance at
Quarter cutoff, so temperature no longer steps strictly at the
district there — intended, noted so nobody is surprised later.

Tickets: T-1161, T-1162

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:31:31 +02:00
jpmschweitzerandClaude Fable 5 3368891976 fix(simulation): PR #194 review round — rung-floor dependency direction, golden body coverage, doc honesty
Tyre's I1 (his ruling: the cutoff's job is Nyquist, a property of the
RUNG): MIN_WL_BANDS_M's District band now derives from 2*DISTRICT_M
directly, decoupled from OCTAVE_WAVELENGTHS_M[3] — a detail_scatter
retune can no longer silently redefine the Atlas rung floor. Direction-
agnostic const assert pins the coincidence so drift on either side
breaks the build for a deliberate human decision; golden_cutoffs_match_
the_scale_ladder now pins the District coupling too. I2: D-226
paraphrase replaced with cites to the T-1150 wire-contract note +
T-1162 refinement resolution (2), plus a self-found stale 2048m claim
fixed in the same comments. I4: golden extended with airless/dry
(ceiling_q==0 short-circuit) and volcanic-coast (ridged warp) body
rows via body_sweep_samples() — fixture regen verified 510 insertions,
0 deletions (existing rows byte-identical, purely appended). Q2 nit:
vegetation_invention module doc now states majority-preservation as
the coherence guarantee, not per-cell class stability (a boundary
cell's flip IS the clearing mechanism). Forward-contract for T-1156:
0x5EED_C0DE promoted to named WINDOW_RELIEF_SALT const. 158 focused
tests green; cargo check --tests clean.

Tickets: T-1162, T-1161

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:31:14 +02:00
jpmschweitzerandClaude Fable 5 918855c878 chore(meta): T-1162/T-1161 to review — PR #194 up (nature-octaves); T-1167 gdlint-debt ticket filed
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:13:04 +02:00
jpmschweitzerandClaude Fable 5 a5b9c28e74 style(simulation): cargo fmt — gate bounce on T-1162 files
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:09:48 +02:00
jpmschweitzerandClaude Fable 5 d33256a8ba test(simulation): regenerate believability golden — deliberate T-1162 output change
The octave extension changes derived window output by design (coast
crinkle below 16384m, voxel relief at Quarter, vegetation moisture
perturbation) — this regen records the sanctioned new baseline per the
ticket's part (d) discipline. The pre-existing BELIEVABILITY_STRICT=1
'vegetation present' advisory failure predates this change (Q-123-
tracked debt) and is unaffected.

Tickets: T-1162

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:56:48 +02:00
jpmschweitzerandClaude Fable 5 5cb63b6867 feat(simulation): T-1162 — invention octaves into the Atlas window path (coast crinkle, quarter relief, vegetation patchiness)
Coast: WARP_OCTAVE_WAVELENGTHS_M 5->9 entries (262144m down to 1024m,
Quarter's Nyquist floor) with new min_wavelength_m cutoff plumbing in
coast_warp_px/warp_fbm (the warp previously had no cutoff at all).
Relief: invent_primitives feeds the VOXEL band (1024-128m, salted) into
elev_q/slope_q under the same envelope/cutoff discipline. Vegetation:
new vegetation_invention module — two-tier (BodyParams+latitude envelope
ceiling; single blended fBm field, never-gated 100-400km massif tier at
70% + cutoff-gated district/voxel texture at 30%) perturbing moisture_q
OUTPUT so precipitation/glaciation/vegetation shift as one world-fact;
wire format unchanged. MIN_WL_BANDS_M 5->6 (adds 1024m band).

Mid-implementation correction caught by tests: District's quantized
floor is 4096m (OCTAVE_WAVELENGTHS_M[3]), not 2x DISTRICT_M — the 8192m
and 4096m coast octaves are legitimately District-admitted enrichment;
only 2048/1024m coast + the voxel band are Quarter-exclusive. Docs and
golden cutoffs corrected to match.

New golden: tests/window_derivation_golden.rs + fixture (derivation_
harness pattern, UPDATE_GOLDEN=1 regen) with structural guards pinning
Quarter/District divergence. Bench (zoom_ladder_bench, release): no
regression — all rungs at or below baseline (District c0 3.54->~3.0
us/cell, Quarter 2.10->1.77, orbital 1.48->1.42, n=6400 window
0.86->0.59 ms). Revert-verified voxel_relief cutoff exclusion. Server
lib 1840 passed; new module 11 tests; district_profile 84 (+6, 1
noise-fragile pre-existing test properly fixed via 8-district
latitude-band averaging).

Tickets: T-1162

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:56:34 +02:00
jpmschweitzerandClaude Fable 5 c9028af77e feat(ui): T-1161 — per-rung composite filter policy (Region NEAREST, District/Quarter LINEAR)
Araminta's ruling (PR #192 follow-up): filter keyed on rung IDENTITY via
the window's own echoed granularity_v2 — Region (incl. the orbital tile
mosaic, whose tiles are all Region-rung requests) samples NEAREST because
GPU bilinear at 204.8 km/cell reads as smoothing-over-absence; District/
Quarter keep LINEAR where cell density earns the blend. One shared helper
(_filter_for_granularity_v2) at both draw call sites; unknown/missing
wire tags fall back to LINEAR (never trusted into NEAREST). COMPOSITE_
SMOOTH survives as the independent compile-time pipeline axis — the
two-axes split is documented in the file header. Washes/border fades
untouched per the ruling. Focused suite 44/44; revert-verified (helper
hardcoded LINEAR -> exactly the three Region-NEAREST tests fail).

Tickets: T-1161

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:36:05 +02:00
jpmschweitzerandClaude Fable 5 ffc24b7312 chore(meta): T-1162 refinement resolutions — bench-baseline-first, window-derivation golden as explicit scope, vegetation invention net-new mirroring coast_invention
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:28:01 +02:00
jpmschweitzerandClaude Fable 5 e41a8dcc8d chore(meta): activate nature-first batch — T-1162 + T-1161 in progress (nature-octaves worktree)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:25:39 +02:00
jpmschweitzerandClaude Fable 5 bbe9099e22 chore(meta): close T-1163 — PR #193 merged (cold-launch starvation fix); review captures T-1164/T-1165/T-1166 filed
Tyre + Hoshe both APPROVE at 8bb09abad (one Hoshe fix round: wrong-body
Pending regression + comment dedupe, both revert-verified independently).
Cold acceptance re-verified on MERGED main: fresh release server, first
connection, Lendel converged mosaic inside 2s, stable while unattended,
legend one-legend-tall (.cache/screenshots/cold-start-main/). Review
tickets: T-1164 tiled terminal-recovery, T-1165 repaint-edge root-cause,
T-1166 scripted cold-launch test tier (both under T-1037 where noted).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 21:30:03 +02:00
jpmschweitzer 6d80936b65 Merge remote-tracking branch 'origin/ladder-cold-start' 2026-07-22 21:22:34 +02:00
jpmschweitzerandClaude Fable 5 8bb09abad0 test(ui): wrong-body Pending must not touch retry state (PR #193 Hoshe finding 1)
Pins on_response()'s guard ordering: body_id check BEFORE the status
branch, so another body's cold Pending can never burn one of our 30
retries or reschedule our timer (multi-body browsing / shared-broadcast
tile fan-out). Revert-verified: reordering the guards makes this test
fail; final own-body Ready assertion proves the request is genuinely
untouched, not just un-retried. 44/44 in the file.

Tickets: T-1163

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 21:15:47 +02:00
jpmschweitzerandClaude Fable 5 4c34327b41 docs(ui): PR #193 review capture — D-226 pending-shape protocol note + stagger comment dedupe
Tyre's APPROVE items (T-1163): record the two-legal-wire-shapes-for-one-
logical-state protocol invariant (whole-response Pending AND Ready+null
district_window both mean 're-poll'; only NotFound/Error are terminal) as
a D-226 note under the T-1124 §4 amendment area, so a future server
refactor of the asymmetry must migrate every consumer in the same change.
Drop the duplicated 5-line stagger comment in atlas_window_tile_set.gd.

Follow-up tickets filed on main: T-1164 (tiled terminal-recovery),
T-1165 (queue_redraw edge root-cause), T-1166 (cold-launch test tier).

Tickets: T-1163

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 21:11:22 +02:00
jpmschweitzer cf1733cdd6 chore(meta): T-1163 — cold-launch starvation bug (ladder-cold-start branch, in review) 2026-07-22 20:59:22 +02:00
jpmschweitzer 3891c83206 fix(client): cold-body Pending responses reach the retry path — the launch-shape starvation root cause
The true cause of the black first launch, server-confirmed after four
disproven theories: a stone-cold body answers the FIRST window request
with a whole-response status 'Pending' (only the whole-body cache-hit
branch sets Ready), and on_response()'s very first check — status !=
Ready -> return — swallowed it before the retry machinery could run.
retries stayed 0 forever; the DERIVING state never resolved. Second
connections worked by luck (the first request warms the whole-body
cache, so they read Ready and take the healthy path). Both tile fan-out
AND single-window first-descents were affected — one shared function,
one fix: branch on the outer status first (the atlas_generation_proxy
reference shape): Pending -> retry, Ready -> existing null-window retry,
NotFound/Error -> give up immediately (the principled give-up policy,
replacing the elapsed-retries ceiling).

Hardening in the same round: deterministic exponential backoff (0.5s
doubling, 4s cap) + per-tile stagger (0.1s * index — six tiles retry at
0.5/0.6/0.7/0.8/0.9/1.0s, strictly-increasing asserted, not jittered);
MAX_RETRIES 20->30 (~110s horizon under backoff).

Regressions are wire-accurate by construction: whole-response Pending
(body_id only, no center/n/granularity — verified against the server's
own response construction) delivered through the REAL fan-out
(tile_set._on_atlas_layers_received, never tile.on_response directly),
mirrored at single-window level. Two first-draft tests that passed with
the bug reverted were caught and strengthened before reporting; every
fix and hardening piece revert-verified independently (7+1 failing
tests without them).
2026-07-22 20:56:46 +02:00
jpmschweitzer ddc4483462 test(simulation): connection-zero district_window delivery regression (bridge_tcp)
Dudley's audit of the suspected ConnectionId(0) starvation: exhaustive
trace of the delivery path (bridge/mod.rs insert/lookup/send paths,
atlas plugin serve/drain, gen_queue coalescing) found NO sentinel or
default-value collision — ConnectionId doesn't even derive Default, and
every id path is a plain monotonic allocation with linear lookup. The
real gap was coverage: every existing window test used ConnectionId(1).

New connection_zero_window_delivery module replicates main.rs's actual
bootstrap (blocking first-accept -> BridgeResource -> accept loop) and
pins: the first-ever connection receives a district window; the exact
six-tile entry shape delivers all six to connection 0; connection 1
keeps working. 5/5 repeated runs, single- and parallel-threaded.

The live 'starvation' itself was client-side (pending responses never
re-requested on the tile path — separate fix in flight); these tests
stay as the server half's permanent pin.
2026-07-22 20:32:09 +02:00
jpmschweitzer dd13760d62 fix(client): cold-start round 2 — DERIVING TERRAIN state, legend re-fit, release server for make atlas
Item 1: while zero tiles have arrived, the viewer draws a centered
screen-space 'DERIVING TERRAIN…' label (text_dim role, no new hue),
dropping the instant the first tile lands — a cold wait now reads as
loading, not broken. New has_any_tile_arrived() predicate (distinct
from has_pending_tiles(): both true mid-arrival, tested exactly there).

Item 2: legend re-fit root-caused empirically, two plausible fixes
disproven by trace before the real one: a manually-positioned Control's
size NEVER tracks a shrinking minimum in this parenting shape, and
RichTextLabel.fit_content reports degenerate minimums until laid out at
real width once — so reset must be DEFERRED and run after refill, not
inside clear(). ImplantPanel.reset_to_content_size() (call_deferred),
wired into both legend refresh()es. The load-bearing test compares
size.y to get_minimum_size().y — a size-to-size comparison passed
trivially with both numbers equally stuck (caught on first draft).

Item 3: make atlas now builds the RELEASE server and passes
SR_SERVER_BIN (a cold DEBUG server delivers zero tiles for >10s on a
new body — live-measured — vs 210ms warm; release serves cold in well
under a second). atlas_standalone._server_binary_path() honors the env
override per the SR_PORT two-tier precedent, debug path unchanged
when unset.

All fixes revert-verified; nine suites green collateral-checked;
gdlint clean.
2026-07-22 19:51:12 +02:00
jpmschweitzer d4526e51ff fix(client): cold-start black screen — self-healing tile repaint, legend re-entry root cause, pending-tile wash
Jeroen hit a black mosaic zooming into a body from a fresh make-atlas
spawn. Live diagnosis showed all six tiles held with colored textures
and no repaint; the original line-specific diagnosis (unpaired
queue_redraw in _on_tile_ready) turned out WRONG — the pairing already
existed (lead's truncated grep misread the function; Stig verified via
git log -p before acting). Rather than chase the exact dropped signal
edge, _process() now self-heals: both viewer and overlay redraw every
frame while the tile set has pending tiles (has_pending_tiles(), new) —
a strict superset that closes the black regardless of which edge drops,
pinned by a _draw()-counting real-subclass spy test.

Legend stacking root cause found by trace, not guess: ImplantApp.
_on_screen_changed() re-runs enter() unconditionally on repeat
same-screen pushes — each re-entry tore down and rebuilt all six tile
requests (the round-6 orphaning fingerprint via a new trigger) and
stacked another legend (~10 deep, full-height dark panel). Fixed both
ends: ImplantPanel.clear() frees immediately (same-frame re-entrant
refresh can never observe stale children — protects every implant app),
and RegionalScreen.enter() no-ops for the same body (different body
still re-enters fresh). The load-bearing regression asserts an ARRIVED
TILE'S DATA survives a repeat push — node identity would not catch the
teardown (the tile-set Node is a fixed field; only its internals reset).

Cold-start UX: pending tiles now draw the single-window path's
COLOR_BORDER_FADE wash instead of raw background — a deriving mosaic
reads as loading, not broken.

Suites green (zoom_ladder 48, viewer 74, tile_set 20, overlay 30,
overlays 46 + 2 new files), gdlint clean, revert-verified throughout.
2026-07-22 19:05:15 +02:00
jpmschweitzer 74662470c6 chore(meta): nature-layer scope ruling — T-1162 gains vegetation patchiness, T-1156 split into nature-first waves (cities uncolored for now, per Jeroen + D-166 outside-in) 2026-07-22 18:33:11 +02:00
jpmschweitzer 0a69710ca5 chore(meta): T-1162 — extend invention octaves into the window path (Jeroen's flatness/coastline feedback; content floor 4km/16km vs 512m transport) 2026-07-22 18:30:52 +02:00
jpmschweitzer 41017166aa chore(meta): zoom ladder shipped — T-1152/T-1153 closed (PR #192 merged, triple review, six live rounds, eight integration bugs pinned) 2026-07-22 17:40:55 +02:00
jpmschweitzer 919660c5ae Merge remote-tracking branch 'origin/zoom-ladder-continuous' 2026-07-22 17:40:20 +02:00
jpmschweitzer da15261276 fix(client): PR #192 review round — per-rung legend, Region coalescing + clamp boundary tests, halving-loop honesty
All Hoshe/Araminta findings addressed (Tyre approved outright), none
retracted — plus a Dudley stop-and-flag discovery that improved on the
asked-for fix:

- Legend 100x lie (Araminta, blocking): subtitle computed via
  spacing_for_rung() and refreshed at all three _held_granularity_v2
  write sites. Region test asserts 204.800 km/cell; the District
  direction needed a stale-header-aware helper — a District-only test
  spuriously passes against the old literal by coincidence.
- Region coalescing coverage (Hoshe 1): both directions tested
  (Region-vs-District separate slots; Region-vs-Region coalesces).
- Clamp boundary tests + dangling citations (Hoshe 2): writing the
  requested halving-loop-fires test surfaced that the loop is PROVABLY
  UNREACHABLE at current constants (per-axis clamp forecloses it —
  brute-forced independently on both server and client sides). Ruling:
  the loop stays as defensive code; the test became a property sweep
  pinning both the wire-cap invariant and the loop's no-op status (a
  future constant change breaks it loudly); doc comments on both sides
  drop the load-bearing framing and state the truth; the old client
  mirror test that claimed the loop fires (passing on the per-axis
  clamp alone) is replaced the same way. Client citations now name the
  real server tests verbatim.
- Governance (Tyre): D-226 amendment note — progressive cross-rung
  refinement EXTENDS T-1124 §4 (not supersedes); legacy u32 field
  scheduled for retirement (T-1159).

Server: 1818 lib tests green, clippy/fmt clean. Client: zoom_ladder
48/48, window_request 26/26, viewer 74/74; gdlint clean. Every fix
revert-verified.
2026-07-22 17:24:07 +02:00
jpmschweitzer 15f0b6936d chore(meta): PR #192 review follow-ups — T-1158 (viewer decomposition), T-1159 (legacy u32 retirement), T-1160 (orbital coastline audit), T-1161 (per-rung filter policy) 2026-07-22 17:05:18 +02:00
jpmschweitzer ab41ea07f9 chore(meta): T-1152/T-1153 to review — PR #192 up (zoom ladder); T-1157 smoke-scenario migration note (Stig) 2026-07-22 16:51:06 +02:00
jpmschweitzer 8517cae66f fix(client): draw smoke — guarded early-return instead of fuzzer-arg skip (gdUnit leaks one internal Node per skipped test, exit 101 bounced the gate at 0 failures) 2026-07-22 16:48:21 +02:00
jpmschweitzer 8414b0fd18 fix(client): T-1153 round 6 — zoom floor at the canonical frame; reset guard purely edge-triggered
The round-5 per-tick zoom comparison inside the reset guard was level-
triggered: at the canonical frame every continued zoom-out tick drifted
_view_zoom a hair below fit, read as 'not there', and re-fired
enter_orbital — tile set torn down/recreated per tick, in-flight
responses orphaned (black entry), server flooded (889 of 897 responses
in one drive phase). The drift concern now lives in _zoom_at as a ZOOM
FLOOR (once at the canonical frame, zoom-out clamps at fit); the guard
keys only on fields that never drift (_held_center/_held_granularity_v2/
_tile_mode) — genuinely edge-triggered. Three shared helpers keep the
guard and the floor on one definition of 'canonical frame'.

Anti-storm regression drives 100 real _zoom_at ticks past the first
reset and asserts tile-set child node identities never change; the
black-entry repro interleaves Lendel's six wire-accurate tile responses
with continued ticks and asserts all six held. Both revert-verified with
the exact live symptoms. Round-5 reset tests pass unchanged. Live-
verified twice: exactly 6 requests at entry and at reset, no storm.
2026-07-22 16:21:31 +02:00
jpmschweitzer ccedba4f24 fix(client): T-1153/T-1152 round 5 — nearest-wrap-image tile draw placement; canonical reset restores the fit zoom and re-fires
The wrapped tile column (Lendel: -6400 canonicalized to 12739) drew at
its canonical column — off-canvas right — leaving the mosaic's left
third black. nearest_wrap_image() re-expresses a tile column as the
wrap-image closest to held_center for DRAWING only (requests/cache keys
stay canonical). The draw-position test asserts overlap FRACTION, not
bare intersects() — the buggy placement still clipped ~2px of viewport
edge at Lendel scale, so intersects() alone would false-pass.

The full-zoom-out reset restored center but not the fit zoom, and its
'already there' guard keyed on a lagging field so it could only ever
fire once. The guard now also matches tile mode and compares _view_zoom
against the freshly computed fit — restoring the FULL canonical
transform (center, offset, fit zoom) and re-firing as a continued
gesture keeps zooming out (Jeroen's hard condition, both live shapes).

+8 revert-verified tests incl. the continued-gesture reset repro; smoke
stub gained get_body_radius_km (crash confirmed real under a real
driver before fixing). Suites 286 green; gdlint clean.
2026-07-22 15:32:04 +02:00
jpmschweitzer 493a7345d3 fix(client): T-1153/T-1152 round 4 — mosaic canvas-local frame, offset recompute on rung crossing, tile texture RID lifetime; real-driver draw smoke
Three live-found rendering bugs, all invisible to green unit suites:
- _draw_tile_mosaic placed tiles from absolute district (0,0); canvas-
  local (0,0) is held_center - held_n/2 everywhere else, and tile-mode
  held_n is the whole-body extent — the entire mosaic drew tens of
  thousands of px off-canvas. New pure district_to_canvas_local() +
  viewer accessors route every tile through the shared frame.
- _maybe_reselect_rung updated held_n across crossings without
  recomputing _view_offset — the single-window composite landed off-
  canvas the moment any crossing happened (why District/Quarter were
  black too). New pure recompute_offset_for_held_n_change().
- _build_tile_texture created an unstored ImageTexture per _draw,
  racing the RenderingServer's deferred upload — CPU pixels correct,
  screen white. Per-tile-index texture cache, same reference-identity
  discipline as the single-window _cached_texture.

Structural close of the twice-bitten 'nothing asserts pixels' gap:
test_atlas_window_overlay_draw_smoke.gd renders overlay output into a
SubViewport and asserts visible pixels for both modes — runs under a
real driver (invocation documented in DEVOPS.md, visual_capture
precedent; migration to the T-1157 harness noted on that ticket), skips
loud-but-green under the gate's headless run (verified green-with-skips
AND genuinely red with detection forced off). +7 geometry/crossing
tests, all revert-verified. Targeted suites 270 green; gdlint clean.
2026-07-22 14:41:00 +02:00
jpmschweitzer 9ffda88e57 docs(docs): §5 erratum superseded — unified coverage-ceiling rung model + tile mode as merged (T-1153 round 3) 2026-07-22 13:04:07 +02:00
jpmschweitzer 6195fd28b3 fix(client): T-1153/T-1152 round 3 — unified rung coverage model, reselect clamp mirror, orbital tile-set mosaic
Bug A (zoom reselection dead): select_rung() redesigned from the two-gate
split to a unified per-rung coverage-ceiling walk (MAX_COVERAGE_M,
finest-first) — which also restores District as a reachable rung
(33-131km extent band; the two-gate model had made it structurally
unreachable). Plus the THIRD instance of the PR #191 C1 clamp-mirror bug
class: _maybe_reselect_rung fed the old rung's _held_n raw into the new
rung's request — the server clamped, the held value didn't, every
cross-rung response stale-dropped. Re-clamped at the boundary; the
leaving_tile_mode flag also fixes a stale request-granularity edge case.

Bug B (orbital = whole body): genuine tile-set model. compute_tile_grid
composes ceil-divided Region-tile centers (canonicalized column wrap,
row clamp, Dictionary-set dedup; Lendel = 3x2 = 6 tiles);
AtlasWindowTileSet owns one AtlasWindowRequest per tile (reusing all
tested request/cache/debounce machinery), fans responses out, per-tile
tile_ready — genuinely progressive; the overlay draws arrived tiles as a
mosaic under the one view transform. enter_orbital branches to tile mode
when >1 tile; single-window path unchanged below the coverage ceiling.
E/W wrap at tile seams live-confirmed (col -6400 wraps to 12739). Pole-
row dedup verified correct but flagged honestly as currently-unreachable
defensive logic (no real radius triggers row collision).

All fixes + fallout verified via revert/confirm-fails/restore. Targeted
suites 256/256; gdlint clean; new 20-test tile-set suite.
2026-07-22 13:03:38 +02:00
jpmschweitzer 11f7927f24 fix(client): T-1153 — v2 granularity is authoritative in the staleness guard; legacy compared only when v2 absent
Second live-round blocker: the T-1150 legacy granularity comparison
stayed armed alongside the v2 check, and the server ALWAYS sends the
u32::MAX Region sentinel in the legacy slot — which can never equal the
client's pinned legacy value, so every Region response was stale-dropped
after the v2 check passed. _echoed_granularity_matches() now branches on
PRESENCE of granularity_v2: present -> v2 is the only comparison; absent
(old server) -> legacy fallback.

Mock-fleet audit while fixing: three tests had responses diverging from
the real wire — the oversized-orbital round-trip omitted the legacy
sentinel (passed for the wrong reason), the Region-accept test used
legacy=1, and the mismatch-drop test left v2 at a masking default that
would have inverted under the new rule. All wire-accurate now with a
named SERVER_LEGACY_GRANULARITY_REGION_SENTINEL const; +2 tests (legacy-
only old-server acceptance; v2-wins-regardless-of-legacy precedence
proof). All three verified to fail against the reverted fix. Full suite
3524/3524.
2026-07-22 12:07:33 +02:00
jpmschweitzer 1c87b6a712 fix(client): T-1153 — clamp _held_n at the viewer's single write site (live eyeball round blocker)
The live round against a real server caught what 3518 unit tests missed:
enter_orbital stored the UNCLAMPED n (Lendel: 19139 raw circumference
cols) into _held_n while AtlasWindowRequest clamped independently to
6400 before sending — every orbital response on a real-sized body was
dropped by the viewer's own w_n != _held_n staleness check. Permanently
blank ladder. The PR #191 C1 clamp-mirror lesson, one layer up: the
mirror must apply wherever held/expected state is recorded, not only at
the request layer.

_enter_at_rung now clamps via _clamp_window_n_mirror_v2 before storing
(the file's only _held_n write site — reselect/refloat read and forward).
Regression closes the coverage hole: the oversized-orbital RESPONSE
round-trip (enter_orbital on GJ380c -> deliver echo n=6400 Region ->
assert accepted). Both new tests verified to fail against the reverted
fix before trusting green. Full suite 3520/3520.
2026-07-22 11:54:06 +02:00
jpmschweitzer 5aa3a84263 chore(meta): T-1156 (overlay port onto the ladder) + T-1157 (capture-harness redesign) — T-1153 deferral follow-ups 2026-07-22 11:42:59 +02:00
jpmschweitzer 55a2909386 docs(docs): §5 erratum — rung-selection rule's literal form has no District band; two-gate split as implemented (T-1153) 2026-07-22 11:42:22 +02:00
jpmschweitzer ce90d69ae8 feat(client): T-1153 + T-1152 client half — continuous cursor-anchored zoom ladder, Region-rung orbital entry, click-through retired
The atlas 'regional' screen now opens the LADDER at the canonical orbital
frame (Region granularity, whole body fitted and centered) and wheel zoom
descends continuously — cursor-anchored, unclamped across rungs, with
progressive refinement (held composite keeps drawing, finer rung swaps in
place on arrival; no blank frame, no mode flip). Full-zoom-out resets to
the canonical planetary frame per Jeroen's HARD condition
(is_fully_zoomed_out = extent >= body circumference, not a zoom-value
heuristic). The district_screen nav hop is deleted — D-013 restored:
descent is a zoom gesture, not a nav push. AtlasViewer's heightmap-texture
path is unreachable from nav (code intact; overlay surface deferred, see
report/tickets).

Rung selection: design doc §5's literal formula has NO legal District band
at any real viewport (visual-tolerance band and n=64 coverage ceiling
never overlap — pinned by executable boundary tests at 1600x900);
select_rung() splits it into a coverage ceiling (decides Region) then the
2x visual tolerance (District vs Quarter), documented at the function.
In practice the ladder steps Region -> Quarter directly.

Wire: window_granularity_v2 encoded (omitted at District for byte-compat),
granularity_v2 echoed value keyed + staleness-guarded end to end; Region
clamp mirror replicates the server's bounded halving loop (no closed
form). MIN/MAX_ZOOM widened to [0.0005, 64] — the old 0.5 floor would
have clamped a real body's canonical fit zoom, violating the reset
condition.

Real pre-existing bug fixed in atlas_window_overlay.gd: the draw path used
echoed n as both cell-grid dimension and district extent — only
coincidentally correct at District granularity; Quarter/Region would have
read wrong array offsets. cell_grid_side_for_window() now mirrors the
server's WindowGranularity::cell_grid_side.

Tests: +26 pure-function geometry tests, new 30-test zoom-ladder suite,
extensions across the window cache/request/overlay/delivery suites.
Full suite 3518 green; cold-parse clean.
2026-07-22 11:41:37 +02:00
jpmschweitzer d356b09926 feat(simulation): T-1152 server half — WindowGranularity enum, derive_orbital_at_metres, Region rung on the same carrier
R1 measured first: a capped Region tile through the real production path
(build_district_window_layer + T-1151 par_iter) at the 64x64 wire cap
costs 0.40-0.48ms — faster than the shipped district n=64 window, so
Jeroen's progressive capped-density tiling ruling is comfortably
interactive on-demand. Raw orbital derive ~0.9µs/cell (~2.3x faster than
full derive; region_baseline dominates, not invent_primitives).

R5 redesign: WindowGranularity enum (Quarter/District/Region), serde
named-variant per the RoadNodeKind precedent, spacing from D-243 scale::
constants — the single source of truth. Additive serde-default
window_granularity_v2 request field (None = legacy u32 path; v2 wins when
Some); DistrictWindowLayer.granularity_v2 always echoed. Legacy u32 echo
for Region uses reserved WINDOW_GRANULARITY_REGION_KEY = u32::MAX (never
a legal input) so the old slot cannot lie about aliasing. Cache and
coalescing keys carry the enum itself (Ord by declaration order, D-010).

n stays district-extent at every rung; Region's cell grid is a DIVISION
(round(n/100), min 1) with its own per-axis ceiling
DISTRICT_WINDOW_MAX_N_REGION=6400 and a bounded halving-loop clamp (no
closed form under the rounding division — the client mirror must
replicate the loop).

derive_orbital_at_metres: bilinear envelope reads + region_baseline
temperature, NO invent_primitives (proven by test — slope_q pinned 0),
routed through the shared build_district_profile classification tail so
the existing colorizer family renders orbital cells unchanged. R2
stepped-categorical behavior documented at the function, not implied.

Region aliasing + clamp/echo tests mirror the T-1150 discipline. 1813
lib tests green; clippy clean; fixture regenerated (254->278 bytes, new
echoed field).
2026-07-22 10:35:37 +02:00
jpmschweitzer 2a4597e108 chore(meta): activate zoom-ladder-continuous batch — T-1152/T-1153 in_progress 2026-07-22 10:01:06 +02:00
jpmschweitzer 896c923d35 chore(meta): zoom-ladder foundations done — T-1149/T-1150/T-1151 closed (PR #191 merged, double review + fix round); T-1152/T-1153/T-1154 now unblocked 2026-07-22 00:54:42 +02:00
jpmschweitzer d02754f6cc Merge remote-tracking branch 'origin/zoom-ladder-foundations' 2026-07-22 00:54:14 +02:00
jpmschweitzer 1ce4085901 style(simulation): cargo fmt on the fix round + governance amendment typo (Hoshe nit) 2026-07-22 00:51:22 +02:00
jpmschweitzer 0159a63cc2 fix(simulation): PR #191 review round — n-clamp mirror, min_wl band quantization, coalescing coverage, fixture consumer
All seven Hoshe/Tyre findings addressed, none retracted:
- n-clamp/echo/staleness triangle (Tyre C1): client _clamp_window_n_mirror
  (bit-for-bit twin of the server clamp, canonicalize_district_center
  precedent) applied before _n is stored/sent; server test pins the
  quarter n=32 -> echo 16 contract.
- min_wl band quantization (Hoshe 1/Tyre C3): quantize_min_wl_m snaps to
  MIN_WL_BANDS_M {0, 32768, 16384, 8192, 4096} before cache key and echo
  (design doc §5's unbounded-key fix), reusing the one true
  OCTAVE_WAVELENGTHS_M array; docstrings now state the server-quantizes/
  client-sends-raw split; same-band cache-sharing test.
- coalescing granularity axis (Hoshe 2): two tests pin different-
  granularity requests as separate in-flight slots and same-granularity
  coalescing unchanged.
- orphaned fixture (Hoshe 3): test_protocol.gd consumer decodes
  atlas_response_ready_with_window.msgpack through the real IPC path and
  asserts the new fields.
- atlas_window_request coverage (Hoshe 4): new test file — stale-drop on
  granularity mismatch, old-server-shape defaults accepted, clamp mirror
  formula + wiring. First draft's quarter-via-request_now test would have
  passed for the wrong reason (request_now resets granularity by design
  until T-1153) — split into formula pin + reachable-path wiring proof.
- granularity type seam (Tyre C2): field + resolver docstrings state
  finer-only integer multiples with resolve_window_granularity as the
  single widening point; matching contract note added to the D-226
  T-1143-rulings amendment.

cargo --lib 1807/1807; goldens bit-identical; gdlint clean.
2026-07-22 00:47:53 +02:00
jpmschweitzer fdd529f576 chore(meta): T-1149/T-1150/T-1151 to review — PR #191 up (zoom-ladder foundations) 2026-07-22 00:28:55 +02:00
jpmschweitzer 3e87fd5b4f feat(simulation): T-1151 window par_iter + T-1150 granularity carrier (five touch points + aliasing tests)
T-1151: build_district_window_layer dispatches one Rayon task per row
(pure derive_window_cell via derive_at_metres), scattered row-major into
the flat arrays; a cfg(test) serial path backs the bit-identical
parallel-vs-serial golden.

T-1150: serde-default window_granularity (1=district, 4=quarter) +
window_min_wl_m on AtlasLayerRequest — additive, no sixth demux shape,
old frames decode unchanged (tested). Quarter mode = full
reclassification at 512m spacing over the same world rect ((4n)x(4n)
cells); WIRE_CAP_CELLS=4096 enforces n*granularity <= cap (quarter
clamps n to 16, the design doc's worked example). Granularity + min_wl
key ALL five touch points: DistrictWindowLayer echo, server FIFO-256
cache key (now a 5-tuple), per-connection coalescing key, client
request codec (omitted-at-default wire fields), client LRU key.

Mandatory aliasing regressions on both ends: identical (body, center, n)
at granularity 1 vs 4 produce distinct cache entries and correct
per-granularity payload shapes (server, 3-thread queue to avoid the
AnalyzeBody thread contention found while writing it) and distinct
client cache keys (gdUnit). Replay fixture regenerated — the layer
struct grew two echoed fields (231->254 bytes, content verified).

Client requests stay district-granularity by default — quarter requests
arrive with T-1153's rung selection.
2026-07-22 00:27:40 +02:00
jpmschweitzer afff859a2c feat(simulation): T-1149 derive_at_metres extraction + min_wavelength octave cutoff
Extract derive_district's fractional-metres interior into the metres-
addressable derive_at_metres(seed, body, params, ta, wx, wy, climate,
min_wavelength_m) — the zoom ladder's keystone (design doc §8 step 1).
derive_district is now a thin DistrictPos-quantizing wrapper calling it
with cutoff 0.0; all four golden/believability/derivation harnesses pass
byte-identical.

enveloped_fbm/terrain_detail/voxel_relief gain min_wavelength_m: octaves
below the cutoff are hard-truncated (amp still advances so surviving
octaves keep relative weight; norm==0 guarded). Amplitude-fade-near-
cutoff is documented as a seam, not built — the pop-risk A/B needs the
client ladder (T-1153). Cutoff 0.0 is bit-identical to pre-change
output, asserted by test.

Measured (release, 4096-cell sweeps, zoom_ladder_bench.rs): district
spacing 1.200µs/cell (cutoff 0) / 1.201µs (cutoff 2048m — all octaves
survive, plumbing check); quarter spacing 1.165µs/cell (cutoff 512m).
Matches the design doc's ~1.2-1.4µs/cell release estimate.
2026-07-22 00:27:21 +02:00