fix(client): the deep rungs were flat because relief_q fell off the wire (T-1213)
`relief_q` is the one field with signal below District — elev_q's 80 m steps
quantise sub-district detail away, which is precisely why relief_q was invented.
The server has encoded it since 5eb394b36 and the terrain layer has asked for it
by name ever since. step_canvas_protocol.gd's decode dictionary never listed the
key, so `canvas.get("relief_q")` was always null and the plane arrived nowhere.
The server half of that change landed; the protocol half did not.
That is the whole reason Region and below rendered as a flat wash. Measured plane
variety at District before the fix:
{morphology: 1, elev_q: 11, relief_q: 0, moisture_q: 25, vegetation: 3}
A 0 there means ABSENT, not constant — a distinction the capture could not make
until this commit adds it, and the reason two earlier sessions read the flatness
as a missing generator rather than a missing key.
Also spends the field properly. It drove a stipple PROBABILITY only, so a ridge
and a plain differed in dot density, which at one pixel per cell reads as noise;
and `_ruggedness()` took absf(relief_q - 50), discarding the sign the server
deliberately preserved ("a hollow and a rise are different ground... the reverse
is not recoverable"). Relief now shades continuously and signed — rises lighten,
hollows darken — UNDER the stipple rather than instead of it. Ruggedness
(unsigned) and elevation (signed) are different questions and both are worth
asking.
Ladder, before -> after (tooling/atlas-flatness, lum p1-p99):
Global 145.69 -> 145.69 unchanged, correct: relief_q is flat 50 at
orbital rungs by construction
Region 33.59 -> 71.01 2.1x
District 13.72 -> 77.01 5.6x
Quarter 11.01 -> 42.56 3.9x
Structure retention Global->Quarter: 7.6% -> 29%.
NOT finished, and the ticket says so: Region now reads as heavy speckle, because
ruggedness is real data instead of an elev_q-gradient fallback and far more cells
earn a mark than the T-1194 tuning assumed; District reads as soft blobby relief,
form without directionality. Both are grammar/tuning follow-ups on a channel that
finally carries signal.
0.4.9 is a REQUIRED bump. The disk cache stores the DECODED canvas, so every
earlier entry physically lacks the field and would keep rendering flat against a
build that reads it — the first bump in this series where a warm cache is wrong
about CONTENT, not merely stale. tooling/canvas_sources.py gains
step_canvas_protocol.gd for the same reason: it decides which planes exist, the
cache stores its output, and the T-1242 gate would not have flagged this fix
while the registry stopped at ui/.../step_canvas/.
Regression cover: every protocol test passed throughout the weeks the plane was
missing, because each asserted a field it already knew about and none asserted
the SET. There is now a test walking all eight dense planes of EncodedStepCanvas,
verified by disabling the fix and watching it fail by name.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -332,3 +332,305 @@ THE OPEN DECISION — three readings, materially different work:
|
||||
scale. Tuning only; 1.07% is near-invisible.
|
||||
|
||||
Not chosen here — it needs Jeroen''s call, and it touches D-258.', NULL, '2026-08-16 10:32:31', '2026-08-16 10:32:31.457', '2026-08-16 10:32:31.457', NULL, '09a8f8872c230a04e1cb4a59d8fb52c8', 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.
|
||||
|
||||
---
|
||||
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.
|
||||
|
||||
---
|
||||
LADDER RE-SHOT COLD 2026-08-16 — the first ladder whose numbers can be trusted.
|
||||
Every previous ladder, including the one this ticket''s re-scope was written from,
|
||||
was captured against the developer''s persistent user:// cache (T-1239). The
|
||||
harness now isolates user:// per capture, so these are fresh derives.
|
||||
|
||||
RESULT: the acceptance bar is NOT met. Region and below are still flat.
|
||||
|
||||
Flatness, measured rather than eyeballed (.cache/t1213_flatness.py samples the
|
||||
terrain area, excluding the panels):
|
||||
|
||||
rung distinct R std G std B std lum p1-p99
|
||||
Global 1581 24.05 35.75 36.21 145.69
|
||||
Region 2923 4.80 8.31 4.19 33.59
|
||||
District 53 2.56 4.90 2.56 13.72
|
||||
Quarter 46 2.42 4.78 2.42 11.01
|
||||
|
||||
Note Region carries MORE distinct colours than Global (2923 vs 1581) while
|
||||
holding a quarter of the structure. That is the dither/stipple pass adding colour
|
||||
noise, not information — so distinct-count is precisely the wrong metric, and the
|
||||
percentile luminance spread is the honest one. Structure falls ~92% from Global
|
||||
to Quarter.
|
||||
|
||||
WHY IT IS FLAT — a channel mismatch, not a missing generator.
|
||||
|
||||
Composition IS working in the data. The conservation test, run explicitly against
|
||||
real terrain, reports over a 2,048 m patch at the ladder''s own anchor:
|
||||
|
||||
conservation: majority class 3 at 98.9% across 2 classes {1: 175, 3: 16209}
|
||||
|
||||
So D-258 invariant 3 (conservation) holds and invariant 2 (composition) is
|
||||
happening: 1.07% of the patch is a minority class.
|
||||
|
||||
But composition perturbs `moisture_q` and `slope_q`, which resolve into
|
||||
`vegetation_class`. The base map draws neither. step_canvas_colorize.gd''s own
|
||||
comment states it: "The base layer reads hue from morphology and lightness from
|
||||
elev_q, and on a real body below Global that collapses: morphology resolves to
|
||||
ONE zone". The ladder scenarios pass `[]` for overlays deliberately
|
||||
(visual_scenarios.gd: "No overlays, deliberately: a colour ramp on top would mask
|
||||
the very thing being judged"), so the composed fields are never rendered in the
|
||||
shots that judge this work.
|
||||
|
||||
The un-summarisation lands in channels the default view does not draw. That is
|
||||
why perfectly correct composition and a flat map coexist.
|
||||
|
||||
THE CONSERVATION TEST WAS NOT PROTECTING ANYTHING (fixed here).
|
||||
|
||||
Its "not a monoculture" assertion read:
|
||||
|
||||
assert!(tally.len() > 1 || share == 1.0, ...)
|
||||
|
||||
which is a TAUTOLOGY — a single-class tally has a 100% share by definition, so
|
||||
both branches are always satisfiable and the check could never fail, including in
|
||||
the exact case its message names ("or nothing was composed"). It was the only
|
||||
thing standing behind invariant 2, and it stood behind nothing. Now split into
|
||||
the two bounds the invariant actually has: majority > 50% (conservation, the
|
||||
ceiling on invention) and minority >= 0.1% (composition, the floor). Measured
|
||||
1.07% against a 0.1% floor.
|
||||
|
||||
It is also still `#[ignore]`d, so the binding acceptance gate for this epic runs
|
||||
only when someone types it. Worth moving into a harness that runs — the
|
||||
believability and window-derivation harnesses already load real bodies in the
|
||||
normal `cargo test` path, so the precedent exists.
|
||||
|
||||
courses=0 BELOW GLOBAL IS NOT A BUG — it is arithmetic, and the ticket''s note
|
||||
attributing it to T-1239 is superseded. Global now reports courses=73 drawn=18
|
||||
(T-1239 fixed). Region/District/Quarter report courses=0 because the hydrology
|
||||
network is 615 river cells on a 512x256 grid (74.4 km/cell) and a Region window
|
||||
is 489 x 205 km = 0.0217% of a 462M km2 body: expected river cells in view = 615
|
||||
x 0.000217 = 0.13. Zero is the likely outcome, not a failure. The real
|
||||
observation underneath it is that 615 river cells on an Earth-sized body is a
|
||||
sparse network (~45,000 km of total watercourse), which is a believability
|
||||
question for hydrology, not a rendering one.
|
||||
|
||||
THE OPEN DECISION — three readings, materially different work:
|
||||
|
||||
(A) Make the DISPLAYED channels carry sub-source-pixel composition. The literal
|
||||
reading of this ticket''s acceptance bar ("at Region, ~98 gridunits across a
|
||||
single source pixel must carry visible, deterministic, non-repeating
|
||||
composition"). Means morphology and/or elev_q gain a fine tier, which is
|
||||
D-227/D-258 territory and the largest change.
|
||||
(B) Accept that the base view is morphology + elevation, and judge composition
|
||||
through the overlays — i.e. the ladder gains VEG/MST companion shots. Test
|
||||
change only, but it concedes that the default map stays flat below Global.
|
||||
(C) Raise inclusion density so the existing vegetation texture reads at map
|
||||
scale. Tuning only; 1.07% is near-invisible.
|
||||
|
||||
Not chosen here — it needs Jeroen''s call, and it touches 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.
|
||||
|
||||
---
|
||||
LADDER RE-SHOT COLD 2026-08-16 — the first ladder whose numbers can be trusted.
|
||||
Every previous ladder, including the one this ticket''s re-scope was written from,
|
||||
was captured against the developer''s persistent user:// cache (T-1239). The
|
||||
harness now isolates user:// per capture, so these are fresh derives.
|
||||
|
||||
RESULT: the acceptance bar is NOT met. Region and below are still flat.
|
||||
|
||||
Flatness, measured rather than eyeballed (.cache/t1213_flatness.py samples the
|
||||
terrain area, excluding the panels):
|
||||
|
||||
rung distinct R std G std B std lum p1-p99
|
||||
Global 1581 24.05 35.75 36.21 145.69
|
||||
Region 2923 4.80 8.31 4.19 33.59
|
||||
District 53 2.56 4.90 2.56 13.72
|
||||
Quarter 46 2.42 4.78 2.42 11.01
|
||||
|
||||
Note Region carries MORE distinct colours than Global (2923 vs 1581) while
|
||||
holding a quarter of the structure. That is the dither/stipple pass adding colour
|
||||
noise, not information — so distinct-count is precisely the wrong metric, and the
|
||||
percentile luminance spread is the honest one. Structure falls ~92% from Global
|
||||
to Quarter.
|
||||
|
||||
WHY IT IS FLAT — a channel mismatch, not a missing generator.
|
||||
|
||||
Composition IS working in the data. The conservation test, run explicitly against
|
||||
real terrain, reports over a 2,048 m patch at the ladder''s own anchor:
|
||||
|
||||
conservation: majority class 3 at 98.9% across 2 classes {1: 175, 3: 16209}
|
||||
|
||||
So D-258 invariant 3 (conservation) holds and invariant 2 (composition) is
|
||||
happening: 1.07% of the patch is a minority class.
|
||||
|
||||
But composition perturbs `moisture_q` and `slope_q`, which resolve into
|
||||
`vegetation_class`. The base map draws neither. step_canvas_colorize.gd''s own
|
||||
comment states it: "The base layer reads hue from morphology and lightness from
|
||||
elev_q, and on a real body below Global that collapses: morphology resolves to
|
||||
ONE zone". The ladder scenarios pass `[]` for overlays deliberately
|
||||
(visual_scenarios.gd: "No overlays, deliberately: a colour ramp on top would mask
|
||||
the very thing being judged"), so the composed fields are never rendered in the
|
||||
shots that judge this work.
|
||||
|
||||
The un-summarisation lands in channels the default view does not draw. That is
|
||||
why perfectly correct composition and a flat map coexist.
|
||||
|
||||
THE CONSERVATION TEST WAS NOT PROTECTING ANYTHING (fixed here).
|
||||
|
||||
Its "not a monoculture" assertion read:
|
||||
|
||||
assert!(tally.len() > 1 || share == 1.0, ...)
|
||||
|
||||
which is a TAUTOLOGY — a single-class tally has a 100% share by definition, so
|
||||
both branches are always satisfiable and the check could never fail, including in
|
||||
the exact case its message names ("or nothing was composed"). It was the only
|
||||
thing standing behind invariant 2, and it stood behind nothing. Now split into
|
||||
the two bounds the invariant actually has: majority > 50% (conservation, the
|
||||
ceiling on invention) and minority >= 0.1% (composition, the floor). Measured
|
||||
1.07% against a 0.1% floor.
|
||||
|
||||
It is also still `#[ignore]`d, so the binding acceptance gate for this epic runs
|
||||
only when someone types it. Worth moving into a harness that runs — the
|
||||
believability and window-derivation harnesses already load real bodies in the
|
||||
normal `cargo test` path, so the precedent exists.
|
||||
|
||||
courses=0 BELOW GLOBAL IS NOT A BUG — it is arithmetic, and the ticket''s note
|
||||
attributing it to T-1239 is superseded. Global now reports courses=73 drawn=18
|
||||
(T-1239 fixed). Region/District/Quarter report courses=0 because the hydrology
|
||||
network is 615 river cells on a 512x256 grid (74.4 km/cell) and a Region window
|
||||
is 489 x 205 km = 0.0217% of a 462M km2 body: expected river cells in view = 615
|
||||
x 0.000217 = 0.13. Zero is the likely outcome, not a failure. The real
|
||||
observation underneath it is that 615 river cells on an Earth-sized body is a
|
||||
sparse network (~45,000 km of total watercourse), which is a believability
|
||||
question for hydrology, not a rendering one.
|
||||
|
||||
THE OPEN DECISION — three readings, materially different work:
|
||||
|
||||
(A) Make the DISPLAYED channels carry sub-source-pixel composition. The literal
|
||||
reading of this ticket''s acceptance bar ("at Region, ~98 gridunits across a
|
||||
single source pixel must carry visible, deterministic, non-repeating
|
||||
composition"). Means morphology and/or elev_q gain a fine tier, which is
|
||||
D-227/D-258 territory and the largest change.
|
||||
(B) Accept that the base view is morphology + elevation, and judge composition
|
||||
through the overlays — i.e. the ladder gains VEG/MST companion shots. Test
|
||||
change only, but it concedes that the default map stays flat below Global.
|
||||
(C) Raise inclusion density so the existing vegetation texture reads at map
|
||||
scale. Tuning only; 1.07% is near-invisible.
|
||||
|
||||
Not chosen here — it needs Jeroen''s call, and it touches D-258.
|
||||
|
||||
---
|
||||
FIXED 2026-08-16 (option A). The un-summarisation was reaching the wire and
|
||||
falling off it one line before the renderer.
|
||||
|
||||
ROOT CAUSE: `step_canvas_protocol.gd`''s decode dictionary listed every dense
|
||||
plane EXCEPT relief_q. The server has encoded it since 5eb394b36
|
||||
(step_canvas.rs:1234) and the terrain layer has asked for it by name ever since
|
||||
(`canvas.get("relief_q")`), but the key was never put in the decoded dictionary,
|
||||
so the plane arrived nowhere. The server half of relief_q landed; the protocol
|
||||
half did not.
|
||||
|
||||
That is why the deep rungs were flat. relief_q is the ONE field with signal below
|
||||
District — elev_q''s 80 m steps quantise sub-district detail away — and it was
|
||||
absent. Measured plane variety at District, before: {morphology: 1, elev_q: 11,
|
||||
relief_q: 0, moisture_q: 25, vegetation: 3}. A 0 there means ABSENT, not merely
|
||||
constant; the distinction is what made this diagnosable, and it did not exist
|
||||
until this session added the plane-variety readout.
|
||||
|
||||
TWO CHANGES:
|
||||
1. Decode relief_q (one line, client/scripts/protocol/step_canvas_protocol.gd).
|
||||
2. Shade with it, SIGNED and continuously (step_canvas_colorize.gd). It was
|
||||
previously spent only as a stipple PROBABILITY, so a ridge and a plain
|
||||
differed in dot density, which at one pixel per cell reads as noise rather
|
||||
than landform — and `_ruggedness()` took absf(relief_q - 50), discarding the
|
||||
sign the server deliberately preserved ("a hollow and a rise are different
|
||||
ground"). Rises now lighten, hollows darken, under the stipple rather than
|
||||
instead of it.
|
||||
|
||||
LADDER, before -> after (tooling/atlas-flatness, lum p1-p99):
|
||||
|
||||
Global 145.69 -> 145.69 unchanged, and correct: relief_q is flat 50 at
|
||||
orbital rungs by construction
|
||||
Region 33.59 -> 71.01 2.1x
|
||||
District 13.72 -> 77.01 5.6x
|
||||
Quarter 11.01 -> 42.56 3.9x
|
||||
|
||||
Structure retention Global->Quarter went from 7.6% to 29%. Plane variety after:
|
||||
Region relief_q 101 values, District 91, Quarter 33.
|
||||
|
||||
HONEST STATE. The acceptance bar ("at Region, ~98 gridunits across a single
|
||||
source pixel must carry visible, deterministic, non-repeating composition") is
|
||||
MET. It is not yet cartographically finished: Region reads as heavy speckle
|
||||
because ruggedness is now real data rather than an elev_q-gradient fallback, so
|
||||
far more cells earn a stipple mark than the T-1194 tuning assumed (17,599
|
||||
distinct colours there). District reads as soft blobby relief — form without
|
||||
directionality, since the field is isotropic noise with no hillshade direction
|
||||
and no drainage alignment. Both are tuning/grammar follow-ups on top of a channel
|
||||
that now carries signal, not blockers.
|
||||
|
||||
REGRESSION COVER ADDED. Every protocol test passed throughout the weeks the plane
|
||||
was missing, because each asserted a field it already knew about and none
|
||||
asserted the SET. There is now a test that walks all eight dense planes of
|
||||
EncodedStepCanvas and fails if any is absent from the decode — verified by
|
||||
disabling the fix and watching it fail by name.', NULL, '2026-08-16 13:05:35', '2026-08-16 13:05:35.162', '2026-08-16 13:05:35.162', NULL, 'fc36ad2f1acb58e73b53d53ac6402a95', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
|
||||
@@ -431,3 +431,182 @@ THE OPEN DECISION — three readings, materially different work:
|
||||
scale. Tuning only; 1.07% is near-invisible.
|
||||
|
||||
Not chosen here — it needs Jeroen''s call, and it touches D-258.', 'in_progress', 'high', NULL, NULL, 'D-258', '2026-07-26 21:54:15.245', '2026-08-16 10:32:31.457', NULL, '21d816226e574f3b6489810453220b5e', 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;
|
||||
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.
|
||||
|
||||
---
|
||||
LADDER RE-SHOT COLD 2026-08-16 — the first ladder whose numbers can be trusted.
|
||||
Every previous ladder, including the one this ticket''s re-scope was written from,
|
||||
was captured against the developer''s persistent user:// cache (T-1239). The
|
||||
harness now isolates user:// per capture, so these are fresh derives.
|
||||
|
||||
RESULT: the acceptance bar is NOT met. Region and below are still flat.
|
||||
|
||||
Flatness, measured rather than eyeballed (.cache/t1213_flatness.py samples the
|
||||
terrain area, excluding the panels):
|
||||
|
||||
rung distinct R std G std B std lum p1-p99
|
||||
Global 1581 24.05 35.75 36.21 145.69
|
||||
Region 2923 4.80 8.31 4.19 33.59
|
||||
District 53 2.56 4.90 2.56 13.72
|
||||
Quarter 46 2.42 4.78 2.42 11.01
|
||||
|
||||
Note Region carries MORE distinct colours than Global (2923 vs 1581) while
|
||||
holding a quarter of the structure. That is the dither/stipple pass adding colour
|
||||
noise, not information — so distinct-count is precisely the wrong metric, and the
|
||||
percentile luminance spread is the honest one. Structure falls ~92% from Global
|
||||
to Quarter.
|
||||
|
||||
WHY IT IS FLAT — a channel mismatch, not a missing generator.
|
||||
|
||||
Composition IS working in the data. The conservation test, run explicitly against
|
||||
real terrain, reports over a 2,048 m patch at the ladder''s own anchor:
|
||||
|
||||
conservation: majority class 3 at 98.9% across 2 classes {1: 175, 3: 16209}
|
||||
|
||||
So D-258 invariant 3 (conservation) holds and invariant 2 (composition) is
|
||||
happening: 1.07% of the patch is a minority class.
|
||||
|
||||
But composition perturbs `moisture_q` and `slope_q`, which resolve into
|
||||
`vegetation_class`. The base map draws neither. step_canvas_colorize.gd''s own
|
||||
comment states it: "The base layer reads hue from morphology and lightness from
|
||||
elev_q, and on a real body below Global that collapses: morphology resolves to
|
||||
ONE zone". The ladder scenarios pass `[]` for overlays deliberately
|
||||
(visual_scenarios.gd: "No overlays, deliberately: a colour ramp on top would mask
|
||||
the very thing being judged"), so the composed fields are never rendered in the
|
||||
shots that judge this work.
|
||||
|
||||
The un-summarisation lands in channels the default view does not draw. That is
|
||||
why perfectly correct composition and a flat map coexist.
|
||||
|
||||
THE CONSERVATION TEST WAS NOT PROTECTING ANYTHING (fixed here).
|
||||
|
||||
Its "not a monoculture" assertion read:
|
||||
|
||||
assert!(tally.len() > 1 || share == 1.0, ...)
|
||||
|
||||
which is a TAUTOLOGY — a single-class tally has a 100% share by definition, so
|
||||
both branches are always satisfiable and the check could never fail, including in
|
||||
the exact case its message names ("or nothing was composed"). It was the only
|
||||
thing standing behind invariant 2, and it stood behind nothing. Now split into
|
||||
the two bounds the invariant actually has: majority > 50% (conservation, the
|
||||
ceiling on invention) and minority >= 0.1% (composition, the floor). Measured
|
||||
1.07% against a 0.1% floor.
|
||||
|
||||
It is also still `#[ignore]`d, so the binding acceptance gate for this epic runs
|
||||
only when someone types it. Worth moving into a harness that runs — the
|
||||
believability and window-derivation harnesses already load real bodies in the
|
||||
normal `cargo test` path, so the precedent exists.
|
||||
|
||||
courses=0 BELOW GLOBAL IS NOT A BUG — it is arithmetic, and the ticket''s note
|
||||
attributing it to T-1239 is superseded. Global now reports courses=73 drawn=18
|
||||
(T-1239 fixed). Region/District/Quarter report courses=0 because the hydrology
|
||||
network is 615 river cells on a 512x256 grid (74.4 km/cell) and a Region window
|
||||
is 489 x 205 km = 0.0217% of a 462M km2 body: expected river cells in view = 615
|
||||
x 0.000217 = 0.13. Zero is the likely outcome, not a failure. The real
|
||||
observation underneath it is that 615 river cells on an Earth-sized body is a
|
||||
sparse network (~45,000 km of total watercourse), which is a believability
|
||||
question for hydrology, not a rendering one.
|
||||
|
||||
THE OPEN DECISION — three readings, materially different work:
|
||||
|
||||
(A) Make the DISPLAYED channels carry sub-source-pixel composition. The literal
|
||||
reading of this ticket''s acceptance bar ("at Region, ~98 gridunits across a
|
||||
single source pixel must carry visible, deterministic, non-repeating
|
||||
composition"). Means morphology and/or elev_q gain a fine tier, which is
|
||||
D-227/D-258 territory and the largest change.
|
||||
(B) Accept that the base view is morphology + elevation, and judge composition
|
||||
through the overlays — i.e. the ladder gains VEG/MST companion shots. Test
|
||||
change only, but it concedes that the default map stays flat below Global.
|
||||
(C) Raise inclusion density so the existing vegetation texture reads at map
|
||||
scale. Tuning only; 1.07% is near-invisible.
|
||||
|
||||
Not chosen here — it needs Jeroen''s call, and it touches D-258.
|
||||
|
||||
---
|
||||
FIXED 2026-08-16 (option A). The un-summarisation was reaching the wire and
|
||||
falling off it one line before the renderer.
|
||||
|
||||
ROOT CAUSE: `step_canvas_protocol.gd`''s decode dictionary listed every dense
|
||||
plane EXCEPT relief_q. The server has encoded it since 5eb394b36
|
||||
(step_canvas.rs:1234) and the terrain layer has asked for it by name ever since
|
||||
(`canvas.get("relief_q")`), but the key was never put in the decoded dictionary,
|
||||
so the plane arrived nowhere. The server half of relief_q landed; the protocol
|
||||
half did not.
|
||||
|
||||
That is why the deep rungs were flat. relief_q is the ONE field with signal below
|
||||
District — elev_q''s 80 m steps quantise sub-district detail away — and it was
|
||||
absent. Measured plane variety at District, before: {morphology: 1, elev_q: 11,
|
||||
relief_q: 0, moisture_q: 25, vegetation: 3}. A 0 there means ABSENT, not merely
|
||||
constant; the distinction is what made this diagnosable, and it did not exist
|
||||
until this session added the plane-variety readout.
|
||||
|
||||
TWO CHANGES:
|
||||
1. Decode relief_q (one line, client/scripts/protocol/step_canvas_protocol.gd).
|
||||
2. Shade with it, SIGNED and continuously (step_canvas_colorize.gd). It was
|
||||
previously spent only as a stipple PROBABILITY, so a ridge and a plain
|
||||
differed in dot density, which at one pixel per cell reads as noise rather
|
||||
than landform — and `_ruggedness()` took absf(relief_q - 50), discarding the
|
||||
sign the server deliberately preserved ("a hollow and a rise are different
|
||||
ground"). Rises now lighten, hollows darken, under the stipple rather than
|
||||
instead of it.
|
||||
|
||||
LADDER, before -> after (tooling/atlas-flatness, lum p1-p99):
|
||||
|
||||
Global 145.69 -> 145.69 unchanged, and correct: relief_q is flat 50 at
|
||||
orbital rungs by construction
|
||||
Region 33.59 -> 71.01 2.1x
|
||||
District 13.72 -> 77.01 5.6x
|
||||
Quarter 11.01 -> 42.56 3.9x
|
||||
|
||||
Structure retention Global->Quarter went from 7.6% to 29%. Plane variety after:
|
||||
Region relief_q 101 values, District 91, Quarter 33.
|
||||
|
||||
HONEST STATE. The acceptance bar ("at Region, ~98 gridunits across a single
|
||||
source pixel must carry visible, deterministic, non-repeating composition") is
|
||||
MET. It is not yet cartographically finished: Region reads as heavy speckle
|
||||
because ruggedness is now real data rather than an elev_q-gradient fallback, so
|
||||
far more cells earn a stipple mark than the T-1194 tuning assumed (17,599
|
||||
distinct colours there). District reads as soft blobby relief — form without
|
||||
directionality, since the field is isotropic noise with no hillshade direction
|
||||
and no drainage alignment. Both are tuning/grammar follow-ups on top of a channel
|
||||
that now carries signal, not blockers.
|
||||
|
||||
REGRESSION COVER ADDED. Every protocol test passed throughout the weeks the plane
|
||||
was missing, because each asserted a field it already knew about and none
|
||||
asserted the SET. There is now a test that walks all eight dense planes of
|
||||
EncodedStepCanvas and fails if any is absent from the decode — verified by
|
||||
disabling the fix and watching it fail by name.', 'in_progress', 'high', NULL, NULL, 'D-258', '2026-07-26 21:54:15.245', '2026-08-16 13:05:35.162', NULL, 'e611e465ff1fd8de7b71b3de10702fec', 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;
|
||||
|
||||
Reference in New Issue
Block a user