docs(composer): record what measuring the world actually found

The notes described Tier 1 as done and had no record of today. Adds §13
(Tier 2 built, and the three artifacts that looked exactly like findings),
§14 (the VerticalShafts bug end to end -- three bugs wearing one coat),
§15 (working notes that cost something), and corrects the Tier 1/Tier 2
entries in §7.

The rule worth keeping, because it held three times out of three: when a
measurement reports something alarming, SUSPECT THE MEASUREMENT FIRST.
"FlatPlain is 99.95% void", "5 of 15 endpoints disconnected" and "7 of 16
seeds fail" were all method, not world.

Also recorded: the two guard directions are not symmetric (a false
positive drops a player through the floor; a false negative merely sends
you fixing healthy code), percolation is a phase transition and not a
knob, and Tier 1 shipped half built in a way only a connectivity
measurement could reveal.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJiTcTSDNkKBtnNdiBtdaU
This commit is contained in:
Fr0zkaandClaude Opus 5 committed 2026-09-03 15:21:41 +02:00
1 parent 9d5633ad54
commit 271bbdd034
1 file changed
+163 -7
+163 -7
View File
@@ -462,15 +462,27 @@ refactor, where three weeks of correct work produced a world unchanged by a sing
tidied without changing every world. Small and isolated. tidied without changing every world. Small and isolated.
### Tier 1 — the primordial law (a BUG FIX, not composer work) ### Tier 1 — the primordial law (a BUG FIX, not composer work)
- **`SuggestLandingPoint` on field sources; passages aim at it** (§6.4). - ✅ **`SuggestLandingPoint` on field sources; passages aim at it** (§6.4) — DONE, **both mouths**.
- **The passage mouth becomes a room plus a distinctive landmark** (§6.5). ⚠️ It shipped HALF BUILT for weeks: only the LOWER mouth was ever aimed. See §14.3 — the ring proxy
could not see it, and only the Tier 2 connectivity measurement could.
- ⬜ **The passage mouth becomes a room plus a distinctive landmark** (§6.5) — not started.
- ⬜ **`SurfaceWorld` still refuses the query** — it needs manager-resolved biome context, which
cannot be answered from a pure free function. Open.
*Standalone value:* fixes a **live hole in the shipping game** — today a player can descend into a *Standalone value:* fixes a **live hole in the shipping game** — a player could descend into a
sealed pocket. Worth doing even if the composer never happens. sealed pocket. Worth doing even if the composer never happens. **It was real**: see §14.
### Tier 2 — the measurement pass (§3.4) ### Tier 2 — the measurement pass (§3.4) — ✅ BUILT (2026-09-03), see §13
*Standalone value:* it **is** F1, `fable-idea.md`'s top-pick world-preview tool. Jahni can finally see `VoxelStrateMeasure.h/.cpp` + `VoxelForge.Generation.StrateConnectivity` / `...Refinement`.
what parameters do instead of tuning blind. It also verifies Tier 1. *Standalone value:* it **is** F1, `fable-idea.md`'s top-pick world-preview tool — the measurement
half. The visualisation on top is not built yet.
**It paid for itself immediately**: it found the `VerticalShafts` primordial-law violation (§14),
which no amount of playing was likely to surface, and it caught three of its own artifacts before
they became "findings" (§13).
⬜ Remaining: the *preview* (F1's visualisation), and the danger/rarity metric families from §3.4
(fall exposure, openness, traversal mix, tortuosity, corpus-centroid distance).
### Tier 3 — op-system prerequisites for free composition ### Tier 3 — op-system prerequisites for free composition
- **Channel read/write declarations** on every op, so ordering derives from a DAG (§3.2). - **Channel read/write declarations** on every op, so ordering derives from a DAG (§3.2).
@@ -677,3 +689,147 @@ assert only that nothing it reports is wrong.*
count and brace balance after any structural edit.** count and brace balance after any structural edit.**
- **Do not run builds while a Codex task is active** — `CodexGuidance.md` §Collaboration: one agent per - **Do not run builds while a Codex task is active** — `CodexGuidance.md` §Collaboration: one agent per
working tree. working tree.
---
## 13. Tier 2 BUILT — and what measuring the world actually found (2026-09-03)
**The measurement pass exists, is falsifiable, and earned itself on the first run by finding a live
gameplay bug that six months of playing might not have surfaced.**
`VoxelStrateMeasure.h/.cpp` — read-only, deterministic, headless. One coarse grid, one 6-connected
air flood fill, every metric derived from that same grid: air fraction, component count, largest
component share, walkable fraction, median feature scale, median vertical clearance, and connectivity
between two points. `VoxelForge.Generation.StrateConnectivity` (fast) and
`...StrateConnectivityRefinement` (the slow sweeps).
### ⭐ The single most important habit this produced
**Every reported number states the volume it was measured in.** `ResolvedMarginVoxels`, `SampledMinZ`,
`SampledMaxZ` are on the metrics struct and printed. This exists because the first version did not
have it, and the consequence is below.
### ⚠️ Three artifacts that looked exactly like findings
Each of these was, briefly, believed. Each was wrong. The pattern is identical every time: **a number
produced by a method nobody had questioned.**
1. **"FlatPlain is a 99.95% empty void."** The interior window excluded a whole chunk (32 voxels) at
each strate boundary to avoid a 4-voxel seal band — 8x too much. On 4-chunk strates that discarded
*half of every strate, floor included*. Walkable fraction was reading 0.00044; with the window
derived from the seal that actually exists (`2 x BoundarySealThickness`), it is 0.0578. **132x.**
*My spec's error.*
2. **"5 of 15 passage endpoints are disconnected."** The test's `LargestComponentAnchor()` did not find
the largest component — it returned a hardcoded guess near the (0,0) spine. And the question itself
was wrong: *"connected to the largest component"* is not the primordial law. A strate can be 57
disconnected shafts and be perfectly good, provided the shaft you arrive in is the shaft you leave
from. Corrected: **13 of 15 connected**, and the real question is `arrival → departure`.
*My spec's error, twice over.*
3. **"7 of 16 seeds fail the law."** `VF_AreConnected` took the shortest coarse BFS route, re-walked it
at full resolution, and on hitting a wall returned false and gave up — never looking for another
way round. Of those failures, only 2 were `NOT_CONNECTED`; **7 were `COARSE_LIED`**, i.e. one
candidate route was blocked. A blocked route is not a disconnected pair. *My verifier's error.*
⇒ **Rule: when a measurement reports something alarming, suspect the measurement first.** It was the
method three times out of three. The cost of checking is minutes; the cost of not checking was nearly
a rewrite of generation that was not broken.
### The guard is two-directional now, and the directions are NOT symmetric
- **False POSITIVE** (coarse says joined, reality is walled) → *dangerous*: no geometry, no collision,
a player falls through the floor. `FullResolutionPathIsAir` re-walks the recovered route at
one-voxel spacing. It fires: **2 of 21 routes** on the first run were coarse false positives.
- **False NEGATIVE** (a corridor thinner than `SampleStep` vanishes) → *merely wrong*, but wrong in the
direction that sends you "fixing" healthy code. Named explicitly as
`NotConnectedAtThisResolution` so a bare negative can never be read as proof.
⇒ **`CoarseLiedBudgetExhausted` means UNKNOWN and must never be folded into "disconnected".**
### Settling a finding: refinement with the confound held fixed
`VerticalShafts` was declared a real bug only after step 4→2→1 (7.34M cells), radius 256→192→128, and
margin 8→4→2→0 (margin 0 includes the seal, which can only *add* solid, so it cannot invent a route) —
with **step and radius varied independently** so neither could explain the result. Then 16 seeds,
because a single fixture cannot distinguish one unlucky world from a broken archetype. See
[[tests-must-be-falsifiable]]; a 7-sample fixture already hid a defect that fired 92.8% of the time.
---
## 14. The VerticalShafts bug, end to end
**Symptom:** descend into a `VerticalShafts` strate and you cannot reach its exit. 15 of 16 seeds.
**It was three bugs wearing one coat.**
### 14.1 The spine was not the backbone there
The (0,0) spine (`OriginSpineRadius` 14) holds 97–100% of the air and is the largest component in
**7 of 8** archetypes. In `VerticalShafts` it punched through as an isolated column holding **9.6%**,
never the largest. Fixed: the spine now participates as a *connector endpoint* — **not** as a carving
shaft; `VF_ApplyOriginSpine` remains sole owner — and is excluded from ledge placement.
Necessary, **not sufficient**: it only joins its own 3x3 neighbourhood, and mouths land 60–200 voxels out.
### 14.2 ⭐ The shaft graph sat below its percolation threshold
The tell was a *plateau*: the largest component sat at **~0.22 in every variant** — roughness 0,
connector radius 8, baseline. Roughness changed the component *count* (it manufactures noise pockets)
but never the giant component's share.
`ShaftDensity` 0.6 sites, `CrossConnectChance` 0.35 bonds, and a `1.6`-cell pair cutoff that silently
drops many neighbour pairs once jitter spreads shafts 1.7 (orthogonal) to 2.4 (diagonal) cells apart.
⛔ **Do NOT fix this by raising those three numbers.** Percolation is a **phase transition**: tuning
toward it buys a world connected at one seed and shattered at the next — which *is* the 1-in-16
behaviour. A phase transition is not a knob.
✅ **Fixed structurally:** a **drainage tree**. Every shaft emits a deterministic connector to the
nearest shaft *strictly closer to the origin*, so chains drain inward and terminate at the spine. The
probabilistic connectors stay as texture and loops — the tree guarantees you can get out, the noise
keeps it from reading as a diagram.
- seed 1337: **30 components / .220 largest → 17 / .975**
- 16 seeds: spine is the largest component **16/16** (was 8/16)
⚠️ **Seam hazard, and the reason for the 7x7 window.** A shaft's parent computed from a 3x3 window
would differ between chunks, so the connector would exist in one and not the other — invisible in the
metrics, very visible in game. **Collect over 7x7, emit only for the inner 3x3**, whose 5x5 candidate
windows are then fully contained. Guarded by `VoxelForge.Generation.VerticalShaftSeamFreedom`
(154 probes, 0 mismatches). The 49 hash rolls happen on **cache rebuild, never per voxel**
(1.634 us rebuild, 0.100 us hot call).
⚠️ Connector radius must exceed the **proven roughness supremum**
(`SurfaceRoughness x VOXEL_NOISE_SCALE x 1.5` = 5.625 at defaults; `sup|FBM|` is **1.5, not 1.0** —
see [[voxelforge-noise-bounds]]). A guaranteed connector that noise can close is not a guarantee.
### 14.3 ⭐ Tier 1 was only ever HALF BUILT
`VF_SuggestLandingPoint` was called **once per passage, for the LOWER mouth only**. The upper mouth
fell out of the control-point chain with no landing query at all. **Tier 1 fixed where a player
ARRIVES and never touched where they DEPART** — and the measurement said so exactly:
`departure → spine` was **0 connected across all 16 seeds**.
**The ring proxy could never have caught this.** It checks each mouth for open space individually, and
an unaimed mouth still has open space around it *because the passage tube carved some*. Only a
connectivity measurement could see it. This is the strongest argument in the whole project for Tier 2
existing at all.
✅ Fixed: each mouth queries **its own** strate independently — which is precisely what keeps the
layout a **set, not a sequence**. Passage `i` never reads passage `i-1`, so
`LayoutOrderIndependence` stays green. ⛔ The "obvious" fix (chain the mouths) would break it.
- `departure → spine`: **0 → 9** of 16 · `arrival → departure`: **4 → 7** of 16
**Status: not yet 16/16.** The remaining gap is mostly `COARSE_LIED`, i.e. §13's verifier defect, not
the world. Fix the measurement before touching generation again.
---
## 15. Working notes that cost something
- ✅ **The `codex exec` hang was stdin.** It prints `Reading additional input from stdin...` and blocks
forever on an inherited pipe. **Always `< /dev/null`.** Cost 4.5 h once. Read the banner's
`reasoning effort:` line back after every launch — Jahni asks for `max`.
- **A killed agent leaves unvalidated edits.** A session teardown killed Codex mid-task; the edits were
complete and correct but had never been built. **Build and run them yourself rather than assume** —
a clean-looking diff is not a passing test.
- **Codex has found six real errors in my specs across nine tasks.** Asking for disagreement in every
spec is the highest-value line in them. Three of today's corrections came from it, not me.
- **Acceptance must be the measured property, never "the code was written."** Twice a task returned
"built, and it does not meet the criterion — here is the number." Both times that honesty pointed
straight at the real cause.