docs(meta): D-258 amendment — the hydrology rationale was false

Written one day after the record, on evidence, and it narrows D-258's scope.

The Rationale claimed hydrology 'was not derivable at all under the old
model'. Not true, and not true when written: layer1.rs already solves drainage
AND settled-equilibrium hydrology once per body, folds the filled surface into
TerrainAnalysis, and every rung bilinearly samples it. The code's own comment
names it — 'a coarse continuous primitive computed once, sampled fresh at
every rung, never re-solved', mechanism B, D-255(f). The pattern rung 0.5 was
invented to provide already existed. I inferred the claim from Region having
no rivers without reading the layer-1 pipeline.

What actually made Global flat was a stale sentinel zeroing its extent, giving
a 2x1 canvas. Once sized correctly Global reads as a world with no hydrology
work at all. Rivers there measured negligible: 375 courses present, 458 of
518,400 pixels changed versus courses-off, because at ~39.7 km/gridunit most
courses are shorter than one gridunit.

Survives: reliefmap-as-plurality, composition-on-descent, the conservation
invariant, and the lake-shore amendment — none depend on hydrology moving.
Weakened: the stored expanded layer and its D-227 carve-out, since the
compute-once-sample-everywhere mechanism it argued for is already shipped.

T-1211 and T-1212 flagged needs-refinement with the reasoning attached; the
measurement as scoped would have priced work that is not required.

The amendment also records why this survived review: the sizing fix's tests
called resolve_canvas_extent directly rather than the serve path, and the
capture goldens could not have caught it either since they never supplied a
body radius. Two verification layers, both green, neither looking at the thing.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-27 20:53:08 +02:00
co-authored by Claude
parent e024cfb3f9
commit dc1c8ca900
+14
View File
@@ -2379,6 +2379,20 @@ Technical foundation decisions that constrain implementation: engine, client-ser
- **Cross-reference:** [D-255](#d-255) (stepped Atlas ladder — this amends its per-rung derivation model, not its rung set or its texel-exactness), [D-243](#d-243) (scale ladder; the climate edge-fuzz rule this extends to biome), [D-227](#d-227) (derive-don't-store — named carve-out above), [D-256](#d-256) (one absolute-metre derive core, which rung 0.5 becomes the input to), [D-202](#d-202) (per-body elevation assets — `import_heightmaps.py` produces both rung-0 files), [D-166](content.md#d-166) (generation before player: a walkable world needs coherent water).
- **Dissent:** None.
- **Amendment (2026-07-27 — THE HYDROLOGY RATIONALE ABOVE IS FALSE; the record's scope narrows accordingly):** Written one day after the record, on evidence. **Do not implement the stored-layer half of this record without re-reading this amendment.**
**(1) The "structural" rationale was wrong.** The Rationale above claims *"hydrology was not derivable at all under the old model … flow is a global solve, so no per-window derivation could produce a coherent water system."* That is not true and was not true when written. `layer1.rs::run_layer1_with_moisture` already solves drainage **and** settled-equilibrium hydrology (`hydrology_equilibrium::solve` — basin fill, overflow re-routing, endorheic classification, gorge carving) **once per body**, folds the continuous filled surface into `TerrainAnalysis`, and every derive-core caller bilinearly samples it. That code's own comment names it: *"a coarse continuous primitive computed once, sampled fresh at every rung, never re-solved"***mechanism B, [D-255](#d-255)(f)**. Compute-once-sample-everywhere, the pattern rung 0.5 was invented to provide, already existed. The claim was inferred from Region having no rivers, without reading the layer-1 pipeline.
**(2) What actually made Global look flat: a stale sentinel, not missing physics.** `serve_step_canvas_request` zeroed Global's wire extent — correct while Global's canvas came from the body's region grid, silently outliving the D-255 extent inversion that made it viewport-sized. Every Global request therefore arrived downstream as `(0,0)`, clamped to `(1,1)`, and resolved to a **2×1 canvas**: the two coloured blocks. Two further places carried the same dead premise (the server's always-keep tier keyed on body id alone; the client's `make_key` collapsing Global's extent), so the first canvas ever built answered every later request and a resize could never take effect. Fixed 2026-07-27. **Once sized correctly, Global reads as a world — continents, oceans, inland lakes, polar ice — with no hydrology work whatsoever.**
**(3) Rivers at Global are measurably negligible.** Both course-suppression gates were disabled experimentally: Global carried **375 courses**, and a pixel diff against courses-off differed in **458 of 518,400 pixels**. At ~39.7 km per gridunit most courses are shorter than a single gridunit and collapse to nothing. Enabling them is not what Global needed. Reverted.
**(4) What survives, and what does not.** **Survives:** the reliefmap-as-plurality reading, sub-biome composition emerging on descent, the conservation invariant, and the 2026-07-26 lake-shore amendment (one shore path, tidal energy over salinity) — none of which depend on hydrology moving. **Materially weakened:** the *stored* expanded layer and its named [D-227](#d-227) carve-out. The carve-out was justified by "a whole-body flow solve is not locally computable, therefore storage buys correctness" — true in itself, but that solve already happens once per body and is already sampled everywhere, so it is not an argument for a *new* stored layer.
**(5) Consequence for implementation.** [T-1211](../../.pql) must be **re-scoped before any child starts**, and [T-1212](../../.pql) (the cost measurement gating it) was scoped to measure moving a hydrology solve that does not need to move. The live question is no longer "what does rung 0.5 cost" but "does biome un-summarisation need a stored layer at all, or does it ride the existing sample-fresh-at-every-rung mechanism like hydrology already does."
**Process note, recorded because it is the reusable lesson:** the false claim survived review because the regression tests for the sizing fix called `resolve_canvas_extent` directly instead of exercising the serve path — the function that was changed, not the path the data takes. The Atlas capture goldens could not have caught it either: the scenarios never supplied `body_radius_km`, Global's only spacing input, so every Global golden had been a degenerate block since creation. Two verification layers, both green, neither looking at the thing.
---
### D-259: Enclosed settlements — open-air requires a breathable atmosphere