docs(meta): D-258 — the storage question was premature (T-1211 re-scope)
The 2026-07-27 amendment closed by naming the live question: does biome un-summarisation need a stored layer, or does it ride the existing sample-fresh-at-every-rung mechanism. A descent ladder answers a prior one: it is not happening in any form, stored or derived. One body, one land-anchored point, one capture per rung, no overlays, at the panel's native 3440x1440. Ferrath's heightmap is 1024x512 over a 38,089 km circumference -- 37.2 km per source pixel. Global draws at 35.267 km/gridunit, about 1:1 with the source, and reads as a world. Region draws at 0.379 -- 98x finer than anything stored -- and is a uniform colour field with dither. District, at 0.0038, is ~9,800x finer and identical in character. The Atlas is legible exactly where it samples the heightmap and flat everywhere it invents. So the D-227 carve-out cannot be argued yet on any basis, disproven or measured, because there is no artefact to store. Ruling: build the expansion as a pure function first, following the mechanism that already exists (D-255(f) mechanism B), measure that, and reopen storage only if the numbers force it. T-1211 re-scoped, T-1212 retired as a gate with its measurement moved downstream, T-1213 unblocked as the epic's first child. Recorded with the same process note the previous amendment earned: this was found by capturing the ladder and looking at it, after the goldens had been failing for 15 commits with two of them passing against blank screens. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT0TX2W0BA10PRR7NMJ2362M', 'description', 'D-258: the Atlas cascade gains a single expanded layer (''rung 0.5''), generated once per body from the rung-0 input pair (heightmap.png + reliefmap.png, never displayed), and every zoom tier below it (Region/District/Quarter/Block/Chunk) derives from that layer instead of independently re-deriving from the source files. Hydrology (drainage, course routing, lake fill) resolves ONCE on rung 0.5 and nowhere else -- it is a whole-body computation, not derivable per-window. Global displays rung 0.5 directly (biome-from-orbit, not a photograph). Same-session amendment: lake shorelines run the same shore-morphology code as ocean shorelines (coastline warp applied to both surfaces in the single rung-0.5 pass; shore-morphology gates key on proximity to water, not to ocean; sea-flavored types like TidalFlat/Estuarine-vs-Delta separated by tidal energy, a derived quantity, never by an is-it-the-ocean switch; salinity excluded from morphology entirely). This is a named, principled carve-out from D-227 derive-don''t-store: a whole-body flow solve is not locally computable, so it cannot be re-derived per window at any price -- storage here buys correctness, not convenience. Not yet ticketed prior to this epic (D-258''s own Implementation note). See governance/decisions/architecture.md#d-258.
|
||||
|
||||
RE-SCOPE REQUIRED BEFORE ANY CHILD STARTS (2026-07-27, D-258 amendment). The structural rationale for this epic was disproven on evidence the day after it was written. D-258 claimed hydrology ''was not derivable at all'' per-window; in fact layer1.rs::run_layer1_with_moisture 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 calls it ''a coarse continuous primitive computed once, sampled fresh at every rung, never re-solved'' (mechanism B, D-255(f)). Compute-once-sample-everywhere already exists. What actually made Global look flat was serve_step_canvas_request zeroing Global''s wire extent (a pre-extent-inversion sentinel), producing a 2x1 canvas -- fixed 2026-07-27; once sized correctly Global reads as a world with no hydrology work at all. Rivers at Global were measured as negligible: 375 courses present, 458 of 518,400 pixels different vs courses-off, because at ~39.7 km/gridunit most courses are shorter than one gridunit. SURVIVES: biome un-summarisation (reliefmap as plurality), composition-on-descent, the conservation invariant, and the lake-shore amendment. WEAKENED: the stored expanded layer and its D-227 carve-out. 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''. Re-scope this epic and T-1212 against that question first.', 'D-258: the Atlas cascade gains a single expanded layer (''rung 0.5''), generated once per body from the rung-0 input pair (heightmap.png + reliefmap.png, never displayed), and every zoom tier below it (Region/District/Quarter/Block/Chunk) derives from that layer instead of independently re-deriving from the source files. Hydrology (drainage, course routing, lake fill) resolves ONCE on rung 0.5 and nowhere else -- it is a whole-body computation, not derivable per-window. Global displays rung 0.5 directly (biome-from-orbit, not a photograph). Same-session amendment: lake shorelines run the same shore-morphology code as ocean shorelines (coastline warp applied to both surfaces in the single rung-0.5 pass; shore-morphology gates key on proximity to water, not to ocean; sea-flavored types like TidalFlat/Estuarine-vs-Delta separated by tidal energy, a derived quantity, never by an is-it-the-ocean switch; salinity excluded from morphology entirely). This is a named, principled carve-out from D-227 derive-don''t-store: a whole-body flow solve is not locally computable, so it cannot be re-derived per window at any price -- storage here buys correctness, not convenience. Not yet ticketed prior to this epic (D-258''s own Implementation note). See governance/decisions/architecture.md#d-258.
|
||||
|
||||
RE-SCOPE REQUIRED BEFORE ANY CHILD STARTS (2026-07-27, D-258 amendment). The structural rationale for this epic was disproven on evidence the day after it was written. D-258 claimed hydrology ''was not derivable at all'' per-window; in fact layer1.rs::run_layer1_with_moisture 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 calls it ''a coarse continuous primitive computed once, sampled fresh at every rung, never re-solved'' (mechanism B, D-255(f)). Compute-once-sample-everywhere already exists. What actually made Global look flat was serve_step_canvas_request zeroing Global''s wire extent (a pre-extent-inversion sentinel), producing a 2x1 canvas -- fixed 2026-07-27; once sized correctly Global reads as a world with no hydrology work at all. Rivers at Global were measured as negligible: 375 courses present, 458 of 518,400 pixels different vs courses-off, because at ~39.7 km/gridunit most courses are shorter than one gridunit. SURVIVES: biome un-summarisation (reliefmap as plurality), composition-on-descent, the conservation invariant, and the lake-shore amendment. WEAKENED: the stored expanded layer and its D-227 carve-out. 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''. Re-scope this epic and T-1212 against that question first.
|
||||
|
||||
---
|
||||
RE-SCOPED 2026-08-06 (Jeroen''s call) — the epic is unblocked, and its question has changed again.
|
||||
|
||||
EVIDENCE. A descent ladder was captured on Ferrath (GJ820Bc) at native 3440x1440,
|
||||
anchored on land, one shot per rung, no overlays (scenarios atlas_GJ820Bc_land_*
|
||||
in tests/visual.json). Ferrath''s heightmap is 1024x512 over a 38,089 km
|
||||
circumference = 37.2 km per source pixel. Against that:
|
||||
|
||||
Global 35.267 km/gridunit ~1:1 with the source pixel a real map
|
||||
Region 0.379 km/gridunit 98x finer flat wash
|
||||
District 0.0038 km/gridunit 9,800x finer flat wash
|
||||
Quarter/Block/Chunk finer still flat
|
||||
|
||||
The Atlas is legible exactly where it SAMPLES the heightmap and flat everywhere
|
||||
it must INVENT. Every rung below Global is a single uniform colour field with
|
||||
dither noise; the courses/settlements readout is 0 at all of them.
|
||||
|
||||
WHAT THIS SETTLES. D-258''s amendment (5) framed the live question as "does biome
|
||||
un-summarisation need a stored layer at all, or does it ride the existing
|
||||
sample-fresh-at-every-rung mechanism". The ladder answers a PRIOR question:
|
||||
un-summarisation is not happening in ANY form. There is no expansion to decide
|
||||
the storage policy for. Storage is therefore a downstream optimisation, not the
|
||||
decision this epic turns on.
|
||||
|
||||
NEW SCOPE. Build the expansion first as a PURE FUNCTION, following the mechanism
|
||||
that already exists rather than inventing a second one: layer1.rs''s
|
||||
compute-once-sample-everywhere primitive (D-255(f) mechanism B) is the model, and
|
||||
the amendment established hydrology already works that way. Measure it. Add a
|
||||
stored layer ONLY if the measured cost forces it — and if it does, that is when
|
||||
the D-227 carve-out argument gets made, on numbers rather than on the disproven
|
||||
"not locally computable" claim.
|
||||
|
||||
Order: T-1213 (the un-summarisation generator) is now the first child and is
|
||||
UNBLOCKED. T-1214 (hydrology onto rung 0.5) stays parked — the amendment showed
|
||||
that solve already runs once per body and does not need to move. T-1216 (Global
|
||||
biome-from-orbit palette) and T-1217 (lake shores through the shared shore path)
|
||||
survive unchanged; both were independent of the storage question.
|
||||
|
||||
T-1212 does not gate this any more (see its own note).', NULL, '2026-08-06 15:59:03', '2026-08-06 15:59:03.757', '2026-08-06 15:59:03.757', NULL, 'eef80bb095e745421957ffdcf7ae7975', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT0TYBD74TQNVKTJMKA8D9KM', 'description', 'MUST run and be reviewed before any other T-1211 child starts -- this measurement could reshape the rung-0.5 design, per the pair session''s explicit sequencing note. Measure, at minimum: (1) per-body derive cost for the expanded layer at a resolution sized so a whole body draws at 2 screen px per gridunit on a large display (the D-258 sizing rule) -- both single-body cold-derive time and the full ~271-body population sum; (2) per-body and total disk footprint if the layer is cached/stored (rung 0.5 is a named D-227 carve-out -- storage is deliberate, but its size must be known, not assumed); (3) whole-body hydrology solve cost on this layer (drainage + course routing + lake fill) at the same resolution, since D-258 requires this to run exactly once per body and nowhere else. Reference point: D-255''s own rung-0 always-keep tier estimate went from ~8.85 MB (measured against a stale ~18K-cell/body figure) to an estimated 226 MB (1080p) / ~900 MB (4K) once the extent inversion made Global viewport-sized -- D-255 amendment item 6 explicitly says ''re-measure against rung 0.5, not against this record.'' This ticket is that re-measurement. Report back to the team before T-1211''s other children are started; if the numbers are structurally bad (e.g. rung 0.5 at the sizing D-258 specifies costs an order of magnitude more than the old rung-0 model), that is grounds to revisit the resolution target with Jeroen before writing generator code. See governance/decisions/architecture.md#d-258 (rationale + Implementation note).
|
||||
|
||||
SCOPE INVALIDATED 2026-07-27 (see T-1211 and the D-258 amendment). This ticket was written to measure the cost of moving a whole-body hydrology solve onto rung 0.5. That solve does not need to move -- it already runs once per body in layer1.rs and is sampled fresh at every rung. Do NOT run this measurement as written; it would price work that is not required. If a measurement is still wanted after T-1211 is re-scoped, the question is narrower: what does BIOME un-summarisation cost, and does it need storing at all.', 'MUST run and be reviewed before any other T-1211 child starts -- this measurement could reshape the rung-0.5 design, per the pair session''s explicit sequencing note. Measure, at minimum: (1) per-body derive cost for the expanded layer at a resolution sized so a whole body draws at 2 screen px per gridunit on a large display (the D-258 sizing rule) -- both single-body cold-derive time and the full ~271-body population sum; (2) per-body and total disk footprint if the layer is cached/stored (rung 0.5 is a named D-227 carve-out -- storage is deliberate, but its size must be known, not assumed); (3) whole-body hydrology solve cost on this layer (drainage + course routing + lake fill) at the same resolution, since D-258 requires this to run exactly once per body and nowhere else. Reference point: D-255''s own rung-0 always-keep tier estimate went from ~8.85 MB (measured against a stale ~18K-cell/body figure) to an estimated 226 MB (1080p) / ~900 MB (4K) once the extent inversion made Global viewport-sized -- D-255 amendment item 6 explicitly says ''re-measure against rung 0.5, not against this record.'' This ticket is that re-measurement. Report back to the team before T-1211''s other children are started; if the numbers are structurally bad (e.g. rung 0.5 at the sizing D-258 specifies costs an order of magnitude more than the old rung-0 model), that is grounds to revisit the resolution target with Jeroen before writing generator code. See governance/decisions/architecture.md#d-258 (rationale + Implementation note).
|
||||
|
||||
SCOPE INVALIDATED 2026-07-27 (see T-1211 and the D-258 amendment). This ticket was written to measure the cost of moving a whole-body hydrology solve onto rung 0.5. That solve does not need to move -- it already runs once per body in layer1.rs and is sampled fresh at every rung. Do NOT run this measurement as written; it would price work that is not required. If a measurement is still wanted after T-1211 is re-scoped, the question is narrower: what does BIOME un-summarisation cost, and does it need storing at all.
|
||||
|
||||
---
|
||||
RETIRED AS A GATE 2026-08-06. This no longer blocks T-1213 or the T-1211 epic.
|
||||
|
||||
It was already SCOPE INVALIDATED (2026-07-27) for pricing a hydrology move that
|
||||
does not need to happen. The 2026-08-06 descent ladder (see T-1211) closes the
|
||||
remaining reason to keep it as a gate: every rung below Global renders a flat
|
||||
wash, so biome un-summarisation is not happening at all. There is no artefact
|
||||
whose cost or disk footprint can be measured, because none is produced.
|
||||
|
||||
The measurement question survives, but it is now DOWNSTREAM of T-1213 rather
|
||||
than upstream of it: once the un-summarisation exists as a pure function, measure
|
||||
THAT, and only then decide whether a stored layer is warranted. Re-scope this
|
||||
ticket to that measurement when T-1213 lands, or close it and let T-1213 carry
|
||||
its own measurement step.', NULL, '2026-08-06 15:59:12', '2026-08-06 15:59:12.825', '2026-08-06 15:59:12.825', NULL, '177c4abeb3d8bc4cb2260f81fe9f5d09', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT0TZC9MJV6KZTSRVRYQ327M', 'description', 'Build the deterministic expansion from rung 0 (heightmap.png 1024x512 16-bit elevation + reliefmap.png 1024x512 colour biome) to rung 0.5, sized per D-258''s 2-px-per-gridunit-at-large-display rule. Same body + same seed must produce the same layer every time (byte-identical, per D-227''s determinism discipline extended by this carve-out). The reliefmap is a PLURALITY, not ground truth: each reliefmap cell already voted-and-discarded the dominant biome across ~38 km of ground, so this generator un-summarises it -- it does not upscale/interpolate it. Three binding invariants from D-258: (1) biome edges are gradients, never lines -- transitions blend so no boundary falls on a rung-0 cell edge (the D-243 climate edge-fuzz rule applied to biome); (2) descending the ladder reveals COMPOSITION not sharpness -- a cell reading ''forest'' globally must be able to contain clearings/marsh/rock/scrub the vote suppressed, emerging deterministically as the ladder descends; (3) CONSERVATIVE invention is the binding acceptance gate -- downsampling rung 0.5 must reproduce the rung-0 summary it came from (a forest cell may gain marsh pockets but must still read as forest from orbit). Blocked on T-1212 (cost/size measurement) landing first. Depends on: nothing else in this epic to start scaffolding, but hydrology (sibling ticket) and this generator are tightly coupled -- coordinate sequencing with whoever picks up hydrology. See governance/decisions/architecture.md#d-258.', 'Build the deterministic expansion from rung 0 (heightmap.png 1024x512 16-bit elevation + reliefmap.png 1024x512 colour biome) to rung 0.5, sized per D-258''s 2-px-per-gridunit-at-large-display rule. Same body + same seed must produce the same layer every time (byte-identical, per D-227''s determinism discipline extended by this carve-out). The reliefmap is a PLURALITY, not ground truth: each reliefmap cell already voted-and-discarded the dominant biome across ~38 km of ground, so this generator un-summarises it -- it does not upscale/interpolate it. Three binding invariants from D-258: (1) biome edges are gradients, never lines -- transitions blend so no boundary falls on a rung-0 cell edge (the D-243 climate edge-fuzz rule applied to biome); (2) descending the ladder reveals COMPOSITION not sharpness -- a cell reading ''forest'' globally must be able to contain clearings/marsh/rock/scrub the vote suppressed, emerging deterministically as the ladder descends; (3) CONSERVATIVE invention is the binding acceptance gate -- downsampling rung 0.5 must reproduce the rung-0 summary it came from (a forest cell may gain marsh pockets but must still read as forest from orbit). Blocked on T-1212 (cost/size measurement) landing first. Depends on: nothing else in this epic to start scaffolding, but hydrology (sibling ticket) and this generator are tightly coupled -- coordinate sequencing with whoever picks up hydrology. See governance/decisions/architecture.md#d-258.
|
||||
|
||||
---
|
||||
UNBLOCKED 2026-08-06 (T-1211 re-scope, Jeroen''s call). The T-1212 blocker edge is
|
||||
removed: that measurement priced a hydrology move that is not happening, and the
|
||||
descent ladder showed there is no expansion artefact to measure yet anyway.
|
||||
|
||||
BUILD IT AS A PURE FUNCTION FIRST, not as a stored layer. The stored-layer half of
|
||||
D-258 was materially weakened by its own 2026-07-27 amendment (the "not locally
|
||||
computable" argument for the D-227 carve-out does not hold, because the whole-body
|
||||
solve it cited already runs once per body in layer1.rs and is sampled at every
|
||||
rung). So follow the mechanism that exists — D-255(f) mechanism B,
|
||||
compute-once-sample-everywhere — measure it, and only argue for storage on those
|
||||
numbers. Do NOT open with a cache.
|
||||
|
||||
WHAT "FLAT" MEANS CONCRETELY, so the fix has a target. Ferrath''s heightmap is
|
||||
1024x512 over a 38,089 km circumference: 37.2 km per source pixel. Global draws at
|
||||
35.267 km/gridunit, roughly 1:1 with the source, and reads as a real map. Region
|
||||
draws at 0.379 km/gridunit — 98x finer than any stored datum — and is a single
|
||||
uniform colour with dither. District is 0.0038 km/gridunit, ~9,800x finer, also
|
||||
uniform. So the acceptance bar is not subtle: at Region, ~98 gridunits across a
|
||||
single source pixel must carry visible, deterministic, non-repeating composition
|
||||
that still downsamples back to that pixel''s summary (D-258''s conservation
|
||||
invariant, the binding gate).
|
||||
|
||||
VERIFY BY CAPTURE, NOT BY REASONING. The scenarios exist: atlas_GJ820Bc_land_*
|
||||
(Region/District/Quarter/Block/Chunk, one land-anchored world point, no overlays)
|
||||
in tests/visual.json. Captures run offscreen under gamescope at native 3440x1440
|
||||
via tests/run-visual --screenshot <name> — they do not steal the desktop. Re-shoot
|
||||
the ladder and look at it; a green unit test proves nothing here.
|
||||
|
||||
Note the ladder currently also reports courses=0 at every rung below Global —
|
||||
rivers vanish on descent. That is tracked separately as T-1239 and is NOT this
|
||||
ticket''s scope, but it will be visible in the same captures, so do not mistake it
|
||||
for a failure of the un-summarisation work.', NULL, '2026-08-06 15:59:39', '2026-08-06 15:59:39.623', '2026-08-06 15:59:39.623', NULL, 'fff0549b0da56272e5c13e9de4374f76', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
@@ -1 +1,97 @@
|
||||
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FXF1VDVQDQ8EFGTXX787M90R', 'bug', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas rivers vanish at native resolution — 375 courses arrive, 0 drawn', 'Found 2026-08-06 when the visual capture resolution was raised from 960x540 to the native 3440x1440. On Ferrath (GJ820Bc) Global the wire delivers 375 river courses and the annotation layer draws NONE: ''courses=375 drawn=0'' in the view-transform readout. At 960x540 the SAME build drew them as visible strokes, so this is resolution-dependent, not a river-generation failure -- the courses are present and correct on the wire. Suspect the D-261 cull (drop a course below 15 px of on-screen length, 3x the 5 px stroke) or the water-truncation step: T-1237 computes the clipped/culled polylines ONCE on canvas adoption (set_frame) rather than per draw, so if adoption runs against a pre-layout or stale viewport the screen-length measurement is wrong for every course at once -- which matches an all-or-nothing drawn=0 rather than a partial cull. Note the scale moved the RIGHT way for visibility (46.792 km/gridunit at 960x540 vs 35.267 at 3440x1440 -- more gridunits across the body, so a river spans MORE of them), which makes a legitimate cull an unlikely explanation. Reproduce: tests/run-visual --screenshot atlas_GJ820Bc_Global and read the drawn= count.', 'backlog', 'high', NULL, 'client', 'D-261', '2026-08-06 14:43:24.765', '2026-08-06 14:43:24.765', NULL, '9597ed74aa67fb7ebeef78f60374d89c', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT0TX2W0BA10PRR7NMJ2362M', 'epic', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Rung-0.5 expanded layer — whole-body hydrology + biome-from-orbit base (D-258)', 'D-258: the Atlas cascade gains a single expanded layer (''rung 0.5''), generated once per body from the rung-0 input pair (heightmap.png + reliefmap.png, never displayed), and every zoom tier below it (Region/District/Quarter/Block/Chunk) derives from that layer instead of independently re-deriving from the source files. Hydrology (drainage, course routing, lake fill) resolves ONCE on rung 0.5 and nowhere else -- it is a whole-body computation, not derivable per-window. Global displays rung 0.5 directly (biome-from-orbit, not a photograph). Same-session amendment: lake shorelines run the same shore-morphology code as ocean shorelines (coastline warp applied to both surfaces in the single rung-0.5 pass; shore-morphology gates key on proximity to water, not to ocean; sea-flavored types like TidalFlat/Estuarine-vs-Delta separated by tidal energy, a derived quantity, never by an is-it-the-ocean switch; salinity excluded from morphology entirely). This is a named, principled carve-out from D-227 derive-don''t-store: a whole-body flow solve is not locally computable, so it cannot be re-derived per window at any price -- storage here buys correctness, not convenience. Not yet ticketed prior to this epic (D-258''s own Implementation note). See governance/decisions/architecture.md#d-258.
|
||||
|
||||
RE-SCOPE REQUIRED BEFORE ANY CHILD STARTS (2026-07-27, D-258 amendment). The structural rationale for this epic was disproven on evidence the day after it was written. D-258 claimed hydrology ''was not derivable at all'' per-window; in fact layer1.rs::run_layer1_with_moisture 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 calls it ''a coarse continuous primitive computed once, sampled fresh at every rung, never re-solved'' (mechanism B, D-255(f)). Compute-once-sample-everywhere already exists. What actually made Global look flat was serve_step_canvas_request zeroing Global''s wire extent (a pre-extent-inversion sentinel), producing a 2x1 canvas -- fixed 2026-07-27; once sized correctly Global reads as a world with no hydrology work at all. Rivers at Global were measured as negligible: 375 courses present, 458 of 518,400 pixels different vs courses-off, because at ~39.7 km/gridunit most courses are shorter than one gridunit. SURVIVES: biome un-summarisation (reliefmap as plurality), composition-on-descent, the conservation invariant, and the lake-shore amendment. WEAKENED: the stored expanded layer and its D-227 carve-out. 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''. Re-scope this epic and T-1212 against that question first.
|
||||
|
||||
---
|
||||
RE-SCOPED 2026-08-06 (Jeroen''s call) — the epic is unblocked, and its question has changed again.
|
||||
|
||||
EVIDENCE. A descent ladder was captured on Ferrath (GJ820Bc) at native 3440x1440,
|
||||
anchored on land, one shot per rung, no overlays (scenarios atlas_GJ820Bc_land_*
|
||||
in tests/visual.json). Ferrath''s heightmap is 1024x512 over a 38,089 km
|
||||
circumference = 37.2 km per source pixel. Against that:
|
||||
|
||||
Global 35.267 km/gridunit ~1:1 with the source pixel a real map
|
||||
Region 0.379 km/gridunit 98x finer flat wash
|
||||
District 0.0038 km/gridunit 9,800x finer flat wash
|
||||
Quarter/Block/Chunk finer still flat
|
||||
|
||||
The Atlas is legible exactly where it SAMPLES the heightmap and flat everywhere
|
||||
it must INVENT. Every rung below Global is a single uniform colour field with
|
||||
dither noise; the courses/settlements readout is 0 at all of them.
|
||||
|
||||
WHAT THIS SETTLES. D-258''s amendment (5) framed the live question as "does biome
|
||||
un-summarisation need a stored layer at all, or does it ride the existing
|
||||
sample-fresh-at-every-rung mechanism". The ladder answers a PRIOR question:
|
||||
un-summarisation is not happening in ANY form. There is no expansion to decide
|
||||
the storage policy for. Storage is therefore a downstream optimisation, not the
|
||||
decision this epic turns on.
|
||||
|
||||
NEW SCOPE. Build the expansion first as a PURE FUNCTION, following the mechanism
|
||||
that already exists rather than inventing a second one: layer1.rs''s
|
||||
compute-once-sample-everywhere primitive (D-255(f) mechanism B) is the model, and
|
||||
the amendment established hydrology already works that way. Measure it. Add a
|
||||
stored layer ONLY if the measured cost forces it — and if it does, that is when
|
||||
the D-227 carve-out argument gets made, on numbers rather than on the disproven
|
||||
"not locally computable" claim.
|
||||
|
||||
Order: T-1213 (the un-summarisation generator) is now the first child and is
|
||||
UNBLOCKED. T-1214 (hydrology onto rung 0.5) stays parked — the amendment showed
|
||||
that solve already runs once per body and does not need to move. T-1216 (Global
|
||||
biome-from-orbit palette) and T-1217 (lake shores through the shared shore path)
|
||||
survive unchanged; both were independent of the storage question.
|
||||
|
||||
T-1212 does not gate this any more (see its own note).', 'backlog', 'high', NULL, NULL, 'D-258', '2026-07-26 21:53:56.448', '2026-08-06 15:59:03.757', NULL, '923892406469abdd3fb6ee9041ae1cbf', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT0TYBD74TQNVKTJMKA8D9KM', 'task', '06FT0TX2W0BA10PRR7NMJ2362M', 'Measure rung-0.5 cost/size BEFORE implementing (compute + disk, whole-body)', 'MUST run and be reviewed before any other T-1211 child starts -- this measurement could reshape the rung-0.5 design, per the pair session''s explicit sequencing note. Measure, at minimum: (1) per-body derive cost for the expanded layer at a resolution sized so a whole body draws at 2 screen px per gridunit on a large display (the D-258 sizing rule) -- both single-body cold-derive time and the full ~271-body population sum; (2) per-body and total disk footprint if the layer is cached/stored (rung 0.5 is a named D-227 carve-out -- storage is deliberate, but its size must be known, not assumed); (3) whole-body hydrology solve cost on this layer (drainage + course routing + lake fill) at the same resolution, since D-258 requires this to run exactly once per body and nowhere else. Reference point: D-255''s own rung-0 always-keep tier estimate went from ~8.85 MB (measured against a stale ~18K-cell/body figure) to an estimated 226 MB (1080p) / ~900 MB (4K) once the extent inversion made Global viewport-sized -- D-255 amendment item 6 explicitly says ''re-measure against rung 0.5, not against this record.'' This ticket is that re-measurement. Report back to the team before T-1211''s other children are started; if the numbers are structurally bad (e.g. rung 0.5 at the sizing D-258 specifies costs an order of magnitude more than the old rung-0 model), that is grounds to revisit the resolution target with Jeroen before writing generator code. See governance/decisions/architecture.md#d-258 (rationale + Implementation note).
|
||||
|
||||
SCOPE INVALIDATED 2026-07-27 (see T-1211 and the D-258 amendment). This ticket was written to measure the cost of moving a whole-body hydrology solve onto rung 0.5. That solve does not need to move -- it already runs once per body in layer1.rs and is sampled fresh at every rung. Do NOT run this measurement as written; it would price work that is not required. If a measurement is still wanted after T-1211 is re-scoped, the question is narrower: what does BIOME un-summarisation cost, and does it need storing at all.
|
||||
|
||||
---
|
||||
RETIRED AS A GATE 2026-08-06. This no longer blocks T-1213 or the T-1211 epic.
|
||||
|
||||
It was already SCOPE INVALIDATED (2026-07-27) for pricing a hydrology move that
|
||||
does not need to happen. The 2026-08-06 descent ladder (see T-1211) closes the
|
||||
remaining reason to keep it as a gate: every rung below Global renders a flat
|
||||
wash, so biome un-summarisation is not happening at all. There is no artefact
|
||||
whose cost or disk footprint can be measured, because none is produced.
|
||||
|
||||
The measurement question survives, but it is now DOWNSTREAM of T-1213 rather
|
||||
than upstream of it: once the un-summarisation exists as a pure function, measure
|
||||
THAT, and only then decide whether a stored layer is warranted. Re-scope this
|
||||
ticket to that measurement when T-1213 lands, or close it and let T-1213 carry
|
||||
its own measurement step.', 'backlog', 'high', NULL, NULL, 'D-258', '2026-07-26 21:54:06.825', '2026-08-06 15:59:12.825', NULL, 'e0d88ae134ccd57737d8eab2627e2b88', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT0TZC9MJV6KZTSRVRYQ327M', 'story', '06FT0TX2W0BA10PRR7NMJ2362M', 'Rung-0.5 expanded-layer generator (deterministic un-summarisation of rung 0)', 'Build the deterministic expansion from rung 0 (heightmap.png 1024x512 16-bit elevation + reliefmap.png 1024x512 colour biome) to rung 0.5, sized per D-258''s 2-px-per-gridunit-at-large-display rule. Same body + same seed must produce the same layer every time (byte-identical, per D-227''s determinism discipline extended by this carve-out). The reliefmap is a PLURALITY, not ground truth: each reliefmap cell already voted-and-discarded the dominant biome across ~38 km of ground, so this generator un-summarises it -- it does not upscale/interpolate it. Three binding invariants from D-258: (1) biome edges are gradients, never lines -- transitions blend so no boundary falls on a rung-0 cell edge (the D-243 climate edge-fuzz rule applied to biome); (2) descending the ladder reveals COMPOSITION not sharpness -- a cell reading ''forest'' globally must be able to contain clearings/marsh/rock/scrub the vote suppressed, emerging deterministically as the ladder descends; (3) CONSERVATIVE invention is the binding acceptance gate -- downsampling rung 0.5 must reproduce the rung-0 summary it came from (a forest cell may gain marsh pockets but must still read as forest from orbit). Blocked on T-1212 (cost/size measurement) landing first. Depends on: nothing else in this epic to start scaffolding, but hydrology (sibling ticket) and this generator are tightly coupled -- coordinate sequencing with whoever picks up hydrology. See governance/decisions/architecture.md#d-258.
|
||||
|
||||
---
|
||||
UNBLOCKED 2026-08-06 (T-1211 re-scope, Jeroen''s call). The T-1212 blocker edge is
|
||||
removed: that measurement priced a hydrology move that is not happening, and the
|
||||
descent ladder showed there is no expansion artefact to measure yet anyway.
|
||||
|
||||
BUILD IT AS A PURE FUNCTION FIRST, not as a stored layer. The stored-layer half of
|
||||
D-258 was materially weakened by its own 2026-07-27 amendment (the "not locally
|
||||
computable" argument for the D-227 carve-out does not hold, because the whole-body
|
||||
solve it cited already runs once per body in layer1.rs and is sampled at every
|
||||
rung). So follow the mechanism that exists — D-255(f) mechanism B,
|
||||
compute-once-sample-everywhere — measure it, and only argue for storage on those
|
||||
numbers. Do NOT open with a cache.
|
||||
|
||||
WHAT "FLAT" MEANS CONCRETELY, so the fix has a target. Ferrath''s heightmap is
|
||||
1024x512 over a 38,089 km circumference: 37.2 km per source pixel. Global draws at
|
||||
35.267 km/gridunit, roughly 1:1 with the source, and reads as a real map. Region
|
||||
draws at 0.379 km/gridunit — 98x finer than any stored datum — and is a single
|
||||
uniform colour with dither. District is 0.0038 km/gridunit, ~9,800x finer, also
|
||||
uniform. So the acceptance bar is not subtle: at Region, ~98 gridunits across a
|
||||
single source pixel must carry visible, deterministic, non-repeating composition
|
||||
that still downsamples back to that pixel''s summary (D-258''s conservation
|
||||
invariant, the binding gate).
|
||||
|
||||
VERIFY BY CAPTURE, NOT BY REASONING. The scenarios exist: atlas_GJ820Bc_land_*
|
||||
(Region/District/Quarter/Block/Chunk, one land-anchored world point, no overlays)
|
||||
in tests/visual.json. Captures run offscreen under gamescope at native 3440x1440
|
||||
via tests/run-visual --screenshot <name> — they do not steal the desktop. Re-shoot
|
||||
the ladder and look at it; a green unit test proves nothing here.
|
||||
|
||||
Note the ladder currently also reports courses=0 at every rung below Global —
|
||||
rivers vanish on descent. That is tracked separately as T-1239 and is NOT this
|
||||
ticket''s scope, but it will be visible in the same captures, so do not mistake it
|
||||
for a failure of the un-summarisation work.', 'backlog', 'high', NULL, NULL, 'D-258', '2026-07-26 21:54:15.245', '2026-08-06 15:59:39.623', NULL, 'd9bfabaf6b4f1751a9261995f84c0b7b', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
|
||||
@@ -2393,6 +2393,14 @@ Technical foundation decisions that constrain implementation: engine, client-ser
|
||||
|
||||
**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.
|
||||
|
||||
- **Amendment (2026-08-06 — the storage question is premature; the expansion does not exist):** the previous amendment closed by naming the live question as *"does biome un-summarisation need a stored layer at all, or does it ride the existing sample-fresh-at-every-rung mechanism."* A descent ladder captured on Ferrath (GJ820Bc) answers a **prior** question instead: un-summarisation is not happening in any form, stored or derived.
|
||||
|
||||
**The measurement.** One body, one land-anchored world point, one capture per rung, no overlays, at the panel's native 3440×1440 (scenarios `atlas_GJ820Bc_land_*`). Ferrath's heightmap is 1024×512 over a 38,089 km circumference — **37.2 km per source pixel**. Against that datum: **Global** draws at 35.267 km/gridunit, roughly 1:1 with the source, and reads as a world; **Region** at 0.379 km/gridunit is **98× finer** than anything stored and renders a single uniform colour field with dither; **District** at 0.0038 km/gridunit is ~**9,800× finer** and renders the same. Quarter, Block and Chunk likewise. The pattern is exact: **the Atlas is legible precisely where it samples the heightmap, and flat everywhere it must invent.**
|
||||
|
||||
**Consequence.** There is no expansion artefact whose storage policy can be decided, so the D-227 carve-out argument cannot be made yet on any basis — neither the disproven "not locally computable" claim nor a measured one. The ruling is therefore to build the un-summarisation **as a pure function first**, following the mechanism that already exists ([D-255](#d-255)(f) mechanism B, compute-once-sample-everywhere — the pattern the previous amendment established hydrology already uses), measure *that*, and open the storage question only if those numbers force it. [T-1211](../../.pql) re-scoped accordingly; [T-1212](../../.pql) retired as a gate and its measurement moved downstream of [T-1213](../../.pql), which is now the epic's first child and unblocked.
|
||||
|
||||
**Process note:** this was found by capturing the ladder and looking at it, after the goldens had been failing for 15 commits and two of them had been *passing* against blank screens. Consistent with the previous amendment's lesson — the verification that finally saw the problem was an eyeball on a real render at a real resolution, not a green assertion.
|
||||
|
||||
---
|
||||
|
||||
### D-259: Enclosed settlements — open-air requires a breathable atmosphere
|
||||
|
||||
Reference in New Issue
Block a user