From 02fe71e9f3033395e21e08ca0bd76ed8cb511e85 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sun, 26 Jul 2026 23:38:18 +0200 Subject: [PATCH] =?UTF-8?q?docs(meta):=20D-258=20amendment=20=E2=80=94=20o?= =?UTF-8?q?ne=20shore,=20not=20two;=20tidal=20energy=20over=20salinity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jeroen, eyeballing the lakes: "they did not seem to run the same coastline code as ocean does". Correct, in two separate ways. The coastline warp was ocean-only. invent_primitives displaces the sample through coast_warp_px before reading the ocean mask, but the lake test read the UNWARPED position, so ocean coasts got invented bays and capes while lake shores traced the bare elevation contour. It cannot be fixed by warping the lake sample alone: a lake is where a filled surface sits above terrain, two reads that must agree, so moving one and not the other puts water on hillsides or holes inside lakes. Both surfaces move together in the rung-0.5 pass, or neither does. And shore morphology was structurally unreachable at a lake edge. Every gate keyed on ocean_fraction_q, which is always 0 in a lake basin because lakes sit above sea level. Ruled: lakes get full shore morphology — cliffs, beaches, deltas. Gates key on proximity to water, not to ocean. No new vocabulary needed; MorphologyZone already carries Fjord, Delta, Wetland, CliffCoast and DuneStrand. The interesting part is what separates the sea-flavoured types, because it isn't salinity. A delta builds land outward where the river deposits faster than the water removes; an estuary is the inverse, a drowned valley widening seaward. The discriminator is tidal energy: the microtidal Mediterranean is ringed with deltas (Nile, Rhone, Po) despite being salt, while the macrotidal Atlantic gives estuaries (Thames, Severn, Gironde). So lakes always resolve to Delta — and so does a tideless sea, which an ocean-vs-lake switch would have got wrong. Tidal energy governs TidalFlat too, so one derived quantity replaces two stipulations and no "is it the ocean" branch survives. Salinity is a property of water, not a landform, and is excluded from morphology entirely. Derive it from below-sea-level connectivity if gameplay ever needs it. Parked. Pair session with Jeroen, 2026-07-26. Co-Authored-By: Claude --- governance/decisions/architecture.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/governance/decisions/architecture.md b/governance/decisions/architecture.md index 70fcb11d2..a98c2740d 100644 --- a/governance/decisions/architecture.md +++ b/governance/decisions/architecture.md @@ -2345,6 +2345,18 @@ Technical foundation decisions that constrain implementation: engine, client-ser 2. **Descending the ladder reveals composition, not sharpness.** A cell reading "forest" globally contains clearings, marsh, rock and scrub — biomes the vote suppressed. Those minorities emerge deterministically as the ladder descends. Detail is a distribution resolving into its parts, never the same picture at higher resolution. 3. **Invented detail must be conservative — the binding invariant.** Downsampling rung 0.5 must reproduce the rung-0 summary it came from: a forest cell may gain marsh pockets, but it must still read as forest from orbit. Detail may add variety; it may never change the summary. This is the test that keeps (1) and (2) honest, and it is the acceptance gate for any sub-biome invention algorithm. + **Amendment (2026-07-26, same session): one shore, not two.** Lake shorelines run the **same** code as ocean shorelines. Jeroen, on eyeballing the lakes: *"they did not seem to run the same coastline code as ocean does"* — correct, in two distinct ways, both of which rung 0.5 closes: + + - **The coastline warp was applied to oceans only.** `invent_primitives` displaces the sample position through `coast_warp_px` (inventing bays and capes) before reading the ocean mask, but the lake test read the **unwarped** position (`district_profile.rs`, `lake_from_hydrology_at(ta, px, py)`). Ocean coasts therefore got invented irregularity while lake shores traced the bare elevation contour — visibly "computed" next to a made-looking sea. It cannot be repaired in place by warping the lake sample alone: a lake exists where a filled water surface sits above terrain, two reads that must agree, so displacing one and not the other yields water on hillsides or holes inside lakes. **Both surfaces move together, in the single rung-0.5 pass, or neither does.** + - **Shore morphology becomes water-body-general.** Every morphology gate was keyed on `ocean_fraction_q`, which is structurally `0` inside a lake basin (lakes sit above sea level, so `ocean_mask` never fires) — making TidalFlat/DuneStrand/CliffCoast/Estuarine unreachable at a lake edge by construction, with `lake_margin_q` (a depth-band tone gradient) as the only substitute. **Ruled: lakes get full shore morphology** (Jeroen: *"I have been to many lakes hugging a cliff and with beaches"*). Gates key on proximity to **water**, not to ocean. No new vocabulary is required — `MorphologyZone` already carries `Fjord`, `Delta`, `Wetland`, `CliffCoast` and `DuneStrand`, every one of which describes a lake shore as readily as a sea shore. + + **The sea-flavoured types are separated by TIDAL ENERGY, a derived quantity — never by an "is it the ocean" switch.** + + - **TidalFlat requires tidal range.** Lakes have effectively none, so they get no flats — because the physics is absent, not because they are lakes. + - **Estuarine vs Delta is a sediment-balance outcome, not a salinity one.** A delta builds land outward in distributaries where the river deposits faster than the receiving water removes; an estuary is the inverse, a drowned valley widening seaward where the water sweeps sediment away. The discriminator is tidal/current energy: the microtidal Mediterranean is ringed with **deltas** (Nile, Rhône, Po) despite being salt, while the macrotidal Atlantic coast gives **estuaries** (Thames, Severn, Gironde). Lakes therefore always resolve to Delta, and so does a tideless sea — which an ocean-vs-lake switch would have got wrong. + - Everything else **scales with** the water body rather than switching on it: dune strands need fetch and sand supply (a great lake earns them, as Lake Michigan does; a tarn does not), fjords are glacially carved and common on glacial lakes, cliffs need only relief at the waterline. A large lake ends up with a rich shore and a small one a bare rim, and that difference is *derived from its size* rather than written down. + - **Salinity is not a morphology input at all.** It is a property of water, not a landform, and is therefore excluded from this classification. If gameplay ever needs it, derive it from connectivity to below-sea-level water (Jeroen: *"if and when we ever need it"*). Explicitly parked. + - **Rationale:** Two failures forced this, one visible and one structural. **Visible:** the Global rung derived a five-class hue map while a per-body artefact explicitly labelled *"clean color hypsometric render (display / Atlas)"* sat unused beside it — the Atlas was ignoring the picture built for it, and read as a data readout rather than a world. **Structural:** hydrology was not derivable at all under the old model. Courses were invented per canvas from a network, but *flow* — which way water runs, where it pools — is a global solve, so no per-window derivation could produce a coherent water system; Region carried no courses whatsoever and lakes could not fill. Deriving one whole-body layer first solves both, and converts cross-rung consistency from something enforced into something structural. The plurality reading of the reliefmap is what prevents the obvious wrong implementation: treating it as ground truth and interpolating, which yields hard biome boundaries on a 38 km lattice — a visibly gridded world, precisely the artefact D-243's edge-fuzz rule exists to prevent one tier up. Conservation (3) prevents the opposite failure, where invention drifts far enough that zooming out no longer agrees with the map you zoomed in from.