isomesh — findings ledger
Started: 2026-08-11 · Append-only. Entries are never deleted, only re-tiered when new evidence arrives — with the old verdict left visible.
This is the project's epistemic state: what we believe, how strongly, and on what evidence. It exists because this project has already been wrong six times in ways that would have silently propagated into code, and because the research corpus contains several published figures that failed verification. A belief with no recorded falsification method is not a finding, it's a preference.
Machines
Every measured figure in this repo comes from one of these two, and machine-specific figures say
which (the README and demo pages lean on this block by reference; added at D-003, sourced from
docs/research/2026-08-13-measured-comparison.md).
| M5 | Apple M5 · macOS · arm64 · Metal — docs/measurements/resolution_sweep.csv |
| Zen 3 | AMD Ryzen 9 5900X · Linux · x86-64 · NVIDIA RTX 3090 (Vulkan) — docs/measurements/resolution_sweep-ryzen9-5900x.csv, and every GPU figure |
How to use this file
- Before acting on a "known" fact, look for it here. If it's not here, it hasn't been checked.
- When a measurement contradicts something written down, that's an entry — the contradiction is the finding, not an inconvenience.
- Falsified entries stay. They're the most valuable rows, because they tell you which sources to distrust, not just which facts.
- Every entry names how it could be shown wrong. If you can't write that line, you have an opinion.
- An experiment that was run and reverted is an entry too — Part 4b. The verdict line is the point: a variant that was built, measured and put back is the most expensive thing to rediscover, because nothing left in the tree records that it was ever tried.
Index
611 entries — 130 falsified, 390 measured, 52 verified, 18 open, 21 experiments. Regenerate with scripts/findings_index.sh; CI fails if this is stale.
| # | Claim |
|---|---|
✗1 |
"Surface Nets produces substantially fewer triangles than Marching Cubes" |
✗2 |
"You can have a manifold mesh or an intersection-free one, not both" |
✗3 |
"Every interior Surface Nets vertex has four neighbours" |
✗4 |
"Dual Contouring is absent from the home-still corpus" |
✗5 |
"naga_oil is the shader composition path for Bevy" |
✗6 |
"Mesh shaders aren't reachable from inside Bevy" |
✗7 |
"CBT 5.78 → 0.40 ms is from Dupuy 2020" |
✗8 |
Velo3D "93M vertices / 31M faces" |
✗9 |
"Marching Cubes' cost inside the volumetric loop was never measured" / "navmesh rebuild cost was never measured" |
✗10 |
"glam should be the internal math library from day one" |
✗11 |
"Plain Marching Cubes has ambiguous faces and produces holes" |
✗12 |
"The equivariant vertex rule needs a fast three-plane path with a fallback" |
✗13 |
"Real::as_f32 is the only narrowing operation in the crate, and the crate itself never calls it" |
✗14 |
"Surface Nets is the cheapest thing in the family and the natural default" |
✗15 |
"Marching Cubes is unconditionally manifold" |
✗16 |
"glam 0.32 lands with A-007's vertex solve" |
✗17 |
"Only the interior test can make Marching Cubes 33 non-manifold, so the face decider alone cannot" |
✗18 |
"A hairline seam difference is a crack no weld can close" |
✗19 |
"Manifold Dual Contouring's uniform-grid surface is always a manifold" |
✗20 |
"Every ACD method assumes closed, watertight, 2-manifold, self-intersection-free, consistently oriented input" |
✗21 |
"Convex Primitive Decomposition is the cutting substrate a plane-cut fracture pipeline wants" |
✗22 |
"MeshReport applies a closed-solid test to render meshes, so it must be split into two report types" |
✗23 |
"Manifold Dual Contouring queries where it needs to, so it wants an on-demand field" |
✗24 |
"Empty-cell rejection benefits every field, however little" |
✗25 |
"Marching Cubes is the only one of the family in the good corner of manifold × intersection-free" |
✗26 |
P-25's mechanism clause is false, and P-25's own falsifier is what named it (R-022b) |
✗27 |
"an exactly-zero SDF gradient detects the medial axis" |
✗28 |
FALSIFIED at 0.98 against a registered 1.5×: the 128³ penalty is a property of the access pattern, not of the stride, an… |
✗29 |
FALSIFIED on both clauses, and the mechanism survives both: the max is the wrong order statistic, and the cost clause wa… |
✗30 |
FALSIFIED: with B the whole closed surface, the registered residual is discrete Gauss–Bonnet in an approximation check's… |
✗31 |
the correlation reproduced out of sample and the line dies anyway: the exponent gap is the normalisation, and a mean's c… |
✗32 |
the two measures split: the Gaussian one is chunk-local and does not sum, the mean one sums and is not chunk-local (P-45… |
✗33 |
the repair is free and total where the critical set is sparse, and catastrophic where it is dense (P-46, R-040a) |
✗34 |
the gradient hole is real, measurable, and three orders too small to matter; the speedup is real and holds (P-47, R-043) |
✗35 |
two Phase 19 entries quote runs that are not in the CSVs they cite, and one of them was a verdict: the bitmap's C2 fails… |
✗36 |
FALSIFIED on all three clauses, and the zero was unreachable by geometry rather than by sampling: a mesh edge is a chord… |
✗37 |
FALSIFIED on three of four clauses, and the algebra says why: Eq. (8) confined to a cell is a contraction toward the cel… |
✗38 |
C1 and C3 HELD, C2 falsified by a measured absence: nothing pierces the empty ball, and between 2.9% and 80.5% of sphere… |
✗39 |
C1 and C2 FALSIFIED, C3 HELD: plain marching_cubes is bit-exactly equivariant under axis relabelling and not under refle… |
✗40 |
FALSIFIED on all three clauses, and two of the three failures are the clause's fault rather than the paper's: reversing… |
✗41 |
9.45× on the 13 chunks where a brush matters |
✗42 |
C1 FALSIFIED and C3 HELD, and C2 passes for a reason that is not its own: the paper's 8 dB reconstruction gain maps to a… |
✗43 |
"one interior vertex per cell is enough": the interior rule fans every contour of a cell from the same apex, and two con… |
✗44 |
"IsomeshPlugin is engine-agnostic and platform-agnostic": its frame budget calls std::time::Instant::now(), which compil… |
✗45 |
"five samples in a cross under the foot beat one": at a fixed depth the cross reaches into terrain above the foot, and t… |
✗46 |
"headless Chrome on this host exposes no navigator.gpu": it exposes the object and no adapter, which is the one failure… |
✗47 |
"GPU_JOBS_MAX bounds the queue": the cap was checked after the push, so it bounded nothing at all (D-014) |
✗48 |
"the field already stops the descent, and the floor slab is scenery": dig out the bottom and the player leaves the world… |
✗49 |
plain Marching Cubes is now bit-exactly equivariant under all 48 octahedral elements |
✗50 |
"MAX_PATCH_TRIANGLES = 24 bounds the trilinear patch": it was a sampled maximum plus two, fan_tunnel's own buffer was al… |
✗51 |
C1 FALSIFIED, C2 HELD, C3 VACUOUS: the prescribed loop shape is a 3–7% regression, %ymm is zero in every monomorphisatio… |
✗52 |
C1 and C2 FALSIFIED, C3 FALSIFIED at 5 of 24 cells: the 83% reproduces at 87.0% and M-160's flat 0.17 ms reproduces at 0… |
✗53 |
sound at k = 17 and not at k = 5 |
✗54 |
C1 FALSIFIED by arithmetic computed at registration, C2 and C3 HELD: the subgroup scan is real at 1.4114× and reproduces… |
✗55 |
C1 FALSIFIED by 10 violations in 19,415 and the registered coefficient is off by exactly one unit: 2 is unsound, 3 is so… |
✗56 |
C1 FALSIFIED on 28 of 60 testable rows and separately VACUOUS on 6 of 16 cases, C2 FALSIFIED at 0 of 7 fields, C3 FALSIF… |
✗57 |
C1 HELD at 0.3996 / 0.1363 ms and still holds at 0.9406 / 1.2215 ms |
✗58 |
C1 FALSIFIED both ways at 2.8997× against a fixture ceiling of 2.9852 and a single-frame spike; C2's recovery half FALSI… |
✗59 |
C1's factor bound FALSIFIED at 3.36–8.38 with c1_holds true on 18 of 72 rows, C1's world-size falsifier HELD at 1.391× a… |
✗60 |
C1 FALSIFIED at 20.3718 against a bar of 3, C2 FALSIFIED by 4 texels on one row with a 66-of-96-arm geometric leak under… |
✗61 |
C1 FALSIFIED on one field of eight with both halves of its falsifier firing, C2 FALSIFIED by 0.62° against a headroom of… |
✗62 |
C1 FALSIFIED by its own falsifier: the capture window is 2R + t, not t, so game_dig's 2-cell body radius makes 2R 4.0 ce… |
✗63 |
C1 FALSIFIED by 44× to 2,275× at 33³ on all eight fields and no integrator could have passed it: a volume integral over… |
✗64 |
10,464–12,726 cycles per fragment |
✗65 |
C1 HELD at 80.3–81.8% and C2 FALSIFIED twice over: the copy is 0.035–0.050% and the BVH does not dominate either, so the… |
✗66 |
C1 FALSIFIED at 3.01% against a 20% bar, and the bar was 15.29× chance rather than 2×: a capsule hits a sliver at 2.30×… |
✗67 |
C1 and C2 HELD, C3 FALSIFIED: an octree navigation graph built on the sign bitmap and never on a triangle repairs P-72's… |
✗68 |
C1 FALSIFIED on both readings (0.688892 and 0.831008 against a 0.90 bar), C2 HELD for the cheap reading and FALSIFIED fo… |
✗69 |
C1 HELD at 4.36× and 1.76×, C2 FALSIFIED at 267% and 46%: 1³ is worse than 2³ on both fields, so M-377's 4³ optimum is n… |
✗70 |
C1 HELD at 6.3916× and 10.4802× on the registered 46–60 bucket, but only at the brick: P-39's chunk-level cull alone rea… |
✗71 |
item 3.6's prediction is exactly inverted: geomorph FAILS on fbm_terrain at 25.0771 px and the gyroid half it was predic… |
✗72 |
C1 FALSIFIED on both of its readings, by 3.00× at the cheapest field |
✗73 |
C1 FALSIFIED on the quantity it is denominated in, C3 FALSIFIED at every rate on every variant, C2 HELD by 509×: the reg… |
✗74 |
C1 HELD on the size half and HELD WITH NO INSTRUMENT on the constancy half, C2 and C3 FALSIFIED: an hour of continuous d… |
✗75 |
C1 and C2 FALSIFIED, C3 HELD: undo is always a re-fold — re-folding from a checkpoint is cheaper at every separation, by… |
✗76 |
C1 VACUOUS on M-38's own fixture, then HELD to 0.0375 and FALSIFIED from 0.075 on a fixture that can move; C2 HELD, C3 H… |
✗77 |
C1 FALSIFIED on 2 of 8 fields by exactly 3 bytes each, C2 FALSIFIED with an empty divergence population, C3 HELD on all… |
✗78 |
C1 HELD at 48 of 48 with worst_component_ulp 0, C3 HELD at 0 open edges, C2 FALSIFIED on both halves on 16 of 16 rows: M… |
✗79 |
C1 FALSIFIED at 3 of 16 and worse than shipped on 9 of them, C3 FALSIFIED by the two duals agreeing on 64 of 64 row-pair… |
✗80 |
C1 FALSIFIED as a whole-fixture gate at 21 of 32 rows clearing 0.10 (23 of 32 in instructions), C2 FALSIFIED on 32 of 32… |
✗81 |
C1 VACUOUS because the layout it is about is unreachable through the public API — the registered control read 1.0173× wh… |
✗82 |
C1 FALSIFIED on 32 of 32 rows with the best c1_deciding_ratio at 64³ reading 1.039764 against a 2× bar, C2 HELD bit-exac… |
✗83 |
C1 FALSIFIED on 24 of 24 rows with offset_share spanning 0.000328–0.009714 against a 0.05 bar, so the offset stage is at… |
✗84 |
C1 FALSIFIED on 16 of 16 exactly as registered: broadword select costs +48.9 to +61.0 instructions per set bit over dual… |
✗85 |
C1 FALSIFIED on 24 of 24 at 7.2959–12.6711 bits per crossing against a 4.0-bit bar it could not have reached — low_bits_… |
✗86 |
C1 FALSIFIED on 24 of 24 rows and in every unit (flip_plus_rank_ratio_instructions 2.2506–2.6863 against a bar of 2.0),… |
✗87 |
C1 FALSIFIED on 16 of 16 rows in all four recorded forms (ratio 0.41717–0.94158, instruction_ratio 0.32412–0.94875, and… |
✗88 |
C1 FALSIFIED on 16 of 16 with the rank arm 2.2× to 8.6× slower (speedup 0.116376–0.461247 against a bar of 1.25), C2 FAL… |
✗89 |
C1 FALSIFIED at 0 of 4 granularities straddling 6.25% and 1 of 4 where the winner varies, C2 FALSIFIED by 2 of 8 rows be… |
✗90 |
C1 HELD at 1.612× (65³) and 2.568× (129³) on the sparsest field as measured, and stronger in instructions — 2.129× and 3… |
✗91 |
C1 FALSIFIED on 16 of 16 rows at access_ratio 57.7683–115.7726 against a registered bar of 2.0 — random access is 29× to… |
✗92 |
C1 HELD at 256 of 256 triangulations identical to CASES, C3 HELD with 4 of 4 properties over 8,712 checks and 0 violatio… |
✗93 |
C1 FALSIFIED with the registered arm lifting 0 of 26 rows and reading the shipped baseline's 6 of 32 exactly, C2 FALSIFI… |
✗94 |
C1 FALSIFIED on 4 of 32 rows, all four fbm_terrain, ratio 1.7965–1.9008 against a 2.0× bar and every one of them decided… |
✗95 |
C1 HELD with the worst residual_share at 0.005195 against a 0.05 bar, C2 HELD with max_reference_integer_share_at_65 = 0… |
✗96 |
C1 FALSIFIED on 0 of 16 rows with branch_miss_ratio spanning 1.001214–1.983313 — the split doubles mispredictions at wor… |
✗97 |
C2 FALSIFIED on 6 of 6 with order_only_share topping out at 0.001373626 against a 0.50 bar, C1 HELD on 6 of 6 at a worst… |
✗98 |
C1 HELD to the integer (516 of 17,201 pinches on bonsai, 0 of 50 on fuel), C2 HELD with distinct_censuses 1 over 128 fac… |
✗99 |
C1 FALSIFIED on every conjunct at once — speedup 0.329 against a registered 10× bar, so the Δ arm is 3.04× slower, and a… |
✗100 |
C1 FALSIFIED with delta_zero_share reaching 1.000000 on box_exact — every one of its surface cells sits exactly on the h… |
✗101 |
C1 FALSIFIED at three of six orbit labels populated (unpopulated_orbits = zero|rank1|zero-rank2), C2 HELD hard — chi_squ… |
✗102 |
on an integer before any clock is read |
✗103 |
C2 FALSIFIED at 3 of 8 fields above the 0.50 bar against a registered 4 (c2_fields_above_bar 3, c2_min_fields 4, decided… |
✗104 |
C1 HELD to the integer on 16 of 16 in-scope rows (chi_measured -8 / -64 / -216 against chi_predicted -8 / -64 / -216 at… |
✗105 |
C1 FALSIFIED on 1 of 10 in-scope rows, schwarz_p at N = 3 reading chi_measured -102 against chi_predicted -108 with non_… |
✗106 |
C1 FALSIFIED by the three-octave half, where resolution_convergence reads never on 4 of 5 seeds and χ is still moving at… |
✗107 |
C1 FALSIFIED with c1_winners 0 of c1_population 4 against a bar of 3: at matched Hausdorff the metric-driven arm is neve… |
✗108 |
C1, C2 and C3 all FALSIFIED: the exponent moved by 0.352013 on fbm_terrain against a 0.1 bar, the fitted constant improv… |
✗109 |
C1 FALSIFIED where it could be read at all: torus's triangle saving is perfectly anti-monotone in the curvature ratio, S… |
✗110 |
C1 and C2 split 16 true / 48 false: they hold on torus alone, where gain_near 0.244932 collapses to gain_wide −0.010015… |
✗111 |
C1 FALSIFIED on 16 of 16 rows (beta_share 0.824659–1.693981 against a bar of 0.10), C2 FALSIFIED at c2_fields_above_bar… |
✗112 |
C1 FALSIFIED at c1_fields_won 2 of eight against a bar of five, C2 FALSIFIED at 0 of 2 named fields with beta_beats_curv… |
✗113 |
C1 FALSIFIED at c1_fields_within_bar 1 of eight against a bar of five, and unreachable at 4 — max_fields_any_constant 4,… |
✗114 |
C1 HELD with strang_fix_order 2 and measured_order 2 on 8 of 8, both derived and not quoted, C2 FALSIFIED at c2_hits 0 a… |
✗115 |
C1 FALSIFIED at c1_fields_within_5pct 5 of a c1_population of 6 (csg_difference at +6.80%), C2 HELD structurally with fo… |
✗116 |
C1 FALSIFIED with c1_hits 0 of c1_population 4: the tricubic Lagrange 4x4x4 filter is genuinely order-4 on its own zero… |
✗117 |
the null arrived exactly as registered: C1 HELD with mixed_derivative_norm divergent on both CSG fields (norm_growth_exp… |
✗118 |
C1 FALSIFIED at fields_improved 3 of 8 against a bar of five and C2 FALSIFIED at fields_in_neighbourhood 1 of 8, with me… |
✗119 |
a null registered on purpose came back not null: C1 FALSIFIED at fields_below_scatter 1 of 8, because measurement_scatte… |
✗120 |
C1 HELD on c1_fields_held 8 of 8 with order_gap spanning −0.072307 to +0.128478 against a bar of −0.15, both filters ord… |
✗121 |
the registered negative HELD and the hoped-for guarantee did not: C1 HELD with is_matroid false on all 6 greedy-meshing… |
✗122 |
C1 HELD on 20 of 20 rows with the per-bit decomposition measured to recompose rather than assumed, C2 HELD on 5 rows and… |
✗123 |
C1 HELD in the strongest reading the clause can have, because symmetry_class_count is 1: all eight corners are a single… |
✗124 |
C1 HELD with c1_fields_nonzero 6 of 8 and transversality failing measurably — box_exact reads non_transverse_fraction 0.… |
✗125 |
C1 FALSIFIED on 24 of 24 rows: intrinsic Delaunay flipping raises the worst-decile minimum angle by at most 1.642437° ag… |
✗126 |
VACUOUS as registered, and the reason is the formula's own algebra: at u = ±1 the Gaussian kinematic formula's (u² − 1)… |
✗127 |
VACUOUS as registered on one field of four, and that field is the finding: box_exact's reach is 0 and this estimator rea… |
✗128 |
the detector works, and it says the opposite of what was registered: C2 HELD on |
✗129 |
the cap was the sign, and it was not the gap. On the sphere's inscribed cube noise_cavity flips from χ |
✗130 |
M-31's cross-platform guarantee broke on the first push of M-494: macOS read |
M-1 |
surface cells = crossed edges + χ |
M-2 |
V_sn = V_mc + χ, F_sn = F_mc + 2χ |
M-3 |
Surface Nets max vertex degree 10; Marching Cubes 9 |
M-4 |
Surface Nets is non-manifold where one cell carries two sheets: 48 non-manifold edges on capped gyroid, 15 on fbm_terrai… |
M-5 |
On box_exact, Surface Nets' nearest vertex to the corner (1,1,1) is 1.15 cells away |
M-6 |
libm::sqrtf lowers to hardware fsqrt (aarch64+neon) / sqrtss (x86-64+sse2) |
M-7 |
dev-dependencies do not propagate: consumer resolves 3 packages, the crate's own lockfile has 137 |
M-8 |
317 packages, both 29.0.4 and 30.0.0 |
M-9 |
Workspace feature unification leaks: -p isomesh alone gives glam libm; whole-workspace gives it std, serde, bytemuck, en… |
M-10 |
Unit sphere at 64³ (h = 4/63), symmetric Hausdorff: Marching Cubes 1.380e-3, Surface Nets 2.288e-3. |
M-11 |
T-003's own acceptance criterion is loose by ~80×. |
M-12 |
Marching Cubes' error falls like h², measured. |
M-13 |
Surface cells ≈ 1.5·A/h², not A/h². |
M-14 |
The reverse direction finds defects the forward direction structurally cannot. |
M-15 |
Surface Nets' non-manifoldness is a resolution effect, not a topology effect. |
M-16 |
The even-χ parity check is not independent of manifoldness — it is a corollary of it. |
M-17 |
A case-table entry naming an uncut edge is caught inside the crate, before any mesh exists |
M-18 |
(refined by T-008 — the arithmetic below is about adjacent cells; the effect on a real mesh is gradual, because a mesh w… |
M-19 |
There is no meaningful fixed cost on the CPU extraction path, and the prediction saying so was written down before the r… |
M-20 |
Marching Cubes' marginal cost is 4.75 ns/sample — 211 M samples/s, single-threaded, f32, Apple M5. |
M-21 |
Surface Nets is not O(n³) over this range; Marching Cubes is. |
M-22 |
✗1's identity holds at every resolution to 256³ |
M-23 |
f64 costs 8–10% on extraction paths with no matrix solve in them. |
M-24 |
Bit-exact lattice equivariance needs magnitude-ordered products, not just sums. |
M-25 |
The sharp-feature solve is nearly free: Dual Contouring costs 3% more than Surface Nets. |
M-26 |
Dual Contouring reaches a box corner to 0.01 cells where Surface Nets stops at 0.58 |
M-27 |
The two dual methods differ only at features, with a 14-order-of-magnitude gap and nothing in between. |
M-28 |
The cell clamp eliminates placement-caused self-intersections entirely, and costs nothing in sharpness. |
M-29 |
The literature's two branches both fire, on disjoint fields — which is a sharper answer than either alone. |
M-30 |
An unclamped solve can fling a vertex 3.18 cells out of its own cell |
M-31 |
libm delivers the bit-identical cross-platform meshes it was chosen for — verified, not reasoned. |
M-32 |
Chunk seams are bit-exact only when the cell size is a power of two. |
M-33 |
E1, the unpublished number: a brush changes 15–36% of the cells in its own bounding box. |
M-34 |
Counting value changes overstates the re-mesh set by 2.8–3.7×. |
M-35 |
A brush stepping two cells sweeps 6–14% of its sign-changed cells entirely through. |
M-36 |
The multiplayer story survives, with a boundary. Eight brushes in all 8! = 40,320 orderings give exactly one result — bi… |
M-37 |
Mixed add and subtract do not commute: 11 distinct results from the same 40,320 orderings. |
M-38 |
Smooth union destroys reordering almost completely: 40,317 distinct results from 40,320 orderings. |
M-39 |
Fixed-point storage is unnecessary for the guarantee it was proposed for. |
M-40 |
The ambiguous face is rarer than the literature suggests — on five of the seven reference fields it never occurs at all. |
M-41 |
88 of the 256 cases change their Euler characteristic when their ambiguous faces are joined. |
M-42 |
The asymptotic decider is free to within a few percent, which is the first time this repo's "~free" claim has had a benc… |
M-43 |
The decider needs no division and no epsilon, and the brief's "guard the denominator" is unnecessary. |
M-44 |
The decider does not widen M-32's chunk-seam problem, and there is margin to spare. |
M-45 |
✗14 reproduces on a second machine and gets worse; its crossover does not reproduce at all. |
M-46 |
A chord is only collidable when its two cut edges share a cube face, and that makes the manifold fix nearly free. |
M-47 |
The validator's duplicate_vertices is an upper bound on what a weld removes, not the count. |
M-48 |
The edge-vertex cache does not share everything, and welding removes a class of sliver nobody expected it to. |
M-49 |
ChunkLayout::cell_of inverts world_of_sample inside a cell and not reliably on its corner — M-32 in a second place. |
M-50 |
E1 and M-34's ratio both reproduce live, under a mouse. |
M-51 |
Marching Tetrahedra costs ~3× the triangles for ~4% worse geometry — and the literature's 2–3× is too low. |
M-52 |
The Marching Tetrahedra ratio is 4.0 when the surface normal lies in one octant and 2.0 when it changes sign, and P-1's… |
M-53 |
The five algorithms fill three of the four corners of manifold × intersection-free, and Marching Cubes is the only one i… |
M-54 |
Dual Contouring is 101× more accurate than Marching Cubes on a sharp field, and indistinguishable on a smooth one. |
M-55 |
O-14 falsified: Marching Tetrahedra's accuracy penalty is 4.3%, not 86%, and it beats Surface Nets rather than losing to… |
M-56 |
Greedy meshing's 2.76× saving over face culling is a property of one scene, not of the algorithm: measured 1.70× to 256×… |
M-57 |
Greedy merging manufactures T-junctions, and no weld can remove them. |
M-58 |
A-010's vertex splitting removes the one-vertex-per-cell pinch completely, and the ticket named a field that was never a… |
M-59 |
The dual of a manifold surface is a manifold complex, and an indexed triangle mesh cannot always represent it. This is a… |
M-60 |
Only two of seven fields ever need a second vertex in a cell, and the rate falls with resolution — so Nielson's "about 1… |
M-61 |
Splitting the vertex makes self-intersection worse, not better — ✗2's report is confirmed and the natural reading of M-2… |
M-62 |
The t = a + b·n³ fit had been printing NaN since the day the algorithm names were spelled out, and once it prints number… |
M-63 |
Both papers docs/research/ lists as "genuinely absent, blocking" are in the home-still corpus, so the acquisition lists… |
M-64 |
A Transvoxel lateral face does not always cross the resolution boundary, and the exception is what transition cells are… |
M-65 |
Central differences at the cell size cost under half a degree of normal direction, and converge at h². |
M-66 |
On a sharp field the geometry and the field disagree by an angle that does not fall with resolution. |
M-67 |
A sign test cannot distinguish 95.6% of the configurations a tetrahedron can actually be in. |
M-68 |
parry3d's constructor is not a validity check: the only mesh it refuses is one with no triangles. |
M-69 |
A chunk seam costs 72 boundary edges, and welding removes exactly those and nothing else. |
M-70 |
Field-derived LOD is exact, not approximate: a coarse sample position is bit-identical to the fine one it sits on. |
M-71 |
Cells fall by 8 per LOD level and triangles by 4 — and the 4 degrades exactly where the grid stops resolving the surface… |
M-72 |
A sub-cell feature does not vanish under coarsening — it aliases, which is worse. |
M-73 |
A transition cell that computes its sample positions by offsetting from a face origin puts a hairline crack in the seam,… |
M-74 |
A zero-width transition cell stitches the hole and has no normal at all — which is what "severe shading problems" means,… |
M-75 |
The transition width is what makes the patch's winding a measurable question at all, and the answer is unanimous. |
M-76 |
Two blocks at differing resolution leave 88 unmatched boundary edges in the seam plane, and transition cells take it to… |
M-77 |
Lengyel's Equation 4.2 loses its level index entirely when written in the block's own cells, and the seam holds at a rea… |
M-78 |
A no_std crate cannot take a millisecond budget, and the honest API is a predicate the caller owns. |
M-79 |
Subgrid MT's conformity is locality plus a shared vertex ordering — it is emphatically not invariance under relabelling,… |
M-80 |
Every point §3.1 leaves unpaired is forced by arithmetic, not chosen — which is what makes the procedure implementable w… |
M-81 |
§3.2.1's first two cases cover the whole of classic Marching Tetrahedra, and the rest of the machinery exists entirely f… |
M-82 |
Theorems B.4 and B.6 hold against a reconstruction that does not use them — 27 of 27 (d₁, d₂) patterns, exactly. |
M-83 |
T-002 is structurally blind to a fold inside a Steiner fan, and §3.2 is built entirely from Steiner fans — so "zero self… |
M-84 |
The Figure-13 subdivision stencil closes: all four sub-tets it produces are themselves normal configurations, on all 27… |
M-85 |
Property II is a statement about Γ_normal's residual, not about the tetrahedron's — and taking it for the tet's silently… |
M-86 |
Conforming does not mean "no boundary at a shared face" — it means "boundary exactly where an open curve was discarded",… |
M-87 |
§3.2 as implemented meshes 3,394 of 4,096 configurations, the entire remaining gap is one construction, and Property II… |
M-88 |
§3.2.2's two labelling rules are stated separately and are checkable against each other, which turns a transcription int… |
M-89 |
On thin_plate — the field this whole track exists for — 93.75% of tets already mesh, and every one of the remaining 6.25… |
M-90 |
A scoop belongs to one face, but its two endpoints lie on an edge that belongs to two — so "both endpoints are on this f… |
M-91 |
The contractible spanning disk introduces no vertices at all, and coverage moves 3,394 → 3,808 of 4,096. |
M-92 |
§3.2 is complete over the tested space: 4,096 of 4,096 configurations mesh, with NoPattern and Inconsistent both zero —… |
M-93 |
Subdivision's output reported 30 self-intersections in 52 triangles, and every one was an artefact of vertex duplication… |
M-94 |
1D root finding resolves a slab at 1/1000 of the edge length — and the fixture that appears to demonstrate its limit pas… |
M-95 |
A-014c's acceptance is met with a number rather than a hedge: thin_plate returns 4,328 triangles at 33³ where greedy qua… |
M-96 |
Orienting each triangle against the gradient at its own centroid is sufficient — the welded output is closed, manifold a… |
M-97 |
§3.2.3's immersion is not hypothetical, and it is the single cause of every violation the subgrid extractor produces: 4… |
M-98 |
Subgrid Marching Tetrahedra costs 70× classic Marching Tetrahedra and 196× Marching Cubes, and the ratio is field evalua… |
M-99 |
The subgrid mesh's connectivity is provably manifold and my weld is what breaks it — the same mechanism as M-59, in a se… |
M-100 |
A demo can be broken in a way that looks entirely correct: E-108's letters, centred on z = 0, are never lost by Marching… |
M-101 |
§3.2.3's inset cannot be reconstructed from its prose, and two attempts made the measured result worse rather than bette… |
M-102 |
ChunkId orders lexicographically on [x, y, z], so a residency sweep must iterate x slowest — and the natural z-outer loo… |
M-103 |
rustdoc had never run on bevy_isomesh, and two doc links were already broken — the third time an excluded workspace turn… |
M-104 |
A radius-based residency rule loads a ball of chunks, and for a heightfield that is 4x too many with most of them meshin… |
M-105 |
E-203's first run reported 439 holes and a verdict of "G-001's overlap is wrong" — and the bug was in the test, one oper… |
M-106 |
The acid test passes with a margin, and the margin is the interesting part: across 495 seam crossings the worst vertical… |
M-107 |
λ is the sharpness/stability trade in one number, and swept over six decades it moves the runaway by a factor of 23 — bu… |
M-108 |
The prediction was registered before the sweep and came out half right, and the half that failed is the more interesting… |
M-109 |
M-61's "splitting the vertex makes self-intersection worse" is a 33³ fact, not a property — across nine resolutions it r… |
M-110 |
The self-intersection counter never tests 99% of the pairs on a dual contouring mesh, and the skipped count is identical… |
M-111 |
bevy_isomesh's four async drain tests do not pass on Linux, and one of them never passes — B-003's acceptance property i… |
M-112 |
E-112's premise is wrong by an order of magnitude, and the failure it names is really two failures with two different la… |
M-113 |
M-112's two laws reproduce in the committed example, and its fitted constant does not survive — the accuracy figure depe… |
M-114 |
HermiteCell::from_corners is public and its contract is not: the corner order it requires lives in a private module, so… |
M-115 |
A moving body is stopped harder and more often by ordinary terrain than by a chunk join — the same shape as M-106's answ… |
M-116 |
Runtime convex decomposition costs 241–272 ms per fragment, which is 14–22 whole frames — so correct destruction collide… |
M-117 |
A metric that reports a defect can be measuring the absence of a floor. E-204's first run accused 15 of 23 working colli… |
M-118 |
B-003's async tests were a wall-clock race, not a plugin defect — and the number of iterations they ran was irrelevant t… |
M-119 |
The obvious repair would have gutted the assertion it was repairing, and the mutation test is what proves the replacemen… |
M-120 |
Transvoxel's mirrored seam works, and it had never been run — E-107 only ever meshed the fine block on the low-x side. |
M-121 |
A level change moves the surface by up to 3.14 cells, which is the pop nobody measures. |
M-122 |
Re-extracting a whole LOD ladder on every level change costs 12–23 ms and hitches; re-extracting only the blocks that ch… |
M-123 |
Aliasing on a composed field came from the field, not the extractor — and swapping Surface Nets for Dual Contouring is w… |
M-124 |
The amortized cost per frame is the number a game spends, and it tracks the budget to within one chunk across a 320x ran… |
M-125 |
The never-livelock guarantee costs one chunk, exactly, and below one chunk's cost it degrades to precisely 1.00 chunks p… |
M-126 |
BrushOp::commutes_with is sound and tight — on eight overlapping brushes it called all seven adjacent pairs correctly, w… |
M-127 |
A fixture built to demonstrate that order matters reported 0 of 7 pairs where order mattered. |
M-128 |
The dual methods do not tile across chunk boundaries and Marching Cubes does — measured on two fields, after the defect… |
M-129 |
The seam counter's own exclusion list was missing an axis, and it accused Marching Cubes of a defect it does not have. |
M-130 |
On a concave edge Dual Contouring's advantage is 3.6x in the mean and only 1.56x in the worst case — nothing like the 10… |
M-131 |
The cell clamp does not bind on a concave edge either, which extends M-28 rather than limiting it — and the prediction t… |
M-132 |
Subgrid Marching Tetrahedra does tile across a chunk boundary — 0 open edges in 20 configurations — and the 1 that said… |
M-133 |
The dual methods are not reliably seam-closing rather than reliably open, which is a weaker and more useful claim than t… |
M-134 |
M-21's negative intercept reproduces in direction on a second machine and a third of the range, and its magnitude is 40x… |
M-135 |
The contour is 29% of a usable mesh, not 54% — and the largest stage is the collider check at 45%. |
M-136 |
"What fraction is the contour" has no single answer — it is 13.1% to 74.3% across seven fields, and the variable is how… |
M-137 |
Paint that lives in the field does not move when the geometry under it is destroyed — drift is exactly 0.000000, not sma… |
M-138 |
The price of exact paint is that every sample walks the edit log, and it is sub-linear in practice: 2.33x the cost per c… |
M-139 |
The wgpu pin holds, and the number it holds at is 29.0.4 rather than the 29.0.3 written down. |
M-140 |
The GPU this repository's numbers will be measured on, and the two limits that bound a dispatch. |
M-141 |
Include-once and cycle detection interact, and the obvious ordering silently accepts a circular graph. |
M-142 |
GPU and CPU Marching Cubes agree on every triangle and disagree on 6% of vertices by exactly one ULP — and the cause is… |
M-143 |
GridParams::sample_position was a mul_add where isomesh is origin + h·i, and a power-of-two cell size hid it through an… |
M-144 |
GPU/CPU bit-identity is a property of the cell size, not of the port — 93.8% at h = 0.125, 1.1% at h = 0.1, 98.0% at h =… |
M-145 |
The GPU extraction itself is essentially free and almost flat — 0.05 ms at 17³ and 0.13 ms at 129³, over 420× the cells… |
M-146 |
Mesh shaders are advertised by this adapter and cannot be enabled from this workspace, because ExperimentalFeatures::ena… |
M-147 |
Bevy's device already has mesh shaders enabled, with no configuration and no unsafe anywhere in this repository — so GPU… |
M-148 |
A WGSL mesh shader's output block is a fixed contract that naga defines and no document states — and it is derivable fro… |
M-149 |
A mesh-shader draw removes the smallest of the GPU path's three data-movement costs — 6.7% at 129³ — and the doc comment… |
M-150 |
Moving the prefix sum onto the GPU took the extraction path from 15.01 ms to 9.65 ms at 129³ — 1.56× — and the stage it… |
M-151 |
A hierarchical GPU scan is exactly the kind of code that is wrong invisibly, so it is asserted element-for-element again… |
M-152 |
"The upload is field evaluation" is 57% true: of the 8.40 ms upload at 129³, evaluation is 2.65 ms, converting Vec |
M-153 |
Eliminating the "redundant" copy into GPU memory costs 1.6×, and the copy that was redundant was a different one. |
M-154 |
GPU field evaluation does not match libm bit-for-bit on any field, including the ones with no transcendentals — and it d… |
M-155 |
Evaluating the field on the GPU takes the 129³ path from 8.37 ms to 0.54 ms — 15.5× — and 37× ahead of a single-threaded… |
M-156 |
The mesh-shader coverage hole is accepted rather than closed, and the deciding constraint is a stated goal rather than a… |
M-157 |
A GPU-interpreted edit log reproduces BrushStack to under 8.4e-7 across every shape, every op and a twelve-brush mixed s… |
M-158 |
The whole pipeline runs on the GPU and never touches the bus: field, edit log, extraction and draw, at 0.41 ms for 16,43… |
M-159 |
The last four bytes cost 0.033 ms to move and 0.375 ms to wait for — because poll(Wait) drains every dispatch queued bef… |
M-160 |
A zero-synchronisation extraction makes CPU time independent of grid size: flat at ~0.17 ms from 33³ to 129³, where the… |
M-161 |
§3.2.3's immersion is real, measured on five of seven fields — and it is not the defect. |
M-162 |
A-014d's blocking question is answered, and the answer is no: the inset needs neighbour information, and the neighbours… |
M-163 |
csg_difference's three surviving non-manifold edges are each 4 faces but only 3 distinct polygons, from exactly 2 tetrah… |
M-164 |
gyroid's 138 inconsistently-oriented edges are not A-014d's, and the ticket's stated mechanism reaches 8% of them. |
M-165 |
Among the configurations that can exhibit it, Chernyaev's numerator-only test is wrong 12.6% of the time — 1,966 of 15,6… |
M-166 |
The interior test does not inherit ambiguity's crack-freeness argument, and the reason is one operator. |
M-167 |
Across the whole GPU series the arithmetic never moved and was never the point: synchronisation was 83% of an extraction… |
M-168 |
Giving a crossing an identity instead of a position removes 5.01× of the subgrid extractor's vertices and changes no tri… |
M-169 |
Identity-based sharing is complete exactly when no root lands on a grid sample point, and the correlation is not approxi… |
M-170 |
A GPU adapter is a finite resource and the test harness was treating it as free: 67 tests opened 67 devices, and once an… |
M-171 |
A shipped example panicked on every run, and three siblings carried the same race unfired. |
M-172 |
A signed distance field's gradient is exactly zero on its medial axis, and for a slab the medial plane is precisely wher… |
M-173 |
Two coincident surfaces are not a rendering bug to be biased away, they are a modelling statement — and the fix is to st… |
M-174 |
CI has been red on every push of the GPU series, and behind the one accepted failure three unrelated ones accumulated un… |
M-175 |
Sorting by magnitude is not enough to make a sum permutation-invariant, and the comment that said it was had been wrong… |
M-176 |
Zero-padding a reduction is transparent, negative zero included — and the reason is the accumulator's seed, not the sort… |
M-177 |
Reordering cannot buy negation equivariance, and the obstruction is structural rather than a missing tie-break. |
M-178 |
A-016 moved 34 of 168 golden rows, not the 42 predicted, and the 8 that held identify their own mechanism. |
M-179 |
A-014h's stated mechanism finds almost nothing, and the reason is a deliberate choice in the root finder. |
M-180 |
The population M-169 named as one defect is two, and only the smaller one is an identity problem — so A-014h cannot reac… |
M-181 |
T-009's own premise was wrong: normalising four scattered weld epsilons onto one moved nothing, because the weld's answe… |
M-182 |
P-7 confirmed, and the check that confirmed it found thin_plate failing at two of the three resolutions nobody was testi… |
M-184 |
Naming a root by the grid point it lies on completes the identity outright: on every field the extractor now emits each… |
M-185 |
Completing the identity turns a sliver into a repeated-index triangle, and the extractor now declines to emit those. |
M-186 |
M-162 is falsified, and A-014d's blocker with it: after A-014h no coincident polygon has a foreign tetrahedron on its bo… |
M-187 |
Orienting each connected component from its most confident triangle drives the inconsistently-oriented-edge count to exa… |
M-188 |
Two of the seven reference fields are non-manifold at a resolution the suite never tested, and one of them is torus. |
M-189 |
Running the subgrid validity census at the three resolutions its own gate names doubles the number of known defects, and… |
M-192 |
I-007's own finding happened to I-007, in the commit that filed it. |
M-193 |
The polygon type A-014d has to inset is the one type its figure could not be read for — measured, not assumed. |
M-194 |
A-014d's acceptance criterion asks §3.2.3 to fix a defect §3.2.3 does not cause, and this repository's own instrument ha… |
M-195 |
The mirrored seam's crack is exactly invisible to a seam-plane counter — 0 edges on the plane, 28 on each side of it. |
M-196 |
Consuming fields:: instead of a hand-rolled copy is a speed-up, not a tidy-up — and a dispatch layer can throw the whole… |
M-197 |
GPU-013's two halves both misnamed their target, and the measurement says the prize is waits rather than submissions. |
M-198 |
The publish job ran for the first time in its life, and failed on a secret that was never set — so the release pipeline… |
M-199 |
Subgrid Marching Tetrahedra is already intersection-free on every reference field at every resolution — so §3.2.3, whose… |
M-200 |
Two of A-014i's three recorded defects are not what the review called them: one is real and its obvious fix is measurabl… |
M-201 |
The subdivision path has a grid-level fixture at last, and it says the orphaned vertices are real — 9.8% of them — which… |
M-202 |
Subdivision only fires where the grid badly under-resolves the field, so "T-001 validity on the subdivision fixture" can… |
M-203 |
A-014i's orphaned vertices are fixed by giving children their parent's names instead of new ones, and the mesh is bit-fo… |
M-204 |
M-166 is closed by two parentheses, and the test that was already asserting the property could not have caught it. |
M-205 |
A-014i's "orphaned bigons" is real, and it is a law rather than a defect: unreferenced positions arrive in pairs, one pa… |
M-206 |
Two independently derived constructions locate the same body saddles, to 1.1e-12. |
M-207 |
The reference implementation loses a root this one keeps, in two places, and both are the textbook quadratic formula. |
M-208 |
Interior ambiguity was unreachable by this crate's entire test suite: 0 of 68,385 reference-field surface cells have six… |
M-209 |
The eighth reference field is searched, not designed — 97 of 610 candidates qualify, and the one taken is the gentlest r… |
M-210 |
The natural level set of gradient noise is its own lattice, which is degenerate — so a noise reference field may not use… |
M-211 |
A-010's zero was conditional, and nobody knew on what: Manifold Dual Contouring is not manifold on a field with interior… |
M-212 |
Welding two coincident vertices can create a non-manifold edge, which a test comment had asserted was impossible. |
M-213 |
Orientation can raise the flipped-edge count, and after <= before was not a law. |
M-214 |
The tunnel and the twelve-vertex contour are told apart by counting rings, and both are reachable: 2,053 and 173 in 396,… |
M-215 |
The u pair's two lines are crossed relative to the other two, and the inner hexagon is what proves it. |
M-216 |
The interior vertex is a transcription, and the check on it is geometric: 149,803 of them, every one on the level set to… |
M-217 |
The disk path costs no new budget: worst case 12 triangles and 1 interior vertex per cell, against MAX_TRIANGLES = 12 an… |
M-218 |
The twelve-vertex contour needs a closing step the tunnel does not, and a manifoldness test found it rather than a readi… |
M-219 |
The reference implementation has a transcription-grade typo in the detached-ring test, and it is one line from six. |
M-220 |
(refined by M-494 — it can, from continuous f64, wherever the field's mirror symmetry is the grid's: 72 singular faces o… |
M-221 |
0 × NaN is NaN, and it took the extractor to find that — not 400,000 random cells. |
M-222 |
χ falls by exactly two per tunnel and by nothing else — the interior rule's topology change is arithmetic, not approxima… |
M-223 |
The interior rule costs 1.95% at 33³ and 0.14% at 65³, on the only field that exercises it. |
M-224 |
Manifold Dual Contouring's non-manifoldness has nothing to do with tunnels, which is what A-017 assumed, and it survives… |
M-225 |
A-017's mechanism, and the grid predicts the mesh defect exactly — 30, 64, 8 and 40, with zero error. |
M-226 |
Subgrid Marching Tetrahedra's output does not need welding and is damaged by it — the doc had been telling consumers to… |
M-227 |
Orientation now reaches zero on every reference field at every resolution, and M-187's caveat was about the walk rather… |
M-228 |
Grosso's tunnel triangulation has an undefined case, it is reachable, and 400,000 random cells could not reach it. |
M-229 |
The contour-count discriminator misclassifies case 13, and the misclassified cells are exactly the ones with no triangul… |
M-230 |
Corollary 6 is the tunnel test; Proposition 1 is not, and the derivation that shows it also validates itself. |
M-231 |
The [9,3] cell is not a topological subcase; it is a singular face that the strict interior test lets through. |
M-232 |
(refined by M-494 — reachable from continuous data too, when the field is mirror-symmetric through a grid plane so a fac… |
M-233 |
A-002i's blocker is not the vertex cache, it is that a singular face needs a third routing and the resolution mask has t… |
M-234 |
A-017 closed by decision rather than by code, and the limit is stated as an identity so it cannot rot. |
M-235 |
The example capture rig renders headlessly but cannot control its own window size, and it fails silently — which is the… |
M-236 |
The shootout's header claimed the wrong counts for both of the things it was counting, and nothing could have caught it. |
M-237 |
The QEF buys 2× accuracy on smooth fields and 100× on sharp ones, and pays for all of it in self-intersections — measure… |
M-238 |
Probabilistic quadrics are this crate's existing solve with a different regularizer, and the derivation is the finding —… |
M-239 |
A window can resize itself without a window manager, and two obvious fixes both fail silently before the third works. |
M-240 |
The crate could subtract and intersect but not union, and nothing noticed because no reference field unions anything. |
M-241 |
Two demo GIFs were shipped that did not show what their captions claimed, and a single frame is not an inspection. |
M-242 |
The shootout's 112 rows came back structurally identical after X-001 rewrote how it enumerates, which is the refactor's… |
M-243 |
An unquoted heredoc executed the words in this script's own Python comments, and it failed silently for a value of "fail… |
M-244 |
A declared Lipschitz constant was wrong on the first run, and the test that caught it was written in the same commit by… |
M-245 |
The eikonal condition cannot tell a CSG underestimate from a true distance, which is why a bound needs two numbers rathe… |
M-246 |
min is not better than max; each is exact in one region and wrong in the other, by the same amount. |
M-247 |
Repeated CSG destroys the worst case and leaves the typical case untouched, and a renderer barely notices what a precisi… |
M-248 |
One field evaluation replaces 576, and buys between 1.1× and 11.8× depending on how much of the volume the surface reach… |
M-249 |
A directional Lipschitz bound buys exactly nothing on five of six fields, and 1.80× on the sixth — the null result F-006… |
M-250 |
Refining an edge crossing on the real field helps curved fields by 13–15% and does nothing at all for the CSG one — the… |
M-251 |
The exact distance transform agrees with brute force to the last bit, and is exactly one sample spacing from the analyti… |
M-252 |
Fast sweeping beats the exact transform everywhere, including where it was predicted to lose — because the seeding, not… |
M-255 |
naive reinitialisation moves the zero set, measured before it was fixed (S-004) |
M-256 |
the narrow band's cost claim needs the march, not the sweep (S-004) |
M-257 |
the approximate GPU method beats both exact CPU ones (S-005) |
M-258 |
a u32 followed by vec3 |
M-259 |
the round trip the crate did not have (S-006) |
M-260 |
a uniform grid over the sample cells lost to a flat box reject, 3.9× (S-006) |
M-261 |
Real gained acos, and libm is why (S-006) |
M-262 |
the winding number beats the pseudonormal on holed meshes, by a widening margin (S-007) |
M-263 |
the boundary must be counted with multiplicity, not as a boolean (S-007) |
M-264 |
the uncertified set is a curve, not a resolution failure (T-015) |
M-265 |
decimation is re-sampling on a nested grid, so the literature's rule has no bite here (T-016) |
M-266 |
M-72's aliasing is alignment, not chance (T-016) |
M-267 |
the sampled gradient supremum is not even monotone in sampling density (T-017) |
M-268 |
field quality is now in the regression gate, and every column is exact (T-017) |
M-269 |
a grid-aligned ray double-counts shared edges, and the constructor shootout is what found it (T-018) |
M-270 |
a benchmark that hands a repair algorithm perfect input measures the benchmark (T-018) |
M-271 |
the exact transform is the hungriest constructor, and the mesh-based pair are free (T-019) |
M-272 |
the pre-registration gate is a const assertion, and that is the whole of it (R-000) |
M-273 |
the first thing done with the pre-registration mechanism was amend a registration to fit the code (R-002) |
M-274 |
the fixture never contained the configuration both experiments were about (R-002) |
M-275 |
FALSIFIED on its first clause, and the residue is an edge defect (R-003) |
M-276 |
the dual methods' non-manifold edges are the ambiguous face, all 314 of them (A-021) |
M-277 |
the index generator was blind to the shape its own file had moved to (R-004) |
M-278 |
HELD, and the crack budget is not where the ticket assumed (R-004) |
M-279 |
the mechanism is FALSIFIED, and the registered falsifier could not have caught it (R-005) |
M-280 |
this harness's nanoseconds are not a unit, and the committed Zen 3 sweep is 1.45× stale (R-005) |
M-281 |
a timing here is a property of the binary, not only of the code (M-001) |
M-282 |
the whole family, in one binary and one run (M-001) |
M-283 |
FALSIFIED, and the fixture that confirmed it agreed to four decimal places (R-006) |
M-284 |
HELD, and the dual's IPC wall is one function (R-007) |
M-285 |
the dual's axis had to be a constant, and that was 82% of its cycles (A-023) |
M-286 |
the misses M-279 measured as free were hidden behind the stall, and now they cost (A-023) |
M-287 |
one bit of the row length was a 3.4× tax at the chunk size everybody uses (A-024) |
M-288 |
FALSIFIED, and the registered definition did not implement the registered claim (R-008) |
M-289 |
the reference gradient was noise, and it falsified two hypotheses that were true (R-009) |
M-290 |
the ambiguous face in the dual path, with the source read at last (A-022) |
M-291 |
FALSIFIED, and the sharper form of it points the other way (A-025) |
M-292 |
no two-cell configuration forces Manifold Dual Contouring's defect (A-025) |
M-293 |
the excluded workspace's fourth gate incident, and this one is local (A-025 follow-on) |
M-294 |
the defect in 48 samples, and the same signs give the decider two answers (A-025) |
M-295 |
the documentation drifted in thirteen places, and one number rotted twice (docs) |
M-296 |
the README answered "is the GPU faster" with no, and its own CSV said 37× (docs) |
M-297 |
no published convex decomposition runs at interactive rates, so this crate's own 241 ms was not an outlier (O-2) |
M-298 |
orientation catches a fan that reverses, not a fan that folds, and a star polygon is invisible to both counters (T-020) |
M-299 |
the on-demand split is free for the pseudonormal and costs a factor of N for the winding number (S-008) |
M-300 |
FALSIFIED, and not where it was predicted: the gap is non-manifold vertices, not self-intersections (R-011) |
M-301 |
the bowtie that passed: a closed, edge-manifold, consistently oriented surface that is not a 2-manifold (T-021) |
M-302 |
the naive orient2d fails by reporting collinear, not by reporting a false crossing (T-024a) |
M-303 |
HELD: the winding crossover is N², not N³, and the per-point cost is linear in boundary edges (S-009) |
M-304 |
a green preflight.sh is not a green CI, because the toolchains differ (0.0.6 release) |
M-305 |
the weld key does what it says, and H's wording was wrong anyway (R-010) |
M-306 |
what empty-cell rejection can save is bounded by a count, and that count is a property of the field (✗24) |
M-307 |
HELD: the primal family seals every reference field, and all three duals leave the domain boundary open (R-024) |
M-308 |
the family comparison's headline conclusion was overturned by optimising one member of the family, not by a better measu… |
M-309 |
FALSIFIED on both clauses, and the first one fails for a reason sharper than the hypothesis (T-026) |
M-310 |
on real scanned volumes, Marching Cubes lands inside the published quality band that analytic fields put it outside of (… |
M-311 |
HELD on both clauses that were about the world, and the clause about the comparison was wrong (R-022a) |
M-312 |
FALSIFIED before it ran, on arithmetic; and the margin that replaces it is bounded by half the field's scale (R-023) |
M-313 |
R-023's hypothesis is falsified: a margin threshold acts away from where the published algorithms disagree (R-023) |
M-314 |
the computation after a local edit is edit-proportional; the output buffer throws that away, and the culprit is a counte… |
M-315 |
R-025's 20% is above the ceiling on any vertex placement, measured before a placement rule was written (R-025) |
M-316 |
a central difference is identically zero at a local extremum, and quantised data manufactures them (A-028) |
M-317 |
the volume meshes: 483 tetrahedra declined around 33 singular points, reported rather than fatal (A-028) |
M-318 |
a grid-edge naming would close the whole edit-proportionality gap, and the obstacle is not the encoding (R-027) |
M-319 |
filling disconnects the air region about one time in six, so R-022b's cheap escape does not exist (R-022b) |
M-320 |
the median split sheds one voxel, so the replacement search the literature is built around is answering a question this… |
M-321 |
HELD on the measured distribution, and the adversarial fixture it demanded costs 1.1× a full rebuild (R-022b) |
M-322 |
chunking makes the bisect bounded rather than cheap, and the advantage is exactly the chunk count (R-028) |
M-323 |
the chunk is the bound; the cost is the edited chunk's share of the severed component, and the two differ by 35× (R-028) |
M-324 |
HELD on both clauses, and the exact zero is a coordinate-origin artifact (R-029) |
M-325 |
the discrete medial score converges O(h) and the mechanics live; the clause that died was C1's own tolerance derivation… |
M-326 |
FALSIFIED on both clauses, while the recorded columns show the mechanism both registered instruments missed (R-031) |
M-327 |
FALSIFIED again, by the distribution this time: heterogeneous wormholing has no gapped aperture histogram, and the same… |
M-328 |
HELD at 20 of 20: the homotopy certificate is never available in a dug scene, and the instrument proved it could have sa… |
M-329 |
the modal kill-shot fired: no one-voxel edit is audible anywhere, including against the thin web, and the direction clos… |
M-330 |
HELD on both golden values: the feasibility solver is now held to external truth, and the coarsening warning would not r… |
M-331 |
FALSIFIED as registered, by an instrument floor the registration promised was fine, and by a corpus that mixed two edit… |
M-332 |
HELD on all three clauses: warm-starting the admissibility solve is bimodal by edit class, and the tilts confirm their o… |
M-333 |
the heat-operator substrate verifies against a dense reference, and its own numbers pre-shrink two of R-035b's expectati… |
M-334 |
FALSIFIED at 1.7× against a registered 20×: the separators eat the update, the prefactored family is dead for live carvi… |
M-335 |
HELD on both clauses with orders to spare, and the premise correction is the part that mattered (R-036) |
M-337 |
HELD on all three clauses: the active-cell test is one bit, the stage is 5.5× and not one triangle moved (P-40, R-039) |
M-338 |
HELD, and the relation is a bijection rather than a correlation: the critical-configuration census does not predict the… |
M-341 |
HELD on all three clauses: a brush that provably cannot win is deleted for free, and the mesh does not move by one ULP (… |
M-346 |
HELD on all three clauses, with exactly zero error where the answer is known: the crate can state a clearance, not just… |
M-347 |
HELD on all three clauses, and the by-product is sharper than the claim: there are 24 cells on the unit sphere where the… |
M-349 |
HELD as three exact equalities on 15 of 15 rows: the bitmap's claim was always a count, and a count does not have a gove… |
M-350 |
HELD, and the bound turned out to be provable: a central difference across a CSG seam is wrong by at most half the creas… |
M-352 |
HELD, FALSIFIED, HELD: every degenerate triangle comes from an exactly-equal corner, the repair moves no geometry at all… |
M-354 |
HELD on all three, and the prediction's shape is what held: affine arithmetic rejects 3.85× more cells on gyroid and exa… |
M-362 |
wasm-opt -Oz shrinks both site modules on disk and makes both bigger gzipped, so it is rejected on all ten (D-012) |
M-365 |
one wgpu::Instance per test deadlocks game_dig's suite at default parallelism, and a shared device halves its runtime (D… |
M-366 |
a GitHub Pages project page is redirected by the user site's custom domain, and an archived repo cannot be fixed through… |
M-368 |
the backpressure was measured against a stale queue: drain_dirty ran before gpu_collect (D-014) |
M-370 |
an existence check passes on a commit that left the branch: git cat-file -e is a property of the checkout, merge-base --… |
M-371 |
MCPro is in the corpus as a 383-character landing page that read "converted, embedded": catalog_read is not a presence o… |
M-374 |
settled for Marching Cubes by exhaustion at 2¹⁸ |
M-377 |
C1 HELD at 51×, C2 and C3 FALSIFIED: the optimum is interior at 4³ on both fields, and the spread is 12.7× larger than t… |
M-378 |
zero unsound certificates over 2,389 tunnel cells |
M-379 |
C1, C2 and C3 all HELD: the case table is proved indexable over all 256 sign patterns in 2.04 s and over all 16,384 (pat… |
M-383 |
the bench that cannot compile off Linux, and every gate that would see it runs on Linux (D-025) |
M-384 |
a gate that is red locally and green in CI, which is M-304 read backwards (D-026) |
M-387 |
C1, C2 and C3 all HELD: per-vertex material weights cost 3.11–3.16% of extraction and the share is flat across a 4× log,… |
M-388 |
C1 HELD (18 = 3 × 6 exactly, cost 2.1115×), C2 HELD on its own falsifier while the clause as worded is VACUOUS, C3 HELD… |
M-393 |
C1 HELD at 8.067× and 4.766 µs against a 3× / 20 µs bar, C2 HELD bit-identical over 10⁶ queries across Zen 3 and an Appl… |
M-410 |
C1, C2 and C3 all HELD: fused into the extraction gather the Plantinga–Vegter certificate costs 0.0553 worst of extracti… |
M-411 |
all three clauses HELD, and the two findings worth more than the HELDs: C1's premise is off by two — rank_all_edges read… |
M-414 |
C1, C2 and C3 all HELD: ✗43's withdrawn rate reproduces exactly — 0 of 8,064 unclosed post-fix on five independent magni… |
M-415 |
seventeen papers acquired and all four missing categories closed, and the eight that did not land are a resolver finding… |
M-419 |
C1, C2 and C3 all HELD on 8 of 8 rows: the circuit is 12 word operations and 24 including the plane build against a bar… |
M-430 |
11 contraction-sensitive expressions |
M-432 |
C1 VACUOUS on all 16 rows because the registered perturbation had nothing to move (baseline_spread 0, and buckets_of_thr… |
M-437 |
C1, C2 and C3 all HELD on 24 of 24 rows: on the ambient complex the predicate discriminates on 8 of 8 fields at every re… |
M-439 |
C1, C2 and C3 all HELD and O-12's dual half is closed by exhaustion: worst_link_components 1 on every non-control arm ov… |
M-440 |
C1, C2 and C3 all HELD: bb - 4ac at marching_cubes/trilinear.rs:246 is Cayley's 2×2×2 hyperdeterminant of the eight corn… |
M-441 |
C1 and C2 both HELD on 48 of 48 rows: count_disagreements, sign_disagreements and corner_value_mismatches are 0 over 7,0… |
M-444 |
C1, C2 and C3 all HELD on 29 of 29 arms: the discriminant == 0 branch at marching_cubes/trilinear.rs:250 does fire on a… |
M-448 |
C1 and C2 both HELD, and Group A's boundary is now a number |
M-449 |
the registered null came back exactly as registered: sign(Δ) is worth nothing on the interior test. |
M-450 |
C1, C2 and C3 all HELD on 25 of 25 rows: the trilinear's "at most 2" is the mixed volume 8 − 6 + 0 = 2 of three unit squ… |
M-451 |
C1 and C2 both HELD, and the price is in the table rather than in the bound: tricubic mixed_volume 116 against the trili… |
M-452 |
C1 and C3 HELD, C2's c2_holds true on 4 rows of 16 and false on 12: Kuhn's six tetrahedra are regular, exhibited by the… |
M-453 |
C1 and C2 both HELD on all 560 rows: six fields with topology prescribed by construction — genus 1, 2, 3, 2, 3, 5 and pr… |
M-454 |
true on 2,112 queries of 2,304 |
M-458 |
C1 and C2 both HELD: a digital-topology oracle reading χ off the field's own signs with no mesh involved reproduces chi_… |
M-461 |
C1 HELD with component-wise determinant swell reaching 6.841331e9 against log-Euclidean's 1.771547e-7 at a 5% bar, C2 HE… |
M-463 |
the registered null came back null and then inverted: Cao's L¹ anomaly did not reproduce — anomaly_reproduced false on a… |
M-472 |
the registered null came back, and it is a null with page numbers: against W_inf^2 — the class the trilinear model is se… |
M-473 |
C1, C2 and C3 all HELD: at matched sample budget the octree-adaptive arm beats uniform on 12 of 12 measured rows with ga… |
M-474 |
C1 and C2 both HELD: s is estimable for both refinement families on 8 of 8 fields over 2.03 decades of field evaluations… |
M-478 |
C1, C2 and C3 all HELD on 24 of 24 rows, and the sharper thing is that greedy meshing is finished: Eppstein's optimum n/… |
M-481 |
the registered null came back registered: C1 HELD on 240 of 240 with closed_form_max_gap 0.000000000000000 and stability… |
M-485 |
the registered obstruction is real, is one dimension lower than the registration claimed, and does not stop Conley: plat… |
M-486 |
the curl residual is free — worst curl_share 0.008061907, 0.81% of an extraction against a 2% ceiling, on 24 of 24 rows… |
M-487 |
the registered null held: at matched cost the normal-cycles incumbent beats discrete varifolds on mean curvature on 28 o… |
M-489 |
caves percolate in 3D and the transition is now a number: on noise_cavity the giant component appears at percolation_iso… |
M-494 |
all three clauses HELD, and the landing cost what the ticket said it would plus five contracts nobody had priced. C1: th… |
M-496 |
Every empty mesh this crate handed to Bevy 0.20's render world cost one allocator WARN … contains no vertices per extrac… |
M-497 |
A dirty-marking rule is a claim about which points of the field an extractor reads, and mark_edit's corner rule is false… |
M-498 |
A test that asserts the state a transition and its absence both leave cannot fail when the transition is dropped: an_edi… |
M-499 |
A report field documented as an edit's own but computed against the caller's whole queue reports the backlog as the edit… |
V-1 |
wgpu / wgpu-types / naga 29.0.3, glam 0.32.0, encase 0.12 |
V-2 |
Bevy 0.19 removed RenderGraph; passes are systems in ECS schedules; non-camera work targets the RenderGraph schedule |
V-3 |
Marching Cubes peak: 5.42 G voxel/s, 330 M tri/s (RTX 2080 Ti). DMC costs 1.52–3.50×; FlexiCubes 2.77–3.92× |
V-4 |
Contouring 68 ms vs halfedge construction 58 ms |
V-5 |
On unstructured grids, Delaunay/MT ratio 15.3×–81.5× — contouring is 1–2% of the pipeline |
V-6 |
73% of FlexiCubes' 64³ Marching Cubes timing is fixed launch overhead |
V-7 |
Cross-paper reproducibility floor is ~1.5× in opposite directions: TetWeave re-measured FlexiCubes at 128³ as 9.63/15.25… |
V-8 |
10.7× more bandwidth bought ~1.7× more throughput |
V-9 |
Same Marching Cubes, compute shader → mesh shader: 114.2 → 2679.4 fps (23.4×) |
V-10 |
CBT sum-reduction, atomics → LDS staging: 5.78 → 0.40 ms |
V-11 |
Meshlet compression: 15.5 M tri in 0.59 ms (RX 7900 XTX) |
V-12 |
Work graphs: 79,710 instances in 3.74 ms — but 2.8–3.4× slower on classification workloads |
V-13 |
nvblox: meshing is the least GPU-accelerable stage, ×3–13 vs fusion's ×174–177 |
V-14 |
Aokana renders 10¹⁰ voxels at 6 ms, 5% resident, RTX 3060 Ti — explicitly not editable |
V-15 |
CoACD vs V-HACD: 49% → 80% downstream manipulation success |
V-16 |
Dimforge migrated parry (0.26.0) and rapier (0.32) off nalgebra onto glam, citing rust-gpu support; performance "nothing… |
V-17 |
No paper since 2020 benchmarks Marching Cubes vs Surface Nets vs Dual Contouring against each other. |
V-18 |
Dual Contouring's own paper quantifies the f32 QEF failure. |
V-19 |
Dual Contouring's topology is Surface Nets' topology. |
V-20 |
A QEF is stored as AᵀA (symmetric 3×3), Aᵀb (3-vector) and bᵀb (scalar) — 10 floats — rather than as A and b |
V-21 |
The corner/contractible spanning disk is supposed to come out degenerate, and mistaking that for a bug would send A-014b… |
V-22 |
(settled at E-206b: adopted as a bevy_isomesh dev-dependency only, avian3d 0.7.0, which compiles clean against Bevy 0.19… |
V-23 |
CLAUDE.md's Metal contradiction is resolved, and both sources were right about different layers. |
V-24 |
Custodio §5.1's correction, verified from the paper and re-derived rather than transcribed. |
V-25 |
"Lewiner's reference implementation omits disambiguation for cases 10 and 12 entirely" is true of the code and false of… |
V-26 |
A follow-up exists that builds MC33's triangulation with no lookup table at all, and A-002b's blocker did not know about… |
V-27 |
§3.2.3's prose is fully retrievable and its triangulation patterns are still only a picture — and the paper offers a sec… |
V-28 |
A-014d's rule-5 stop is lifted, and not by the figure — by the authors' own reference implementation, shipped as arXiv a… |
V-29 |
Two sources this repo recorded as unobtainable were obtainable, and one of them removes the largest single piece of A-00… |
V-30 |
Grosso's quadratic re-derived, and now agreeing three ways rather than two. |
V-31 |
The reference implementation both Grosso papers cite has been deleted from GitHub, and it survives — the paper's own lis… |
V-32 |
Two more rows of meshing-library-target.md marked PAYWALL are in the corpus, and the table's status code has now been wr… |
V-33 |
A paper_download that reports success can return a landing page, and this is the third producer of that signature. |
V-34 |
Manifold Dual Contouring's uniform-grid criterion is one vertex per cycle of a decider-modified Marching Cubes table, an… |
V-35 |
Grosso 2017's implementation does not exist publicly, and that is now checked rather than assumed. |
V-36 |
CoACD's intersection-free guarantee is a property of its cut, and its own default merge stage breaks it — which resolves… |
V-37 |
the instrument R-024 needs is published and in this corpus; the question it asks is not |
V-38 |
the published AR>4 and sliver figures are not a baseline this crate can be measured against, and one of them is misattri… |
V-39 |
the comparable triangle-quality baseline is Grosso & Zint's, not FlexiCubes', and it comes with a prediction (T-026) |
V-40 |
Open SciVis Datasets is HTTP-only, and the publisher's own SHA-512 is what makes that fine (M-006) |
V-41 |
R-022's hypothesis is two problems with different costs, and a voxel lattice is the easy case for one of them (R-022) |
V-42 |
R-023's quantity does not exist as stated, and the one that does is a decision margin rather than a persistence (R-023) |
V-43 |
R-020's "unobtainable" prior art has been in the corpus since the day before the ticket was written, and it narrows the… |
V-44 |
R-021's caveat is contradicted by the paper R-021 is built on, and the cheap half is already delivered (R-021) |
V-45 |
R-027's design does not merely change extract_into's contract; it converts a shipped determinism check's failure conditi… |
V-46 |
R-030's specified oracle cannot tell the identity from a wrong one; the inversion rule fails before the harness exists (… |
V-47 |
a wgpu storage buffer bound read_write and read_only in one bind group is a validation error, not a free alias (GPU-014) |
V-48 |
wgpu 29 puts every subgroup operation in the native half of the split Features struct, so the browser backend cannot hav… |
V-49 |
a correction to V-23 / GPU-007: WGSL mesh shaders on Metal are unimplemented!() in naga 29, full WGSL support landed in… |
V-50 |
CGAL shipped an Isosurfacing package in 6.1 whose own manual pictures cracks at octree level transitions, so M-128/M-132… |
V-51 |
C1, C2 and C3 all HELD on 8 of 8 rows with doi_verified true on every one, including the registered trap: 10.1137/072201… |
V-52 |
Bevy 0.20 never evicts a render asset whose usages drop RENDER_WORLD when it is modified, but its mesh allocator frees t… |
O-1 |
Settled at G-002 (M-33, M-34), and confirmed live under a mouse at E-202 (M-50). |
O-2 |
Settled at A-009 (M-28, M-29): not entirely, and the residue names its own mechanism. |
O-3 |
Marching Cubes vs Surface Nets vs Dual Contouring vs MT — actual relative speed on one machine? |
O-4 |
Settled at G-003 (M-36, M-37, M-38): conditionally, and the condition is narrow. |
O-5 |
Do mesh shaders work on macOS/Metal? |
O-6 |
What is amortized meshing cost per frame under continuous editing? |
O-7 |
What fraction of our pipeline is contouring vs everything else? |
O-8 |
Does Dual Contouring's vertex placement need f64 in practice, or is f32 enough? |
O-9 |
How much does T-003's gradient-flow chord over-estimate distance at a concave seam? |
O-10 |
What is Surface Nets' non-manifold rate as a function of feature thickness over h? First curve measured at A-010 (M-60),… |
O-11 |
(ANSWERED at R-007, M-284: the dual carries a fourth stage Marching Cubes has not — emit_quads, which walks every grid e… |
O-12 |
Is Marching Cubes unconditionally manifold now? |
O-13 |
Pre-registered: Marching Tetrahedra vertex count = 3.0× Marching Cubes, converging from above Confirmed at A-003/M-001,… |
O-14 |
Pre-registered: Marching Tetrahedra symmetric Hausdorff at 64³ ≈ 2.6e-3, about 1.86× Marching Cubes, i.e. slightly worse… |
O-15 |
Answered at A-003 (M-52): the normal's sign pattern, not its direction. |
O-16 |
Can the parallel dual-edge collapse (M-59) be removed without giving up the cycle partition? |
O-19 |
Which direction does the λ-medial-axis filter run — Attali's keep-r ≥ λ, or the 3D Skeletons STAR's discard-circumradius… |
O-20 |
Why are ✗41's 216 near-surface unnecessary survivors unnecessary? |
E×1 |
Surface Nets' centroid as Dual Contouring's vertex rule |
E×2 |
A separate probabilistic-quadric solver |
E×3 |
Crossing-count-scaled regularizer |
E×4 |
Weld gated on the pairwise link condition, rejected pairs left split |
E×5 |
The crossing stored as a signed offset from the edge midpoint |
E×6 |
The sample loop restructured for autovectorisation |
E×7 |
A staging ring, so the geometry read-back is amortised instead of waited on |
E×8 |
A subgroup prefix scan, replacing the Hillis-Steele ladder |
E×9 |
Six connectivity-weighted vertex normals, as a fourth NormalStrategy |
E×10 |
Capsule-vs-field contact by branchless golden-section search, against the parry3d TriMesh query |
E×11 |
gss_min_branchy — the same golden-section search with the if left in |
E×12 |
The classical origin-fan signed-tetrahedron integrator, against the surface form that shipped as mass.rs |
E×13 |
Lipschitz brush pruning at the brick, beneath P-39's chunk-level cull |
E×14 |
A two-level chunk scheduler — coarse everywhere, fine inside every coarse chunk the trace has touched |
E×15 |
One write_buffer per frame through a host arena, replacing the per-chunk upload bevy_isomesh ships |
E×16 |
A bespoke entropy coder for the edit log |
E×17 |
A dense Checkpoint field, so undo re-folds from a snapshot instead of from the log |
E×18 |
The Plantinga–Vegter certificate fused into the extraction gather, replacing the standalone validate::isotopy pass |
E×19 |
The barycentric (Kuhn/Freudenthal) 24-tetrahedron cell decomposition, replacing the six-tet split |
E×20 |
Crossings accumulated as a running sum in a relabelling-invariant key order |
E×21 |
dot_equivariant(g, g).sqrt() in place of vec3::length, one line, one call site |
When this file splits
Stated in advance, so the decision is not made under pressure by whoever is holding it when it
becomes unbearable. At 500 entries or 600 KB, whichever comes first, FINDINGS.md becomes the
index plus Parts 5 and 6 — the method rules and the how-to — and Parts 1 through 4 move to
findings/ split by axis, not by date: findings/correctness.md, findings/performance.md,
findings/sources.md, findings/method.md. Date order is how the file grew and is useless for
lookup; nobody has ever wanted "everything we learned in August".
Two things do not change at the split. The index stays generated — scripts/findings_index.sh
gains the directory and keeps one table across all files, because an index per file is four places
to look and therefore none. And entry numbering stays global: M-231 keeps its identifier
wherever it lives, since every cross-reference in the backlog, the archive and a year of commit
messages names it by number and a renumber would silently break all of them.
The index above carries the current count; it is generated, so it cannot drift from the file.
Confidence tiers
| Tier | Glyph | Meaning | Bar |
|---|---|---|---|
| M | 🔬 | Measured here | We ran it. Code and numbers in this repo, reproducible by checkout. |
| V | 📖 | Verified externally | We read the primary source ourselves. DOI or file attached. |
| R | 📄 | Reported | A credible source asserts it; we have not independently checked. |
| F | 🗣️ | Folklore | Widely repeated, no verified primary source found. |
| ✗ | 💥 | Falsified | Tested and found false. Includes what we believed and why. |
Never cite an R or F claim as justification for a design decision without saying which tier it is.
Glyphs, from 2026-08-17. A new ### entry opens with its tier glyph before the id — ### 🔬
M-324 — … — and 🧊 stands in for 🔬 when the measurement's finding is a null: no effect, and that is
the result. Emoji are reserved for rows that carry news, so they stay a signal rather than
decoration. A result that moved an open question, died instructively as a pre-registered
prediction, or survived a targeted literature search that came back empty earns a
> 🎉🎊🔥✨🏆 **DISCOVERY** 🏆✨🔥🎊🎉 blockquote directly under its heading, and the banner must say
which of those it claims; a banner on a routine row devalues every other banner in the file, so
routine confirmations and expected timings stay austere. scripts/findings_index.sh parses the
glyph and fails loudly on any entry-shaped heading it cannot index (the M-277 class, now guarded).
Rows older than this date carry no glyph and are not retrofitted.
Part 1 — Falsified
The most valuable section. Each row includes where the wrong belief came from, because provenance predicts the next error.
✗1 — "Surface Nets produces substantially fewer triangles than Marching Cubes"
Believed because: stated in this repo's own implementation brief, and near-universal folklore. Falsified by: A-004 measurement, then derivation, then independent numeric check. What's true instead: on a closed manifold surface meshed on the same grid, both counts are pinned by Euler's formula:
V_sn = V_mc + χ F_sn = F_mc + 2χ
Exactly, at every resolution. V_mc = C (one vertex per crossed grid edge), F_sn = 2C (two
triangles per crossed edge), F = 2V − 2χ on any closed triangulated manifold. The middle step is a
combinatorial identity worth naming on its own: surface cells = crossed edges + χ.
| field | χ | crossed edges C | surface cells S | S−C |
|---|---|---|---|---|
| sphere 17³ / 49³ | 2 | 414 / 4206 | 416 / 4208 | 2 / 2 |
| torus 33³ / 49³ | 0 | 1296 / 3216 | 1296 / 3216 | 0 / 0 |
| box 49³ | 2 | 4374 | 4376 | 2 |
| two disjoint spheres 49³ | 4 | 1300 | 1304 | 4 |
Consequence: Surface Nets' case must rest on quad connectivity and inner-loop cost, not output size. In
M-001 the count columns are a checksum with a predicted value, not a result.
Would be shown wrong by: any closed-manifold pair on the same grid where the difference ≠ 2χ.
Legitimately breaks at: boundary-clipped meshes (incoming at G-001 chunking — expect the
assertion to fail there and do not "fix" it), A-013 welding, Marching Cubes vs Marching Cubes 33 differing in χ.
A-013 landed and sharpened the welding clause (M-48): a weld lowers V_mc only where a grid
sample lands on the isosurface, which is a sampling accident rather than a property of welding —
measured at 48 of 654 vertices on sphere at 25³, and zero at 17³ and 33³ and on four of the
seven fields entirely. So the identity is not broken by A-013 existing; it is broken by a field that
happens to touch a lattice point, and by chunking.
✗2 — "You can have a manifold mesh or an intersection-free one, not both"
Believed because: folklore, repeated in several secondary sources. Falsified by: literature review round 1. Manson & Schaefer 2010 achieved both. ODC (2024) measured Manifold Dual Contouring at 100% of models self-intersecting against ODC at 0 of 1500. Consequence: guaranteed intersection-free extraction is on the table, which is the premise under A-009 and the runtime-convex-decomposition opportunity.
✗3 — "Every interior Surface Nets vertex has four neighbours"
Believed because: written into isomesh's own module docs before measuring. Falsified by: A-004. Measured max degree 10 — higher than Marching Cubes' 9. Method rule earned: a doc comment the test suite disproves is worse than no doc comment.
✗4 — "Dual Contouring is absent from the home-still corpus"
Believed because: distill_search returned nothing.
Falsified by: catalog_read on 10.1145_566570.566586 — present, with zero Qdrant chunks.
Root cause: 342 documents are readable but invisible to distill_search.
Method rule earned: presence in the corpus is decided by catalog_read / catalog_list, never
by search. Any claim of absence made from a search result is unfounded.
✗5 — "naga_oil is the shader composition path for Bevy"
Believed because: it was, and it's the name everyone knows. Carried into this project's premise. Falsified by: naga_oil's last release is v0.18, 2025-06-26 (14 months stale), and Bevy 0.19's own release notes say they will "port our existing internal shaders to use WESL, and endorse it as the shader language of choice for Bevy." Consequence: GPU-002 uses a ~40-line preprocessor; WESL revisited when shader count justifies it.
✗6 — "Mesh shaders aren't reachable from inside Bevy"
Believed because: an imprecise claim made in this project's own speed analysis.
Falsified by: wgpu v28 shipped Features::EXPERIMENTAL_MESH_SHADER; Bevy 0.19 pins wgpu
29.0.3; WgpuSettings.features requests it at device creation and
RenderDevice::wgpu_device() -> &wgpu::Device gives raw access.
What's actually true: wgpu's maturity is the blocker, not Bevy. Experimental, redesign issue
open, no browser support, Metal status contradictory (see O-5).
✗7 — "CBT 5.78 → 0.40 ms is from Dupuy 2020"
Numbers confirmed. Attribution wrong — it's the Unity SIGGRAPH 2021 talk. Method rule earned: verify the source separately from the number. A correct figure with a wrong citation propagates as an uncheckable claim.
✗8 — Velo3D "93M vertices / 31M faces"
Unsupported. No primary source located. Removed from the catalog rather than softened.
✗9 — "Marching Cubes' cost inside the volumetric loop was never measured" / "navmesh rebuild cost was never measured"
Both false. Dong 2018 measured meshing at 76.5–89.6% of the pipeline; van Toll 2012 measured navmesh rebuild. Both were asserted as gaps in this project's v2 catalog and corrected in round 1. Method rule earned: "nobody measured X" is a claim requiring the same evidence as any other.
✗10 — "glam should be the internal math library from day one"
Believed because: stated in this repo's architecture doc.
Refined by: the agent at I-001. The core took libm only; glam is deferred to A-007, where the
3×3 solve is the first thing that actually needs matrix math.
Why the refinement is better: the public API is arrays, so glam was never load-bearing; deferring
it means the crate carries zero exposure to glam's ~quarterly breaking releases until it buys
something. Consumers need no conversion impls either — glam::Vec3::from([f32; 3]) already exists.
✗11 — "Plain Marching Cubes has ambiguous faces and produces holes"
Believed because: stated in this repo's own implementation brief (Stage 2, "Plain Marching Cubes has ambiguous
faces and produces holes"), carried into BACKLOG.md's A-002 acceptance criterion, and near-universal
folklore about Marching Cubes.
Tested by: validate_table() (marching_cubes/mod.rs:319), which checks all 256 cases structurally, and the
assertion assert_eq!(report.face_disagreements, 0) at marching_cubes/tests.rs:30.
Result: zero face disagreements, across all 256 cases.
What's true instead: holes require two cells sharing a face to disagree about how the surface
crosses it. In this implementation a face's segments are a function of that face's own four corner
signs and nothing else — the two cells meeting on a face read the same four corners, so they cannot
disagree. The property is structural, not empirical, and it falls out of the table being derived at
compile time by walking each face counter-clockwise rather than transcribed from a diagram.
The folklore is not wrong about Marching Cubes in general; it is wrong about this Marching Cubes. Lorensen & Cline's original table was transcribed per-case and its ambiguous cases were resolved inconsistently between complementary configurations, which is where the holes came from.
Consequence: A-002's acceptance criterion was unsatisfiable and has been re-scoped. Marching Cubes 33's
remaining value is topological agreement with the trilinear interpolant — a genuinely different
surface on ambiguous faces, measurable as a χ difference — not crack-fixing. The research is
explicit that a game wants consistency over topological fidelity, so the L slot is now spent
knowingly rather than against a test that could never go green.
Would be shown wrong by: any field producing boundary_edges > 0 from A-001 on a closed field, or
any non-zero face_disagreements.
✗12 — "The equivariant vertex rule needs a fast three-plane path with a fallback"
Believed because: BACKLOG.md split it into A-007 ("the three-plane rotation-equivariant rule…
falls through to A-008 when the triple product is near zero") and A-008 ("for >3 planes and degenerate
cells"), and the brief says "falls back when the triple product is near zero (near-parallel planes)".
The crate architecture doc says the same in a third phrasing: "fall back to the regularized
normal-equation form only for >3 planes".
Tested by: reading the audit doc all three of them cite —
docs/research/2026-08-10-adjacent-math-transfer-audit.md:182-219.
Result: the audit gives the Tikhonov-adjugate form as the production form and describes it as
"branch-free, handles all degeneracies", closing with "no eigendecomposition, no SVD, no iteration,
no data-dependent branch". It is a single unconditional path in the source, not a fallback arm.
Worse, the audit's diagnosis of why Dual Contouring pops is the branch itself: Dual Contouring's hard SVD
truncation at σ < 0.1 is a discontinuous branch, and over 20,000 trials seeded at the threshold in f32
the rank branch disagreed after a rotation in 454 cases, with ‖f(Rx) − Rf(x)‖ median 2.13 and
max 9.10 — a several-cell vertex pop from an infinitesimal rotation. A triple-product threshold is
the same construction with a different discriminant, so the split would have reintroduced the exact
failure the rule exists to remove.
The measured equivariance residual (f32, coordinates in [0,256], 4000 random cells) also shows the "fast path" is not the accurate one:
| rule | median | p99 | max |
|---|---|---|---|
| Dual Contouring normal equations | 6.80e−05 | 2.48e−01 | 5.6e+02 |
| dual basis (Cramer) | 1.61e−05 | 7.23e−04 | 3.6e−01 |
| Tikhonov adjugate | 1.59e−05 | 1.81e−04 | 6.4e−04 |
Tikhonov dominates Cramer on both tail columns, so nothing is traded away by dropping the three-plane form. The two paths also do not agree to within noise, which means the branch would have been observable in the output.
Consequence: A-007 and A-008 merged into one ticket with one unconditional path. Two requirements
the audit states and no ticket had recorded are now in it: magnitude-sorted 3-term dot products
(4328/9600 equivariance failures unsorted, 0/9600 sorted — the guarantee does not hold in f32
without this), and the derivation of λ = 0.01 as the value that reproduces Dual Contouring's σ = 0.1 truncation
smoothly. The corpus circulates three constants — 0.01, 0.1, and σ=0.1 — and an implementer reading
only the algorithm catalog would have picked 0.1.
Would be shown wrong by: a measured configuration where the adjugate form is less accurate or less
equivariant than the Cramer form, or where det(M + λI) is small enough at λ = 0.01 to matter.
✗13 — "Real::as_f32 is the only narrowing operation in the crate, and the crate itself never calls it"
Believed because: stated in real.rs's own doc comment for as_f32, which frames it as an output
convenience — "it exists for consumers writing into an f32 vertex buffer".
Tested by: grep -rn "as_f32()" crates/isomesh/src/.
Result: three call sites, none of them a consumer and none of them writing a vertex buffer:
| site | purpose |
|---|---|
fields/noise.rs:82 lattice_index |
Perlin lattice coordinate |
validate.rs:810 quantise |
duplicate-vertex bucketing |
validate/tri_grid.rs:60 cell_of |
spatial-grid binning |
All three are the same idiom, f.as_f32() as iN — a float→integer narrowing. Two predate this
session, so the doc comment has been false since I-002.
Why this is more than a tidiness point. The doc's framing hides the property that actually matters
at these call sites: as_f32 on an f64 is exact only up to 2²⁴, so using it as an integer
narrowing step carries a silent lattice cliff. noise.rs knows this and guards with a
LATTICE_LIMIT debug assertion; the other two did not, and nothing said they should. See M-18 for
where that bites.
Consequence: the doc comment corrected in place, and T-008 opened for the one exposed call site.
Method rule earned: ✗3's, again — a doc comment the code disproves is worse than no doc comment.
Twice now the false comment has been an architectural claim ("nothing calls this", "every vertex has
four neighbours") rather than a factual slip, which is the kind that shapes later decisions.
✗16 — "glam 0.32 lands with A-007's vertex solve"
Believed because: stated in four places — CLAUDE.md's crate layout ("Deps: libm today; glam 0.32
joins it at A-007. Nothing else, ever.") and its dependency-justification section, BACKLOG.md's A-007
ticket, BACKLOG_ARCHIVE.md's I-001 note, and ✗10 itself, which deferred glam to A-007 on the grounds
that "the 3×3 solve is the first thing that actually needs matrix math".
Tested by: reading glam 0.32.1's source before adding the dependency.
Result: glam has no scalar abstraction. Mat3 lives in src/f32/mat3.rs and DMat3 in
src/f64/dmat3.rs as separate concrete types, lib.rs re-exports per-scalar modules, and there is no
generic Mat3<T> and no trait spanning the two. The only pub trait in the crate is FloatExt, a
scalar extension trait.
What's true instead: the premise was right and the conclusion did not follow. The solve does need
matrix math — but this crate is generic over Real, which spans f32 and f64, and glam's types
do not. Using it would mean a bridge trait with two impls forwarding every operation, which is more
code than the 3×3 adjugate it would wrap, adds a dependency, and puts two float backends inside one
solve — the exact thing the libm justification rejects.
So the 3×3 lives in dual_contouring/solve.rs as a six-entry symmetric matrix over [R; 3], about 40 lines, and
the crate stays at one dependency. The "as light as possible" pitch survives A-007 intact.
Would be shown wrong by: glam gaining a generic scalar parameter, or this crate dropping f64.
Note this is ✗10's second correction. ✗10 moved glam from "day one" to "A-007"; the deferral target
was wrong too. The recurring error is reasoning about glam from its reputation rather than its API.
✗15 — "Marching Cubes is unconditionally manifold"
Believed because: every measurement in this repo said so. M-4 contrasts Surface Nets'
non-manifoldness against "Marching Cubes' zero at every resolution", the README says "Marching Cubes
stays manifold", and the mechanism looked airtight — Marching Cubes places vertices on grid edges rather than
one per cell, so the multi-sheet argument that sinks Surface Nets does not apply. SurfaceGate::Closed's own doc
comment asserted it.
Falsified by: T-005b's marching_cubes_meshes_sphere_unions, on its first run against a fresh
proptest seed — during T-006, which is a nice demonstration that the property tests keep working after
the ticket that wrote them.
Result: a union of three spheres at h = 2/3 gives 2 non-manifold edges and 3 non-manifold
vertices on a mesh that is otherwise perfect: closed, χ = 2, one component, consistently oriented,
zero boundary edges.
What's true instead: Marching Cubes is manifold when the grid resolves the surface. Where the surface pinches inside a single cell — two lobes of a union meeting at sub-cell scale — the shared grid edge ends up carrying four faces. Refinement fixes it, and sharply:
| n | 7 | 9 | 13 | 17 | 25 | 33 | 49 | 65 |
|---|---|---|---|---|---|---|---|---|
| non-manifold edges | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Consequence: the property suite's gate is renamed from ClosedAllowingMultiSheet to
ClosedAllowingUnresolvedTopology and now covers Marching Cubes on generated fields too, because the condition
was never about the algorithm — it is about whether the grid resolves the field. The strict gate is
still asserted where it is actually true, on the seven reference fields in marching_cubes/tests.rs. The exact
counts are pinned in both directions by
an_under_resolved_pinch_makes_marching_cubes_non_manifold, following M-4's precedent: the defect is
an assertion, not an exclusion, so it fails if it spreads and if it silently disappears.
Would be shown wrong by: the same field at h = 2/3 coming back manifold, or any resolved field
coming back non-manifold under Marching Cubes.
Worth noting for G-001: a chunk boundary is a place where a surface can be under-resolved relative
to the chunk it lands in. This is a plausible source of seam defects later.
The counterexample stands; the mechanism was wrong, and A-015 proved it. The falsification
condition above — "the same field at h = 2/3 coming back manifold" — is now met, by a change that
touched no geometry at all: the union of three spheres reports 0 non-manifold edges and 0 non-manifold
vertices once cycles are fanned from a chord-safe apex.
That settles the attribution, because a triangulation cannot repair a pinch. If two sheets genuinely met inside a cell they would still meet however each is triangulated. What was actually happening is the fan chord of ✗17: two cells choosing the same interior diagonal, four faces on one mesh edge. The refinement table above is real but was reading a proxy — refinement changed which sign patterns occurred, not whether the grid "resolved" anything.
The reading of χ was wrong too, and in a way worth keeping: a collided mesh edge is counted once in
E while carrying four faces, so E was short by exactly the two collisions and χ was long by two.
The old χ = 2 was not a topology measurement. The same fixture now reports χ = 0, genus 1 — three
lobes meeting in a genuine handle at that spacing.
Consequence: the property suite's Marching Cubes gate goes back to the strict SurfaceGate::Closed it was
waived from, and passes 8,000 generated cases where before A-015 it failed on the first fresh seed.
Whether Marching Cubes is unconditionally manifold is now open, not settled — see O-12. Nothing
here proves it; only that the one mechanism ever exhibited is gone.
✗17 — "Only the interior test can make Marching Cubes 33 non-manifold, so the face decider alone cannot"
Believed because: it was written down as a prediction in A-002's plan, and the reasoning looked
tight. Custodio et al. (2013) §6.2 give exactly one mechanism for Marching Cubes 33's non-manifold edges — "two
adjacent voxels that share an ambiguous face have tunnels in the voxel interior" — and tunnels come
from the interior test, which A-002 deliberately does not implement. The face decider only re-pairs cut
edges; it moves no vertex and creates no new one.
Falsified by: every_closed_reference_field_meshes_cleanly_under_the_decider, on its first run.
Result: the capped gyroid at 25³ gives 2 non-manifold edges and 3 non-manifold vertices under
the decider against plain Marching Cubes' 0, on a mesh with zero boundary edges and zero
inconsistently oriented edges. At 17³ and 33³ the two rules agree exactly.
What's true instead — and it is not the decider's fault. Both offending mesh edges carry four
faces. Inspected rather than reasoned about: each joins two cut cube edges that lie on a shared cube
face but are not connected by a segment there, and each is emitted twice by each of the two
adjacent cells. They are fan chords. marching_cubes/table.rs's triangulate fans each cycle from its first
edge, and any triangulation of a k-gon that adds no vertices has k − 3 interior chords; nothing
local stops two neighbouring cells choosing the same one.
An exhaustive two-cell search settles the attribution. Two cells stacked along z share a face and have twelve samples between them, so all 4,096 sign patterns fit in a loop:
| rule | worst faces on one mesh edge | patterns affected |
|---|---|---|
| separated (A-001) | 4 | 12 / 4096 |
| decider (A-002) | 4 | 12 / 4096 |
Identical. Plain Marching Cubes has this defect at exactly the same rate. The decider only changes which sign patterns are reached, and on the gyroid at 25³ it happens to reach one.
Consequence: the defect is ticketed against Marching Cubes as A-015, not against Marching Cubes 33, and the
fix is a per-cycle centroid vertex — the only chord-free triangulation of a polygon. That breaks
✗1/M-2/M-22's V_mc = C identity and re-baselines every golden hash, which is why it is its own
ticket rather than a fix folded into this one. Meanwhile is_closed() is deliberately not the gate
in the decider's reference-field sweep, because it folds in manifoldness and manifoldness is owned by
the fan; the census is pinned exactly instead, following M-4.
Fixed at A-015, and for far less than it looked like it would cost. The obvious repair — a centroid
for every cycle of four or more — works and is ruinous: +73% vertices and +74% triangles across the
seven reference fields, up to +99.7% on box_exact, because almost every cycle is long enough to
qualify. The cheap repair follows from asking which chords can collide rather than eliminating all of
them: only a cell containing both of a chord's cut edges can emit it, and two cells share a pair of
cube edges only when those edges share a cube face. So a fan is safe when none of its chords joins
two edges of one face, and that is a local, const-evaluable test. Measured over all 256 cases and
every canonical mask, a safe apex exists for every cycle of length 3–7 and for 48 of the 60 length-8
cycles; only lengths 9 and 12 have none, and plain Marching Cubes tops out at 7. Final cost across the
whole golden fixture: one row's counts changed — marching_cubes+decider/gyroid/25, +6 vertices and +12 triangles.
V_mc = C is intact.
Would be shown wrong by: the two-cell search returning a different count for the two rules, or the offending mesh edges turning out to be face segments rather than chords. Method note: the prediction was written into the plan before the code ran, which is the only reason this reads as a falsification rather than as a bug that was quietly fixed.
✗14 — "Surface Nets is the cheapest thing in the family and the natural default"
Believed because: this repo's own algorithm catalog states it as the engine verdict —
docs/research/2026-08-10-meshing-algorithm-catalog-v2.md:163, "cheapest thing in the family and the
natural default" — reinforced by the same folklore ✗1 already corrected once.
Tested by: T-006's resolution sweep, cargo bench --bench resolution_sweep. Sphere, f32, single
thread, median of 5 timed runs after 2 warm-ups, identical grid and reused output buffers for both
algorithms. Raw data committed at docs/measurements/resolution_sweep.csv.
Result: Surface Nets is cheaper only below about 48³. The crossover sits between 48³ and 64³, and
past it Surface Nets loses steadily and then sharply:
| n | Marching Cubes ms | Surface Nets ms | Surface Nets/Marching Cubes | Marching Cubes ns/sample | Surface Nets ns/sample |
|---|---|---|---|---|---|
| 16 | 0.090 | 0.038 | 0.42 | 21.88 | 9.17 |
| 32 | 0.601 | 0.296 | 0.49 | 18.33 | 9.04 |
| 48 | 1.251 | 0.976 | 0.78 | 11.31 | 8.82 |
| 64 | 2.246 | 2.425 | 1.08 | 8.57 | 9.25 |
| 128 | 10.195 | 20.006 | 1.96 | 4.86 | 9.54 |
| 192 | 33.898 | 70.432 | 2.08 | 4.79 | 9.95 |
| 256 | 80.257 | 221.223 | 2.76 | 4.78 | 13.19 |
What's true instead: the two curves are not parallel — one converges and the other degrades.
Marching Cubes' per-sample cost falls from 21.9 to 4.78 ns as the O(n²) surface term amortises
away, then is flat from 128³ on. Surface Nets' is flat at ~9 ns to 128³ and then rises, reaching
13.19 ns/sample at 256³ — a 33% jump from 192³ alone.
Consequence: taken with ✗1, which showed Surface Nets emits 2χ more triangles rather than
fewer, both halves of the case for Surface Nets as the default are now falsified by measurement in
this repo. What it actually retains is quad connectivity and one vertex per cell — a topology
argument, not a cost one. M-001's shootout must not present it as the cheap baseline, and the choice of
a default extractor for the game should be revisited.
Would be shown wrong by: a machine where Surface Nets' per-sample cost stays flat to 256³, which would localise this to one cache hierarchy rather than to the algorithm.
Amended again the same day (M-285), and this time the conclusion itself moves. A-023 made
emit_quads' axis a const generic — three monomorphisations of one function, same order, byte-identical
mesh — and Surface Nets went 693.8 → 224.4 ms at 256³, SN/MC 5.43× → 1.72×, IPC 1.20 → 2.77.
At 48³ Surface Nets is now faster than Marching Cubes, 30.7 cycles per sample against 33.1. So the
sentence "Surface Nets never wins on Zen 3, at any resolution" is false, and the cost half of the case
against Surface Nets as a default is much weaker than this entry says: 1.7× at the largest grid, a win at
the smallest. ✗1's half is untouched — Surface Nets still emits 2χ more triangles — so the entry is
narrowed rather than reversed, and the residual gap is the cache story of M-286 rather than the algorithm.
Amended 2026-08-16 (M-282), and the conclusion is stronger while every number here is superseded.
Measured in one binary and one run on the Ryzen: surface_nets / marching_cubes at 256³ is 5.43×
against the 3.72× above, and 3.19× at 16³. Marching Cubes got 1.74× faster between d2ab82a and
now while Surface Nets got 1.17×, which is where the widening comes from. The mechanism is also no
longer "per-sample cost rises": M-279 measured that the whole family divides on IPC — everything
table-driven runs at 3.7–4.2 and everything on DualMesher at 1.20–1.42 — and that the dual's rise
with n is a 16% IPC decline on an instruction stream that is flat per sample. And per M-281, the
absolute milliseconds in this entry are comparable only against others from the same binary.
Confirmed on a second machine at O-11, and harder — but the crossover is not (M-45). On an AMD
Ryzen 9 5900X, Surface Nets' per-sample cost climbs 37.4 → 49.1 ns over the same sweep, so the
falsification condition above is not met: the verdict is a property of the algorithm rather than of one
cache hierarchy. The ratio is worse there — 3.72× at 256³ against the M5's 2.65×.
What does not transfer is the sub-claim "Surface Nets is cheaper only below about 48³". That crossover exists on the M5 only because Marching Cubes starts expensive there — 24.99 ns/sample at 16³ — and converges. On Zen 3 Marching Cubes is flat at 13–15 ns from 16³ up, so it has nothing to converge from and Surface Nets is behind at every resolution measured, 2.46× even at 16³. Any statement of the form "Surface Nets wins at small grids" is an Apple-silicon statement.
Narrowed by A-007. Dual Contouring, which shares the dual topology and differs only in vertex
placement, shows the same curve: 218.9 ms at 256³ against Surface Nets' 212.5, and the same
negative fitted intercept. So the superlinearity is a property of the shared dual engine — its
sampling and its strided quad walk — and not of either vertex rule. That is a real narrowing of O-11's
search: the suspect is the gather in emit_quads, whose z-stride is n² cells apart.
✗18 — "A hairline seam difference is a crack no weld can close"
Source: this repository — M-73, and transvoxel::cell's own module docs, which say it twice.
"A weld cannot rescue it: welding merges vertices it can see are the same, and these two differ in the last bit." (M-73)
"The weld can close a seam it can see; it cannot invent a shared vertex where the two sides disagree in the last bit." (
cell.rs, module docs)
Falsified at R-004 (M-278). "Vertices it can see are the same" reads as bit-identity, and the
welder's rule is not that: it is first fit within epsilon, and the one policy is
epsilon_for(h) = h · 1e-4. At h = 1/12 that is 8.33e-6 against a worst measured seam
disagreement of 1.440e-15 — nine orders of magnitude inside the tolerance, and the 27-cell
lattice probe means straddling a bucket boundary does not save it either.
Measured on the two-resolution fixture, offset arithmetic, all five spacings and both LOD pairs: 0 seam-plane boundary edges in all twenty rows under the crate's own weld — including the twelve where a bit-identity merge leaves 63 to 348.
Two things survive, and they are why the M-73 fix was still right.
- A consumer that does not weld gets the crack in full. M-69 is that consumer on the record: "a seam of unshared vertices that a renderer draws correctly and a collider reads as a hole." Sharing by construction is structural; sharing by tolerance is a policy someone can change.
- The weld is not free to lean on. R-001 measured that it can create a non-manifold edge (M-226) and R-002 that its result depends on input order. "The weld will catch it" is a bad thing to design against even when it is true.
And the claim understates the damage in the other direction, in 2 of 12 rows. The offset
arithmetic is not always a hairline: on torus at h = 1/12 the widest bit-identity crack is
2.076 cells at LOD 0–1 and 1.053 at 1–2, because a sample perturbed in its last bit crossed
zero and the two sides then disagreed about whether an edge was cut at all. That is a hole, not a
rounding error, and no weld epsilon short of a cell would close it.
✗19 — "Manifold Dual Contouring's uniform-grid surface is always a manifold"
Source: the paper itself, read at A-022 (V-34). Schaefer, Ju & Warren, §3:
"To create polygons, the algorithm constructs one polygon connecting the vertices associated with that edge in the four adjacent cells. … this surface is always a manifold because the original MC algorithm always constructs a manifold and the dual preserves the topology of the surface."
Unconditional, and at the uniform-grid level — before any octree, any simplification, any clustering.
Falsified at A-022 (M-290). Eight reference fields × three resolutions, no chunking, no weld:
| extractor | non-manifold edges | non-manifold vertices |
|---|---|---|
marching_cubes |
0 | 0 |
marching_cubes + asymptotic decider |
0 | 0 |
manifold_dual_contouring, unmodified table |
143 | 286 |
manifold_dual_contouring, decider-modified table — the paper's own construction |
114 | 222 |
surface_nets / dual_contouring |
1,128 | 2,156 |
The interesting part is which half of the argument fails. The premise is "the original MC algorithm always constructs a manifold" — ✗15 records that as false in general, so the obvious guess is that the premise is what breaks. It is not: Marching Cubes measures 0 on all 24 configurations here, under both face rules, A-015 having removed the fan chords that made ✗15's counterexample. The premise holds and the conclusion still fails, so what is false is "the dual preserves the topology of the surface".
And the mechanism was already written down in this crate, as something the paper did not claim.
manifold_dual_contouring's module docs say the residue is "two crossed edges of one shared face
resolving to the same cycle pair", producing four quads on one dual edge, and then: "Schaefer, Ju
and Warren separate sheets within a cell and never claimed to handle [this], so this is outside
what they guarantee rather than a defect against it." That charitable reading was written while the
paper was unobtainable. They do claim it, in one sentence, unconditionally. So the residue is a
defect against the paper's stated guarantee and not outside it, and the crate's own docs need the
correction — which they now have.
What is not falsified. The paper's contribution is the octree vertex-clustering algorithm and
its topology-preservation proofs, none of which this touches. What fails is the one-sentence argument
for the uniform-grid base case it builds on, and it fails on noise_cavity only — the field A-002e
added because none of the other seven produces a cell with an interior ambiguity (M-208).
Part 2 — Measured here (tier M)
| # | Finding | Evidence |
|---|---|---|
| M-1 | surface cells = crossed edges + χ | 4 topologies × 3 resolutions, table in ✗1 |
| M-2 | V_sn = V_mc + χ, F_sn = F_mc + 2χ |
A-004 tests, all four clean fields |
| M-3 | Surface Nets max vertex degree 10; Marching Cubes 9 | A-004 |
| M-4 | Surface Nets is non-manifold where one cell carries two sheets: 48 non-manifold edges on capped gyroid, 15 on fbm_terrain at 33³ | A-004; pinned as non-zero assertions, not excluded silently |
| M-5 | On box_exact, Surface Nets' nearest vertex to the corner (1,1,1) is 1.15 cells away |
A-004 — this gap is what E-104 exists to show |
| M-6 | libm::sqrtf lowers to hardware fsqrt (aarch64+neon) / sqrtss (x86-64+sse2) |
libm 0.2.16 source: src/math/arch/aarch64.rs raw asm, dispatched by select_implementation! on target_feature |
| M-7 | dev-dependencies do not propagate: consumer resolves 3 packages, the crate's own lockfile has 137 | Experiment, cloud container |
| M-8 | Cargo silently co-resolves two wgpu majors — 317 packages, both 29.0.4 and 30.0.0, no resolution error; fails later as expected TextureFormat, found a different TextureFormat |
Experiment |
| M-9 | Workspace feature unification leaks: -p isomesh alone gives glam libm; whole-workspace gives it std, serde, bytemuck, encase, rand |
Experiment — the reason bevy_isomesh is excluded |
| M-10 | Unit sphere at 64³ (h = 4/63), symmetric Hausdorff: Marching Cubes 1.380e-3, Surface Nets 2.288e-3. Mean absolute error Marching Cubes 6.50e-4, Surface Nets 1.367e-3. Surface Nets is 1.66× worse than Marching Cubes on both |
T-003, a_unit_sphere_at_64_cubed_is_within_one_cell_diagonal |
| M-11 | T-003's own acceptance criterion is loose by ~80×. One cell diagonal is 0.10997; Marching Cubes measures 0.00138. A harness returning a constant 0.01 would pass it |
T-003 — which is why the ticket also ships a convergence-order test and closed-form fixtures |
| M-12 | Marching Cubes' error falls like h², measured. Mean error 2.7168e-3 at 32³ against 6.5015e-4 at 64³ — a ratio of 4.179, against the ideal ((4/31)/(4/63))² = 4.13 |
T-003, the_error_falls_like_h_squared |
| M-13 | Surface cells ≈ 1.5·A/h², not A/h². Measured 1.450 (25³), 1.442 (33³), 1.517 (64³) on the unit sphere. The constant is derivable: a plane of unit normal n crosses (\|nₓ\|+\|n_y\|+\|n_z\|)/h² cells per unit area, and E[\|nₓ\|] = ½ over the sphere, so an isotropic surface gives E[Σ\|nᵢ\|] = 3/2 |
T-003. Predicted 6,430 triangles at 64³ from A/h² and measured 9,452 — a 1.47× miss, which is this factor |
| M-14 | The reverse direction finds defects the forward direction structurally cannot. box_exact at 33³: forward 0.0833, reverse 0.1443 — the reverse number is Marching Cubes' rounding of the sharp corner. thin_plate at 33³: forward 0.0083, reverse 0.0893 — an under-resolved plate |
T-003. Deleting one face of an octahedron leaves mesh_to_field bit-identical and moves field_to_mesh to √(3/2 − 2/√3) |
| M-15 | Surface Nets' non-manifoldness is a resolution effect, not a topology effect. M-4 measured it on gyroid (48 edges) and fbm_terrain (15) and read it as a high-genus / open-field property. T-005b finds it on a randomly generated convex body — 1–2 non-manifold edges, 3–4 non-manifold vertices, zero boundary edges. Any feature thinner than one cell forces two sheets through it |
T-005b, surface_nets_meshes_convex_bodies. This is why the sweep has a named SurfaceGate rather than a per-field exception |
| M-16 | The even-χ parity check is not independent of manifoldness — it is a corollary of it. χ = 2 − 2g holds for a closed orientable manifold, so a gate that waives manifoldness and keeps parity is incoherent. Measured: Surface Nets on a generated convex body gives χ = 1 with one non-manifold edge and zero boundary edges |
T-005b. Cost one wrong gate before it was noticed; SurfaceGate::ClosedAllowingMultiSheet now documents the omission rather than leaving it to be rediscovered |
| M-17 | A case-table entry naming an uncut edge is caught inside the crate, before any mesh exists — edge_crossing's is_inside(a) != is_inside(b) precondition fires. Real defence, but it is a debug_assert, so it is absent from a release build |
T-005b. The mutation check therefore confines its wrong-edge corruption to cut edges, which is both the plausible transcription error and the one that actually reaches the validity gate |
| M-18 | (refined by T-008 — the arithmetic below is about adjacent cells; the effect on a real mesh is gradual, because a mesh whose vertices span many lattice cells keeps resolving them for a while after neighbours have merged. Measured on a 1158-vertex sphere at h = 0.125: no collapse at all at 1e4, and 1158 → 918 buckets, a 21% loss, at 1e6. Fixed by anchoring the lattice to the mesh's own minimum corner, so the scale depends on the mesh's extent rather than its position) quantise's weld lattice collapses beyond ~105 world units, and it is a performance cliff rather than a correctness one. It scales absolute coordinates by 1/(h·1e-4) — 160,000 at h = 0.0625 — so it passes f32's exact-integer range at 2²⁴·weld_epsilon ≈ 104.86. Measured: at p = 104 two cells one apart stay distinct; at p = 105 they collapse; by p = 1000 a whole region is one bucket. Correctness survives — coarsening only merges buckets, and the 27-neighbour probe plus exact distance test still finds every duplicate — but the scan degrades toward quadratic, silently, at exactly the coordinates G-001 chunking and G-007 streaming produce. TriangleGrid is immune because it quantises relative to its own AABB origin, which is the fix pattern |
T-005b follow-up, ✗13. Ticketed as T-008 |
| M-19 | There is no meaningful fixed cost on the CPU extraction path, and the prediction saying so was written down before the run. Marching Cubes' fitted a is 0.49 ms against a largest measured run of 80.3 ms — 0.61%. V-6's "73% of a published 64³ figure was fixed launch overhead" is a GPU dispatch property and does not transfer; the "stop trusting single-grid numbers" rule belongs to Phase 6, not here. Caveat that matters: a is 543% of the smallest measured run, so the fit must not be extrapolated below 16³ — down there the O(n²) surface term dominates |
T-006, benches/resolution_sweep.rs. The prediction is in that file's module docs, committed before the first measurement |
| M-20 | Marching Cubes' marginal cost is 4.75 ns/sample — 211 M samples/s, single-threaded, f32, Apple M5. Per-sample cost is flat within 2% from 128³ upward, r² = 0.99986 |
T-006. Against V-3's 5.42 G voxel/s on an RTX 2080 Ti that is a ~26× gap, which is the number the Phase 6 GPU decision should be argued from rather than from folklore |
| M-21 | Surface Nets is not O(n³) over this range; Marching Cubes is. Surface Nets' fitted intercept is negative — −3.13 ms full sweep, −7.32 ms on the tail — which is physically impossible and is the signature of a curve convex in n³. r² = 0.9899 against Marching Cubes' 0.99986. Per-sample cost rises 9.0 → 13.19 ns while Marching Cubes' falls and flattens |
T-006. Cause unmeasured — see O-11. This is why ✗14's gap widens rather than staying constant |
| M-22 | ✗1's identity holds at every resolution to 256³: V_sn − V_mc = 2 and F_sn − F_mc = 4 exactly, nine resolutions, χ = 2. The original table topped out at 49³, so this is corroboration at 5× the resolution and 16.8 M samples |
T-006's sweep, which records vertex and triangle counts alongside the timings |
| M-23 | f64 costs 8–10% on extraction paths with no matrix solve in them. At 65³ on a sphere: Marching Cubes 1.3928 ms (f32) against 1.5083 ms (f64), +8.3%; Surface Nets 2.3625 against 2.6036, +10.2%. Not the 2× a naive "twice the bytes" guess suggests, because the work is dominated by field evaluation and branchy table lookup rather than by memory bandwidth |
T-006, benches/extract.rs, the precision group. Partially answers O-8 for the non-QEF paths; A-007's solve is where AᵀA squares the condition number and the answer may differ |
| M-24 | Bit-exact lattice equivariance needs magnitude-ordered products, not just sums. The audit prescribes "magnitude-sorted 3-term dot products", which is necessary and not sufficient: a cofactor expansion of det(M+λI) along a fixed row selects three of the six entries by position, so relabelling the axes evaluates a different expression. Measured 19 ULP disagreement under a cyclic permutation, on all three fixtures, with the dots already sorted. Fixed by the symmetric determinant form with magnitude-ordered 3-factor products — FP multiplication is commutative but not associative, so (a·b)·c ≠ (b·c)·a. Now 72/72 rotation×fixture cases are bit-identical |
A-007, the_vertex_is_bit_exactly_equivariant_under_lattice_rotations, which failed before the fix |
| M-25 | The sharp-feature solve is nearly free: Dual Contouring costs 3% more than Surface Nets. At 256³ on a sphere, 218.9 ms against 212.5 ms; marginal 78.1 against 80.4 M samples/s. A full 3×3 regularized solve per surface cell, and it barely registers — because both methods are dominated by the shared dual topology (sampling and the quad walk), not by vertex placement |
A-007, benches/resolution_sweep.rs, now sweeping three algorithms |
| M-26 | Dual Contouring reaches a box corner to 0.01 cells where Surface Nets stops at 0.58 — measured at 27³ on box_exact, 0.0009 against 0.0888 in world units. The resolution is deliberately not grid-aligned; on an aligned grid this measures the zero-classification rule instead (E-103's trap) |
A-007, the_corner_is_sharper_than_surface_nets. This is E-104's money shot, measured before the example exists |
| M-27 | The two dual methods differ only at features, with a 14-order-of-magnitude gap and nothing in between. On box_exact at 27³: 864 of 1016 vertices agree with Surface Nets to within 2e-15 cells, 152 move by 0.35–0.57 cells, 0 land between. Exact reason: on a planar patch every crossing lies in the plane, so pᵢ − c ⊥ n, every dᵢ is exactly zero, g is exactly zero and the solve returns the centroid |
A-007, dual_contouring_moves_only_the_feature_vertices. Consequence: E-104's side-by-side measures the feature and nothing else. Note the agreement is to rounding, not to the bit — the two centroids are computed by different expressions |
| M-31 | libm delivers the bit-identical cross-platform meshes it was chosen for — verified, not reasoned. T-007's 63 golden hashes were generated on macOS / arm64 and pass unchanged on Linux / x86-64 in CI. Every position, normal and index bit-for-bit equal across two architectures, two operating systems and two libm-vs-hardware float paths |
I-001 chose libm over std unconditionally on the grounds that std's sin/cos are the platform's own and differ between macOS and Linux, and recorded that T-007's committed hashes would be the proof. They are. The claim moves from a design argument to a measurement |
| M-32 | Chunk seams are bit-exact only when the cell size is a power of two. Two adjacent chunks meshed independently agree on 16 of 16 shared-plane vertices bit-for-bit at h = 0.125, and on 0 of 14 at h = 4/35 — worst gap 1.57e-16 world units, 1.37e-15 cells. Cause: an extractor computes origin + h·local, so chunk c's last plane is (o + h·cn) + h·n while c+1's first is o + h·(c+1)n — equal by algebra, not by IEEE. 22% of 200,000 random (origin, h, cells, chunk) combinations disagree, by one or two ulp |
G-001. A rounding error rather than a crack, but it decides whether a chunked world can claim the bit-identity T-007 and M-31 establish for a single volume. Recommend power-of-two cell sizes for chunked worlds, and note G-003's commutativity acceptance will depend on this |
| M-33 | E1, the unpublished number: a brush changes 15–36% of the cells in its own bounding box. Measured for a sphere brush carved two cells deeper, h = 0.0625: radius 0.25 → 36.0%, 0.50 → 29.2%, 0.75 → 24.4%, 1.00 → 14.9%. It falls roughly as 1/r, and the reason is geometric — the changed set is a shell of fixed thickness, so it grows as r² inside a bounding box that grows as r³ |
G-002. The research doc asks for this and records that nobody has published it. The incremental case is real but not overwhelming: a bounding-box re-mesh does 3–7× the necessary work, not 30× |
| M-34 | Counting value changes overstates the re-mesh set by 2.8–3.7×. An SDF brush perturbs values throughout its support — carving a sphere deeper moves the field everywhere the sphere term dominates, including deep inside the solid — but a cell wholly inside or wholly outside emits no triangles either way, so its output is unchanged. Measured at radius 0.25: 100% of cells changed value, 36% changed output. At 1.00: 55% against 15% |
G-002. The first version of E1 counted value changes and read 100%, which would have been published as "incremental meshing buys nothing" — the exact opposite of what the data says |
| M-35 | A brush stepping two cells sweeps 6–14% of its sign-changed cells entirely through. Every corner flips from outside to inside in one edit, so the cell is a surface cell neither before nor after and needs no re-mesh at all. Measured 167 of 1155 at radius 0.25, 1040 of 8660 at 1.00. Consequence: a sign change does not imply an output change, which looks obviously false and is why the assertion caught it |
G-002. The signature of an edit moving further than one cell per step, which is where a stroke starts skipping geometry between frames |
| M-36 | The multiplayer story survives, with a boundary. Eight brushes in all 8! = 40,320 orderings give exactly one result — bit-identical — when they are all Add, and again when all Subtract. min and max are commutative and associative in IEEE, and they introduce no rounding at all: they select an argument rather than computing a value. Concurrent clients may reorder a run of same-kind hard edits freely and converge bit for bit |
G-003, the ticket's acceptance criterion. No fixed-point storage was needed to achieve it, which is worth recording because the ticket proposed i32 storage for exactly this guarantee — see M-39 |
| M-37 | Mixed add and subtract do not commute: 11 distinct results from the same 40,320 orderings. Carving a hole and then filling it is a different solid from filling and then carving. Semantic, not numerical — no storage format or arithmetic repairs it, and a concurrent-editing protocol must preserve order across an add/subtract boundary while remaining free to merge within a run | G-003. BrushOp::commutes_with returns the honest answer rather than the optimistic one |
| M-38 | Smooth union destroys reordering almost completely: 40,317 distinct results from 40,320 orderings. Smooth-min is not associative — measured 1.694e-2 apart on smin(smin(a,b),c) against smin(a,smin(b,c)), four orders above rounding — and it is not bit-commutative either, disagreeing by 1 ulp when its arguments are swapped. So "all the same operation" is not sufficient for reordering; only "all the same hard operation" is |
G-003. The two failures are independent and have different fixes: fixed-point would repair the 1-ulp one and nothing repairs the associativity one |
| M-39 | Fixed-point storage is unnecessary for the guarantee it was proposed for. G-003's ticket asks for an i32 option "for bit-exact determinism", but min and max are already exact in IEEE — the ordering guarantee in M-36 holds in f64 with nothing added. The only place fixed-point would help is smooth-min's 1-ulp commutativity gap (M-38), and that is the lesser of its two reordering failures |
G-003. Not implemented, on the evidence: Real is a sealed trait and adding a fixed-point scalar is a large change to buy a property already held |
| M-28 | The cell clamp eliminates placement-caused self-intersections entirely, and costs nothing in sharpness. λ (pairs per 1,000 triangles) at 33³, clamp off → on: torus 2.66 → 0, gyroid 71.43 → 3.12, fbm_terrain 189.46 → 13.84; sphere, box_exact, csg_difference and thin_plate were already 0. Corner gap on box_exact at 27³: 0.0057 cells either way — identical, because a convex corner's solution is interior to its own cell, so the constraint never binds where the feature is |
A-009, the_clamp_measured_on_every_reference_field. Default is now Clamp::ToCell, chosen by this measurement rather than by preference |
| M-29 | The literature's two branches both fire, on disjoint fields — which is a sharper answer than either alone. The review states the rule in advance: λ→0 means placement was the cause, λ unchanged means the defect is connectivity and needs A-010. Measured: λ → exactly 0 on five of seven fields, and drops 23× and 13.7× on gyroid and fbm_terrain without reaching it. Those two are precisely the fields with multi-sheet cells (M-4, M-15). So the clamp removes the placement failure completely and the residue is exactly A-010's problem, with nothing left unaccounted for |
A-009 |
| M-30 | An unclamped solve can fling a vertex 3.18 cells out of its own cell — measured max displacement on gyroid at 33³, with 618 of 5240 vertices outside; fbm_terrain 2.17 cells and 1097 of 1958. On the smooth closed fields it never leaves at all: sphere, box_exact and thin_plate have zero vertices outside |
A-009. This is the failure mode the clamp exists for, quantified rather than asserted |
| M-40 | The ambiguous face is rarer than the literature suggests — on five of the seven reference fields it never occurs at all. At 33³: sphere 0 of 1160 surface cells, torus 0 of 1128, box_exact 0 of 1352, csg_difference 0 of 1388, thin_plate 0 of 512. Only gyroid (27 of 5240, 0.515%) and fbm_terrain (30 of 1958, 1.532%) reach it, and the decider joins roughly half the ambiguous faces it finds — 12 and 18 respectively. So Marching Cubes 33 and Marching Cubes are bit-identical on five of seven fields at every resolution tested, which the 84-row golden fixture now pins |
A-002. Verifies Custodio et al. 2013's "the vast majority of Marching Cubes cases match the non-ambiguous configurations" (tier R) against this crate's own fields and finds it understated. Consequence for E-102: an Marching Cubes-vs-Marching Cubes 33 example must use gyroid or fbm_terrain or it will show two identical meshes |
| M-41 | 88 of the 256 cases change their Euler characteristic when their ambiguous faces are joined. The smallest is case 6 — corners 1 and 2 inside, diagonally opposite on the z = 0 face and on no other face together, so exactly one ambiguous face: separated it is two discs (χ = 2), joined it is one (χ = 1). 136 of the 256 cases have no ambiguous face at all, so the rule cannot reach them. The decider's worst cell is 10 triangles against the separated table's 5 — predicted before running, from the longest cycle that can use all twelve cut edges |
A-002's acceptance criterion, the_decider_and_marching_cubes_disagree_about_chi. Searched over all 256 cases rather than picked, and pinned in both directions |
| M-42 | The asymptotic decider is free to within a few percent, which is the first time this repo's "~free" claim has had a benchmark behind it. Median extraction, f32, Apple M5: sphere 33³ 206.25 → 205.65 µs (−0.3%, i.e. noise), sphere 65³ 1.4954 → 1.5189 ms (+1.6%), gyroid 33³ 786.89 → 795.44 µs (+1.1%), gyroid 65³ 5.6378 → 5.8236 ms (+3.3%). sphere has no ambiguous face at all (M-40), so its difference is the price of asking — one table lookup and a branch per surface cell; gyroid's extra ~1.7 points is the price of answering, building the cell's triangulation at run time instead of reading it |
A-002, cargo bench --bench extract -- decider. Confirms the v1 catalog's "~free" (tier R) for the decider, against its "730 subcases in the LUT" for the guaranteed version |
| M-43 | The decider needs no division and no epsilon, and the brief's "guard the denominator" is unnecessary. On an ambiguous face one diagonal is strictly negative and the other non-negative — a sample of exactly zero is outside — so v0 + v2 − v1 − v3 is strictly non-zero by the sign rule alone. Only sign(S) is wanted and the denominator's sign is already known, so the whole test is joined ⟺ d_in > d_out on the two diagonal products. Both branches of the derivation reduce to the same comparison, and it is invariant under rotation and reflection of the corner order because IEEE multiplication is commutative and correctly rounded — which is what makes two adjacent cells agree bit for bit |
A-002. Structurally the same argument as edge_crossing's missing epsilon: strictness in the sign rule pays for itself twice |
| M-44 | The decider does not widen M-32's chunk-seam problem, and there is margin to spare. Over 217 seam planes where the two chunk expressions differ bit for bit and 499,968 faces lying in them: 0 where the ulp moved a corner across zero (which would be a crack for plain Marching Cubes too, not just for the decider), 205 ambiguous faces, 0 decision flips. The closest any ambiguous seam face came to its own decision boundary was a relative margin of 1.535e-2 — about fourteen orders of magnitude above the ~1e-16 perturbation the seam arithmetic introduces |
A-002, the_decider_at_a_chunk_seam_is_measured. A count of zero says nothing about how nearly it happened, which is why the margin is recorded alongside it. The first sweep found 0 ambiguous seam faces and the test's own reachability gate caught it — the fixture trap for the third time |
| M-45 | ✗14 reproduces on a second machine and gets worse; its crossover does not reproduce at all. Same sweep, same field, same commit, AMD Ryzen 9 5900X (Zen 3, x86-64, single thread) against the Apple M5. Per-sample cost, 16³ → 256³: Marching Cubes M5 24.99 → 4.78 ns, Marching Cubes Zen 3 15.18 → 13.19; Surface Nets M5 8.40 → 12.66, Surface Nets Zen 3 37.38 → 49.08. So Surface Nets degrades on both — the effect is the algorithm's memory pattern, not one cache hierarchy — and Surface Nets/Marching Cubes at 256³ is 3.72× on Zen 3 against 2.65× on the M5. But Surface Nets never wins on Zen 3, at any resolution: 2.46× behind even at 16³. The M5 crossover exists only because Marching Cubes starts expensive there and converges, which Zen 3's Marching Cubes does not do because it is flat from the start |
O-11, cargo bench --bench resolution_sweep on big at commit d2ab82a. Raw data committed as docs/measurements/resolution_sweep-ryzen9-5900x.csv beside the M5's. Also: the M5 is 2.76× faster than the Ryzen on Marching Cubes at 256³ (80.2 vs 221.4 ms) single-threaded, while the Ryzen is faster below about 32³ |
| M-46 | A chord is only collidable when its two cut edges share a cube face, and that makes the manifold fix nearly free. The naive repair — centroid-fan every cycle of four or more — costs +73.1% vertices and +73.8% triangles over the seven reference fields at three resolutions (23,034 → 39,881 and 45,662 → 79,356), worst on box_exact at +99.7%, because nearly every cycle qualifies. Restricting it to cycles with no chord-safe apex costs +6 vertices and +12 triangles, on one row of eighty-four. The enabling fact is local: only a cell containing both of a chord's cut edges can emit that mesh edge, and two cells share a pair of cube edges only if the edges share a face. A safe apex exists for every cycle of length 3–7 and 48 of the 60 length-8 cycles; plain Marching Cubes never exceeds length 7, so it never pays anything and V_mc = C survives |
A-015. The naive version was implemented and measured first, which is the only reason the cheap one was looked for — the ticket had been written expecting to re-baseline ✗1/M-2/M-22 and the whole golden fixture |
| M-47 | The validator's duplicate_vertices is an upper bound on what a weld removes, not the count. It asks whether any earlier vertex is within ε; the welder asks for the lowest-indexed kept one, and the two part company wherever a chain of near-misses exists — the validator counts the middle of a chain as a duplicate of its start, the welder leaves the end of the chain unwelded. Predicted before running and both halves held: equal on a real chunk seam (14 and 14), where duplicates are pairs an ulp apart with no chains, and different on a constructed chain (2 against 1). Also measured, two chunks of a unit sphere at h = 4/35: 273 → 259 vertices, boundary edges 85 → 59, duplicate_vertices 14 → 0, χ 2 → 1 — two discs glued along an arc |
A-013. The two share one Lattice so they cannot disagree about which cells are probed; what differs is the question, and that difference is now measured rather than assumed |
| M-48 | The edge-vertex cache does not share everything, and welding removes a class of sliver nobody expected it to. The cache shares vertices between cells meeting on a grid edge; when a grid sample lands on the isosurface, t is 0 or 1 and the crossing sits at that sample, so every cut edge meeting there places its own vertex at the same point and nothing shares them. Whole-volume weld census over the seven fields at 17/25/33³: sphere 25³ 48 vertices and 96 triangles, gyroid 2 and 4 at all three resolutions, fbm_terrain 33³ 1 and 2, everything else zero. The 96 is exactly the degenerate-sliver count A-001 measured at that resolution from the 30 lattice points sitting exactly on the unit sphere — the same 96, so welding is a fix for that class of sliver |
A-013. Falsified a claim written in weld.rs's own module docs the same day — "every reference mesh reports duplicate_vertices == 0" — which was asserted from the edge cache's design rather than measured. The test that disproved it was written to confirm it |
| M-49 | ChunkLayout::cell_of inverts world_of_sample inside a cell and not reliably on its corner — M-32 in a second place. world_of_sample computes origin + h·sample, cell_of computes floor((p − origin)/h); inverse by algebra, not by IEEE. Measured over three cells: 3 of 3 corners round-trip at h = 0.125, 1 of 3 at h = 4/35, where the division lands a hair under the integer and floor takes it down. The interior of a cell is unambiguous at any spacing. No epsilon was added — a point exactly on a cell boundary belongs to either cell by convention, and at a non-power-of-two spacing "exactly on" is not a decidable question, so snapping would trade a visible ambiguity for an invisible one |
A-013's cell_of, added for E-202. Callers needing a cell range pad it; E-202 pads by the cell size. The test was written to assert a round trip and immediately caught that it does not hold |
| M-50 | E1 and M-34's ratio both reproduce live, under a mouse. E-202 carves with a brush and re-meshes only the dirty chunks, reporting per edit: a typical carve is 265 of 1,728 cells in the brush's bounding box = E1 15.3%, against 756 cells whose sample value moved — a ratio of 2.85×, inside M-34's measured 2.8–3.7×, and E1 inside M-33's 15–36%. Over a scripted 60-carve run E1 ranges 0.6% to 27.3%. Cost per re-meshed chunk against edit-log length, median: 0.158 / 0.354 / 0.525 / 0.589 ms for logs of 1–15 / 16–30 / 31–45 / 46–60 — 3.7× for 7× the log, and flattening. So the BrushStack walk is a real cost and not proportional at these lengths, which is weaker than "every sample walks every brush" suggests |
E-202, ISOMESH_AUTOCARVE=60. The first offline measurements of E1 (M-33) and of the value-versus-output ratio (M-34) were made on synthetic edits; this is the first time either has been measured on the interactive path they were written to justify |
| M-51 | Marching Tetrahedra costs ~3× the triangles for ~4% worse geometry — and the literature's 2–3× is too low. Vertex and triangle ratio against Marching Cubes on identical grids, seven reference fields at 33³ and 49³: gyroid and fbm_terrain 2.87×, sphere and torus 3.04×, csg_difference 3.83×, thin_plate 3.84×, box_exact 3.91×. The tier-R figure from 10.1109/2945.485620 covers only the two roughest fields. On the other side, Lewiner et al. 2003's "weaker geometrical accuracy… the vertex position cannot be adjusted to fit the geometrical trilinear approximation" measures 4.3%: symmetric Hausdorff on a unit sphere at 64³, marching cubes 1.3798e-3 against marching tetrahedra 1.4386e-3. Directionally right and far weaker than it reads |
A-003. The marching cubes figure reproduces M-10's recorded 1.380e-3 exactly, so the harness is measuring what it measured before. P-1's 2.992 is confirmed on the smooth closed fields and is not the whole story — see M-52 |
| M-52 | The Marching Tetrahedra ratio is 4.0 when the surface normal lies in one octant and 2.0 when it changes sign, and P-1's 2.992 is the average of the two. Written out for a single plane of normal n, the crossings are Σ\|nᵢ\| on the three axis families, Σ\|nᵢ+nⱼ\| on the three face diagonals and \|nₓ+n_y+n_z\| on the body diagonal. With every component the same sign nothing cancels and those sum to exactly 4·Σ\|nᵢ\| — so the ratio is 4.0 for any orientation inside one octant, which is why a plane at four different orientations measured 3.919 / 3.939 / 3.945 / 3.943. Across a sign change the diagonal terms cancel to 2.0; measured 1.980 / 2.265 / 2.267. Integrating over the sphere gives 2.9916, reproducing P-1 to four figures |
A-003, O-15. This explains the whole reference-field spread with no new mechanism: box_exact's faces are axis-aligned one-octant normals (3.91), a sphere samples every octant (3.04), gyroid sits just below the isotropic average because its normals favour the cancelling ones (2.87). Two earlier hypotheses of mine — orientation, then curvature — were tested and killed first; the second failure is what forced doing the algebra instead of guessing a third time |
| M-53 | The five algorithms fill three of the four corners of manifold × intersection-free, and Marching Cubes is the only one in the good one. Seven reference fields, two grids, one process, one run: marching_cubes and marching_cubes+decider 0 non-manifold edges and 0 self-intersections; marching_tetrahedra 0 non-manifold but 3.405 per 1k on csg_difference; surface_nets 128 non-manifold and 0 self-intersections; dual_contouring 128 and 13.837 per 1k on fbm_terrain. So each of the three non-Marching-Cubes methods fails exactly one property or both, and the method the folklore treats as the crude baseline is the only one that fails neither |
M-001. Cross-checks that the numbers are the same numbers: dual_contouring's 13.837 and 3.118 reproduce M-28's clamped fbm_terrain 13.84 and gyroid 3.12 exactly, and Surface Nets' triangle ratio of 0.977–1.001 is ✗1's F_sn = F_mc + 2χ seen from the other side |
| M-54 | Dual Contouring is 101× more accurate than Marching Cubes on a sharp field, and indistinguishable on a smooth one. Symmetric Hausdorff at 65³: box_exact 7.217e-2 → 7.145e-4 (101×), thin_plate 4.593e-2 → 5.892e-4 (77.9×), csg_difference 7.655e-2 → 2.057e-2 (3.7×) — against sphere 1.2× and torus 1.6×. Marching Tetrahedra sits within 6% of Marching Cubes on the smooth fields and better on the sharp ones (box_exact 5.103e-2 against 7.217e-2), because its extra edge families sample the corner from more directions |
M-001. M-26 measured this as a corner gap — 0.01 cells against 0.58 — and this is the same result as a whole-surface distance, which is the form that transfers to a field whose features are not corners. It also puts a number on the sentence the crate's pitch rests on: the sharp-feature solve is worth two orders of magnitude exactly where the features are sharp, and nothing at all where they are not |
| M-55 | O-14 falsified: Marching Tetrahedra's accuracy penalty is 4.3%, not 86%, and it beats Surface Nets rather than losing to it. Symmetric Hausdorff on a unit sphere at 64³: Marching Cubes 1.3798e-3, Marching Tetrahedra 1.4386e-3 (1.043×, against a pre-registered 2.6e-3 and 1.86×), Surface Nets 2.251e-3 (1.69×). And on the sharp fields Marching Tetrahedra is better than Marching Cubes — box_exact 5.103e-2 against 7.217e-2 — because its extra edge families sample a corner from more directions |
M-001b. The prediction was registered before the measurement and is wrong in its most interesting clause: "more vertices and worse accuracy" was flagged as the counterintuitive part, and the accuracy half does not hold. Lewiner et al. 2003's underlying claim survives in direction and not in magnitude — see M-51 |
| M-56 | Greedy meshing's 2.76× saving over face culling is a property of one scene, not of the algorithm: measured 1.70× to 256×. Same occupancy, merge on against merge off, seven reference fields at 33³: gyroid 1.70×, sphere 1.94×, torus 2.69×, fbm_terrain 4.60×, csg_difference 10.64×, box_exact 256×. Merging pays for flat runs, so a grid-aligned box collapses to six quads at every resolution — 12 triangles at 17³, 33³ and 65³ alike — while a sphere's staircase surface barely merges at all. The published figure (tier R, the UE5 benchmark) happens to sit beside torus |
A-005. Predicted before running that it would not reproduce as a constant and that box_exact would collapse while sphere would not, for exactly this reason. Against Marching Cubes the blocky path costs 0.004× the triangles on box_exact and 0.32–0.58× elsewhere, which is the budget end of the tradeoff table with numbers on it |
| M-57 | Greedy merging manufactures T-junctions, and no weld can remove them. A blocky mesh carries split vertices on purpose — a cube corner has three faces at three normals — so its index buffer describes an open surface: a merged quad contributes five edges of which four are unshared. A-013's weld fixes that wherever quads meet corner to corner, and cannot fix a T-junction, because where a long quad butts against several short ones the vertex they meet at does not exist on the long quad's edge and there is nothing to merge it with. Measured on sphere at 33³: 2568 → 848 vertices, boundary edges 2568 → 768, so the weld closes 70% and the remainder is T-junctions. On box_exact, where every face merges to one quad and no T-junction can arise, 24 → 0 and the result is closed with χ = 2 |
A-005. The box is the control that makes this a mechanism rather than an observation. It is also the concrete form of the catalog's "no LOD, no seam story": the same missing-vertex problem that breaks a greedy mesh internally is what breaks it at a chunk seam |
| M-58 | A-010's vertex splitting removes the one-vertex-per-cell pinch completely, and the ticket named a field that was never a counterexample. Manifold Dual Contouring against plain Dual Contouring, identical grids: gyroid at 33³ 15 non-manifold edges and 40 non-manifold vertices → 0 and 0, at 49³ 48 and 99 → 0 and 0. All seven reference fields at 17³ and 33³ come out with non_manifold_edges == 0, non_manifold_vertices == 0 and χ equal to Marching Cubes'. But csg_difference — the second field the ticket names as one "plain Dual Contouring will not manage" — measures 0 non-manifold edges under plain Dual Contouring already, at 33³ and 49³ |
A-010. Half the acceptance criterion was vacuous as written, which is why the test asserts the comparison is non-vacuous (any_pinched) rather than only asserting the new number. M-53's 128 is a total over every field and resolution, and it is gyroid and fbm_terrain that supply all of it |
| M-59 | The dual of a manifold surface is a manifold complex, and an indexed triangle mesh cannot always represent it. This is a second non-manifold mechanism, unrelated to the one A-010 fixes. Where two cells share a face carrying two surface segments and each cell puts both segments in the same cycle, the two dual edges have the same two endpoints; an index buffer has no way to keep them apart, so they collapse into one edge with four faces. Exhibited on the ✗15 fixture — the same three-sphere union at h = 2/3, reached independently by proptest shrinking — where Marching Cubes is clean (χ = 0, zero non-manifold edges, since A-015) and the dual reports 1 non-manifold edge, 2 non-manifold vertices, χ = 1. The mechanism is identified by arithmetic rather than inspection: a collapse costs exactly one edge and nothing else, so χ_dual − χ_mc == non_manifold_edges must hold, and it does — 1 − 0 == 1. Gone by 9³ and at every resolution above, where χ_dual == χ_mc exactly |
A-010, the_parallel_dual_edge_collapse_is_the_only_residue. This bounds Nielson's guarantee, quoted in the module docs as "always a manifold because the original MC algorithm always constructs a manifold and the dual preserves the topology" — the dual preserves the topology of the complex, and the index buffer is where it is lost. Same coarse-grid shape as ✗15, and the reason the property gate is ClosedAllowingUnresolvedTopology rather than Closed. See O-16 |
| M-60 | Only two of seven fields ever need a second vertex in a cell, and the rate falls with resolution — so Nielson's "about 1.3%" is a statement about the case table, not about a scene. Extra vertices over plain Dual Contouring, by field and grid: gyroid 3.13% / 2.05% / 0.53% at 17³/25³/33³, fbm_terrain 1.70% / 0.84% / 0.77%, and sphere, torus, box_exact, csg_difference, thin_plate exactly 0 at every resolution. So the cost of the manifold guarantee is zero on five of seven fields and under one percent on the other two once the grid resolves them And it costs ~5% of the run time: median 1.046× plain Dual Contouring over the shootout's 14 (field, grid) points, range 1.007× (fbm_terrain 33³) to 1.178× (gyroid 33³) — the timing column is the noisy one, so read the median rather than the ends. Triangle counts are identical to Surface Nets' and Dual Contouring's on every field (0.977–1.001× Marching Cubes), because splitting moves vertices without adding quads |
A-010. The falling rate is M-15 seen from the other side — "any feature thinner than one cell forces two sheets through it", so refining removes the multi-sheet cells rather than adding them — and it is the first curve for O-10, which asked for exactly this rate as a function of resolution. Nielson's "typically comprise about 1.3% of all configurations" counts configurations in the 256-case table; on a real field the answer is field-dependent and usually zero. Fourth figure in this repo to turn out field-dependent, after ✗14, M-51 and M-56 |
| M-61 | Splitting the vertex makes self-intersection worse, not better — ✗2's report is confirmed and the natural reading of M-29 is falsified. Self-intersections per 1,000 triangles at 33³, plain → manifold Dual Contouring: gyroid 3.118 → 5.669 (1.82×), fbm_terrain 13.837 → 15.434 (1.12×); sphere, torus, box_exact, csg_difference, thin_plate 0 → 0. The two fields that get worse are exactly the two that split (M-60), so the extra intersections are caused by the splitting itself |
A-010. The prediction registered before running was the opposite, reasoning from M-29's "the residue is exactly A-010's problem, with nothing left unaccounted for" that removing the shared vertex would remove the residue. M-29's attribution is right — only multi-sheet cells have a non-zero count — and the inference from it was wrong. The mechanism is Manson & Schaefer's: the cell clamp's partition argument assumes one vertex per cell, and two vertices in one cell is precisely the assumption being dropped. So ✗2's ODC figure (Manifold Dual Contouring 100% of models self-intersecting) reproduces in direction here, and the tradeoff is real rather than an artefact of their implementation |
| M-62 | The t = a + b·n³ fit had been printing NaN since the day the algorithm names were spelled out, and once it prints numbers it falsifies the ticket that asked for it. report() in resolution_sweep filtered on ["mc", "sn", "dc"] while Extractor::NAME had become marching_cubes / surface_nets / dual_contouring; every selection came back empty and fit divided by zero. Fixed by deriving the list from the rows. Fitted on the committed CSV: marching_cubes a = 0.5118 ms, b = 4.7389 ns/sample, r² = 0.99976, and a is 0.64% of the largest run — so there is no meaningful fixed cost, against M-002's "expect a large fixed cost at small grids." Worse for the dual methods: surface_nets a = −2.746 ms (r² = 0.9923) and dual_contouring a = −2.449 ms (r² = 0.9928). A negative intercept is not physically possible, so the two-term model does not describe them at all — their cost grows faster than n³ over this range |
The report() fix, found while adding A-010's row. Two lessons, one of them a method rule: a list that names a thing it does not derive from will drift from it, and nothing in this repo asserts on a benchmark's stdout, so it drifted silently for however long. The a < 0 result is O-11 stated by the bench itself rather than inferred from a ratio table, which is a stronger form of the same evidence |
| M-63 | Both papers docs/research/ lists as "genuinely absent, blocking" are in the home-still corpus, so the acquisition lists are stale rather than the corpus thin. catalog-v2.md:629 names "Transvoxel (Lengyel 2010 …); Manifold Dual Contouring" as blocking absences, and catalog.md:711 and meshing-library-target.md:97 repeat the second. Both were retrieved and read this session: 10.1109/TVCG.2007.1012 as stem dualsimp_tvcg, and the Lengyel dissertation as transvoxel_dissertation_lengyel2010. Two out of two |
A-010, A-011a. Method rule, added to Part 5: search home-still before believing a doc that says a paper is missing. The cost of not doing so is high and asymmetric — A-010's ticket named the wrong paper for its own algorithm precisely because nobody had opened the right one |
| M-64 | A Transvoxel lateral face does not always cross the resolution boundary, and the exception is what transition cells are for. Written as an assertion — "a lateral link always joins a full-resolution sub-edge to a half-resolution one" — and falsified by the case with only the midpoint sample inside: both fine sub-edges are cut, the coarse edge is not, and the lateral links fine to fine, capping the feature off entirely on the fine side. Correct, because the coarse neighbour has both endpoints outside and cannot represent that feature at all. The rule that does hold is sharper: a lateral link crosses the resolution boundary iff its half-resolution edge is cut. Over all 512 cases and every ambiguity mask: 2,080 links stitch the seam, 1,128 cap a sub-coarse feature And the dissertation prescribes exactly this, which was found only after the assertion failed — §4.3: "In the two configurations for which the sample states alternate, either inside-outside-inside or outside-inside-outside, a mesh edge is placed on the boundary edge between the lateral face and the full-resolution face, and it is thus not connected to the half-resolution face." So the derivation reproduces a rule the paper states, without the rule having been read into it | A-011a. Also measured, and both needed by A-011b: the longest cycle is 12 edges and a cell yields at most 4 cycles — the same slot budget the cube needed at A-010, so CellVertices transfers unchanged |
| M-65 | Central differences at the cell size cost under half a degree of normal direction, and converge at h². Analytic gradient against CentralDifference { step: h } on sphere, worst and mean angle between the two normals: 0.460° / 0.299° at 17³, 0.121° / 0.079° at 33³, 0.031° / 0.020° at 65³. Successive mean ratios 3.76 and 3.92 — h², which is what a central difference must be, asserted as a range rather than only printed |
A-012. This is the number a game without an analytic field actually gets, because a sampled voxel buffer has nothing finer than its own spacing to difference over. Same convergence order M-12 measured for position error, now for direction, and measured independently of it |
| M-66 | On a sharp field the geometry and the field disagree by an angle that does not fall with resolution. Mean angle between area-weighted face normals and the analytic gradient: sphere 3.25° → 2.16° → 1.08° and torus 11.65° → 6.07° → 2.45° at 17/33/65³, both falling; box_exact's mean falls 13.55° → 6.73° → 3.34° but its worst is 35.796° at all three resolutions, identical to six figures. Refining a grid does not soften a corner — the disagreement there is geometry, not discretisation, where on a smooth field it is discretisation and shrinks |
A-012. So "which way does the surface face" and "which way does the field increase" are different questions wherever the surface has a crease, and that is the whole reason the strategy is selectable rather than fixed. Asserted as the mechanism (box worst resolution-invariant, sphere worst falling) rather than as a pinned constant, since the constant is a property of the box's corner angle and would move with a different field |
| M-67 | A sign test cannot distinguish 95.6% of the configurations a tetrahedron can actually be in. Over every edge-coordinate vector with counts 0–3 on a tet's six edges, 181 satisfy normal surface theory's two conditions (even sum, triangle inequality) and only 8 are classic — every edge carrying at most one crossing. The other 173 put two or more crossings on some edge, where a sign test reads the parity alone and returns the classic configuration with the same parities. And classic Marching Tetrahedra is exactly the 0/1 corner of this encoding: taking eᵢⱼ = 1 where corner signs differ reproduces A-003's triangle count on all 96 (tet, configuration) pairs, as 48 corner cuts and 36 diagonal cuts |
A-014a, from Baktash, Gillespie & Crane 10.48550/arXiv.2606.00454 §2. The paper's own framing is that marching tetrahedra "reinvented a small piece of this story" — this puts a number on how small. It is also the quantitative form of A-005's thin_plate result: a feature thinner than a cell does not exist to a sign-based method, and 173 of 181 is how much else does not either |
| M-68 | parry3d's constructor is not a validity check: the only mesh it refuses is one with no triangles. TriMesh::new returns Result, and its documented failure is "the index buffer is empty (at least one triangle is required)." Measured: it accepts a single zero-area triangle (three collinear points) and it accepts a two-chunk mesh with an unwelded seam, both without complaint. What does check is set_flags(TriMeshFlags::HALF_EDGE_TOPOLOGY), which builds the half-edge adjacency and returns TopologyError when the mesh cannot support one, and TriMeshFlags::ORIENTED, which needs a closed consistently-oriented surface to compute pseudo-normals from |
G-005, parry3d 0.30.2. So a caller who treats "the constructor took it" as "the mesh is fine" has checked nothing, which is the gap collider::ColliderReadiness exists to fill. The carved acceptance case — csg_difference at 41³, 4,484 triangles — passes both flags |
| M-69 | A chunk seam costs 72 boundary edges, and welding removes exactly those and nothing else. Two adjacent 16-cell chunks of a torus, meshed independently and concatenated: 36 duplicate vertices and 180 boundary edges. After a weld at 1e-4 cells: 0 duplicate vertices and 108 boundary edges. The 108 that remain are the two-chunk slab's own outer border, which is legitimately open — the surface leaves through the sides — so the weld closed the 72 that were the seam and left the rest alone |
G-005. A renderer draws the unwelded version correctly and a physics engine reads those 72 as a hole, which is the concrete form of G-005's ticket note "a chunked collider must be welded first or parry sees a seam of unshared vertices." M-46 measured the same seam at A-013 as 80 boundary edges and 40 duplicated vertices on a different chunk pair; the mechanism is the same and the count is a property of the pair |
| M-70 | Field-derived LOD is exact, not approximate: a coarse sample position is bit-identical to the fine one it sits on. Level k doubles the spacing k times, so a level-k sample at index s and a level-0 sample at index 2^k·s must land on the same world point — and they do, bit for bit, over cell sizes 0.125, 4/35, 0.1 and 1/3 and levels 0–3. Doubling is exact in IEEE and so is doubling a small integer, so (h·2^k)·s and h·(2^k·s) are the same real rounded the same way |
G-004. Asserted rather than argued, because M-32 and M-49 both caught this crate assuming an algebraic identity IEEE did not honour — cell_of round-trips 3 of 3 cell corners at h = 0.125 and 1 of 3 at h = 4/35. This one holds at every spacing tried, including those two. It is the precondition A-011b rests on: no coordinate drift can open a crack at an LOD boundary before transition cells get a chance to be wrong |
| M-71 | Cells fall by 8 per LOD level and triangles by 4 — and the 4 degrades exactly where the grid stops resolving the surface. Unit sphere over a fixed world extent, levels 0–3: 262,144 / 32,768 / 4,096 / 512 cells (exactly 8× each, by construction) against 9,512 / 2,312 / 536 / 104 triangles, ratios 4.114, 4.313, 5.154. A surface is two-dimensional so its triangle count tracks area / h², but that is a continuum claim: by level 3 the sphere is four cells across and a 104-triangle staircase is not approximating anything smoothly |
G-004. So each level buys back 8× the sampling work and only 4× the rendering, which is the whole economics of LOD and the reason the ticket's own acceptance figure is about cells. The tight 3.8–4.6 bound is asserted only on the two steps where the premise holds, and the upward drift is asserted as a direction rather than waived as tolerance |
| M-72 | A sub-cell feature does not vanish under coarsening — it aliases, which is worse. thin_plate across LOD 0–3: 4,088 → 1,016 → 248 → 56 triangles, still 56 at h = 0.5 where the plate is a fraction of a cell thick. The test was written asserting it would be gone by the coarsest level and that assertion is what failed. Marching Cubes samples corners and cuts edges, so whichever edges happen to straddle a thin slab still register a sign change and what comes back is a partial, holey remnant |
G-004. The contrast is the mechanism: A-005 measured the same field returning zero triangles under greedy quads, which asks one question per cell centre and therefore misses it cleanly. For a streamed world the aliasing is the worse behaviour — a feature that vanishes at a known distance can be faded, one that disintegrates into a resolution-dependent scatter pops. It is also the cost M-67 quantified from the other side |
| M-73 | A transition cell that computes its sample positions by offsetting from a face origin puts a hairline crack in the seam, and no weld can close it. The first version of TransitionCell::sample took the face's world origin and added local offsets. At h = 4/14 a half-resolution crossing came out at y = -1.11e-16 where the coarse mesh had the same vertex at exactly 0 — because (origin + h·i) + h ≠ origin + h·(i + 1) in IEEE at a spacing that is not a power of two. Indexing from the grid origin instead, origin + h·index, which is exactly ChunkLayout::world_of_sample's expression, makes the coarse origin + (2h)·c and the fine origin + h·(2c) bit-identical by M-70. Measured after the fix: 56 half-resolution crossings over 256 transition faces on a sphere at h = 1/8, and 24 on a torus at h = 4/14, every one matching a coarse mesh vertex exactly |
A-011b. Third time this crate has assumed an algebraic identity IEEE does not honour — M-32 at a chunk seam, M-49 in cell_of, now here — and the first where the consequence is a visible hole rather than a classification wobble. epsilon_for(h) = h · 1e-4, not bit-identity, and it closes every one of these — 0 seam-plane boundary edges in all twenty offset rows. The headline claim stands and the reason changes: what the offset arithmetic costs is sharing by construction, which is what an unwelded consumer gets (M-69's collider), plus a tail where an ulp flips a sign and opens a hole 1.05–2.08 cells wide. The test searches an actual coarse vertex buffer rather than re-deriving the interpolation, because two copies of a formula agreeing proves only that they were written on the same day |
| M-74 | A zero-width transition cell stitches the hole and has no normal at all — which is what "severe shading problems" means, precisely. All nine of a transition cell's samples lie in the transition face, so at zero width every crossing does too and every triangle it emits is coplanar with that face. Measured: the worst \|cos\| between a patch face's normal and the field's gradient is exactly 0 over 136 faces — the patch stands perpendicular to the surface it is stitching. A winding test against the gradient therefore cannot mean anything, which is how this was found: it reported 136 of 136 faces inward, and reversing the fan reported the same 136 |
A-011b. Lengyel 2010 §4.3 says a zero width "still produce[s] results that seamlessly stitch multiresolution meshes together, but this width leads to severe shading problems" — the stitch closes the hole and shades as a hard crease because it is one, a flat wall standing edge-on. So the transition width is not a polish item to defer after the gap closes: it is what gives the patch a normal, and it is a hard dependency of any correct winding rather than a nicety. A-011c owns it |
| M-75 | The transition width is what makes the patch's winding a measurable question at all, and the answer is unanimous. With Lengyel's w = 2^(k−2) — half the adjacent full-resolution cell — the patch stops being coplanar with the transition face and becomes a ribbon: best \|cos\| against the surface normal 1.000, where M-74 measured 0.000 at zero width. The orientation is then decided by measurement rather than convention: one fan order faces away from the solid on 144 of 144 faces and the other on none. Also measured, and the property the seam depends on: the width displaces the half-resolution face and nothing else — over 256 transition faces, 88 fine crossings unmoved bit-for-bit and 56 coarse crossings displaced by exactly the width along the face normal, with no in-plane movement |
A-011b. Two winding attempts were made before this one and both were meaningless, reporting the identical count in either direction, because the quantity being tested was dot(face_normal, gradient) on faces exactly perpendicular to the gradient. The lesson is the method rule, not the sign: a test that returns the same answer when you invert the thing it is testing is not measuring that thing |
| M-76 | Two blocks at differing resolution leave 88 unmatched boundary edges in the seam plane, and transition cells take it to 0. A full-resolution block over x ∈ [−2, 0] at h = 1/8 against a half-resolution one over x ∈ [0, 2] at 2h, both meshed with Marching Cubes and welded: the fine side ends on a contour of 32×32 sub-squares, the coarse on 16×16, and 88 boundary edges lying wholly in the seam plane are the crack between them. Adding one transition cell per coarse cell face — 28 of the 256 were cut — takes that count to exactly 0 |
A-011b's acceptance. Asserted in both directions: the before > 0 half is what stops the test passing vacuously if the two resolutions ever stopped disagreeing. Counted in the seam plane only, because both blocks are legitimately open at their outer borders — a global boundary count says nothing about a seam, which is the same distinction collider::ColliderReadiness draws for a chunk |
| M-77 | Lengyel's Equation 4.2 loses its level index entirely when written in the block's own cells, and the seam holds at a real width. The published form is Δx = (1 − 2^−k·x)·w(k) for x < 2^k, zero in the middle, (s − 1 − 2^−k·x)·w(k) beyond 2^k(s−1) — in level-0 cell units, which is where the 2^−k comes from. Substituting x = c·2^k with c the coordinate in this block's own cells, k cancels: Δ = (1 − c)·w for c < 1, 0 for 1 ≤ c ≤ s − 1, (s − 1 − c)·w beyond. A linear taper across the first and last cell and nothing between. Measured with w = 2^(k−2): 0 gaps at the fine plane, 0 at the coarse plane, and the patch's best \|cos\| against the surface normal is 1.000 where M-74 measured 0.000 at zero width |
A-011c. The cancellation is what makes it a post-pass over a finished MeshBuffer rather than something extraction has to know about — a block does not know which of its neighbours are coarser when it is meshed, and that can change while it is resident. Lengyel stores two positions per boundary vertex for exactly that reason; here the primary mesh is the un-inset one and the secondary is a tapered copy. A vertex at c = 0 moves by exactly w, which is precisely the displacement TransitionCell gives its half-resolution face, and that coincidence is the whole reason the seam survives the width |
| M-78 | A no_std crate cannot take a millisecond budget, and the honest API is a predicate the caller owns. G-006 asked for mesh_within_budget(ms). core has no Instant, so the only ways to accept a duration are a std feature — two paths, which this crate does not do — or a number the crate cannot compare against anything. The shipped signature takes spend: FnMut() -> bool, and a caller with a clock writes \|\| start.elapsed() < budget. And the predicate is consulted after each chunk, never before: checking first means a budget too small for one chunk drains nothing, forever, while the queue grows — a livelock that presents as a memory leak. Overshooting by at most one chunk is the price, and it is the right way round |
G-006. The no_std constraint is doing real design work here rather than being an inconvenience: "how long does the queue take" is the question mesh_dirty answers and the wrong one, and being unable to phrase the ticket's version forced the API that matches what a frame actually does. Ordering is nearest-first by squared distance — same order, and the square root is not free per chunk per frame — with ties broken by ChunkId so the schedule is a pure function of the set's contents and the camera, never of insertion order |
| M-79 | Subgrid MT's conformity is locality plus a shared vertex ordering — it is emphatically not invariance under relabelling, and the difference is testable. §3.1 promises "identical curves on triangles shared by neighboring tetrahedra", and the obvious reading — that the construction is symmetric in a face's corners — is false. Step 3(b) skips "the first residual point along oriented edge ij (assuming a canonical orientation i < j)", so swapping i and j skips the point at the other end: measured on e = (3, 0, 0), one labelling pairs crossings {1, 2} and the swapped one pairs {0, 1}. What is actually true is locality: a face's segments are a function of that face's own three edge coordinates and nothing else, verified over 4,096 configurations against all 64 fillings of the three edges a neighbouring tet would differ on. Two tets share the face's global vertex indices, so they agree on i < j without communicating |
A-014b. The first version of the test asserted the symmetry and failed, which is how this was found. The construction depends on vertex order by design and that is safe — but only because the ordering is global. A mesh that renumbered vertices per tet would crack along every shared face, and nothing in the paper's phrasing warns you |
| M-105 | E-203's first run reported 439 holes and a verdict of "G-001's overlap is wrong" — and the bug was in the test, one operator wide. A probe misses only counts as a hole once every chunk layer that could hold the surface has been meshed; the guard said || where it must say &&, so a column whose surface sat in the one layer still in the meshing queue reported a gap. Diagnosed by printing the field at the offending points rather than by reasoning: f(y = 0) = +0.42, f(y = −4) = −3.58 put the surface at y ≈ −0.42, in layer −1, and colliders[−1] = false — that layer had not meshed yet. Corrected, the same run gives 495 seam crossings, 0 holes |
E-203. The rule this instance argues for is already in CLAUDE.md — "when investigating whether an issue is fixed, actually inspect the underlying data/code first; do not assume a file is broken" — and it applies with more force when the test is newer than the code it accuses. G-001 has M-32, M-46 and M-69 behind it; a two-hour-old probe sweep does not, and the prior should be weighted accordingly |
| V-22 | (settled at E-206b: adopted as a bevy_isomesh dev-dependency only, avian3d 0.7.0, which compiles clean against Bevy 0.19. It costs a duplicate glam — Avian pulls parry3d 0.27, which brings glam 0.33 alongside Bevy's pinned 0.32, exactly the silent double-compile CLAUDE.md warns about. Confined to [dev-dependencies], so no consumer inherits it.) Avian has not been evaluated for this project — it appears once in the research, incidentally, as evidence about release cadence rather than as a physics choice. docs/research/2026-08-11-meshing-crate-architecture.md:133 cites avian3d 0.7.0 shipping the day after Bevy 0.19 to argue that a Bevy wrapper rides Bevy's train, and its comparison table lists bevy_rapier3d (55,916) as the Bevy physics data point. Measured 2026-08-13: avian3d 0.7.0 at 127,279 90-day downloads against bevy_rapier3d 0.36.0 at 56,538 — so the doc's table names the less used of the two by a factor of 2.25, and parry3d itself is 596,889, an order above both |
Queried from crates.io, and the repository the user cited (github.com/avianphysics/avian) is the one crates.io lists — verified rather than recalled. What does not change: Avian is built on parry, so the geometry contract is the one G-005 already encodes — welded, manifold, correctly wound — and M-69 measured its cost at 72 boundary edges per seam. What it would change: E-204's "debris becomes rigid bodies", E-207 and E-209 need simulation, which a raycast cannot provide, and E-206b needs a capsule that slides. Where it must not go: crates/isomesh (rule 2), and arguably not bevy_isomesh's [dependencies] either — the plugin stops at Handle<Mesh> precisely so a consumer picks their own renderer, and picking their physics engine for them is the same mistake |
| M-129 | The seam counter's own exclusion list was missing an axis, and it accused Marching Cubes of a defect it does not have. The two-chunk block has six walls and a boundary edge on any of them is the block ending rather than a seam failing — but the first version excluded only x and z. On blobs, whose spheres extend past the chunk's y range, the surface clipped at the top and one of those edges landed in the seam plane: marching_cubes reported 1 open edge on a seam it closes perfectly. Adding y takes it to 0 on both fields |
B-006. Ninth instance this session, and the second time this exact omission has been made — E-205's crack counter needed the same fix for the same reason four commits earlier, and I wrote that one too. The pinning test carries the note so the next person adding an axis-aligned exclusion does not make it a third time |
| M-141 | Include-once and cycle detection interact, and the obvious ordering silently accepts a circular graph. GPU-002's preprocessor pastes each module at most once, because WGSL has no forward declarations and a duplicated function is a hard error — so "two modules both include the shared header" has to work. Written the natural way, the include site checks have I already included this before am I currently inside this, and then a includes b includes a finds a already included, skips, and reports success on a genuinely circular graph. Swapping the two checks fixes it |
GPU-002. Found by a test written from the module docs' own claim that "a cycle is still an error rather than being absorbed by that rule" — the sentence was written first, the code did not implement it, and the test that asserted the sentence is what noticed. Second failure in the same commit from the same cause: a bare #ifdef with no symbol fell through the "#ifdef "-with-a-space matcher and was emitted as text, so the error surfaced one line later at the orphaned #endif. Splitting #keyword from its argument without requiring the space makes a malformed use of a known keyword an error where it occurs, while leaving an unrecognised #word to pass through untouched |
| M-142 | GPU and CPU Marching Cubes agree on every triangle and disagree on 6% of vertices by exactly one ULP — and the cause is float contraction, not the algorithm. Same 33³ grid, same f32 samples, and the same case table (the shader's is uploaded from isomesh's CASES rather than transcribed). Triangle counts match exactly on sphere, torus and box_exact. Of 6,936 emitted vertices: 6,507 bit-identical to a CPU vertex, 429 within one ULP per axis, 0 further — worst separation 5.96e-8, which is 2⁻²⁴, one ULP at magnitude 1 |
GPU-004, RTX 3090 / Vulkan. Bit-equality was the expectation and it is wrong for a reason worth writing down. Both sides evaluate the same expressions — t = a / (a − b), then lo + (hi − lo)·t over origin + h·index — so the arithmetic is identical on identical inputs. WGSL permits a multiply-add to be contracted into a fused one, and this driver takes that permission: an FMA rounds once where the CPU rounds twice. This is the divergence GPU-005's ticket anticipates, measured before that ticket starts rather than discovered during it, and the assertion is the bound rather than a tolerance — two ULPs would fail the test. Diagnosed by measuring the magnitude of the miss rather than by reasoning about it: 429 mismatches could have been a formula error, and 1 ULP could not Amended 2026-08-27 at D-024, and the amendment is a fact about adapters rather than about this crate. P-61 replaced t = a/(a − b) with the centred offset d = ((a + b)/2)/(a − b), and the divergence moved with it — by different amounts on different adapters, and to zero on one. Same 33³ sphere, same 6,936 vertices, 0 further than one ULP on both: RTX 3090 / Vulkan reads 6,632 bit-exact and 304 within 1 ULP (from 6,507 / 429), and Apple / Metal reads 6,936 and 0 — GPU and CPU now agree bit for bit on every vertex there. So the 6% is this adapter's number and not the crate's, and the mechanism is confirmed from the other side: fewer multiply-adds to contract, less contraction. This surfaced as a CI failure rather than as a measurement, because every_gpu_vertex_is_a_cpu_vertex_to_within_one_ulp asserted within > 0 — reasoning that a zero meant the bound was checked over an empty set. It is not: the bound is asserted over the emitted vertices, and both directional counts are properties of the driver's contraction that this crate neither controls nor promises. The test now asserts the bound plus complete accounting over a non-empty population, which is the non-vacuity guard it actually needed. |
| M-143 | GridParams::sample_position was a mul_add where isomesh is origin + h·i, and a power-of-two cell size hid it through an entire GPU test suite. The GPU crate's own sample-position helper decides where the field is evaluated before upload, so it must be the same expression marching_cubes::corner_position evaluates — a multiply and then an add, rounding twice. mul_add rounds once. At h = 0.125 the two forms are bit-identical because h·i is exact, so GPU-004's whole suite passed at that spacing and reported 0 vertices further than one ULP. E-301 ran at h = 0.1 and 8,951 vertices came back further than a ULP from any CPU vertex — the GPU was reading a field sampled at different points |
GPU-005. Fifth instance in this repository of an algebraic identity IEEE does not honour, after M-32, M-49, M-70 and M-73, and the first where the wrong form was chosen rather than assumed. The guard is a test at h = 0.1 that asserts the expression and asserts that the spacing can tell the two forms apart — at a power of two it cannot, and a fixture that cannot fail is M-44's rule wearing a new hat |
| M-144 | GPU/CPU bit-identity is a property of the cell size, not of the port — 93.8% at h = 0.125, 1.1% at h = 0.1, 98.0% at h = 0.0625 — and what holds at every spacing is a distance, under 2.1e-6 cells. Same sphere, same samples, same uploaded case table, RTX 3090 over Vulkan through Bevy's own device |
GPU-005, cargo run --example gpu_compute_mc. Full table, and triangle counts are equal at every row with zero vertices moved: 33³/0.125 6,507 of 6,936 bit-identical, worst offset 4.77e-7 cells; 41³/0.1 121 of 11,112, worst 2.02e-6; 65³/0.0625 27,954 of 28,536, worst 9.54e-7. So GPU-005's "bit-identical, or document the divergence" resolves to the second, and the reason is not the algorithm. Both sides evaluate the same expressions on the same samples; WGSL permits a multiply-add to be contracted into a fused one and this driver takes it, which is invisible wherever h·i is exact and near-universal wherever it is not. Reporting the bit-identical fraction without the spacing would be reporting a property of the fixture. 11.54 / 11.95 / 14.36 ms against the CPU's 0.46 / 0.88 / 2.82 ms — 5× to 25× behind.counts_readback, against 0.04 ms for the same call warm. Warmed and taken as a median of three, 65³ is 1.95 ms against the CPU's 2.36, i.e. the GPU ahead. The instrument was a single cold shot; the lesson is the one this repo keeps relearning about single samples |
| M-145 | The GPU extraction itself is essentially free and almost flat — 0.05 ms at 17³ and 0.13 ms at 129³, over 420× the cells — and everything the GPU path costs is data movement around it. Warmed, median of three, sphere, RTX 3090 over Vulkan through Bevy's device |
GPU-006, docs/measurements/gpu_vs_cpu.csv. Total against a single-threaded CPU: 17³ 0.22 vs 0.05 ms (4.4× behind), 33³ 0.47 vs 0.33 (1.4× behind), 49³ 1.01 vs 1.04 (level), 65³ 2.09 vs 2.33, 97³ 6.38 vs 8.28, 129³ 15.03 vs 19.02 (1.27× ahead). So GPU-006's expectation was right and the crossover is at about 40³ — the gap closes at small grids and inverts. But the interesting number is the other one: with the mesh left on the GPU, count + emit is 0.13 ms against 19.02, and the ratio runs 1.04× → 0.01×. The extraction is ~150× faster; the whole of the loss is getting data in and out. The ceiling is the upload, and it is architectural. At 129³ upload is 8.61 of 15.03 ms (57%) — and FieldBuffer::sampled evaluates the SDF on the CPU, so this design does not remove field evaluation from the CPU's budget, it adds a copy to it. M-136 measured field evaluation at 65–74% of the whole job on fbm_terrain: on exactly the workload a GPU would help most, this design helps least. Evaluating the field in the shader is what changes that. Read-back is the rest, falling from 72% to 43% of the GPU path as the grid grows |
| M-146 | Mesh shaders are advertised by this adapter and cannot be enabled from this workspace, because ExperimentalFeatures::enabled() is unsafe and the workspace forbids unsafe. Probe over every adapter on every backend: NVIDIA GeForce RTX 3090, Vulkan, DiscreteGpu — EXPERIMENTAL_MESH_SHADER advertised, _MULTIVIEW advertised, _POINTS advertised. But requesting any of them at device creation needs an ExperimentalFeatures token, and its constructor is a const unsafe fn in wgpu-types 29.0.4 src/tokens.rs, with disabled() documented as "uses of Features prefixed with EXPERIMENTAL are disallowed" |
GPU-007, cargo run -p isomesh-gpu --example mesh_shader_probe. unsafe_code = "forbid" is set workspace-wide and in bevy_isomesh, so nothing in this repository can open a mesh-shader device without that being changed deliberately.isomesh-gpu never opens a device — its API takes &wgpu::Device, which is GPU-001's rule — so the token is not its problem at all. Bevy writes that unsafe itself and already ships it, and E-303 is a Bevy example. What genuinely needs unsafe is only headless::Gpu opening its own mesh-shader device, which is a test convenience and not the ticket. The first version of the probe reported usable: false for this adapter and it was measuring its own configuration: it requested the feature while passing ExperimentalFeatures::disabled(), then reported the refusal as a property of the hardware. The field was removed rather than fixed, because without unsafe there is nothing honest for it to say |
| V-23 | CLAUDE.md's Metal contradiction is resolved, and both sources were right about different layers. It records that "wgpu's spec table lists MSL as planned while the tracking issue says the Metal HAL backend merged". wgpu-types 29.0.4's own source settles it on EXPERIMENTAL_MESH_SHADER: "Supported platforms: Vulkan (with VK_EXT_mesh_shader), DX12, Metal" followed by "Naga is only supported on vulkan. On other platforms you will have to use passthrough shaders." |
Read from wgpu-types-29.0.4/src/features.rs, GPU-007. So the feature reaches Metal and the WGSL compiler does not: on Metal a caller hands wgpu pre-compiled MSL rather than the WGSL this crate composes. Mesh shaders are therefore a fork in the shader pipeline, not a flag on it, which is the fact GPU-008 has to be designed around. Metal remains unmeasured here — this machine is Linux with one Vulkan adapter, and the probe says so rather than inferring. naga 29 does implement the WGSL side on Vulkan, verified by parsing rather than by reading: enable wgpu_mesh_shader; is accepted as implemented (not merely named), @task parses, and @mesh requires @mesh(<global>) naming an output variable in the workgroup address space (front/wgsl/parse/mod.rs:1922, valid/interface.rs:1531) — which is how the first test failed, having written a bare @mesh and a dispatchMeshWorkgroups call that does not exist; the task dispatch is a builtin output, @builtin(mesh_task_size) |
| M-147 | Bevy's device already has mesh shaders enabled, with no configuration and no unsafe anywhere in this repository — so GPU-008 was never blocked, and the block was my inference rather than a measurement. Measured on Bevy 0.19's RenderDevice in a running example: mesh_shader=true multiview=true points=true |
GPU-007's correction, RTX 3090 / Vulkan. Three facts compose to it, each read from source. WgpuSettings' default priority is Functionality (bevy_render-0.19.0/src/settings.rs:89), which sets features = adapter.features() — every feature the adapter advertises. features \|= options.features then honours anything a caller adds explicitly (renderer/mod.rs:318). And Bevy passes the experimental token itself: experimental_features: unsafe { wgpu::ExperimentalFeatures::enabled() } at renderer/mod.rs:335, carrying its own SAFETY: TODO and a tracking issue. So the crates here stay 100% safe Rust and still reach mesh shaders, because isomesh-gpu takes &wgpu::Device and never creates one — GPU-001's API rule paying a dividend it was not designed for. The error worth recording is the reasoning, not the fact. M-146 measured a real constraint on isomesh-gpu's own headless device and generalised it to "nothing in this repository can open a mesh-shader device", without checking the path E-303 actually takes. A blocker asserted from one crate's configuration is a claim about the consumer, and it needed the consumer to be looked at. It is also worth knowing that the unsafe guards nothing: ExperimentalFeatures::enabled()'s entire body is Self { enabled: true } — a struct literal with a bool. The unsafe is a hand-raise token acknowledging that experimental features may carry UB, not a memory operation |
| M-148 | A WGSL mesh shader's output block is a fixed contract that naga defines and no document states — and it is derivable from the source rather than guessable, which is the difference between writing one and inventing one. The mesh output must be a var<workgroup> struct whose members carry exactly four builtins: @builtin(vertex_count) u32, @builtin(primitive_count) u32, @builtin(vertices) array<V, N> and @builtin(primitives) array<P, M>, both arrays constant-sized (ArraySize::Dynamic is rejected), with the topology inferred from the primitive struct — @builtin(triangle_indices) → triangles, point_index → points, line_indices → lines |
GPU-008a, read from naga-29.0.4 proc/mod.rs:723 and valid/interface.rs:1531, then confirmed by validating. Derived this way the first candidate parsed and validated on the first attempt, where three earlier guesses at the syntax had each failed. And one real language restriction fell out of it: a function parameter may not be a pointer into the storage address space — naga reports InvalidArgumentPointerSpace — so a shared read_vec3(ptr, i) helper is impossible and two near-identical readers are the language's requirement rather than a preference. The consequence for coverage is the useful part: the shader validates with no GPU, so GPU-003's naga sweep covers it in CI even though GPU-009 records that it cannot be executed headlessly. Validity is covered; behaviour is not; and those are now separable claims |
| M-149 | A mesh-shader draw removes the smallest of the GPU path's three data-movement costs — 6.7% at 129³ — and the doc comment claiming otherwise was written before the arithmetic was done. Breaking gpu_vs_cpu.csv's 129³ row down: upload 8.63 ms (57%), CPU prefix sum 3.27 ms (22%), counts read-back 1.97 ms (13%), geometry read-back 1.00 ms (6.7%) — and the geometry read-back is the only one a mesh-shader render path eliminates |
GPU-008a, from docs/measurements/gpu_vs_cpu.csv. The share falls with resolution, from 40.5% at 17³ to 6.7% at 129³, because it scales with triangle count while upload scales with cells. So the saving is largest exactly where the whole path is cheapest and least worth optimising. The counts read-back is bigger than the geometry read-back (1.97 against 1.00) — 4 bytes per cell beats 36 bytes per triangle at any resolution where the surface is sparse in the volume, which is all of them. What would actually remove the movement is a GPU prefix scan feeding draw_mesh_tasks_indirect (verified present in wgpu-29.0.4 api/render_pass.rs:303): the counts never come home, the total never comes home, and the draw reads its own workgroup count from GPU memory. Ticketed as GPU-010. The error being recorded is an overclaim in prose that the repo's own committed CSV contradicted — mesh_render.wgsl said "there is no read-back" and "removes the largest remaining piece" while docs/measurements/gpu_vs_cpu.csv had the numbers to disprove it. Checking a claim against data already in the repository costs one query, and this one was not made until the ticket after |
| M-150 | Moving the prefix sum onto the GPU took the extraction path from 15.01 ms to 9.65 ms at 129³ — 1.56× — and the stage it replaced went from 5.24 ms to 0.37 ms, a factor of 14. Predicted 34.9% from M-149's breakdown, measured 35.7% | GPU-010a, docs/measurements/gpu_vs_cpu.csv, RTX 3090 / Vulkan, warmed, median of three. Against a single-threaded CPU the whole path goes from 0.79× to 0.51× — 1.27× ahead to 1.95× ahead — and every row from 49³ up improves. What it removed was not computation, it was a copy: the CPU prefix sum needed every per-cell count, which is 4 bytes × 2,097,152 cells = 8.4 MB read home at 129³ purely to add up. The scan leaves four bytes crossing the bus, the grand total, needed only to size the geometry buffer. It is a small loss at tiny grids and that is worth saying: 17³ went 0.24 → 0.28 ms (0.85×), because two extra dispatches cost more than summing four thousand numbers on the CPU. The crossover is around 25³, well below the 40³ where the GPU path as a whole starts winning, so it never has to be chosen against. The consequence for what comes next: upload is now 87% of the GPU path (was 57%), and upload is FieldBuffer::sampled evaluating the SDF on the CPU and copying samples over. Every remaining stage together is 13%. Evaluating the field in the shader is the largest lever left, and it is not ticketed |
| M-151 | A hierarchical GPU scan is exactly the kind of code that is wrong invisibly, so it is asserted element-for-element against a CPU reference at all three depths — and the depth is asserted too. ScanOutput::levels is exposed for that reason: a suite that only ran inputs under 65,536 elements would exercise one and two levels and never touch the cross-block add that three levels need, while reporting full coverage |
GPU-010a. Tested: 200 elements (1 level), exactly 256, 1000 (2 levels), 300,000 (3 levels, the depth a 129³ extraction uses), all-zeros, all-ones, single element, and a sparse clustered distribution shaped like real Marching Cubes counts — zero almost everywhere with short runs where a surface crosses — because a scan tested only on smooth data has not met its actual input. Every case compared offset-by-offset against cpu_prefix_sum, not by total. A total-only comparison would pass on a scan that shuffled the offsets, and shuffled offsets produce triangles written to each other's slots: a mesh that renders, has the right triangle count, and is silently corrupt. The end-to-end evidence is separate and stronger — the pre-existing CPU-comparison tests still report identical triangle counts and vertices within one ULP with the scan in the path |
| M-152 | "The upload is field evaluation" is 57% true: of the 8.40 ms upload at 129³, evaluation is 2.65 ms, converting Vec<f32> to Vec<u8> is 1.14 ms and write_buffer is 0.86 ms. Timed separately, release build, warmed, RTX 3090 host |
GPU-011a/GPU-012's premise, checked before either was written. So there are two independent levers, not one, and they serve different consumers: evaluating the field in a shader removes the whole upload for a caller with an analytic SDF and can do nothing for a caller who already has samples — a voxel volume or an imported scan — whose upload is 100% copy. Writing samples straight into a mapped buffer helps that caller and is worth ~43% of the upload either way. Two smaller corrections fell out of the same measurement. create_buffer for 8.4 MB measures 0.00 ms — wgpu allocates lazily, so "the upload allocates a fresh buffer every call" is not a cost worth avoiding. And the first run of this measurement reported eval 98.76 ms, which is a debug build: cargo test does not inherit --release, and a timing taken that way is 37× off and looks like a catastrophic finding rather than a mistake. The repo already knows this — CLAUDE.md says "always --release for examples" — and the same rule needed applying to a test used as an instrument |
| M-153 | Eliminating the "redundant" copy into GPU memory costs 1.6×, and the copy that was redundant was a different one. GPU-012 predicted 43% of the upload recoverable by writing samples straight into a mapped_at_creation buffer. Three variants, 129³ upload: Vec<u8> + write_buffer 8.40 ms (the code that was already there), mapped_at_creation + per-element write_iter 13.47 ms, mapped_at_creation + bulk copy_from_slice 8.62 ms |
GPU-012. So the mapping is not the problem and per-element writes are. wgpu says why in a comment on the type itself: BufferViewMut deliberately does not deref to [u8] because "mapped memory may be write-combining memory" — where a stream of small writes is far worse than one memcpy. A bulk copy into a mapping merely ties write_buffer, so write_buffer was already doing the efficient thing and there was nothing to reclaim there at all. What did work was the copy nobody had named: sampled built a Vec<f32> and then converted it to bytes in a second full pass over 8.4 MB. Evaluating straight into the byte layout takes the upload to 7.04 ms and the whole path from 9.65 to 8.15 ms — 1.18×, and from 1.95× to 2.33× ahead of a single-threaded CPU. The prediction was 43% of the upload and the answer was 16%, because half the target turned out to be an irreducible 8.4 MB memcpy. Registering the number first is what made that visible as a miss rather than a success |
| M-154 | GPU field evaluation does not match libm bit-for-bit on any field, including the ones with no transcendentals — and it does not change the mesh. Same grid, same expressions in the same order, h = 0.125 from origin -2.0 so the sample positions are bit-identical and only the field arithmetic differs. Bit-exact samples of 35,937: sphere 26,009, torus 25,449, box_exact 30,637, gyroid 3,873; worst absolute deviation 2.38e-7 / 4.77e-7 / 1.19e-7 / 6.56e-7 |
GPU-011a. The hypothesis was that sqrt-only fields would agree exactly, and it is wrong: a GPU may contract x*x + y*y + z*z into fused multiply-adds, rounding once where libm rounds twice — M-142's cause, one layer up from the vertex positions where it was first found. box_exact comes closest for a structural reason worth generalising: its expression is abs/max/min, exact in IEEE, over a sqrt whose argument is identically zero inside the box, so only the exterior shell has anything to round — 1 ULP worst against sphere's and torus's hundreds. So the drift is a property of the expression, not of the GPU, which is the fact GPU-011b has to design around. And the consequence that actually matters is measured rather than argued: the mesh is unchanged. Extracting from a CPU-uploaded field and a GPU-evaluated one gives identical triangle counts on all four fields, including gyroid at a non-power-of-two spacing where the positions differ too — no sample within 7e-7 of zero crossed the sign test. ULP counts are reported but not gated, because a signed distance field is zero on its own surface and ULP distance is unbounded near a zero crossing; absolute deviation is the quantity that decides whether a crossing moves |
| M-155 | Evaluating the field on the GPU takes the 129³ path from 8.37 ms to 0.54 ms — 15.5× — and 37× ahead of a single-threaded CPU. The prediction was "under 2 ms and ≥4×", registered before the work. Warmed, median of three, RTX 3090 / Vulkan | GPU-011a, docs/measurements/gpu_vs_cpu.csv. Full sweep, GPU-native against the uploaded path: 17³ 0.22 vs 0.30, 33³ 0.22 vs 0.42, 49³ 0.26 vs 0.78, 65³ 0.27 vs 1.35, 97³ 0.33 vs 3.72, 129³ 0.54 vs 8.37. The shape is the finding as much as the number: it is nearly flat — 0.22 → 0.54 ms across a 420× increase in cells — the same not-remotely-saturated signature M-145 found in count + emit, now for the whole path. What was 86% of the run has become nothing, because the samples are produced where they are read and the bus is never touched. The crossover moves to about 25³: at 17³ the GPU is still 3.7× behind on ~0.22 ms of fixed overhead, and from 33³ up it wins, by 37× at 129³. Cumulative across the three tickets that touched this path: 15.01 ms at GPU-010a's start, 0.54 ms now — 28× — and none of it came from making the extractor faster. count + emit never moved: it was 0.11 ms before and 0.04-0.05 ms now. Every gain was data movement removed |
| M-156 | The mesh-shader coverage hole is accepted rather than closed, and the deciding constraint is a stated goal rather than a technical one. headless::Gpu cannot open a device with EXPERIMENTAL_MESH_SHADER without an unsafe block, so a mesh-shader kernel can be validated headlessly (GPU-003's naga sweep needs no device) and refused headlessly (MeshShaderRenderer::new errors, asserted) but never run |
GPU-009. The alternative was to relax unsafe_code = "forbid" for one crate and confine the unsafe to one documented call — which would work, and whose entire body is Self { enabled: true }. It is not taken because the user's stated goal is a crate that can be described, accurately, as safe Rust, and one #[allow(unsafe_code)] costs exactly that description for a test-only convenience. What is bought and what is given up, separated: shader validity stays covered in CI; mesh-shader behaviour does not, and must be asserted inside an application whose device asked for the feature — Bevy's does by default (M-147). Compute kernels are entirely unaffected: Marching Cubes, the scan and the field sampler all run and are tested headlessly. The doc is pinned by a test asserting the device really has no experimental features, so if wgpu stops gating them or the lint policy changes, the claim fails loudly instead of quietly becoming false |
| M-157 | A GPU-interpreted edit log reproduces BrushStack to under 8.4e-7 across every shape, every op and a twelve-brush mixed sequence — and extracts the same mesh. Worst deviation from isomesh's CPU fold, 25³ grid: each op alone 1.19e-7, each shape alone 2.38e-7, a 12-brush mixed log 8.34e-7; an empty log reproduces the base field bit-identically; and a three-brush log at 49³ gives the same triangle count as the CPU-sampled equivalent |
GPU-011b. The mixed-log case is the one that matters and it is not redundant. Mixed adds and subtracts do not commute and a smooth add is not associative (M-36..M-38), so folding first-to-last is part of the value, not an implementation detail — a shader that batched or reordered brushes for parallelism would pass every single-op test and fail only this one. The design was chosen over composing a consumer's WGSL for a reason measurement supports rather than taste: M-154 established that arithmetic drift is a property of the expression rather than of the GPU, so an interpreter evaluating the same primitives drifts the same as compiled WGSL would — option (b) buys no accuracy, while option (a) survives editing without recompiling a shader per carve. What it costs is stated rather than hidden: the log is bounded by sphere, box and capsule, so a consumer with an arbitrary analytic SDF is not served, and that is the CAD half of the audience |
| M-158 | The whole pipeline runs on the GPU and never touches the bus: field, edit log, extraction and draw, at 0.41 ms for 16,436 triangles at 65³, 60 fps. E-303 evaluates a base sphere with three moving brushes folded over it (GPU-011a/b), extracts with the GPU-scanned Marching Cubes (GPU-010a), and draws straight out of the position and normal buffers with a mesh shader (GPU-008a). Per frame the CPU sends a camera matrix and three brushes | GPU-008b, RTX 3090 / Vulkan through Bevy. Two integration facts cost a run each and are worth writing down. A render pipeline must match the pass's MSAA sample count, and wgpu refuses the draw outright rather than degrading — "the RenderPass uses textures with sample count 4 but the RenderPipeline uses attachments with format 1". Bevy defaults to 4×, so MeshShaderRenderer::new gained a samples parameter; reading it from ViewDepthTexture::texture.sample_count() is better than assuming, because the view owns it. And Bevy 0.19 has no Node trait: Core3d is a schedule with Prepass → MainPass → EarlyPostProcess → PostProcess, so a custom pass is a system in one of those sets — EarlyPostProcess here, which orders after the opaque pass by the chain without naming a Bevy system and depending on it staying public. The refusal branch is forced and screenshotted rather than assumed: ISOMESH_NO_MESH_SHADER=1 makes the unsupported path reachable on hardware that supports the feature, because a branch nothing can execute is precisely the failure this project keeps finding, and "never panics on an unsupported adapter" was otherwise an untested claim |
| M-192 | I-007's own finding happened to I-007, in the commit that filed it. The new msrv leg for bevy_isomesh went red immediately, and not on a Rust version: wayland-sys's build script panicked because libwayland-dev is absent from the runner. Bevy 0.19 enables Wayland by default on Linux, so its build scripts need the system packages even to type-check — the bevy job has carried an apt-get step for exactly this since it was written, complete with a comment recording that "none of these exist on macOS, which is why a local verification could not have caught it" |
I-007. cargo +1.95 check --all-targets passes locally in that directory, so the code was never the problem; the job was, in the one way the excluded workspace always breaks jobs. That is the fourth instance of the pattern I-007 filed — after rustfmt, rustdoc and MSRV itself — and it arrived inside the fix for the third. A rule earned twice in one commit is worth more than the incident: any new CI step that enters bevy_isomesh needs that directory's whole environment, not just its Rust toolchain, and the only reliable way to know is to copy the bevy job's prologue rather than to reason about what a step "should" need |
| V-27 | §3.2.3's prose is fully retrievable and its triangulation patterns are still only a picture — and the paper offers a second option the ticket never recorded. Retrieved from the source (10.48550/arXiv.2606.00454 §3.2.3, via home-still): the inset construction is stated in full — "we insert the midpoints of all polygon edges contained in any edge of f, and move them a small distance in the inward normal direction. For pentagons, we also insert the midpoint of the edge opposite the distinguished corner." — and is immediately followed by "The triangulation patterns in Figure 15, right ensure that inset regions stay within the tetrahedron." The patterns themselves appear nowhere in the text. The sentence A-014d did not have is the one after it: "This procedure is needed only when taking the union of the two polygons would yield a nonmanifold edge. If manifold connectivity is not required, one can also just discard one of the polygons." |
A-014d's rule-5 check. So there are two published routes, not one, and the paper is explicit that the cheap one costs manifold connectivity. This crate cannot take it: the_validity_suite_over_every_reference_field gates on manifoldness and csg_difference's pinned (3, 6, 6) is precisely a manifoldness row, so discarding a polygon would trade the defect the ticket owns for a different one. The rule-5 stop therefore stands exactly where the ticket predicted — at the quad/pentagon/hexagon triangulations, which must be derived or the figure read, and not invented |
| V-28 | A-014d's rule-5 stop is lifted, and not by the figure — by the authors' own reference implementation, shipped as arXiv ancillary material that nobody had looked for. V-27 concluded the triangulation patterns "appear nowhere in the text" and left the ticket stopped on "derive the patterns or look at the figure". Both halves have now been done, and a third route turned out to exist. (a) The figure was read. Figure 15 is on page 9; rendered with pdftoppm at 1200–2400 DPI it is fully legible, and the quad and hexagon patterns transcribe exactly. The figure's own colouring is the key the prose never states: thick blue is a segment of γ, along which the two coincident copies stay glued — which is why two quads make an annulus and the paper can call the pair a "tube" — and thin black is a polygon edge contained in an edge of f, the ones §3.2.3 inserts a midpoint into. Measured rather than eyeballed, because the pentagon panel turns on it: sampling the rendered PPM gives blue-excess +109 on the two chord edges and 0, 0, +14 on the three ∂f edges. The crate already carries this distinction — Arc::Chord against Arc::Edge in subgrid/surface.rs. (b) The pentagon could not be read, and it is the only type A-014d needs (M-193). Its structure is unambiguous — a fan from one interior point over the boundary ring — but which edge that point is the midpoint of cannot be told apart from the drawing, and the prose's "insert the midpoints of all polygon edges contained in any edge of f" contradicts a figure that inserts one. (c) The arXiv listing has ancillary files — anc/SubgridSupplement.pdf and anc/subgrid-tet.html — and the second is a standalone JS implementation with a "Simplicial Embedding" checkbox. combFaceToPolygonSoup(combFace, tetPositions, edgeIsectTs, midScoopVertices, bulge) is §3.2.3, from its authors, in executable form |
A-014d. What the implementation settles that neither prose nor figure did. Ordinary crossings never move — if (!cv.scoopSteiner && !cv.scoopInteriorSteiner) return pos; — so conformity across tets is preserved by construction, which is the exact worry M-101 raised twice and the reason the inset is safe at all. An inserted point is the midpoint of two consecutive crossings on the same tet edge, displaced lerp(midPos, otherEdgeMid, bulge) toward the midpoint of the opposite tet edge; two tets sharing f have different fourth corners, so their copies move apart and each into its own tet. INTERIOR_HEXAGON is 9 vertices and 7 triangles, [8,2,5] [2,8,0] [2,0,1] [5,2,3] [5,3,4] [8,5,6] [8,6,7] — inserted at ring positions 2, 5, 8, central triangle on all three — which reproduces the hexagon transcribed from the figure triangle-for-triangle, two independent sources agreeing. INTERIOR_CORNER_TYPE inserts one Steiner point at ring position 1, at lerp(mid(v0,v1), mid(commonI, opposite), bulge) where commonI is the tet corner shared by the first two vertices' edges, and fans the whole polygon from it. So the figure was right and the prose was the loose one. The method rule is the finding: V-27 asked whether a paper stated something and stopped at the paper. An arXiv abs page lists ancillary files in the HTML; one curl would have found an executable answer at any point in this ticket's life |
| M-193 | The polygon type A-014d has to inset is the one type its figure could not be read for — measured, not assumed. §3.2.3 names three ("a quad, a hexagon, and a pentagon made at a corner"), and implementing a type no field produces would be unverifiable code, so which_polygon_types_coincide_across_a_shared_face counts them. A coincident polygon is a Region of one face seen by two tets; classifying by (loop kind, chords, edges) — Arc::Chord against Arc::Edge, the figure's blue against black — gives, at 17³ over all seven fields: (contractible, 1, 1) 384, (corner, 1, 1) 126, (corner, 1, 2) 14, (corner, 2, 3) 5. sphere and torus have none of any kind |
A-014d. Three things follow. (1) (corner, 2, 3) is 5 arcs from a corner-type loop — exactly Figure 15's "pentagon made at a corner" — and it is precisely csg_difference's 3 plus thin_plate's 2, which is the ticket's whole target restated from the other side. The quad and hexagon patterns, the two that transcribed cleanly, are unreachable on every reference field. (2) The 510 (*, 1, 1) entries are bigons — one chord, one edge — the zero-area scoop V-21 predicted. They are invisible to the triangle-keyed census that pins csg_difference at 3, because a 2-node region emits no triangles at all: for k in 1..corner.len()-1 is an empty range. Two instruments, two different denominators, and neither was wrong. (3) box_exact carries 84 coincident bigons and zero of anything else, which is why M-161 called it the worst field and M-186 found it at 0 — it was never §3.2.3's immersion |
| M-205 | A-014i's "orphaned bigons" is real, and it is a law rather than a defect: unreferenced positions arrive in pairs, one pair per bigon nothing else reaches. A bigon is a two-arc region — one chord, one edge piece, the zero-area scoop V-21 predicted and M-193 counted 510 of — and it emits no triangle at all, since a fan over fewer than three nodes is an empty range. Where its two crossings are reached by no other region, the fill records two positions and nothing uses them. Measured per patch, because cell_tet hands every position to the sink and a neighbour may then reference it: sphere and torus have 0 bigons and 0 orphans; the other five have both, and every affected tetrahedron leaves exactly two |
A-014i, third defect, characterised and not fixed because there is nothing to fix. The apparent exception is the best part. fbm_terrain leaves 302 across 148 tetrahedra where twice-per-tetrahedron gives 296, which read as a second mechanism until the histogram was printed: 145 tetrahedra with 2 and three with 4, i.e. two bigons in one tetrahedron. 145·2 + 3·4 = 302. So the law is exact on all seven fields once stated as pairs rather than as two per tetrahedron, and the assertion is now evenness — which is ✗1's rule, assert the identity and the counterexample explains itself. Why this is not a defect. A bigon legitimately emits nothing: it has zero area, and A-014d closed as not required precisely because there is no geometry to inset into it. Its two positions carry real global crossing identities, so a neighbouring tetrahedron consumes them — which is exactly what M-201 measured, where dropping such positions changes vertex order and not vertex count. Unlike the subdivision orphans, which nothing consumed and which M-203 fixed |
| M-204 | M-166 is closed by two parentheses, and the test that was already asserting the property could not have caught it. The interior test's denominator was v[0] + v[2] - v[1] - v[3], which evaluates as ((A + C) − B) − D — a fixed subtraction order that a rotation permutes, and IEEE addition is not associative. So two cells reading one shared face could evaluate the same sweep to different bits and disagree about a tunnel, which is why A-002b was blocked on this. Grouping each diagonal, (A + C) − (B + D), makes every symmetry of the face exact: a two-corner rotation swaps the operands within each parenthesis and IEEE addition is commutative, so the result is bit-identical; a one-corner rotation or a reflection exchanges the two parentheses and IEEE subtraction is exactly antisymmetric, so the result is the exact negation — which cancels against the numerator's own exact negation in saddle. Over 20,166 corner quadruples the old order disagrees on 2,764 and the grouped one on zero |
A-002b's named prerequisite. The existing test asserted this property and passed with the defect present, which is the part worth keeping. the_test_is_deterministic_and_independent_of_diagonal_order rotates by two corners and compares saddles, and strengthening its tolerance to bit-identity still passes — opposed()'s corners are all of similar magnitude, so both orders round the same way. That is the fixture trap for the fifth time (M-32, M-38, M-44, G-003, here), and the fixture that exposes it had to be searched for: (1, 1, 1, 10⁻⁸), giving 0.99999999 against 0.9999999900000001. The new test asserts first that the fixture still separates the two orders, then that the sweep agrees bit-for-bit — and it fails on the old expression and passes on the new one, verified in both directions. A tolerance was doing the work of a fixture search: the original comment correctly identified the risk and deferred it, and the deferral outlived the two lines that fix it |
| M-203 | A-014i's orphaned vertices are fixed by giving children their parent's names instead of new ones, and the mesh is bit-for-bit the same mesh. M-201 measured 16,296 of 166,591 vertices referenced by nothing on the subdividing plane fixture, and named the cause: a subdivided parent records a position for every crossing its cycles name, and its four children then re-derive those same points as child-local positions beyond crossings.len(), with no identity at all. fill_append now takes an inherited map, and fill_subdivision builds one per child from the parent's own crossing indices — forward or reversed exactly as the parameters are. Result: the bare (4, 2) tetrahedron goes 112 positions → 64 with zero unreferenced, and the grid fixture 166,591 → 104,767 vertices with 46 unreferenced, a 37% reduction |
A-014i. The triangle count is identical in both — 52 and 219,084 — which is the evidence that this renamed vertices rather than changing geometry. All 523 tests pass including the golden hashes, which is the second guard: subdivision is unreachable on the seven reference fields, so a change confined to it must leave every golden alone, and it does. The detector for the 1 − t re-lerp moved and had to be re-checked rather than assumed. M-200's bare-tetrahedron test worked by observing that children duplicate parent crossings, and inheritance removes exactly that — rediscovered goes 24 → 0, which is now the invariant it asserts. Inverting the branch is still caught, but by the grid fixture instead, verified by re-running the mutation after the fix. Had that not been checked, the fix would have silently deleted the only test with power over a defect this ticket had just finished proving was untested. The 46 remaining are pinned, not chased: 0.04%, and crossings the parent named that no child's cycle reaches at all, which is a different mechanism from the systematic duplication measured here |
| M-202 | Subdivision only fires where the grid badly under-resolves the field, so "T-001 validity on the subdivision fixture" cannot be a clean gate — the fixture is compromised by construction. The k = 96 plane fixture welds to 73,855 vertices with 249 non-manifold edges, 295 non-manifold vertices and 131,815 inconsistently oriented, which reads as a subdivision defect and is not one. Holding the algorithm and the grid fixed and moving only the frequency: the same plane family at k = 8, which this 9³ grid resolves and which fires no subdivision at all, gives 0, 0, 0 — clean, with 948 boundary edges, which is a plane family leaving through the walls of a finite box and is the field rather than the mesher. Same extractor, same grid, same field family, opposite verdicts |
A-014i, and ✗15's condition — "the grid resolves the surface" — measured for this extractor rather than inherited. The structural consequence is the finding. Case (5) needs a residual with g > 1 and ℓ > 8, which needs many crossings per edge, which needs the surface to oscillate several times inside one cell. That is under-resolution, by definition. So every fixture that exercises subdivision is necessarily in the regime where manifoldness fails for reasons that have nothing to do with subdivision — and it is why the seven reference fields, all comfortably resolved at 17³–33³, never reach it. A-014i's "T-001 validity on the fixture" has to be re-read as a comparison against the resolved case, not as an assertion of zero. Determinism, by contrast, is a clean gate and passes: two extractions of the subdividing field are byte-identical, which T-004 could never have checked because it only runs the reference fields. The obvious control was the wrong instrument, and worth recording as such: classic Marching Tetrahedra on the same field returns 2,113 vertices against subgrid's 73,855 and looks far cleaner, because M-67 measured a sign test as blind to 95.6% of tetrahedron configurations — it is reconstructing a much simpler surface, not the same one more carefully |
| M-201 | The subdivision path has a grid-level fixture at last, and it says the orphaned vertices are real — 9.8% of them — which falsifies the inference M-200 was heading toward. Every measurement of case (5) until now was on a bare tetrahedron built from hand-chosen edge coordinates, the one configuration where a crossing has no neighbour to be shared with. M-200 observed that dropping unreferenced positions on the reference fields changes vertex order but not vertex count, and the natural inference — that such positions are always consumed by an adjacent tetrahedron, so the bare-tet orphans are a fixture artefact — is wrong. Searched rather than assumed: sin(k(x+y+z)) at k = 96 fires case (5) 276 times on a 9³ grid, and extracting it gives 166,591 vertices, 219,084 triangles and 16,296 referenced by nothing |
A-014i. Why the neighbour argument holds on the reference fields and fails here. A parent's crossings are real grid crossings carrying global identities, so an adjacent tetrahedron that does not subdivide reuses them — which is exactly why they only reorder on the seven reference fields, where subdivision == 0 is pinned. A subdividing parent's children instead re-derive those same points as child-local positions beyond crossings.len(), with no identity at all, so where both sides of a face subdivide nobody consumes the parent's registration. That names the fix and rules out the tempting one: children should inherit the parent's crossing identities on parent edges rather than re-deriving anonymous copies; dropping the orphans afterwards is the shape that does not work, because it removes positions the reference fields legitimately share. Finding a usable field was itself the hard part. sin(kx)·sin(ky)·sin(kz) reaches case (5) most readily of anything tried — subdivision wants two transverse families of cuts — and its gradient vanishes where those families meet, so the extractor refuses it with DegenerateNormal. The obvious way to write the configuration is also the degenerate way; the plane family works because on sin = 0 the cosine is ±1, so ‖∇f‖ = k√3 everywhere on the zero set |
| M-200 | Two of A-014i's three recorded defects are not what the review called them: one is real and its obvious fix is measurably wrong, and one is not a code fault at all but a hole in the test suite. The ticket's own instruction was that the three names are "one-line summaries, not verified re-derivations", so each was reproduced before anything was touched. The fixture is derivable rather than searched for: case (5) is taken only when ℓ ∉ {4, 8} and loop_count > 1, so with ℓ = 4(d₁+d₂)/g and g = gcd it needs g > 1 and d₁ + d₂ > 2g. The smallest is (4, 2) — g = 2, ℓ = 12, two loops, 4(d₁+d₂) = 24 intersections, which is exactly the "≥24 edge intersections" the ticket quotes. It is also the only one of the twenty patterns in every_implemented_case_emits_an_intersection_free_patch's sweep that reaches case (5), so that sweep has covered this path all along and nothing said so |
A-014i. Orphaned vertices: real, 24 of 112 positions for 52 triangles, and the 24 is exactly the parent's own crossing count — fill_append records a position per named crossing because every case except subdivision triangulates over exactly those, and subdivision hands the work to four children that re-derive their own. The obvious fix is wrong, measured: dropping unreferenced positions at the end of fill and remapping takes the fixture to 88 positions and 0 orphans, and drifts six golden rows — gyroid and fbm_terrain at all three resolutions — with identical vertex and triangle counts and a different hash. So on the reference fields it removes nothing and only reorders: an unreferenced position there still carries a global crossing identity and seeds the map a neighbouring tetrahedron reuses, so dropping it moves which tetrahedron emits that vertex first. A-014i's own guard is that reference-field output must not change, and that guard is what caught it. Count pinned at 24, per M-4's rule. The 1 − t re-lerp: the code is correct and nothing tested it. fill_subdivision already reverses the list and maps t ↦ 1 − t, and inverting that branch passes all 32 tests in the module, including the intersection-free sweep — because the child.coordinates() == predicted guard counts crossings per edge and a mirror leaves every count identical. The assertion with power is that a parent crossing must be re-derived bit-identically by whichever child expresses it: 24 of 24 with the code as written, 12 of 24 under the mutation, verified in both directions. That is ✗-tier "verify a property test can actually fail" applied to a defect report rather than to a test |
| M-199 | Subgrid Marching Tetrahedra is already intersection-free on every reference field at every resolution — so §3.2.3, whose entire purpose is to remove self-intersections, has nothing to remove and A-014d has no reachable target. §3.2.3 turns an immersed Δ-complex into an embedded simplicial complex; the paper is explicit that the coincident pairs it addresses "define manifold connectivity, but degenerate geometry". M-194 falsified the manifoldness half of A-014d's acceptance. This measures the half that was actually left: T-002's counter over the extractor's own welded output, which had never been run there — subgrid/surface/tests.rs runs it per tetrahedron on synthetic patterns, a different question. Result: 0 intersecting pairs on all 21 rows, seven fields × 17³/25³/33³, up to 32,364 triangles on gyroid at 33³ |
A-014d, closed as not required rather than blocked. The control is what makes the twenty-one zeroes mean anything. Dual contouring, through the identical pipeline — same fields, same resolution, same epsilon_for(cell) weld, same counter — reports gyroid 18 pairs (7.143 per 1k) and fbm_terrain 21 pairs (24.249 per 1k), which is A-009's residue (M-28, M-29) showing up exactly where it was measured before. So the counter is live on this path and subgrid's zero is a property of the surface. The first control tried was worse than useless and the test caught it: counting the unwelded soup, on M-93's note that neighbours sharing a position but not an index are counted, reads zero too — face-touching is not crossing — and the reachability assertion failed rather than passing quietly. What would reopen this ticket is a field or resolution where this census goes non-zero; nothing else. Cost: the census adds ~120 s, dominated by subgrid extraction rather than by the intersection test |
| M-198 | The publish job ran for the first time in its life, and failed on a secret that was never set — so the release pipeline has still never published anything, and now the reason is known rather than inferred. M-174 established that 0.0.3 and 0.0.4 reached crates.io by hand, and that the job had been skipped on every run since it was written because the suite was red. Closing the last of that red (I-007, and this session's four tickets) made the whole suite green for the first time, which is the only condition under which needs: [lint, test, bevy, msrv, package] lets the job execute. It executed, and died on CARGO_REGISTRY_TOKEN is not set — the secret exists neither at repository level nor in the crates-io environment the job declares. It never reached scripts/publish.sh, which would have found 0.0.4 already on the registry for both crates, skipped both and exited 0 |
GPU-013's push, and M-174's rule collecting its third instance. The check was in the wrong place, and the script's own header said so. publish.sh opens by explaining that it is version-driven precisely because "the alternative … would leave main permanently red and train everyone to ignore it" — and the workflow then required a token unconditionally, on every push to a green main, including the ones that upload nothing. The check now lives next to the upload it guards, and both directions are verified rather than argued: with no token and nothing to publish it exits 0 (published 0, skipped 2), and with the workspace version bumped so an upload is imminent it exits 1 with the loud error before cargo publish runs. What is still owed is the user's: the secret has to exist before any real release, and nothing in CI can tell you it is missing until a version bump makes an upload imminent — which is the correct trade, but worth knowing in advance rather than at release time |
| M-197 | GPU-013's two halves both misnamed their target, and the measurement says the prize is waits rather than submissions. (a) The duplicated prologue is not between the functions the ticket names. extract has no prologue at all — it delegates to extract_buffers and reads two buffers home. The ~30 duplicated lines are between extract_indirect and extract_buffers, and the ticket's stated justification is also wrong: the indirect-draw budget-clamp fix (99415af) landed 15 and 74 lines past the end of the shared region. The real justification is that the copies had already drifted — counts carried STORAGE \| COPY_SRC in one and STORAGE \| COPY_DST \| COPY_SRC in the other, and both explanatory comments existed in only one. The unified version drops COPY_DST: nothing in the crate copies or writes into counts, so the flag was dead where it existed rather than missing where it did not. (b) Batching the two geometry read-backs is worth 8–9%, measured on an RTX 3090 at gpu+read: 97³ 0.835 → 0.764 ms, 129³ 1.341 → 1.223 ms, with after-run spread ±0.005. The saving is roughly constant rather than proportional to the bytes moved, which is the signature of removing a fixed synchronisation rather than bandwidth — poll(Wait { submission_index: None }) drains the entire queue whether it carries four bytes or five megabytes |
GPU-013. The number that decides the rest of the ticket comes from the harness this added, because gpu_vs_cpu had never timed extract_indirect at all and a claim about its submissions cannot be checked against a path nothing measures. The zero-read-back path costs 0.155 / 0.169 / 0.188 / 0.265 / 0.264 / 0.304 ms at 17³…129³ — nearly flat across a 435× rise in cell count, which refines M-160's "~0.17 ms" and confirms it is pure CPU recording. All eight of its queue.submit calls live inside that 0.304 ms. Against them, extract_buffers costs 0.552 ms at the same size, and the entire 0.25 ms difference is one poll(Wait) — the counts read-back that sizes the geometry buffers, which cannot be batched away because its value is what sizes them. So batching submissions can recover at most a fraction of 0.3 ms and removes no wait; batching read-backs removes a whole wait and measured 8–9%. Submissions are not where this crate's time goes, waits are — M-159 and M-167 restated with the two paths side by side. The dispatch-submit batching is therefore answered rather than deferred, and it carries a cost besides: ExtractTimings' per-stage count_ms/scan_ms/emit_ms are CPU wall-clock around each submission, so collapsing them into one encoder would destroy the attribution M-149 and M-160 both rest on, and the alternative — GPU timestamp queries — needs a device feature this crate does not request |
| M-196 | Consuming fields:: instead of a hand-rolled copy is a speed-up, not a tidy-up — and a dispatch layer can throw the whole benefit away silently. Sdf::gradient's default is central differences: six extra sample calls per normal. fields::BoxExact, Sphere, Difference and Intersection all override it analytically; the examples' private re-implementations implemented sample alone, so every normal they produced cost seven field evaluations instead of one. Measured on game_csg_props at 41³, extract time per frame: dual contouring 5.81 → 5.35 ms, dual contouring with the clamp off 5.82 → 5.25 ms, surface nets 2.82 → 2.76 ms |
E-212. The trap is the dispatch enum. game_destruction's Solid wraps three fields and implemented only sample, which means swapping its variants for the crate's types would have bought nothing — the default gradient would have been reimposed one layer above the fields that carry the real one. Forwarding gradient through the enum is what makes the swap real, and nothing about the types would have warned that it was missing. Two things this measurement cannot say. The demo's accuracy columns are driven by a moving reflex edge on a wall clock, so a fixed frame index samples a different phase run to run — the baseline read dc worst 0.3700 where the changed build read 0.2255, and neither is evidence about the other. What is checkable is that the changed build reproduces the figure the demo's own HUD prose has recorded all along (0.2255, and surface nets 2.34× further out), which the baseline run did not reach by frame 61. A like-for-like accuracy comparison needs a deterministic sweep this demo does not have |
| M-195 | The mirrored seam's crack is exactly invisible to a seam-plane counter — 0 edges on the plane, 28 on each side of it. E-211 said game_lod_flyover's HUD scans the seam plane while Eq-4.2's taper puts transition geometry at seam ± w, and estimated the blind spot from the 44 boundary edges the 2026-08-14 review found. the_mirrored_seam_closes_only_with_the_signed_width now measures it directly, headless and in CI, on the configuration E-107 never ran — coarse block below the seam, its high face tapered to seam − w. With the signed width the three planes (seam, seam − w, seam + w) report (0, 0, 0). With the unsigned width — the one-token revert of the fix — they report (0, 28, 28) |
E-211. The middle zero is the finding. 56 boundary edges are open and not one of them lies on the seam plane, so the blind spot is not a matter of tolerance but of geometry: the taper moves every open edge off the plane the counter watches, and w ≥ BASE_H against a BASE_H · 0.25 window puts the band four tolerances outside it. An instrument reading 0 on a mesh with 56 holes in it is the strongest possible statement of E-208's rule, and this is the first time this project has had the number for a case where the instrument was structurally blind rather than merely starved. The test carries its own positive control — the unsigned run is asserted non-zero — because M-44 and E-208 both say a zero that cannot go non-zero is not a measurement, and here the zero being reported was the bug. Confirmed end-to-end in the example too, run on this machine's RTX 3090: with the band-scanning counter the fixed build reports open_low 0, open_high 0, and reverting the one token sample_width → width makes it report open_low 44 — the review's own figure, recovered by the instrument that could not see it before, and only on the rows where seams_low is 1, which is the mirrored configuration and no other |
| M-194 | A-014d's acceptance criterion asks §3.2.3 to fix a defect §3.2.3 does not cause, and this repository's own instrument has been saying so, in a passing test, since it was written. With the source finally in hand (V-28) the inset was implemented three ways and measured on csg_difference at 17³ against a baseline that is closed — (3, 6, 6), 0 boundary edges, 1 component, χ = 5. (a) A midpoint on every polygon edge contained in an edge of f, per the prose: (0, 12, 6) — but 48 boundary edges, 9 boundary loops, 4 components. (b) One Steiner point on the segment across the omitted distinguished corner, per the reference implementation's corner-type branch: (0, 12, 0), and the same 48/9/4. Both tear, and for one reason: in this decomposition a region is one face's share of a disk, so every part of its boundary is already shared — a chord with the coincident copy in the neighbouring tet, an edge piece with the same tet's region on the adjacent face, the corner cut with §3.2.2's cap. The paper's comb face spans the whole tet boundary, where those segments really are free. (c) Displacement moved to the only place this decomposition has room for it, the interior — one Steiner at the ring's centroid pushed toward the corner the shared face does not carry, coning over the ring. Closed again (χ = 5, 1 component, 0 boundary edges) and nm-edges unchanged at exactly 3 |
A-014d. (c) is the result. It separates the two copies perfectly — different apexes, no shared interior edge — and the non-manifold count does not move, because duplication was never the cause. the_defects_traced_back_to_the_tetrahedra_that_made_them already reports csg_difference as duplication-only 0, three-distinct 3, and its own comment states the criterion: "if fewer than three remain, duplication is the whole story and §3.2.3's inset is the fix. If three or more distinct polygons genuinely meet, it is not." All 3 are genuine three-sheet junctions — 4 faces, 3 distinct triangles, 2 tets — so one tet contributes two sheets and the other two, and the pair being identical is incidental. The paper agrees in advance: "Pairs of identical polygons … define manifold connectivity, but degenerate geometry" — §3.2.3 buys intersection-freedom, not manifoldness, and T-002 is the counter it should be graded against. Where the inset does have a target: fbm_terrain is duplication-only 2 of 4 bad edges. That is the whole reachable prize, and it is on a different field from the one the ticket names. This is ✗11's rule happening a second time — "a ticket's acceptance criterion is itself a claim about the code; check it against the code before starting" — and the check cost one cargo test against a counter that was already green |
| M-189 | Running the subgrid validity census at the three resolutions its own gate names doubles the number of known defects, and every new one is on a field the suite called clean. T-010 widened the_validity_suite_over_every_reference_field from n = 17 to [17, 25, 33]. (non-manifold edges, non-manifold vertices, inconsistently oriented), the rows that are not all-zero: 17³ csg_difference (3, 6, 6), gyroid (0, 0, 138), fbm_terrain (4, 6, 19); 25³ torus (4, 6, 6), thin_plate (0, 0, 8), gyroid (0, 0, 150), fbm_terrain (2, 3, 29); 33³ csg_difference (0, 0, 36), thin_plate (0, 0, 6), gyroid (0, 0, 330), fbm_terrain (8, 12, 53) |
T-010. Three of the seven fields were believed clean and are not: torus is non-manifold at 25³ only, thin_plate is incoherently wound at 25³ and 33³ only, and csg_difference — whose 17³ row is A-014d's entire target — is clean at 25³ and non-manifold at neither finer size. The defect that ticket exists to remove occurs at one of three resolutions and was never checked at the other two. The lesson is not that 17³ is a bad choice, it is that one sample of a stated range is not a sample of it: every one of these fields is defect-free at some resolution and defective at another, so any single size gives an answer that is true and unrepresentative |
| M-187 | Orienting each connected component from its most confident triangle drives the inconsistently-oriented-edge count to exactly zero on every mesh whose edges are all manifold — and the residue where it does not is non-manifoldness, not a limit of propagation. Before → after, all seven fields at 17³/25³/33³: gyroid 138 → 0, 150 → 0, 330 → 0; thin_plate 0 → 0, 8 → 0, 6 → 0; csg_difference 6 → 6, 0 → 0, 36 → 0; fbm_terrain 19 → 6, 29 → 3, 53 → 12; torus 0 → 0, 6 → 6, 0 → 0; sphere and box_exact 0 throughout. The law is exact and holds on all 21 rows: every row with non_manifold_edges == 0 comes out at 0, and every row with a residue has non-manifold edges |
A-014f, every_reference_field_comes_out_coherently_oriented. The mechanism is forced rather than incidental: an edge carrying four faces cannot have them pairwise oppose, so no assignment of windings makes it consistent — that residue is A-014d's defect wearing an orientation costume. Vertex counts, face counts, manifoldness and boundary counts are asserted unchanged across the pass, so it moves winding and nothing else. The seed is the most confident triangle rather than the first, which is load-bearing and has its own test: a triangle whose gradient lies in its own plane has a vote of ~0, and seeding from one flips a whole component on a coin toss |
| M-188 | Two of the seven reference fields are non-manifold at a resolution the suite never tested, and one of them is torus. Measured while establishing M-187's law, which needed the non-manifold count per row: torus reports 4 non-manifold edges at 25³ and 0 at 17³ and 33³; csg_difference reports 3 at 17³ and 0 at both 25³ and 33³; fbm_terrain 4, 2, 8. So csg_difference's pinned (3, 6, 6) — the row A-014d exists to drive to zero — is a 17³-only defect that the field does not exhibit at either finer resolution |
A-014f. This is the same hole as M-182 and it is worse than it looked: the subgrid validity census runs at n = 17 alone (T-010), and 17³ is not merely a sample of the three, it is the resolution that decides which defects this project believes it has. A-014d's target exists at one of the three resolutions it was never checked at the others of |
| M-184 | Naming a root by the grid point it lies on completes the identity outright: on every field the extractor now emits each vertex exactly once, and a positional weld removes nothing. Raw → welded, all seven at 17³: sphere 812 → 812, torus 912 → 912, box_exact 338 → 338, csg_difference 482 → 482, thin_plate 422 → 422, gyroid 4014 → 4014, fbm_terrain 1758 → 1758. Every one of those raw counts is exactly what a positional weld used to reach, so M-169's gap is closed and M-180's ceiling is beside the point — it bounded rules that leave positions alone, and this moves them |
A-014h. The rule is not a cleverer key: an endpoint root is emitted at the grid point's own position, origin + cell_size · index, the expression corners already uses and every cell computes identically (M-32). Detection is f(G) == 0 exactly — no tolerance — because that is the definition of the surface passing through G and it is a property of G alone, so every one of the up-to-24 tetrahedra meeting there reaches the same answer without consulting the others. The cost is 15 of 168 golden rows, and its shape is the check that it is right: 14,171 vertices removed and 28,342 triangles — exactly 2 per vertex, on all 15 rows independently. That is the edge-collapse signature (ΔV = −1, ΔE = −3, ΔF = −2), which preserves the Euler characteristic, and the validity suite's χ = 2 rows confirm it did. The 6 rows that held are torus and fbm_terrain at all three resolutions — precisely the two fields M-169 measured with zero vertices on a grid point. The correlation that opened the ticket also closes it |
| M-185 | Completing the identity turns a sliver into a repeated-index triangle, and the extractor now declines to emit those. When the surface passes exactly through a grid point, the two tetrahedron edges meeting there each carry a root at it; naming both by the point makes them one vertex, and any triangle spanning both becomes a triangle with two equal indices. validate_indexed counts that as a structural error — 36 of them on sphere at 17³, INVALID: 36 violations — not as the recorded metric it treats a near-zero-area sliver as |
A-014h. Declining to emit them is not dropping geometry: they carried no area before the merge either, and the alternative is shipping an index buffer this crate's own validator rejects. What confirms it rather than merely excusing it: with them gone, sphere validates 0/0/0/0 with χ = 2 and one component, and every pinned defect census in the_validity_suite_over_every_reference_field is unchanged — csg_difference (3, 6, 6), gyroid (0, 0, 138), fbm_terrain (4, 6, 19). A geometry change that moved 15 golden rows disturbed not one of the numbers those rows exist to protect |
| M-186 | M-162 is falsified, and A-014d's blocker with it: after A-014h no coincident polygon has a foreign tetrahedron on its boundary edges, and none is cross-cell. M-162 is what blocked A-014d — "the inset needs information no per-tetrahedron and no per-cell rule carries" — measured as csg_difference carrying 33 coincident polygons, 27 of them with foreign tetrahedra standing on their boundary edges, 312 such triangles and 150 of them in a different cell. Re-measured on the same instrument with the identity complete: csg_difference 3 coincident, 0 with foreign edge users, 0 cross-cell, all 3 within one cell; fbm_terrain 4, likewise all within one cell; every other field 0, box_exact included — the field M-161 called "the most coincidence of any field, 30 polygons and 348 triangles" |
A-014h, which_polygons_coincide_across_a_shared_face. So most of what M-162 measured was never §3.2.3's immersion at all — it was one grid point wearing many names, and it disappeared when the names were fixed rather than when any geometry was inset. the_defects_traced_back_to_the_tetrahedra_that_made_them agrees from the other side: thin_plate's 2 soup non-manifold edges → 0, csg_difference's 6 → 3, and the 3 that went are exactly the duplication-only ones, leaving the 3 M-163 identified as genuinely three-distinct polygons. A-014d is now a per-cell problem on 3 edges of one field, which is a different ticket from the one that was blocked |
| M-182 | P-7 confirmed, and the check that confirmed it found thin_plate failing at two of the three resolutions nobody was testing. P-7's limb (b) holds exactly as registered: welded thin_plate is one component, 0 boundary edges, χ = 2, 0 non-manifold edges and 0 non-manifold vertices at 17³, 25³ and 33³ — a closed genus-0 surface, so its top and bottom are joined at a rim and are one component by topology rather than by tolerance. Both remaining falsifiers fail to fire: the component count is 1, and it stays 1 at every epsilon from h·10⁻⁹ to h·10⁻². But the inconsistently-oriented-edge census is 17³ → 0, 25³ → 8, 33³ → 6 |
A-014f/P-7, the_plate_is_one_closed_orientable_component_at_every_tolerance. The reason nobody had seen it is the interesting part: the_validity_suite_over_every_reference_field runs at n = 17 and nothing else, while Phase 1's own gate says "no unexplained violations on all seven test fields at three resolutions". The subgrid extractor has been meeting one third of its stated gate, and 17³ is the resolution where the plate happens to be clean. This strengthens the case for A-014f's remedy rather than weakening it: the surface is orientable and there is a coherent orientation to propagate to — A-014e's per-triangle vote simply is not finding it, on the very field the per-triangle rule was written to protect. P-7's worry was that propagation would invert a sheet; the measurement says the plate is a single closed orientable component, which is the precondition under which propagation is safe |
| M-181 | T-009's own premise was wrong: normalising four scattered weld epsilons onto one moved nothing, because the weld's answer is flat across six orders of magnitude. The ticket said "normalizing shifts pinned non-manifold censuses — which is exactly why this is a ticket rather than a drive-by." Four policies were in use (h·1e-4 via the constant, h·1e-4 as a literal, h·1e-6, h·1e-5) across 38 call sites. Routing all of them through one changed not a single pinned count anywhere in the suite. Welding the subgrid output at h·10⁻⁹ … h·10⁻³: every field returns the same vertex count at all seven — sphere 812, torus 912, box_exact 338, csg_difference 482, thin_plate 422, gyroid 4014, fbm_terrain 1758 |
T-009, the_weld_answer_is_flat_across_the_range_the_four_policies_spanned. The plateau's edge is the useful half. First factor whose answer differs from the policy: h·10⁻² on gyroid (4014 → 3932) and fbm_terrain (1758 → 1735) — the two multi-sheet/rough fields — and h·10⁻¹ on sphere, torus, csg_difference and thin_plate. box_exact never changes, even at h/2, because its geometry lives on lattice planes and its genuine neighbours are a whole cell apart. So the policy sits 100× below the nearest tolerance that changes any answer, and 1000× below on five of seven fields. That margin is why four different numbers coexisted for months without disagreeing — and exactly why they were dangerous: they agree until a field puts two real vertices 10⁻⁵·h apart, and then they stop agreeing silently |
| M-179 | A-014h's stated mechanism finds almost nothing, and the reason is a deliberate choice in the root finder. The ticket — and M-169 before it — says "a crossing at parameter 0 or 1 should be named by the grid point it lies on." Measured over every tetrahedron edge of every cell at 17³, across all seven fields: no root anywhere reports t == 0, and 36 report t == 1, all on gyroid, out of 52,488 roots. refine returns the upper end of its final bracket by design, so it can keep the ascending-and-distinct contract when a root sits on a sample — which means a root at an edge's lower endpoint comes back as a tiny positive parameter and never as zero. The position behaves asymmetrically too, and that was not predicted either: a + (b − a)·t never rounds back onto corners[a] on any field, while it lands exactly on corners[b] 1,692 times on box_exact, 1,284 on csg_difference, 112 on thin_plate, 36 on gyroid and 18 on sphere |
A-014h, no_root_reports_parameter_zero_and_almost_none_reports_one. The two endpoints were assumed to behave alike; only one does. A t == 0.0 \|\| t == 1.0 test would have been written, passed its own unit test, and moved nothing |
| M-180 | The population M-169 named as one defect is two, and only the smaller one is an identity problem — so A-014h cannot reach its stated acceptance. M-169 measured that a positional weld removes vertices identity-based sharing could not, and concluded the fix was a second keying rule. That assumes the copies are the same point. Counting raw vertices, raw vertices distinct by bit pattern, and vertices after the weld: box_exact 1262 → 1028 → 338, csg_difference 1280 → 1094 → 482, sphere 830 → 830 → 812, thin_plate 450 → 444 → 422, gyroid 4020 → 4014 → 4014, torus and fbm_terrain unchanged throughout. The middle column is the ceiling on any rule that leaves positions where the extractor put them, and on box_exact it is 1028 against the weld's 338: an exact rule can remove 234 of the 924 duplicates, and 690 are positions IEEE calls different numbers |
A-014h, how_much_of_the_positional_weld_an_exact_identity_could_ever_reach. Two tetrahedra reach one grid point along different edges and a + (b − a)·t rounds differently on each, so merging them is not naming a shared vertex, it is moving two distinct ones together. The split runs by field and is not uniform: gyroid's 6 merges are entirely exact, so an identity closes it completely; sphere's 18 are entirely inexact, so an identity closes none of it. Same symptom, opposite causes. What A-014h now has to decide is whether the extractor may canonicalise an endpoint root onto the grid point's own position — a geometry change of a few ulps, not a keying change |
| M-175 | Sorting by magnitude is not enough to make a sum permutation-invariant, and the comment that said it was had been wrong since ✗12. sort_by_magnitude's doc argued that "ties need no tie-break, since IEEE addition and multiplication are both commutative — only associativity fails — so two terms of equal magnitude give the same answer either way round." True of a + b against b + a; false of every longer sum, which is the only kind that occurs here. Witness, measured: smallest-magnitude-first, [1e-16, +1, −1] sums to 0 and [1e-16, −1, +1] to 1.11e-16. Both are correctly sorted by magnitude — the ±1 pair ties, so a stable insertion sort left their order to the order they arrived in, which in this crate is the axis or edge labelling that a lattice rotation permutes |
A-016, sorting_on_magnitude_alone_would_still_depend_on_the_arrival_order. Found by writing the padding test, not by reading the code — the first three attempts at the test all failed for this reason and were read as fixture bugs before the third one was traced. The fix is to compare the signed values on a tie (−c before +c), which makes the sequence a function of the multiset alone. Why the original claim survived ✗12's 9600 trials: dot_equivariant's terms are products of two components, and a signed permutation flips both signs inside each product, so its terms permute without negating and a tie group is always repeats of one value. The claim was true in the only place it had been tested |
| M-176 | Zero-padding a reduction is transparent, negative zero included — and the reason is the accumulator's seed, not the sort. A-016 reduces over twelve slots keyed by edge label with absent edges at R::ZERO, so the padding question is load-bearing: a twelve-slot reduction over three real terms must give the same bits as a three-slot one or every cell with fewer than twelve crossings would answer differently for nothing. It does. The one place an exception was predicted — every real term −0.0, where the padded form was expected to return +0.0 against an unpadded −0.0 — does not occur, because sum_equivariant seeds at R::ZERO and +0.0 + (−0.0) is +0.0 under round-to-nearest, so both return +0.0 |
A-016, negative_zero_survives_padding_because_the_accumulator_starts_positive. The predicted exception came from reasoning about the sorted sequence and forgetting the seed. Pinned in both directions rather than deleted, because the golden hash deliberately distinguishes signed zero and this is exactly the kind of claim that gets re-derived wrongly later |
| M-177 | Reordering cannot buy negation equivariance, and the obstruction is structural rather than a missing tie-break. A-016's brief was to make the QEF accumulation "a function of the set of terms". Permutation invariance is achievable and is delivered. φ(−S) = −φ(S) is not achievable by any ordering rule: a magnitude tie group holds m copies of −c and n of +c, negation swaps those counts, and no order that is a function of the multiset can map the group onto its own reverse unless m == n. Witness: [1e-16, +1, −1] sums to 1.11e-16, its negation to 0 |
A-016, negation_equivariance_is_not_achievable_by_ordering_and_here_is_the_witness. This bounds what ✗12's "bit-exact equivariance" can mean for a sum of components. A lattice rotation can negate a component, so a sum of positions or of normal-outer-product entries is not bit-exactly equivariant under the full octahedral group by this route — where the three-term dot product is, for M-175's reason. The property the extractors actually need and now have is the weaker, sufficient one: the vertex is a function of the crossings, not of the edge labels they arrived under. Anything stronger needs exact summation, not a better sort |
| M-178 | A-016 moved 34 of 168 golden rows, not the 42 predicted, and the 8 that held identify their own mechanism. All 21 dual-contouring rows and all 21 manifold rows were expected to shift, since both share the solve path. 17 of 21 did, twice over: 34 hashes changed, 0 vertex or triangle counts changed, and no algorithm outside those two was touched. The four that held are box_exact and thin_plate at 17³ and 33³ — the two axis-aligned fields at the two resolutions whose cell size is a binary fraction of the domain (16 and 32 cells; 25³'s 24 is not). On axis-aligned geometry at an exactly-representable spacing the crossing coordinates are exact, their sums are exact, and reordering cannot change a result that was never rounded — which is why the same two fields did move at 25³ |
A-016. This is M-94's fixture trap in its useful direction: the fields that are easiest to reason about are also the ones least able to detect a floating-point defect, and a suite that only used them would have reported this fix as a no-op |
| M-172 | A signed distance field's gradient is exactly zero on its medial axis, and for a slab the medial plane is precisely where you would aim. game_destruction fires charges at Vec3::new(u * 1.9, v * 1.5, 0.0) — z = 0 is the wall slab's mid-plane, equidistant from both faces — and BrushStack::gradient there returns [0.0, 0.0, 0.0], measured on two consecutive shots. On a third, off-centre shot it returned [0.17, 0.98, 0.00]: non-zero, and pointing along the wall rather than out of its face, because the nearest surface to that charge was the top edge |
E-204's z-fighting fix. "Which way is out of the solid" reads as the obvious use for a gradient and is wrong twice over here — it is undefined exactly where the geometry is symmetric, and where it is defined it names the nearest surface, which is not necessarily the one you meant. The general rule is that a gradient answers "where is the nearest surface", never "which way did the projectile go"; the second question needs a second piece of information, and in this case the camera already had it. ⚠ AMENDED 2026-08-17 — the medial-axis reading is retired (✗27, M-324). The measurement stands; the detector does not. The zeros are real and reproduce — 4,225 of 4,225 on an aligned slab — but they are the sampling arithmetic's, not the axis's: half a voxel of plane offset takes them to 0 while the field's ‖∇ρ‖ < 0.1 band moves 0.00%, and even a full-voxel re-alignment restores only 3,136, because the cancellation needs the plane at the coordinate origin. On the axis generally ‖∇ρ‖ = cos(θ/2), zero only for antipodal nearest points — a slab's mid-plane and nothing a player digs. Read ‖∇ρ‖ as a continuous stability score, never a boolean detector; do not build on this row's headline — quote ✗27 |
| M-173 | Two coincident surfaces are not a rendering bug to be biased away, they are a modelling statement — and the fix is to stop the geometry coinciding. game_destruction's fragment is solid ∩ charge and its crater is solid − charge, so the two share a surface exactly: the same sphere, extracted twice from two different fields. A fragment left at rest in the hole it came from renders as a chunk fused into the wall |
E-204. Velocity alone did not fix it, measured: some fragments leave at 9 m/s while others sit at the impact with a velocity of 0.004 and no response to gravity, on bodies whose mass is a healthy 1.19 and whose sleeping is disabled — so the cause is inside avian's solver and not somewhere the example can reach. What does fix it is spawning the fragment at the mouth of the crater rather than inside it: a fragment that fails to move then fails clear of the wall, which is the only place its faces are not coincident by construction. Depth bias would have been the wrong instrument — it would hide the overlap at one camera angle and not another, where moving the geometry removes the overlap at every angle |
| M-171 | A shipped example panicked on every run, and three siblings carried the same race unfired. game_terrain_stream dies with "Entity despawned: the entity with ID 404v0 is invalid; its index now has generation 1" — attach_meshes queues commands.entity(e).insert(Mesh3d…) for a chunk in the same frame the streamer queues commands.entity(e).despawn(), and whichever order the queue flushes, the insert can land on a dead entity |
Found while re-recording the README's GIFs, not by a test — nothing in CI opens a window, so no example is ever run. game_walk, game_showcase and game_capsule_walk have the identical pattern and had simply never streamed aggressively enough to hit it. Fixed with try_insert at all five sites. That is not a swallowed error and the distinction matters here: attaching a mesh to a chunk that no longer exists is vacuous, not degraded — there is no other thing it could correctly do — where a fallback would be picking a different, worse outcome for the same input. The gap this exposes is coverage, not the fix: 30 examples compile in CI and none of them runs, so a panic on frame 200 is invisible until a human launches it |
| M-174 | CI has been red on every push of the GPU series, and behind the one accepted failure three unrelated ones accumulated unseen — including the two that block the release itself. The test (ubuntu) job runs cargo test --workspace --all-targets and GitHub's ubuntu runners expose no GPU adapter, so every isomesh-gpu device test has panicked there since GPU-001 (headless.rs refuses software rasterisers by design — GPU-009, M-147 — so there is nothing to fall back to; macOS runners expose Metal and stayed green). With that job red as the norm, nobody saw: (1) the lint job's rule-2 gate grep -ril bevy crates/ matching 11 files — every one a comment, README or manifest note explaining the wgpu-follows-Bevy pin, zero dependencies (verified: non-comment .rs matches = 0, comment-stripped manifest matches = 0, resolved-graph bevy count = 0); (2) the msrv job failing because rust-version = "1.85" was never true once isomesh-gpu existed — wgpu/naga 29.0.3 and 29.0.4 both declare 1.87 (registry index), and the dev graph's wide/safe_arch (via parry3d) declare 1.89, while bevy_isomesh claimed 1.85 against Bevy 0.19's own 1.95; (3) a one-line rustdoc redundant explicit link in bevy_isomesh/src/mesh.rs. The publish job needs: [lint, test, bevy, msrv, package] and reports publish to crates.io: skipped on every run — four of its five gates red. This finding's first draft concluded that 0.0.3 and 0.0.4 were therefore never uploaded, and checking it against the registry falsified that outright: both are on crates.io (0.0.3 at 11:37:52Z, 0.0.4 at 12:17:57Z, 2026-08-14), uploaded by hand from the developer machine seconds after each push, and before the publish job existed at all — that job landed at d01756f, 12:22Z, after both. So the release process was never dead; it was manual, and the automation written to replace it has still never run once. That is the worse of the two states and much the harder to see, because versions appearing on crates.io is exactly the evidence you would use to conclude the pipeline worked |
Review of 2026-08-14, from gh run list (failures back through the whole visible GPU series) + --log-failed on run 31796991183, each cause reproduced locally; the upload claim re-checked against the crates.io API and gh run view --json jobs on 2026-08-14, which is what falsified it. Fixes in the same session: the ubuntu leg now tests the CPU crate (the one the cross-OS golden-hash claim is about) and macOS keeps the full workspace; rule 2's gate checks dependency positions and non-comment code instead of prose; rust-version = "1.89" verified by cargo +1.89 check --workspace --all-targets clean. The method failure is the interesting part: an accepted red is indistinguishable from a new red. GPU-009 accepted a coverage hole and left it expressed as a permanent failure, which converted CI from a signal into noise for the entire series |
| M-170 | A GPU adapter is a finite resource and the test harness was treating it as free: 67 tests opened 67 devices, and once another process held 5.4 GB of the card, request_adapter stopped answering partway through the run. Deterministic, not flaky — the same 11 tests failed on two consecutive runs, every one of them passes in isolation, and every failure is Error::NoAdapter |
Found while verifying 0.0.3 for release. The boundary is visible in the log: device tests pass up to #38 and every device test after it fails, while pure-CPU tests keep passing throughout. The crate's own no-software-fallback rule is what made this legible — a fallback adapter would have quietly run eleven tests on a CPU rasteriser and reported success. The fix is one shared device behind a OnceLock, and it is the more accurate harness rather than a workaround: this crate's API takes &wgpu::Device and never opens one, so nothing under test wants a fresh device; only Gpu::new itself does, and headless::tests still calls it directly because that is its subject. 67 passed in 0.85 s against 6.72 s before — 8× faster and green |
| M-168 | Giving a crossing an identity instead of a position removes 5.01× of the subgrid extractor's vertices and changes no triangle at all. Across the 21 golden rows: 389,146 → 77,605 vertices, per-row 4.76× (fbm_terrain) to 5.08× (torus), and 0 of 168 golden rows changed a triangle count |
A-014g. The key is (the tet edge's two grid points, the root's ordinal). It works because TETS[t] orders corners by inclusion, offsets are the grid point minus the cell origin, and subtracting the same origin preserves the componentwise comparison — so the edge runs the same direction from whichever cell it is viewed, and FacePoint already counts index from the lower corner for exactly this reason. The point is not the vertex count. A vertex now has an identity rather than only a location, so a later stage can move one and every triangle standing on it moves too. Welding by position cannot do that — after the move the copies no longer coincide — and that is precisely the tearing M-101 measured twice and M-162 traced to 150 triangles in neighbouring cells |
| M-169 | Identity-based sharing is complete exactly when no root lands on a grid sample point, and the correlation is not approximate. Raw vertices → welded, with the count sitting on a lattice point: torus 912 → 912, 0 on lattice; fbm_terrain 1758 → 1758, 0; sphere 830 → 812, 24; gyroid 4020 → 4014, 7; thin_plate 450 → 422, 58; csg_difference 1280 → 482, 1087; box_exact 1262 → 338, and all 1262 are on a lattice point |
A-014g, how_complete_the_shared_table_is_against_a_positional_weld. The two fields where the weld finds nothing to do are exactly the two with nothing on a grid point, and the field where every vertex is on one loses 73%. The mechanism is that a root at a tetrahedron edge's endpoint sits on a grid point that up to 24 tet edges meet at, so it has one position and a different (edge, index) on each — one point wearing many names, which no correct sharing under this key can merge. That is a property of how the field sits on the grid, not of the algorithm: box_exact's faces are axis-aligned and land on sample planes, which is M-94's fixture trap showing up structurally rather than by accident. The remedy is still an identity and not a weld — a crossing at parameter 0 or 1 should be named by the grid point it lies on rather than by the edge it was found along — and it is named rather than done, because it is a second keying rule and belongs in its own commit |
| M-167 | Across the whole GPU series the arithmetic never moved and was never the point: synchronisation was 83% of an extraction and the payload 7%. Breaking the 0.454 ms extract_buffers at 129³: count pass 0.017 ms (3.7%), the four-byte read-back's own transfer 0.033 (7.3%), and the poll(Wait) around it 0.375 (82.6%) |
GPU-010a, GPU-012, GPU-011a, GPU-010b together. The cumulative figure is 15.01 ms → 0.54 ms, 28×, and count + emit — the actual Marching Cubes — was 0.11 ms at the start and 0.04 ms now. Every gain came from data movement or a stall removed: a CPU prefix sum and an 8.4 MB counts read-back (1.56×), a second pass over 8.4 MB during evaluation (1.18×), the entire upload (15.5×), and finally the wait itself. Attribution matters here and the obvious citation is the wrong one. V-10's atomics → LDS staging result is directionally the same thing. V-9 is not support for it — that is the compute-shader → mesh-shader 23.4× figure, and M-149 measured in this repo that the mesh-shader draw removes the smallest of the three movement costs, so quoting V-9 as confirmed here would contradict a correction this file already carries. The thesis stands on this series' own numbers |
| V-24 | Custodio §5.1's correction, verified from the paper and re-derived rather than transcribed. The swept saddle value is f(x_c(t)) = (A_t·C_t − B_t·D_t) / (A_t + C_t − B_t − D_t) = F(t)/Δ(t), with F quadratic in t and Δ linear. Chernyaev's test tracks F alone: "the polynomial F(t) … is a second order equation in t and thus can only allow for two sign changes. Therefore, the sign tracked by the MC33 algorithm will not match the expected one at some point" |
A-002c, 10.1016/j.cag.2013.04.004 §5.1, read this session. The quotient of a quadratic by a linear is a hyperbola, so where Δ has a root the saddle has a pole and the sign jumps across it — three sign changes on (0,1), which no quadratic can track. Their Figure 6 is a case 13.5.2 read as 13.5.1 for exactly this reason. The three coefficients were re-derived here before being compared — expanding A_t = A₀ + tα gives a = αγ − βδ, b = C₀α + A₀γ − D₀β − B₀δ, c = A₀C₀ − B₀D₀ — and they agree with the paper's term for term, which is how rule 5 is satisfied without transcribing a formula |
| V-25 | "Lewiner's reference implementation omits disambiguation for cases 10 and 12 entirely" is true of the code and false of the literature, and A-002b's row stated it as the latter. The paper's §5.4 calls it "a missing step in the implementation" and then gives the rule: 10.1.1 positive nodes separated on both faces and at the cube diagonals; 10.1.2 separated on both faces but not at the diagonals; 10.2 separated on top and connected on the bottom face | A-002c, same paper §5.4 and §6.4. §6.4 is explicit that the fix is a code change — "We fixed the MC33 implementation by adding the lines 16-20, which in the original implementation were replaced by the result case 10.1.1" — so what was missing was never the published disambiguation. This weakens A-002b's rule-5 stop from "no correct source exists" to "the source is prose and a figure rather than a table", which is a different and much smaller obstacle |
| V-26 | A follow-up exists that builds MC33's triangulation with no lookup table at all, and A-002b's blocker did not know about it. Custodio, Pesco & Silva, An extended triangulation to the Marching Cubes 33 algorithm, 10.1186/s13173-019-0086-6 (2019): vertices are labelled +/−/=, connected into groups of vertices and groups of edges, and each group's geometry is the boundary of a convex hull with the cube-face triangles removed |
A-002c, read this session. Three categories — simple leaves (discs), tunnel (cylinder), interior point (disc plus a cell-centre vertex) — with case 13.3, 13.5.1 and 13.5.2 given as named combinations of them. The authors state the consequence directly: "the triangulation is generated without the need of a look up table." So A-002b's "there is no correct published table to transcribe" is answered by a construction that needs no table, and the = label additionally removes the degenerate slivers Marching Cubes emits by construction. The same paper also confirms the non-manifold remedy is a grid change rather than a table change: split the two cells at the shared ambiguous face's critical point |
| M-165 | Among the configurations that can exhibit it, Chernyaev's numerator-only test is wrong 12.6% of the time — 1,966 of 15,625. Every one of the 15,625 has a pole inside the sweep, by construction | A-002c, how_often_the_correction_changes_the_answer. The family swept is face pairs opposed in sign — A/C positive on the low face and negative on the high one — which is the structure Appendix A's counterexample has and the only one that can put Δ's root inside (0, 1), since Δ is linear and a linear function positive at both ends is positive throughout. This is not Custodio's rate and must not be quoted as one. They report once in 10,000 random 5×5×5 fields and six times across 50 isosurfaces of the Skull dataset; that is a rate over fields, and it is small because the opposed family is itself rare. Within the family the correction is not a rounding detail |
| V-29 | Two sources this repo recorded as unobtainable were obtainable, and one of them removes the largest single piece of A-002b. docs/research/2026-08-10-meshing-library-target.md:76-77 lists Grosso 2016 (10.1111/cgf.12975) and Grosso 2017 (10.1145/3095140.3095179) as PAYWALL. Both are in home-still, converted and indexed — 10.1111_cgf.12975 (16 chunks) and 10.1145_3095140.3095179 (5 pages, 11 chunks) — and have been since 2026-08-10, the same sweep that acquired the papers A-002c was built on |
A-002d, read this session. What the availability changes is the ticket, not just the citation. A-002b was sized around Custodio's non-manifold remedy, a grid preprocessing pass that splits both cells at a shared ambiguous face's critical point (V-26). Grosso §6 says outright that this is not the only route: "The algorithm proposed by Custodio et al. [CEPS13] … do not really solve the manifold problem for case 13. Instead, they split neighbor cells to avoid consistency problems across cells borders. Our method solves manifoldness across cells based on the asymptotic decider adding additional interior vertices." So the ticket's constraint (b) — "the non-manifold remedy is a grid change, not a table change" — is true of one route and false of the other, and the route that avoids it keeps unambiguous cells on the existing table path. The method rule is V-28's, one ticket later and still not learned: an acquisition status recorded once was trusted for four days without being re-checked against the library that had meanwhile acquired it |
| V-30 | Grosso's quadratic re-derived, and now agreeing three ways rather than two. The coefficients of a·u² + b·u + c, whose roots are where two opposite faces' hyperbolas meet, were expanded here from (i₀ − g₀)(g̃₁ − g̃₀) − (i₀ − g̃₀)(g₁ − g₀) before being compared with anything: a = (f₅−f₄)(f₀+f₃−f₁−f₂) − (f₁−f₀)(f₄+f₇−f₅−f₆), b = (i₀−f₀)(f₄+f₇−f₅−f₆) − (f₁−f₀)(f₆−f₄) − (i₀−f₄)(f₀+f₃−f₁−f₂) + (f₅−f₄)(f₂−f₀), c = (i₀−f₀)(f₆−f₄) − (i₀−f₄)(f₂−f₀). They agree term for term with the paper's eq. (4) and with the authors' own program, which writes them in a different but algebraically identical grouping |
A-002d, the_coefficients_reproduce_the_face_hyperbola_difference — worst disagreement against a direct evaluation 1.33e-15 over 20,000 cells. V-24 had a derivation agreeing with a paper; this has a derivation, a paper and an implementation. Also settled: Grosso's corner numbering is this crate's, v₀ = (0,0,0), v₁ = (1,0,0), v₂ = (0,1,0), v₄ = (0,0,1) … is exactly cube.rs's (i&1, (i>>1)&1, (i>>2)&1), so every formula transcribes with no permutation. That is a coincidence and not a design, so grosso_corner_numbering_is_ours pins it |
| V-31 | The reference implementation both Grosso papers cite has been deleted from GitHub, and it survives — the paper's own listing of the inner hexagon is corrupt, so recovering it was load-bearing rather than tidy. github.com/rogrosso/tmc 404s and the author's public repositories list only infovis. Software Heritage has a full snapshot: swh:1:snp:8b33006176ec6abd716a2f259933f4f14f42b46d, visited 2024-04-06, revision swh:1:rev:b2048b9081bb2a097fbbcabf500784afa726490d, from which mc/MarchingCubes.cpp (swh:1:cnt:b77a45b1f2be63e877521746be225e5903fc45df, 2,226 lines, MIT) reads out intact. The Wayback Machine has only the repository's root page — its subdirectory listings 404 — so it would have answered nothing |
A-002d. Three things the program settles that the prose does not. (a) The paper's own hexagon listing, in the copy this project holds, assigns p₁ and p₂ the same triple, which cannot be a ring; the program's order is (u₀,v₀,w₀), (u₀,v₀,w₁), (u₁,v₀,w₁), (u₁,v₁,w₁), (u₁,v₁,w₀), (u₀,v₁,w₀) — consecutive vertices differing in exactly one coordinate, verified here as a closed axis-parallel ring over 1,146 hexagons. (b) "Three quadratic equations" is one quadratic: "It is enough to compute a pair of solutions for one face. The other solutions are obtained by evaluating the equations for the common variable." (c) Tunnel-versus-twelve-vertex-contour is not decided by the asymptote-side predicate of Proposition 1 and Corollary 1, whose precise form the prose never pins down. The program does not evaluate one; it branches on the number of closed contours. BodySaddles::same_asymptote_side); measured against the contour count over 400,000 random cells it agrees exactly — false precisely when there is one contour, which is Corollary 1. So the program's shortcut is equivalent to Proposition 1, and following it was sound. What it is not is the whole tunnel test: Corollary 6's length bound is what excludes the [9,3] cells, and neither Proposition 1 nor the contour count sees them. The method note survives all three revisions: the prose was called unpinnable without the derivation being attempted, and one derivation settled in an afternoon what two amendments had guessed at. |
| V-32 | Two more rows of meshing-library-target.md marked PAYWALL are in the corpus, and the table's status code has now been wrong four times. Nielson 2003 On Marching Cubes (10.1109/tvcg.2003.1207437) and Lopes & Brodlie 2003 (10.1109/tvcg.2003.1175094) both answer to a corpus query and both were marked as having no open-access route |
A-020, checked while looking for a second source on the case-13 tunnel criterion. This is V-29's finding repeating: that entry corrected the two Grosso rows on 2026-08-14 after they had been indexed since 2026-08-10, and the same mistake was sitting two rows away. PAYWALL in that table records what the resolver could not reach, which is a statement about the tooling and reads as a statement about the library. The doc now says so in a callout above the legend, because correcting the individual rows is what was done last time and it did not stop the next pair. The method rule is V-28's, one level up: ask the artefact before believing the index that describes it — and if an index has misled you twice, fix the index rather than the entry |
| V-33 | A paper_download that reports success can return a landing page, and this is the third producer of that signature. 10.1142_s0218195912600060 (Attali, Lieutier & Salinas) reports downloaded and converts to French HAL UI chrome plus an abstract — no body. Purge and re-fetch from hal.science/hal-00785082/document, the direct PDF path |
noted during the Phase 8–15 backlog build-out. A second identifier to protect, and the failure mode is the opposite one: Dey, Edelsbrunner, Guha & Nekhayev, Topology preserving edge contraction (1999) — the primary source for the link condition R-001 rests on — has no DOI at all. Semantic Scholar carries it with doi: null; it is free at emis.de. Nothing may invent one. A fabricated DOI is worse than a missing one because it resolves to something, and the citation then looks checked. The method rule is V-28's, applied to acquisition rather than to archives: a tool reporting success is not evidence the artefact arrived — open it and look |
| M-206 | Two independently derived constructions locate the same body saddles, to 1.1e-12. interior::SweptFaces sweeps a plane between two opposite faces and solves a quadratic in the sweep height t for the heights at which the plane's bilinear saddle sits on the surface. trilinear::BodySaddles intersects the two faces' hyperbolas, solving a quadratic in the face coordinate u, and interpolates the other two coordinates linearly. They share no arithmetic, no coefficient and no parametrisation. Over 200,000 random cells, 1,076 reached the comparison and the worst gap between the two answers was 1.13e-12 |
A-002d, the_body_saddle_heights_agree_with_the_swept_saddle_roots. This relationship was not predicted; it was measured, and the reasoning that preceded it was wrong. The two were expected to differ, because a swept-plane saddle has ∂F/∂u = ∂F/∂v = 0 while a hexagon vertex is the crossing of two axis-parallel lines and so has a different pair of partials vanishing. They coincide anyway. Two supporting measurements from the same sweep: all 6,618 hexagon vertices lie on the level set to within 1.8e-13, which is Grosso's equation (5) checked rather than assumed; and over 200,000 cells relabelled by a cyclic axis permutation there are 0 disagreements about the saddle count, which is M-204's rotation property holding for a construction that is deliberately asymmetric in the axes. Six body saddles occur in 1,140 of 200,000 uniformly random cells (0.57%) — the population A-002e has to find a field to reach |
| M-207 | The reference implementation loses a root this one keeps, in two places, and both are the textbook quadratic formula. (−b ± √d)/2a divides by 2a, so where a is exactly zero the equation is linear with a real root −c/b and the formula returns infinities instead; and the reference guards with d > 0, so an exact tangency — a double root, one intersection point — is dropped rather than counted once |
A-002d, a_linear_equation_keeps_its_root and a_double_root_is_one_point_not_two. Both matter downstream rather than here: Grosso §5.3 selects a cell's interior vertex by counting face pairs with a single solution, a count the textbook form cannot produce. This module solves the linear case as a linear equation and reports a tangency as one point, not two — the second guarding against a degenerate zero-area "hexagon" claiming six saddles. Both fixtures are constructed, not searched, and the reason is the fixture trap in a new direction: a bisection onto a tangency lands near the crossing, where the discriminant is a small non-zero number and two nearly-equal roots is the correct answer, so a searched fixture would have tested the branch next to the one it names. Constructing the coefficients backwards out of exact binary fractions (a, b, c = 1, −1, ¼, double root at u = ½) makes the discriminant exactly +0.0. Also carried over from A-002c: Kahan's stable form rather than the textbook one, for the reason interior.rs already records — a is a difference of near-equal products with nothing keeping it away from zero |
| M-214 | The tunnel and the twelve-vertex contour are told apart by counting rings, and both are reachable: 2,053 and 173 in 396,877 random surface cells. Six body saddles mean a cell is one or the other and the saddles cannot say which (M-206). Grosso states an asymptote-side criterion for the split (Proposition 1, Corollary 1) whose precise predicate the prose never pins down; the authors' implementation does not evaluate one, branching on the number of closed contours instead, and so does this | A-002f, six_saddles_split_into_tunnels_and_twelve_vertex_contours, both branches asserted reachable so neither is dead code. 0.52% tunnels and 0.044% twelve-vertex contours, against Grosso's own 2,057 and 7 on a 512²×641 CT skull — the same order for tunnels and a ratio two orders apart for the rarer case, which is what uniformly random corner values buy over real data. Two exhaustive results alongside it, over all 256 cases × 64 masks (16,384 combinations). Every cut edge lies on exactly one closed ring and the rings follow the links at the wrap, so the walk is the link structure and not a re-derivation of it. And the ring lengths produced are exactly {3, 4, 5, 6, 7, 8, 9, 12} — the set the paper lists, with ten and eleven absent, which is the half worth noticing: an eleven-ring would leave one cut edge of a twelve-edge cell over, and the face walk's parity forbids it. At most 4 rings and longest 12, both pinned so an over-sized buffer is as visible as an under-sized one |
| M-215 | The u pair's two lines are crossed relative to the other two, and the inner hexagon is what proves it. A line joining one pair of opposite faces is fixed by the other two coordinates, and the obvious reading is that solution k contributes the line at (v[k], w[k]). That is right for the v and w pairs and wrong for u: reading the hexagon's ring — consecutive vertices differ in exactly one coordinate, so a pair differing only in u is a u-line — gives (v₀, w₁) and (v₁, w₀), indices 0,1 and 1,0 |
A-002g, the_line_inventory_agrees_with_the_inner_hexagon, checked over 1,083 hexagons against the ring rather than against any transcription. The authors' implementation agrees (fc3 = fs[1][0]*fs[2][1] + fs[1][1]*fs[2][0], crossed, against fc1 and fc2 uncrossed), and the disagreement with the obvious reading is what made it worth deriving — a copied crossed index looks like a typo to fix, and fixing it would have put the interior vertex off the surface in a third of cells |
| M-216 | The interior vertex is a transcription, and the check on it is geometric: 149,803 of them, every one on the level set to 6.7e-12. Grosso §5.3 says only "if there are only two such lines, the additional vertex is the intersection point. If there are three such lines, the additional inner vertex is the midpoint between the two saddle points" — which does not determine the four-line case at all, and does not say which of three lines' three pairwise intersections the "two saddle points" are. So the branch selection comes from the authors' program (V-31) | A-002g, the_interior_vertex_lies_on_the_level_set. A transcription cannot be checked by re-reading it, only by a property it must have: the point is a saddle of the trilinear interpolant, so it lies on the surface, and an index taken from the wrong axis lands it somewhere the interpolant is not zero. All three reachable branches fire — 99,777 two-line, 32,916 three-line, 17,110 four-line — and the five-and-six-line arm is separately asserted unreachable from the disk path over 397,666 cells, so its None is not a silent wrong answer |
| M-217 | The disk path costs no new budget: worst case 12 triangles and 1 interior vertex per cell, against MAX_TRIANGLES = 12 and MAX_CENTROIDS = 3 already in place. A ring of k fanned from an interior vertex costs k triangles against a vertex fan's k − 2, so the twelve-vertex ring goes 10 → 12 — which is exactly the bound A-015 already raised it to, for the same reason (a centroid fan emits one triangle per cycle edge) |
A-002g, the_worst_case_triangle_count_is_pinned, exhaustive over all 16,384 (case, mask) pairs. The ticket asked for the per-cell vertex bound at mod.rs:140-141 to be re-derived rather than reused, and the re-derivation is that §5.3 adds at most one cell-local vertex where A-015 budgeted three. u32 index-space check does not move for eitherMAX_CENTROIDS and MAX_TRIANGLES. The claim was made from the earlier paper without checking which one the construction being implemented came from |
| M-218 | The twelve-vertex contour needs a closing step the tunnel does not, and a manifoldness test found it rather than a reading of the paper. A tunnel is an annulus: its two contours pass the inner hexagon from opposite sides, so every hexagon edge is traversed twice and the patch closes itself. A twelve-vertex contour is a disk — one ring, circling the hexagon once — so it leaves the hexagon as a six-edge hole. Without a closure the cell emits a patch with a boundary no neighbour shares, which is a hole in the mesh | A-002h, found by the_tunnel_patch_is_manifold_inside_the_cell on its first run, not by reading §5.2 — which does say "at the end, vertices of the inner hexagon are merged into three inner vertices which generates the last triangle", and which I had implemented as far as the ring walk and no further. The winding cannot be fixed either: a twelve-vertex ring circles the hexagon in either direction depending on the configuration, so the closing fan's orientation is derived from the hexagon edges the ring walk actually laid. The first two attempts were a fixed winding in each direction and the directed-edge check rejected both. Measured: 2,297 tunnel and twelve-vertex patches, every one manifold and consistently wound inside the cell — each non-contour edge traversed exactly once in each direction, each contour edge exactly once, because its second face belongs to the neighbouring cell. That is the property Chernyaev's tunnel triangulation fails and the entire reason this route needs no grid subdivision. Costs, pinned: 22 triangles and 6 interior vertices worst case, both above the budgets A-015 set |
| M-219 | The reference implementation has a transcription-grade typo in the detached-ring test, and it is one line from six. Finding which of three contours is not part of a tunnel means comparing the ring's span in u against the interval between the two u roots. The reference computes that span with umax = (u_e2 > umax) ? u_e1 : umax — comparing the third vertex and then storing the second |
A-002h, 10.1111/cgf.12975's implementation, recovered per V-31. The other five lines of the same six-line block are written correctly, and a max that can return a value smaller than the one it just compared is not a max. Written correctly here. The point is not the typo but what it says about the method: this is the one file that settled three questions the papers left open (V-31), and it is also a file with a bug in it. Transcribing from a reference implementation and verifying by a geometric or topological property — as A-002g and A-002h both do — is the only combination that survives either source being wrong |
| M-220 | (refined by M-494 — it can, from continuous f64, wherever the field's mirror symmetry is the grid's: 72 singular faces on graph_theta_g2 and graph_k4_g3 at 17³, zero at 33³ and 65³) The singular face is an artifact of quantised data, and this crate cannot reach it: 0 of 1,838 on eight reference fields and 0 of 299,215 over 400,000 random cells. A face is singular when its bilinear saddle sits exactly on the level set — the two hyperbola branches degenerate into crossing straight lines, and the asymptotic decider's binary choice is between two answers that are both wrong because the surface passes through the saddle. Grosso 2017 exists for this case and Table 1 counts 8, 58 and 20 of them per 512²×~700 CT volume |
A-002i's reachability, measured before implementing it, how_often_a_face_is_singular. The difference is the data, not the code. A singular face needs v₀·v₂ and v₁·v₃ to be bit-identical f64s. CT voxels are quantised integers and collide into that readily; a continuous signed-distance field essentially never does. Two consequences. A-002b is not blocked by A-002i, which is how the series was originally sequenced: a case no reference field can produce cannot change any mesh the acceptance criteria measure, so it cannot be a prerequisite for them. And the case is still worth implementing eventually, because a consumer feeding quantised density — u8 voxels, the normal thing in a voxel game — reaches it immediately, which is exactly the audience this crate is for. The fixture will have to be constructed rather than sampled, as ✗22's was |
| M-221 | 0 × NaN is NaN, and it took the extractor to find that — not 400,000 random cells. The interior-vertex construction selects among candidate coordinates by multiplying each by a 0/1 flag and summing, which is a selection for finite values only. A coordinate the mask marks as out of range can be non-finite: the linear solve for v or w divides by a difference that vanishes wherever the interpolant does not vary along that axis. So a zero weight does not suppress it |
A-002b, found the first time extract ran the trilinear path, on noise_cavity at 17³ — mask 0b011010, giving [0.758, NaN, 0.347]. The reference dodges this and this crate deliberately did not: it substitutes −1 for every non-finite coordinate on creation, where BodySaddles documents the mask as the single authority on which numbers mean anything and stores whatever the arithmetic produced. Keeping that is right — a sentinel is a second representation of "absent" — but it makes the consumers responsible, and the selection has to be a branch rather than a product. Why 400,000 random cells missed it: the_interior_vertex_lies_on_the_level_set checks trilinear(f, p) ≈ 0, and a NaN coordinate makes that comparison false, so the assertion worst < 1e-9 never fired on it — NaN.max(x) returns x. A test that tracks a maximum cannot see a NaN; the extractor's debug assertion could |
| M-222 | χ falls by exactly two per tunnel and by nothing else — the interior rule's topology change is arithmetic, not approximate. A tunnel is a handle and a handle costs a closed surface exactly two. Everything else the rule does is topology-neutral by construction: giving an ambiguous contour an interior vertex and fanning from it adds one vertex, three edges and two faces, and 1 − 3 + 2 = 0. Measured across all eight reference fields at three resolutions, against a tunnel count taken from the classifier rather than from the mesh: noise_cavity 17³ 3 tunnels χ 62 → 56; 25³ 4 tunnels 72 → 64; 33³ 2 tunnels 10 → 6, and χ unchanged on all seven other fields |
A-002b, chi_falls_by_two_for_every_tunnel_and_by_nothing_else. The 33³ row is what makes this a test rather than a tautology. That resolution has four six-saddle cells but only two tunnels: the other two are twelve-vertex contours, which have the same six saddles and are disks, not handles. A rule that treated all six-saddle cells alike would miss by exactly four, and the identity catches it. Confirms A-002f's ring-count discriminator end to end, from a direction it was not built from |
| M-223 | The interior rule costs 1.95% at 33³ and 0.14% at 65³, on the only field that exercises it. noise_cavity, f32, median of criterion's samples, Ryzen 9 5900X / Linux: decider 2.8492 ms → 2.9048 ms at 33³ and 18.630 ms → 18.656 ms at 65³ |
A-002b, cargo bench --bench extract -- noise_cavity. The cost falls as the grid refines, which is the same relationship M-209 records from the other end: tunnels are an undersampling phenomenon, so a finer grid has proportionally fewer cells for the rule to do anything in — 3, 4, 4 six-saddle cells at 17/25/33 and none at all by 65³ on this field. The rule is confined to cells with an ambiguous face, so on the five reference fields that have none it is byte-identical to the decider, which the golden fixture pins: 15 of the 24 new rows share a hash with marching_cubes+decider and 9 differ, and the 9 are exactly gyroid, fbm_terrain and noise_cavity (M-40's two, plus the field added to reach the third case) |
| M-224 | Manifold Dual Contouring's non-manifoldness has nothing to do with tunnels, which is what A-017 assumed, and it survives the correct face rule. Three measurements on noise_cavity, each ruling out an explanation. (a) Not tunnels. Exactly one of the 30 offending edges at 17³ and one of the 64 at 33³ lies within 1.5h of a tunnel cell, while all of them lie within 1.5h of an ambiguous cell — the field has 193 and 502 ambiguous cells against 3 and 2 tunnels, so the correlation is with ambiguity in general at a rate of about 13–15% of ambiguous cells. (b) Not duplication. Every offending edge carries exactly four faces and four distinct triangles, uniformly — no threes, no fives, nothing emitted twice. Four distinct triangles on one edge is two sheets genuinely meeting, which is the opposite of ✗17's finding for Marching Cubes' fan chords, where the four faces were two cells each emitting the same triangle twice. (c) Not the face pairing. Under FaceAmbiguity::AsymptoticDecider the count falls from 30 to 8 at 17³ but does not reach zero — and the same setting introduces 3 offending edges on gyroid at 25³ where the default Separate gives none |
A-017, the_manifold_dual_contouring_defect_is_four_distinct_faces_on_one_edge, pinned in both directions. So A-017's own framing was wrong in both halves: it asked whether this is a defect in this crate's construction or the published guarantee not covering a cell whose interior the interpolant joins, and the answer is neither, because interior topology is not involved. What is left is the quad walk around a crossed grid edge. The gyroid row is the sharpest part — it means no face rule is uniformly better, so this cannot be fixed by choosing one |
| M-225 | A-017's mechanism, and the grid predicts the mesh defect exactly — 30, 64, 8 and 40, with zero error. An ambiguous face has all four of its edges cut. Manifold Dual Contouring places one vertex per cycle per cell, so when all four of those edges lie in one cycle in each of the two cells sharing the face, all four dual quads — one per crossed grid edge — connect the same pair of cell vertices. Four quads on one dual edge, and a quad gives exactly one of its two triangles to each side, which is the four distinct faces M-224 measured. The identity is non_manifold_edges == shared ambiguous faces whose four cut edges lie in one cycle on both sides, computed from the grid with no mesh involved against a count the validator takes from the mesh with no grid involved |
A-017, the_defect_count_is_predicted_from_the_grid_alone. Exact at 17³ and 33³ under both face rules: Separate 30 and 64, AsymptoticDecider 8 and 40. This is a limit of one-vertex-per-cycle rather than a defect in this transcription. Schaefer, Ju & Warren's argument separates sheets within a cell and nothing in it stops two different crossed edges of one shared face resolving to the same pair of cycles — which is only possible at all because an ambiguous face has four crossings rather than two. It also kills the obvious fix: the decider reduces the count without reaching zero and raises it on gyroid, so no choice of face rule makes the output manifold |
| M-226 | Subgrid Marching Tetrahedra's output does not need welding and is damaged by it — the doc had been telling consumers to do the harmful thing. The module said "vertices are emitted per tetrahedron and are not shared … before welding, the output is a triangle soup: every edge looks like a boundary edge", and told callers to weld before validating. That was true when M-93 and M-96 were written; A-014h ended it by giving every crossing a global identity, and the doc did not follow. Measured on all eight reference fields at 17³: the raw output already has boundary_edges == 0 on every closed field — it is a surface, not a soup — and the weld is a no-op on seven of them, identical vertex count and identical topology |
A-018. On noise_cavity it is worse than a no-op: it merges exactly one pair of vertices that are coincident by position and distinct by identity, fusing two sheets and taking non-manifold edges from 288 to 290 and vertices from 392 to 395. Sharing by identity is strictly finer than sharing by position, so once identity sharing is complete the coarser rule can only contribute mistakes. The general statement is the finding: a positional weld is not a way to make a mesh a surface, it is a way to join two surfaces, and applying it to output that is already shared trades correctness for nothing. The subgrid validity suite now judges the extractor's own output, which is both more honest and two edges kinder; the weld-specific tests keep welding, because measuring the weld is what they are for |
| M-227 | Orientation now reaches zero on every reference field at every resolution, and M-187's caveat was about the walk rather than the mesh. M-213 had found after <= before was not a law — noise_cavity went 1,580 → 2,422 at 25³. The cause is propagation crossing a four-face edge: with no well-defined neighbour there, the flood fill takes whichever it reaches first and carries a consistent winding across a patch that is consistent with the wrong side. Stopping at such an edge instead — one if neighbours.len() > 2 { continue; } — leaves each sheet to be seeded and oriented on its own evidence |
A-019, the flipped-edge census, now all zeros. The result is larger than the ticket asked for. It wanted the growth removed; what it got is the residue eliminated: csg_difference 6 → 0, torus 6 → 0, thin_plate 8 → 0, gyroid 138 → 0, fbm_terrain 19 → 0, noise_cavity 1,629 → 0 and 1,580 → 0. So M-187's second half was a property of the walk, not of the mesh. It said "no assignment of windings can make four faces pairwise oppose across one edge", which is true and does not imply a residue — that edge only contributes one if the walk visits it, and inconsistently_oriented_edges counts runs of exactly two faces, which a four-face edge is not. The non-manifold edges are still there and still counted as non-manifold; what has gone is the orientation damage they were causing elsewhere |
| M-228 | Grosso's tunnel triangulation has an undefined case, it is reachable, and 400,000 random cells could not reach it. The rule closes each contour edge by how many steps its two endpoints are apart around the inner hexagon — one triangle for zero, two for one, three for two. Three steps has no rule. The paper gives none and the authors' implementation has no branch for it: its switch runs case 0/1/2 with no default, so it silently emits nothing and leaves a hole |
A-002h's gap, found at E-213 while searching for a presentable demo configuration. The fixture trap, for the sixth time in this repository (M-32, M-38, M-44, G-003, M-204, here): the_tunnel_patch_is_manifold_inside_the_cell asserted the three-step count was zero over 2,297 tunnel patches and passed, because uniform random corner values never produce the shape. Where it lives: Marching Cubes' case 13 — the four alternating corners, the only case with all six faces ambiguous — at particular face resolutions, giving a tunnel whose two contours are nine and three vertices. That is also outside Grosso's Corollary 6, which says a tunnel's contours are at most six and three; the random sweep produces only [3,3] [3,4] [3,5] [3,6] [4,4] and [3,3,6], all compliant, which is why the corollary looked verified. The response is a refusal, not a repair. extract returns Error::UnresolvedTunnel rather than emitting the hole — inventing the missing triangulation is exactly what rule 5 forbids, and a hole reachable only on case 13 is the kind of defect that arrives in a consumer's collider before anyone notices. A-020 owns deriving it |
| M-229 | The contour-count discriminator misclassifies case 13, and the misclassified cells are exactly the ones with no triangulation rule. Contours::topology calls a six-saddle cell a tunnel when it has two or more contours — which is what the authors' implementation branches on, and what V-31 recorded as making Proposition 1's asymptote-side predicate unnecessary. Measured by flood-filling the cell's inside region on a 96³ grid and counting how many components its inside corners fall into, a computation sharing nothing with the classifier: a genuine tunnel joins its same-signed corners through the interior and lands in one component, and both shipped tunnel fixtures do. The [9,3] case-13 cells land in two — their inside region is two separate blobs, which is not a cylinder |
A-020, a_nine_and_three_cell_is_not_one_connected_tunnel. Grosso's Corollary 6 was right and was being read as a description rather than a test: it says a tunnel's contours are at most six and three, so a [9,3] cell is excluded from the tunnel case by the corollary itself, and the ring count admits it anyway. The two findings are one finding. M-228's undefined three-step edge and this misclassification occur on the same cells, and in that order: the cell is called a tunnel it is not, sent to a triangulation built for a cylinder, and that triangulation then meets a configuration it has no rule for. So A-020 is a classification problem first — which is cheap, and is where its ticket now says to start — and a triangulation problem only if some genuinely-tunnel cell also reaches three steps, which nothing has yet shown |
| M-208 | Interior ambiguity was unreachable by this crate's entire test suite: 0 of 68,385 reference-field surface cells have six body saddles. Swept over all seven reference fields at 17³, 33³ and 65³ with A-002d's classifier. sphere, box_exact and thin_plate reach zero saddles in every surface cell; torus and fbm_terrain top out at three; gyroid and csg_difference reach five, five times between them in the whole sweep. Six — the configuration that carries a tunnel or a twelve-vertex contour — never happens |
A-002e, how_often_the_reference_fields_reach_six_body_saddles. This is M-40 one level deeper and much stronger. That entry found the ambiguous face absent from five of seven fields; this finds the ambiguous cell absent from all seven. The consequence is what matters: every gate the A-002 series could have leaned on — the T-001 validity sweep, the golden fixture, the property suite — was structurally incapable of exercising the code the series exists to write, and a per-cell proof was all it could ever have got. Smooth analytic solids do not produce tunnels because they are too smooth: a tunnel needs the field to reverse twice across one cell, and a sphere never does. Both papers behind MC33's corrections used randomly generated scalar fields for precisely this reason |
| M-230 | Corollary 6 is the tunnel test; Proposition 1 is not, and the derivation that shows it also validates itself. Grosso's Proposition 1 splits tunnel from twelve-vertex contour by whether both roots of the quadratic lie at the same side of the corresponding asymptotes, which V-31 recorded as unpinnable prose. It is not: §3 gives the face bilinear the normal form G = α + η(s−s_c)(t−t_c) and names the asymptotes, and matching coefficients against a + (b−a)s + (c−a)t + (a+d−b−c)st gives η·s_c = a − c directly. Because a point on the hyperbola has η(s−s_c)(t−t_c) fixed and non-zero, one coordinate per face decides it, and the division-free form η·s − (a−c) needs no guard for an untwisted face |
A-020, the_asymptote_side_predicate_is_corollary_1, corollary_6s_length_bound_agrees_with_the_flood_fill, the_tunnel_contour_shapes_are_pinned. Three results, and the first is what makes the other two usable. (a) The derivation is right, graded by something that shares no arithmetic with it. Over 400,000 random cells the predicate is false exactly when the cell has one contour — zero disagreements — which is Corollary 1 stated the other way round. A derived predicate and a face-segment walk agreeing cell-for-cell is evidence in the shape V-30 established. (b) It is therefore not what A-020 needed. Every multi-contour shape passes it, the [9,3] cells included, so Proposition 1 admits exactly the cells Corollary 6 excludes and the plan that expected it to separate them was wrong. The fix is the corollary's length bound read contrapositively — a contour past six cannot belong to a tunnel — which is one comparison against the existing Contours::longest. (c) Half of Corollary 6 is false. It reads "one of the contours can have at most 6 vertices and the other 3 vertices"; the measured tunnel shapes are [3,3] [3,4] [3,5] [3,6] [4,4] and [3,3,6], and [4,4] has no three-vertex contour at all. Only the bound is used, and only as a necessary condition. The independent grade on the bound is M-229's flood fill, restricted to two-contour cells — a three-contour tunnel's detached ring caps its own corner group and so correctly gives two components, and a twelve-vertex contour gives one while being a disk, so the oracle is decisive nowhere else. On two-contour cells the bound and the flood fill agree on all 400 sampled. The three-step hole M-228 found is now unreachable from the tunnel path and its error is kept as a live guard rather than deleted, because "nothing has reached it" is a sample, not a proof |
| M-231 | The [9,3] cell is not a topological subcase; it is a singular face that the strict interior test lets through. A-020 classified a six-saddle cell with a contour past Corollary 6's bound as SeparateDisks and made extract refuse it, and A-020b was written to derive the triangulation it needs. There is nothing to derive. Measured over 2,000,000 random cells per sweep: continuous corner values produce zero such cells among 11,354 six-saddle ones, and every one that quantised values produce has a body saddle within 1e-12 of a cell face — 261 of 261 across quanta of 0.1, 0.25, 0.05 and 1/3. A saddle on a face is Grosso 2017 §4.2's singular configuration, which has_inner_hexagon's strict 0 < x < 1 test admits because the arithmetic misses the face by a few ulps |
A-020b, every_separate_disks_cell_has_a_saddle_on_a_face. The control is what makes it a finding rather than an observation about rounding. The same degeneracy among six-saddle cells that are not SeparateDisks runs at 8.0% at quantum 0.05 and 79.4% at 1/3 — it swings by an order of magnitude with the quantum while the SeparateDisks rate stays pinned at 100%. So the association is with this configuration, not with quantisation in general. Two things it costs. A-020b is blocked on A-002i and will most likely be closed by it. And A-002i's own reachability claim needs reading carefully: it measured 0 of 1,838 ambiguous faces singular on the reference fields by a bit-exact product comparison, which is true and narrower than it sounds — 86–100% of these cells have a bit-exact singular face and the rest are the same configuration a rounding away, so the exact test undercounts the phenomenon it is testing for. The method note is the fixture trap again, in its eighth appearance, and from the other direction: the shipped [9,3] fixtures were found by a search over rounded corner values, and rounding is precisely what creates the degeneracy. A fixture found by search carries the search's bias, and here the bias was the phenomenon |
| M-232 | (refined by M-494 — reachable from continuous data too, when the field is mirror-symmetric through a grid plane so a face's diagonal products tie to the bit: 72 on two of the six prescribed-genus fields at 17³) A singular face is unreachable from continuous data and routine from quantised data — and the rate at u8 density matches Grosso's CT counts. A-002i measured 0 of 1,838 ambiguous faces on the eight reference fields and 0 of 299,215 over 400,000 random cells, and read that as the case being rare. It is not rare; it is conditional, and the condition is the one this crate's audience meets. Quantise the same 400,000 random cells and the count goes to 6,658 at a quantum of 0.1 and 20 at 1/255 — u8 density — against 0 unquantised |
A-002i, a_singular_face_needs_quantised_data, and the pre-existing how_often_a_face_is_singular census is unchanged at 0 and 0 because it now calls the crate's own singular_face_mask rather than a copy of the predicate, so the two cannot drift. 20 per 400,000 cells is the number to compare: Grosso 2017 Table 1 counts 8, 58 and 20 singular faces per 512²×~700 CT volume (tier V), the same order, from data quantised the same way. The method note is the one M-208 earned, applied to a rate rather than a property: a count of zero is a statement about the sample, and the sample here was continuous f64 while the stated audience feeds integers. Nothing was wrong with the original measurement; it was narrower than the conclusion drawn from it |
| M-233 | A-002i's blocker is not the vertex cache, it is that a singular face needs a third routing and the resolution mask has two bits of room. The BLOCKED note said the work was "a new cache keyed on faces, not a branch in a decider". The cache half is right and is determined — Grosso 2017 §4.2 says "three saddle points will lie on a singular face, but only one will be shared with the neighbor cell", so one slot per grid face suffices, and a grid face is named by min-corner sample plus normal axis exactly as an edge is named by lower sample plus direction axis. The other half was missed. Definition 3.2 requires that a singular face not divide the surface into two branches, and on a singular ambiguous face all four edges are cut with the level set being the two crossing asymptotes — so the four cut edges must meet at the hyperbola centre, a four-valent junction. segment_links takes joined as one bit per face: exactly two routings exist, and both are permutations of the cut edges, asserted over all 384 (case, ambiguous face, bit) combinations with no exceptions |
A-002i, a_face_has_only_two_routings_so_a_singular_face_has_nowhere_to_go. So the blocker is representational and sits in Contours, which the whole trilinear path and A-002's 16,384-pair decider validation rest on — a larger and more delicate change than a second cache, and the reason the ticket's size is still wrong. A third obstacle is a rule-5 stop rather than work: §4.2's fewer-than-six-saddle arm is fully specified, but its six-saddle arm says "the other two points are slightly moved towards the interior of the cell" and gives no distance. The recovered reference is the 2016 code (V-31), whose singular handling is the face-pairing choice of the 2016 paper rather than §4.2's construction — verified by reading it — so no artefact supplies the constant. The method note: the ticket's blocker had been written from the symptom (two cells emit coincident vertices) rather than from the construction, and a blocker written from a symptom under-describes the work. Reading §4.2 and Definition 3.2 against the code took an hour and moved the ticket from M to something that needs splitting |
| M-234 | A-017 closed by decision rather than by code, and the limit is stated as an identity so it cannot rot. Manifold Dual Contouring's headline property — "the entry that takes the non-manifold count to zero" — was conditional on the seven original reference fields being unable to produce an interior ambiguity (M-208). The user chose option 1 of three on 2026-08-15: document the limit, keep the censuses, stop making the unqualified claim | A-017. Options 2 and 3 are recorded as rejected, not deferred: splitting the cycle needs a second vertex where Schaefer, Ju and Warren give one and stops being their algorithm, and taking the dual of the trilinear surface changes what A-010 claims. The documentation is placed where the claim was made, not in a notes file — the module header states the precondition beside the guarantee, the crate README's tradeoff row carries the exception, and A-010's archive row is amended. The method note is what makes this cheap rather than lossy: the limit is written as the identity non_manifold_edges == shared ambiguous faces whose four cut edges lie in one cycle on both sides, which is asserted grid-against-mesh with zero error under both face rules (30/64 and 8/40). A documented limit that is also an executable prediction fails loudly if it is ever wrong, which a paragraph of prose does not |
| M-235 | The example capture rig renders headlessly but cannot control its own window size, and it fails silently — which is the guarantee it was written to provide. examples/common/mod.rs's size_window reads ISOMESH_WINDOW=WIDTHxHEIGHT and its doc comment says it exists so "two captures of the same example" do not "come back different shapes". Measured on a bare X server with no window manager: 1280x720 and 1600x900 both produce exactly 836×1356, portrait, with no error logged |
E-214. The half that works is worth recording too: ISOMESH_SCREENSHOT produced a correct 264 KB still of marching_cubes_tunnel — HUD, contours, gold hexagon — because it goes through Bevy's own screenshot path and reads back from the GPU rather than scraping the root window. So the rig needs a compositor for geometry and not for rendering, which is the opposite of what one would guess, and it is why an Xvfb display fixes it while the whole thing already works over an unmapped window. The method note is the silent-default one: size_window returns early on a missing variable and logs on a malformed one, but has no branch for applied and ignored — the case that actually occurred. A setting that cannot verify it took effect is a setting that reports success when it did nothing. size_window merely ran in PreStartup, before bevy_winit creates the OS window, so the write landed on an entity and was overwritten. No compositor and no Xvfb were ever needed |
| M-236 | The shootout's header claimed the wrong counts for both of the things it was counting, and nothing could have caught it. benches/shootout.rs printed "seven reference fields, five algorithms" while the run enumerated eight and seven — noise_cavity landed at A-002e and the marching_cubes+decider row was added later, and neither edit reached the string |
X-001. This is the failure mode the ticket predicted, found in the ticket's own subject. X-001's premise was that hand-enumeration makes adding an algorithm an O(N) edit; the sharper cost is that the edit fails silently — a bench that measures seven algorithms while its header says five compiles, runs, and writes a CSV nobody doubts. Both counts now derive from the lists. The registry's order was checked against the committed evidence rather than assumed: docs/measurements/shootout.csv's algorithm column matches ALL_EXTRACTORS element for element, which is what says the conversion preserved the file that ✗14, M-19 through M-22 and O-11 all quote |
| M-237 | The QEF buys 2× accuracy on smooth fields and 100× on sharp ones, and pays for all of it in self-intersections — measured with one algorithm and one rule swapped. X-002's seam makes DualContouring generic over its VertexRule, so Qef and Centroid run through the same cell classification, quad walk, sign conventions and buffers. Symmetric Hausdorff at 65³, as a ratio of QEF to centroid: sphere 0.486, torus 0.457, csg_difference 0.255, box_exact 0.010, thin_plate 0.010 — a factor of two where the surface is smooth and a factor of a hundred where it has a feature, which is precisely what A-007 exists for. Self-intersections per 1,000 triangles at 33³: QEF 3.118 on gyroid, 13.837 on fbm_terrain, 29.745 on noise_cavity; centroid 0.000 on all three |
X-002, benches/ablation.rs, docs/measurements/ablation.csv. Both halves were pre-registered in the bench's own report before the run and both hold. The controlled part is what makes it a measurement of the rule. Vertex counts, triangle counts and non-manifold-edge counts are identical between the two arms on every field and resolution — gyroid 33/33 and 15/15 and 69/69, noise_cavity 131/131 and 297/297 and 322/322 — so the rule provably does not reach the topology. the_ablation_arms_differ_only_in_position pins the same thing behaviourally: 680 vertices, byte-identical index buffers, and all 680 positions different. A comparison between SurfaceNets and DualContouring cannot say this, because those are two structs with two extract methods and any difference between them is a difference between two implementations |
| M-238 | Probabilistic quadrics are this crate's existing solve with a different regularizer, and the derivation is the finding — X-004's premise that they supersede it is falsified. Trettner & Kobbelt (10.1111/cgf.13933) §3.1 gives the probabilistic plane quadric under Gaussian normal noise as A = Σnᵢnᵢᵀ + N·Σₙ, b = Σnᵢnᵢᵀqᵢ + Σₙ·Σqᵢ. This crate already solves in centroid-relative coordinates, so writing x = c + Δ and qᵢ = c + rᵢ with isotropic Σₙ = σ²I turns that system into (M + Nσ²I)Δ = Σnᵢdᵢ + σ²Σrᵢ — and Σrᵢ ≡ 0, because c is defined as the arithmetic mean of the qᵢ. The term the paper adds to b vanishes and what remains is solve_with at λ = Nσ² |
X-004, the_probabilistic_quadric_is_the_existing_solve. Checked numerically, not left as algebra: a direct assembly of the paper's equations in world coordinates, sharing no line with the crate's solve, agrees to 1.110e-16 over 296 cells. So no ProbabilisticQuadric solver was written — it would be a second execution path computing numbers the existing path already computes, which the one-path rule forbids. What shipped is the part that genuinely differs: the regularizer scales with the crossing count where Qef applies one fixed λ to every cell. Measured over all eight fields at 65³ (docs/measurements/ablation.csv): Hausdorff ratio of scaled to fixed is 1.0000 sphere, 0.9957 torus, 0.9992 csg_difference, 0.7519 box_exact, 0.7519 thin_plate — no worse anywhere, 25% better on both sharp-feature fields, and identical on both of them to four figures, which is itself unexplained. Self-intersections per 1k at 33³ fall too: gyroid 3.118 → 2.551, fbm_terrain 13.837 → 13.571, noise_cavity 29.745 → 28.749. The paper's headline does not apply here and that is worth saying: its selling point is robustness without an SVD, and this crate's solve never used one — it is a 3×3 adjugate (✗16). Its real novelty is anisotropic Σₙ, which needs a noise model that analytic fields with exact gradients do not have |
| M-239 | A window can resize itself without a window manager, and two obvious fixes both fail silently before the third works. E-214 was blocked on the belief that controlling window size needs a compositor (M-235). It does not. The fault was when the request was made | E-214, examples/common/mod.rs. Three attempts, and the first two are the instructive part. (1) PreStartup — the OS window does not exist yet, so the write lands on an entity and is overwritten by whatever the window comes back as: 1280x720 and 1600x900 both gave 836×1356. (2) Update, latching once the window reports the requested size back — also 836×1356, because Window::resolution reads back the value this system wrote rather than what the platform granted, so it latched on its own echo. (3) Update, re-applying across the first 30 frames, then stopping — 1280x720 → 1493×840 and 1600x900 → 1866×1050, both exactly the request at the display's 1.1666 scale factor, and 1493/840 is 16:9 to four figures. The method note is that a blocker is a hypothesis. M-235 recorded "needs a compositor for geometry" from two measurements that were both consistent with it and with the true cause, and the ticket sat blocked on a system package nobody needed to install. The cheap disproof — move the system and re-run — took one attempt |
| M-240 | The crate could subtract and intersect but not union, and nothing noticed because no reference field unions anything. Difference exists because csg_difference needs it and Intersection exists because Gyroid needs capping — every combinator in the crate was there because a fixture asked for it, so the most basic CSG operation was the one missing. Found by trying to write an authoring demo, which is the first thing that ever wanted to put two primitives together |
E-216. The fixture trap again, in its ninth appearance and from a new direction: the previous eight were properties that held because no fixture could falsify them (M-208's five at once, M-228's three-step edge, M-231's [9,3] cells). This is the same mechanism applied to API surface rather than to a claim — not a wrong belief but an absent capability, invisible for exactly as long as nothing exercised it. Union is also the safe direction and that is worth having written down: min of two 1-Lipschitz functions never overestimates distance, so a sphere tracer stepping by it can only under-step, where the max in Intersection and Difference overestimates near concave seams — the direction that lets a tracer step through a surface. That asymmetry is what Phase 11's F-001 gives a type |
| M-241 | Two demo GIFs were shipped that did not show what their captions claimed, and a single frame is not an inspection. Both were checked by reading one still and both passed that check while failing their purpose | E-214, E-216, raised by the user looking at them. marching_cubes_tunnel had no Mesh3d at all — every triangle was three gizmos.line calls, with a per-triangle normal tick added "so the two sides read as surfaces rather than as a cage of lines", which concedes the problem in a comment. Interactively it is a good diagram, because you can see through it to the hexagon and the contours; as a picture it fails, because the claim is about surfaces — two discs against one cylinder — and an outline shows no surface. Filled, the tunnel's hole is unmistakable. sdf_authoring never turned its own knob: 79 frames at a fixed k = 0.12, advertising a blend sweep it never performed, when Capture::taken is exposed specifically so a sweep runs in step with the capture. The method note is that a GIF has a failure mode a still cannot expose, and it is the one that matters: a recording of something that does not change is a recording of nothing. Check the first frame against the last, or check the parameter the caption names |
| M-242 | The shootout's 112 rows came back structurally identical after X-001 rewrote how it enumerates, which is the refactor's independent check. Converting benches/shootout.rs from a hand-written Algorithm enum to the for_each_extractor! registry touched every measurement the file produces. Re-run and compared row for row against the previously committed CSV: 112 rows, zero differences in vertices, triangles or non-manifold edges |
T-011. This is what the baseline is for and it earned its keep on the first run. A refactor of the code that drives the measurements is exactly the change golden hashes cannot see — T-007 pins meshes from the extractors, not from the bench — and "the diff looked mechanical" is not evidence. The regression gate's tolerances follow the same split: vertices, triangles and non-manifold edges are compared exactly, because they are deterministic and a tolerance there could only hide a real change; hausdorff gets 2% and self_intersections_per_1k 5% for cross-architecture float accumulation; median_ms gets 60%, which is a tripwire for a doubling rather than a benchmark. Baselines are per machine and the machine is in the filename, so a run on another host finds none and says so instead of comparing against numbers that never applied to it |
| M-243 | An unquoted heredoc executed the words in this script's own Python comments, and it failed silently for a value of "failed" that exits zero. scripts/regress.sh embeds Python in a <<PYEOF heredoc. Unquoted, bash expands the body — so a backtick in a docstring becomes command substitution, and a comment reading "it found no row with a median_ms" made bash run median_ms and print command not found on every invocation |
T-014, found while wiring provenance into baselines. The gate still passed. Command substitution failing does not fail the script; the noise went to stderr and the exit code was zero, so a CI step would have stayed green while printing an error on every run — the kind of thing that survives for months because it looks like someone else's warning. Fixed structurally rather than by escaping: the heredoc is quoted and the four values it needs come through the environment, which removes the whole class rather than the instance. The method note is that prose inside a heredoc is code, and this repository writes unusually long comments, so it is unusually exposed to it |
| M-244 | A declared Lipschitz constant was wrong on the first run, and the test that caught it was written in the same commit by the same person. F-001 replaced is_exact_distance() -> bool with a declared FieldBound, and the first draft gave noise_cavity Lipschitz { l: 2.598 }, reasoned loosely from Perlin noise's gradient bound. every_field_meets_the_bound_it_declares measured |∇f| reaching 7.734 and failed it immediately |
F-001. The defect is identical to the one the ticket existed to remove — csg_difference declaring true with // away from the seam beside it — reproduced by the person removing it, one screen away, in the same sitting. A declaration is not evidence about the thing declared, however careful the declarer. The gyroid's constant was guessed too and survived only by luck: √3 was declared, the sampled maximum came out 1.695, and the test passed. Deriving it properly gives |∂g/∂x| = |cos a cos b − sin c sin a| ≤ 2, hence |∇g| ≤ 2√3 ≈ 3.464 — twice the guess, and the guess would have been an under-declared bound, which is the dangerous direction: a sphere tracer dividing by a constant smaller than the true one steps through the surface. noise_cavity is now Unbounded rather than measured, because a sampled maximum is a lower bound on a supremum and declaring one as a Lipschitz constant would be unsound in exactly that direction. F-002 is where a real constant gets established |
| M-245 | The eikonal condition cannot tell a CSG underestimate from a true distance, which is why a bound needs two numbers rather than one. csg_difference is max(box, −sphere) and measures 100.0% eikonal — ‖∇f‖ within 5% of one on every sample — while its values are not distances near a concave seam. Away from the seam the active operand is an exact distance, so ‖∇f‖ = 1 there; the seam is a measure-zero set a grid essentially never lands on |
F-002, every_reference_field_meets_its_declared_bound. So |∇f| ≈ 1 is necessary and not sufficient, and the obvious single-number validator — check the field is eikonal — would have passed the exact field this whole phase exists because of. FieldBound carries l for how fast the field changes and q for how far its value is from the distance precisely because the first cannot detect a failure of the second. The census across all eight fields, sup ‖∇f‖ and eikonal fraction: sphere/torus/box_exact/thin_plate/csg_difference all 1.000 and 100%; gyroid 1.727, 67.0%; fbm_terrain 2.850, 11.7%; noise_cavity 7.748, 85.6%. Note noise_cavity's pairing — a high eikonal fraction and a gradient reaching 7.7 — which is a second way the fraction alone misleads |
| M-246 | min is not better than max; each is exact in one region and wrong in the other, by the same amount. F-003 predicted an asymmetry — that composing two exact fields with min "yields a declared bound F-002 confirms" while max yields "a strictly weaker one" — and asked for a test asserting it. Measured against closed-form ground truth on two overlapping unit-ish balls, over 64,000 sample points: union is exact outside (0.000e0) and wrong inside by 6.989e-1; intersection is exact inside (0.000e0) and wrong outside by 6.995e-1 |
F-003, min_and_max_are_both_inexact_and_the_asymmetry_is_by_region. A ratio of 0.999 — they are mirror images. The prediction was directionally wrong in an interesting way: there is an asymmetry and it is by region, not by operator. min gets the outside right because the nearest surface of a union is the nearest surface of one of its parts; max gets the inside right for the dual reason. Neither operator is better than the other; they are wrong about opposite halves of space. The test asserts the ratio stays within 0.5–2.0, so if one operator ever does become strictly weaker the prediction is revived rather than silently forgotten |
| M-247 | Repeated CSG destroys the worst case and leaves the typical case untouched, and a renderer barely notices what a precision bound calls ruin. F-004 asked how fast a field stops being a distance under repeated subtraction. Carving a box with N seeded random spheres and measuring the empirical underestimate ratio q̂ = |f| / d_ray over 13,824 points: worst case 0.5774 → 0.1815 → 0.0726 → 0.0040 at 0, 4, 32 and 256 strokes — 143× down — while the median stays at 1.0000 at every count, and mean sphere-tracing steps go 5.2 → 5.5 → 9.9 |
F-004, benches/csg_degradation.rs, docs/measurements/csg_degradation.csv. So "the field is no longer a distance" and "the field is no longer usable" are different questions with different answers: the precision bound is wrecked at a handful of strokes and the practical cost has not quite doubled at 256. A destructible game should watch the tracing cost, not the bound. The eikonal column is the control and it reads 100.0% at every stroke count — confirming M-245 operationally, and confirming that F-004's own proposal to sample ‖∇f‖ would have produced a flat line and concluded nothing degrades. One caveat is in the measurement rather than the field: q̂ uses a ray distance, and a ray from a box corner leaves along the diagonal, so an uncarved box reports q̂_min = 0.5774 ≈ 1/√3. That is this metric's floor, not a defect, and the curve is read against it |
| M-248 | One field evaluation replaces 576, and buys between 1.1× and 11.8× depending on how much of the volume the surface reaches. F-005 applies Hart's bound to subgrid Marching Tetrahedra: with Lipschitz constant l, a cell whose centre satisfies |f| > l·(√3/2)·h cannot contain the surface, so one sample settles what M-98 measured as 576 evaluations. At 33³ with 16 samples per edge, cost against Marching Cubes before → after: sphere 204× → 36.7×, torus 294× → 45.6×, box_exact 381× → 88.9×, csg_difference 400× → 91.4×, thin_plate 389× → 32.9×, gyroid 449× → 295× |
F-005, empty_cell_rejection_is_measured_per_field. The spread is the finding, and it is geometric. thin_plate gains 11.8× because a plate leaves almost all of its domain empty; gyroid gains 1.5× because a triply periodic surface reaches nearly every cell, and because its Lipschitz constant is 3.46 rather than 1, which inflates the rejection radius by the same factor and disqualifies cells a distance field would have rejected. So the optimisation pays in proportion to emptiness and is taxed by a loose constant — which is a second reason F-001's constants had to be derived rather than guessed, beyond soundness. Bit-identical output is the safety property and it is checked, not argued: a rejection test that is ever wrong produces a hole, and a hole is invisible to every validity gate — the mesh is simply missing a piece and remains perfectly manifold |
| M-249 | A directional Lipschitz bound buys exactly nothing on five of six fields, and 1.80× on the sixth — the null result F-006 asked for. Galin et al.'s segment tracing marches by a bound computed along the ray rather than over all directions. The paper states the condition for its own failure: "when the implicit objects have an almost uniform distribution of primitives and a uniform Lipschitz bound over their support Ω, the benefit is limited or negative in terms of speed." Five of this crate's fields are exactly that — sphere, torus, box_exact, csg_difference and thin_plate are 1-Lipschitz everywhere, so no directional bound can be smaller than 1 |
F-006, a_directional_bound_helps_only_where_the_global_one_is_loose. Measured, sphere-tracing steps global → directional: 228 → 228, 360 → 360, 108 → 108, 108 → 108, 148 → 148 — identical, asserted as equality rather than as a small difference. The gyroid is the one field that can gain, and its directional bound is derived rather than sampled: along a coordinate axis the directional derivative is a single partial, |∂g/∂x| ≤ 2, against the global |∇g| ≤ 2√3. Steps 2184 → 1213, a gain of 1.80× from a bound 1.73× tighter — slightly more than the ratio, because fewer steps also accumulate less conservatism. So the technique is worth exactly what the field's global bound is loose by, which for an analytic distance primitive is nothing, and this crate's tracing costs are dominated by fields whose constants are already tight |
| M-250 | Refining an edge crossing on the real field helps curved fields by 13–15% and does nothing at all for the CSG one — the reverse of F-007's prediction, and for a reason the ticket did not consider. The ticket argued that min/max kink the field along an edge crossing a seam, so linear interpolation misses the root, and set its acceptance as "csg_difference's Hausdorff improves". The reasoning about the kink is correct; the conclusion about the measurement is not |
F-007, refinement_helps_curved_fields_and_not_the_kinked_one. Measured at 33³ with 24 bisection steps, Hausdorff before → after: sphere 5.361e-3 → 4.561e-3 (0.851×), torus 1.379e-2 → 1.201e-2 (0.871×), box_exact 1.443e-1 → 1.443e-1 (1.000×), thin_plate 8.927e-2 → 8.927e-2 (1.000×), csg_difference 1.515e-1 → 1.515e-1 (1.001×). The mechanism: csg_difference is max(box, −sphere) and a box is planar, so its field is exactly linear along an axis-aligned edge and there is nothing for a root-finder to find. Its Hausdorff is dominated by the box's own edges and corners, which Marching Cubes cannot represent at any resolution — that is A-007's problem and no amount of refinement touches it. The fields that improve are the ones whose error genuinely is interpolation error: a sphere and a torus are curved, so f along an edge is a curve and a straight line through its endpoints really does miss. The method note is that "where the field is kinked" and "where the error is" were assumed to be the same place and are not — the ticket reasoned from the defect's mechanism to the metric without checking what the metric was measuring |
| M-251 | The exact distance transform agrees with brute force to the last bit, and is exactly one sample spacing from the analytic sphere — which is the sampling limit, not an error. Felzenszwalb & Huttenlocher's separable O(n) transform, checked two independent ways: against an O(n²) search sharing no line of code with it (1,287 samples, exact equality, not a tolerance), and against the closed-form sphere (worst 0.10000 against a spacing of 0.1 = 1.0000 cells) |
S-001, agrees_with_brute_force_exactly, matches_the_analytic_sphere_within_one_spacing. The two checks answer different questions and both are needed: brute force proves the algorithm computes what it intends — the lower-envelope pass is subtle and its failure mode is plausible numbers — and the analytic comparison proves the intent is a distance field. The one-cell gap is structural. The transform answers with the distance to the nearest opposite-signed sample, and the surface lies between samples, so a point whose nearest crossing falls mid-cell is off by up to a full spacing. Landing exactly on the bound rather than inside it is the expected result, and the test compares against 1 + ε for that reason rather than for slack. The grid is deliberately not a cube — 11×9×13 — because an axis transposition survives a cube and dies here |
| M-252 | Fast sweeping beats the exact transform everywhere, including where it was predicted to lose — because the seeding, not the solver, is where the accuracy is. S-002's docs asserted that sweeping "accumulates: a value ten cells away is the result of ten Godunov updates, each a first-order approximation", and would therefore lose at distance. Measured on a sphere at 41³ against the analytic field, worst error by band: within two cells of the surface, swept 0.0333 against the exact transform's 0.1000; beyond eight cells, swept 0.0933 against 0.1000 | S-002, sweeping_and_the_exact_transform_trade_places_with_distance. Sweeping wins by 3× near the surface and still wins, narrowly, far from it. The mechanism is the seed rather than the sweep: the exact transform answers with the distance to the nearest opposite-signed sample and is therefore quantised to the grid, floor one full spacing (M-251), while sweeping seeds from the interpolated crossing and starts sub-cell. A sphere's characteristics are radial straight lines, the eight-orthant sweep follows them, and that head start survives to the edge of the domain. The prediction was mine and was written into a doc comment as though established — the same failure M-244 and M-250 record, which is three times in one day that a stated expectation went into prose before a measurement went into a test. The assertion is now "does not lose", so a field that flips the ordering fails loudly rather than quietly vindicating the original claim |
| M-209 | The eighth reference field is searched, not designed — 97 of 610 candidates qualify, and the one taken is the gentlest rather than the richest. The criterion was three-fold and all of it measured: the meshed result must be closed at 17³, 25³ and 33³, it must reach six body saddles at all three rather than at a lucky one, and extraction must not trip the zero-gradient assertion. noise_cavity — one octave of gradient noise at frequency 3.45, iso 0.25, capped to a sphere of radius 1.5 over [-2, 2]³ — reaches 3, 4, 4 six-saddle cells and thins to zero by 65³ |
A-002e, the_tunnel_field_actually_contains_tunnels, pinned in both directions. 97 qualifying combinations is the important number: this is a plateau, not a knife edge, unlike the gyroid at high iso where the same search found the property appearing and vanishing between iso = 1.44 and 1.45. The gentlest was taken deliberately. Frequency 4.9 reaches four times as many six-saddle cells (4/13/16, still 3 at 65³) and roughly quadruples Subgrid Marching Tetrahedra's damage — 713 non-manifold and 5,803 flipped edges at 17³ against 3.45's 290 and 1,629. That extra is collateral from sampling noise near its feature size, not coverage of the interior rule, and the ticket asked for a field that reaches the configuration rather than one that maximises it. The undersampling is not a defect but the mechanism: Grosso reports refining a volume with 16 tunnels twice leaves one, and it reproduces here from the other direction |
| M-210 | The natural level set of gradient noise is its own lattice, which is degenerate — so a noise reference field may not use iso = 0. Perlin noise is exactly 0.000e0 at every point of its integer lattice, measured at six lattice points against 1.5e-1-ish just off it. The zero level set therefore contains the whole lattice, and the surface is pinned through a regular array of the noise's own critical points |
A-002e. The first version of noise_cavity used iso = 0 on the grounds that it was the field's own balanced surface and no constant would be doing hidden work — an argument that is aesthetically right and geometrically wrong. It tripped unit_gradient's zero-gradient assertion during extraction. Any non-zero level avoids the lattice entirely. The method note is that the reasoning was backwards: "zero is the least arbitrary choice" is a statement about the number, and what mattered was a property of the generator that one println! of six samples settled |
| M-211 | A-010's zero was conditional, and nobody knew on what: Manifold Dual Contouring is not manifold on a field with interior ambiguity. On noise_cavity it returns 30 non-manifold edges / 60 vertices at 17³ and 64 / 128 at 33³, where all seven original fields give zero at every resolution. Its Euler characteristic parts company with Marching Cubes' too — −30 against −96 at 17³ — which is the sharper half, because χ agreement was P-5, pre-registered before A-010 ran |
A-002e, pinned as MDC_NON_MANIFOLD_CENSUS and MDC_CHI_CENSUS, owned by A-017. Note the exact factor of two in every row: each offending edge carries exactly two offending vertices, its own endpoints, so the defect is a property of edges and the vertex count is a corollary. Why P-5 was always going to fail here rather than merely happening to: the dual identity V' = F, E' = E, F' = V needs the two methods to be describing the same surface, and on a cell whose interior is ambiguous they are not — Marching Cubes separates a tunnel that the trilinear interpolant joins. The prediction was sound and its precondition was invisible while no field could reach the configuration (M-208) |
| M-212 | Welding two coincident vertices can create a non-manifold edge, which a test comment had asserted was impossible. subgrid/extract/tests.rs reasoned that "sharing by identity is a subset of sharing by position, so every counter must be at least as good after welding as before". True of the sharing, false of the counters: merging two vertices that are geometrically coincident and topologically distinct fuses two sheets, which is exactly the pinch A-010 exists to avoid. On noise_cavity it costs one merged pair — 5,567 → 5,566 — and that pair adds 2 non-manifold edges and 3 non-manifold vertices |
A-002e, owned by A-018. One pair explains three separate failures, which is how it was identified as one mechanism rather than three: the over-merge itself; P-7 limb (a)'s weld plateau, [5567, 5567, 5566] across the four tolerances T-009 merged; and A-014h's completeness claim, where the exact identity rule removes 0 of the weld's 1. That last one is the confirmation rather than a fourth problem — the exact rule leaves the pair alone correctly, because they are different crossings, so the disagreement points at the weld and not at the identity rule. The margin is inverted, not small: the pair merges at exactly the 1e-4 policy and stays separate at every finer tolerance, so the usual "how far to the nearest disagreement" ratio comes out below one. A relaxed floor would have reported a direct hit as a near miss |
| M-213 | Orientation can raise the flipped-edge count, and after <= before was not a law. Propagation was expected to only ever agree edges it reaches, so the residue could shrink but not grow. On noise_cavity it shrinks at 17³ (1,629 → 1,015) and grows at 25³ (1,580 → 2,422) and 33³ (1,477 → 3,341) |
A-002e, pinned in the flipped-edge census, owned by A-019. The mechanism is the same four-face edge M-187 already names as the residue's cause, reached often enough to change what propagation does rather than merely what it cannot fix: with 318 non-manifold edges the flood fill crosses one, commits to one side's winding, and carries a consistent orientation across a whole patch that is consistent with the wrong neighbour. Nothing is more wrong afterwards — a different and larger set of edges is now the one that disagrees. M-187's law survives exactly where it was stated (zero non-manifold edges ⟹ zero residue); what fails is the monotonicity that had been assumed alongside it and never separately tested |
| M-166 | The interior test does not inherit ambiguity's crack-freeness argument, and the reason is one operator. The face decider reduces to comparing two products, and IEEE multiplication is The face decider reduces to comparing two products, and IEEE multiplication is commutative, so two cells reading a shared face in rotated order get bit-identical answers. The interior test's denominator is ((A + C) − B) − D — a fixed subtraction order that a rotation permutes — and floating-point addition is not associative |
A-002c, found while writing the_test_is_deterministic_and_independent_of_diagonal_order, which originally asserted bit-identical agreement and could not justify it. So two cells meeting on a face could evaluate the same sweep to different bits and disagree about a tunnel. M-32's caveat in a second place: equal by algebra is not equal by IEEE, and only the same expression is safe. The test now asserts agreement to a tolerance and says why; establishing the exact-agreement property is A-002b's, before any of this is wired into an extractor |
| ✗22 | Appendix A's counterexample could not be recovered from the converted PDF, and fitting the numbers until they matched would have been rule 5's exact failure. The OCR lists eight (_0, _1) value pairs with their letters scrambled, and no grouping of them reproduces the paper's own c = A₀C₀ − B₀D₀ = 0.1701 |
A-002c. Two candidate groupings give 0.0417 and 0.0598; a third that lands within 0.0002 requires reading D₀ = −0.1075 where the text says D₀ = −0.1692. That last one is the trap — it is close enough to feel like a win and is arrived at by searching for the answer, which is precisely how a wrong case table gets into a repository. The fixture used instead is derived: lo = [0.1, −2, 10, −2], hi = [−10, 2, −0.1, 2], both faces ambiguous, F convex and negative at both ends so negative throughout, Δ running +14.1 → −14.1. It has the same sign structure as Appendix A's — which is itself corroboration, since that structure was not chosen to match but fell out of requiring a pole |
| M-161 | §3.2.3's immersion is real, measured on five of seven fields — and it is not the defect. Coincident polygons, counted by exact position over the unwelded soup with every triangle traced to the tetrahedron that emitted it: box_exact 30, csg_difference 33, thin_plate 4, fbm_terrain 4, gyroid 1; sphere and torus none |
A-014d's unblocking measurement, which_polygons_coincide_across_a_shared_face. box_exact carries the most coincidence of any field and validates (0, 0, 0). If duplication were the defect those two columns would track each other and they invert. Two further contradictions of the section as this repo restated it: every coincident pair is wound the same way, not oppositely — A-014e imposes winding from the gradient at the triangle's centroid, and two coincident triangles share a centroid, so the pair survives the weld as a doubled face rather than as the two sides of a sheet — and three pairs on box_exact, three on csg_difference and two on fbm_terrain come from tetrahedra that do not share a face at all, which §3.2.3's framing ("two adjacent tetrahedra sharing a face f") does not cover |
| M-162 | A-014d's blocking question is answered, and the answer is no: the inset needs neighbour information, and the neighbours are not all in this cell. Of csg_difference's 33 coincident polygons, 27 have other tetrahedra standing on their boundary edges — 312 triangles in total, up to 12 on a single polygon — and 150 of those 312 (48%) belong to a different cell. box_exact: 348 foreign users, 168 cross-cell, the same 48% |
A-014d, same instrument. §3.2.3 moves the midpoints of polygon edges lying in an edge of the shared face; every triangle standing on those edges must move with it or the disk detaches, which is precisely what M-101's two reverted attempts measured. So the condition is not expressible per tetrahedron — and a per-cell rewrite would not reach it either, because half the affected triangles are in another cell. That makes the inset an architectural change to the extractor, on a number rather than on the suspicion the ticket recorded. Two fields escape: thin_plate's 4 pairs and fbm_terrain's 4 have zero foreign edge users, so those could be inset locally — the obstruction is not universal, which is worse than if it were, since a rule that works on some fields and tears on others is the failure mode this repo's one-path rule exists to prevent |
| M-163 | csg_difference's three surviving non-manifold edges are each 4 faces but only 3 distinct polygons, from exactly 2 tetrahedra in one cell. ([11, 11, 7], tets 4 & 5), ([11, 7, 11], 2 & 3), ([7, 11, 11], 0 & 1) — the three symmetric images of one feature. The soup carries 6 bad edges; the 3 that are duplication-only do not survive the weld and the 3 with three distinct polygons do |
A-014d, the_surviving_non_manifold_edges_are_not_duplicated_polygons, matched by exact position from the welded mesh's validate_features back to the soup. This is the one row where §3.2.3 is the right remedy: removing the duplicated pair from such an edge leaves exactly 2 faces, which is manifold. It is also the row that shows deduplication would not be enough — dropping one copy leaves 3 faces and the edge is still bad. The two tetrahedra being siblings in one cell is what makes it look locally fixable; M-162 is why it is not |
| M-164 | gyroid's 138 inconsistently-oriented edges are not A-014d's, and the ticket's stated mechanism reaches 8% of them. 186 triangles stand on those edges: 0 zero-area, 15 with the gradient lying in the triangle's own plane, 171 with a decisive vote |
A-014d, what_gyroids_flipped_edges_are_standing_on. The ticket claims insetting "gives those polygons area and a normal transverse to the gradient, which fixes both symptoms at once." The first half is real — those 15 have no answer to A-014e's dot(face_normal, gradient(centroid)) and a transverse normal would settle them. The other 171 have an unambiguous answer and disagree with their neighbour anyway: two triangles of one sheet, each correctly oriented against the gradient at its own centroid, wound opposite ways. That is A-014e's per-triangle vote having no consistency guarantee between neighbours, not §3.2.3's immersion, and no inset reaches it — gyroid has 1 coincident polygon in 8,088 triangles, so there is almost nothing there to inset. Moved to A-014f. (Zero-area reads 0 rather than the soup's 12 because the weld removes a triangle with a repeated vertex before the validator sees it) |
| M-159 | The last four bytes cost 0.033 ms to move and 0.375 ms to wait for — because poll(Wait) drains every dispatch queued before it, not just the copy. Breaking extract_buffers down at 129³: total 0.454 ms, count pass 0.017, scan-plus-four-byte-read-back 0.408 — while a bare four-byte read-back with nothing queued measures 0.033 ms |
GPU-010b's premise, checked before building it. So "remove the read-back" was the wrong framing and the ticket's own wording invited it. The bytes are free; what costs is the synchronisation point, and what it waits for is the GPU doing work the caller asked for. Removing it does not delete that work — it stops the CPU standing still through it. Same discipline as GPU-012: the premise was checked and it turned out to be about something else |
| M-160 | A zero-synchronisation extraction makes CPU time independent of grid size: flat at ~0.17 ms from 33³ to 129³, where the synchronising path grows to 0.722 ms — 4.2× at the top and widening. Median of seven, warmed, same field and grid for both | GPU-010b. Measured: 33³ 0.170 → 0.167, 65³ 0.245 → 0.206, 129³ 0.722 → 0.171. The flatness is the result, not the ratio. extract_indirect never waits, so what remains is CPU recording — buffer creation, bind groups, submits — which does not depend on how many cells there are. The synchronising path's cost is the GPU's execution time surfaced at the first wait, so it tracks the workload. The GPU still does the work, and saying otherwise would be M-149's mistake again: a frame is no shorter, the CPU is simply free during it. That is worth little to a demo extracting one surface and a great deal to a caller meshing many chunks, where the stalls serialise what could overlap. What it costs is stated as a contract rather than hidden: without the total the geometry buffers are sized from a budget. Worst case would be MAX_TRIANGLES = 12 per cell — 906 MB per buffer at 129³, 1.8 GB for the pair, against a measured 38,456 triangles, a factor of 190×. So the budget is the caller's, a surface exceeding it is truncated, and IndirectGeometry::total holds the real count for a caller who chooses to check — the same shape as collider::readiness being a check the caller runs rather than a promise the extractor makes |
| M-139 | The wgpu pin holds, and the number it holds at is 29.0.4 rather than the 29.0.3 written down. CLAUDE.md requires wgpu to match Bevy 0.19 exactly, on the grounds that Cargo resolves two majors side by side with no resolution error. Checked rather than assumed, against the two independent lockfiles this repo keeps: the root workspace and bevy_isomesh both resolve wgpu 29.0.4 and wgpu-types 29.0.4 — the same patch in both, from "29.0.3" requirements that are caret ranges on both sides |
GPU-001. So the pin is doing its job and the documented version is one patch stale; the thing that matters is that the two agree, and they do. Five API details differ from what the architecture doc's era would suggest, all found by the compiler rather than by reading: PollType::Wait is a struct variant carrying submission_index and timeout, InstanceDescriptor has no Default (it has new_without_display_handle_from_env), Instance::new takes the descriptor by value, DeviceDescriptor gained a required experimental_features field, and Limits::max_storage_buffer_binding_size is u64 where an AdapterReport written from memory would type it u32 |
| M-140 | The GPU this repository's numbers will be measured on, and the two limits that bound a dispatch. headless::Gpu on the Ryzen 9 5900X box reports NVIDIA GeForce RTX 3090, Vulkan backend, DiscreteGpu, with max_storage_buffer_binding_size 2,147,483,644 bytes and max_compute_workgroups_per_dimension 65,535 |
GPU-001, cargo test -p isomesh-gpu -- --nocapture. The storage limit is the one GPU-004 has to size against: at 4 bytes per f32 sample it caps a single binding at 536,870,911 samples, about 812³ — so a 1024³ grid does not fit in one binding on this adapter and will need splitting, which is worth knowing before writing the dispatch rather than after. The adapter type is asserted, not merely printed: a test fails if device_type is Cpu, because force_fallback_adapter: false is a promise that a software rasteriser would silently break, and a lavapipe run reports timings orders of magnitude off while looking merely slow |
| M-137 | Paint that lives in the field does not move when the geometry under it is destroyed — drift is exactly 0.000000, not small — and the L²-nearest attribute transfer the research prices this feature on is not cheap here, it is unnecessary. docs/research/2026-08-11-novel-gameplay-opportunities.md:16 builds row 4 on "common subdivision + L²-nearest attribute transfer" (Integer Coordinates §3.8, §4.4), on the reasoning that the shared tet grid is the common refinement so the expensive half comes free. That machinery moves attributes from an old mesh to a new one and is needed exactly when the attributes live on the mesh. This crate's world is a base field plus an ordered edit log, so paint goes in the log and is a function of world position: a carve moves the surface, and the paint was never on the surface. Measured over a scripted run of 40 sprays and 2 carves, 320 recorded world points: drift 0.000000 on both carves, with 20 probes losing their surface entirely (320 → 308 → 300 still within a cell of solid) |
E-208, bevy_isomesh/examples/game_paint.rs. The control is the load-bearing half, and the first version of this measurement did not have one. The script originally sprayed a single colour, so overpainting red with red was indistinguishable from paint staying put and the instrument reported 0.000000 either way — a number that could not have come out otherwise. Cycling the palette makes it sensitive: 27 of 40 sprays now register non-zero drift, up to 0.886, and the two carves still read exactly zero. A transfer-based implementation could only ever report a tolerance; this reports an equality, and there is a core test asserting the same thing bit-for-bit in paint::tests |
| M-138 | The price of exact paint is that every sample walks the edit log, and it is sub-linear in practice: 2.33x the cost per chunk for 40x the log. Median milliseconds per re-meshed chunk over a scripted 42-step run, binned by how many edits were in the log at the time: 0.1375 (edits 1–10), 0.1748 (11–20), 0.2450 (21–30), 0.3200 (31–40) | E-208. Same shape as game_dig's measured 3.7x-for-7x on brushes alone (E-202), and the mechanism is the same — the walk is real cost and not the dominant one at these lengths. Two design choices keep it this cheap and both are asserted by test. PaintStack's Sdf::sample skips sprays without evaluating their shapes, so meshing a painted world costs one match arm more than meshing an unpainted one and not a field evaluation more — pinned by a test that a spray does not move the surface, bit-for-bit. And a log containing no sprays samples bit-identically to the equivalent BrushStack, because both fold through the same brush::apply; that test exists so the painted and unpainted paths cannot silently diverge, which is the failure rule 1 is actually about |
| M-135 | The contour is 29% of a usable mesh, not 54% — and the largest stage is the collider check at 45%. Seven reference fields at 33³ and 65³, f64, one process, median of seven timed runs after two warmups. Mean share per stage: contour 29.0%, weld 25.5%, collider 45.0%, normals 0.4%. The published comparison M-003 cites has contouring at 68 ms against halfedge construction at 58 ms — 54% — so this repository's own ratio is half that, and optimising the extractor alone can buy at most 1.41x on the whole job |
M-003, docs/measurements/stage_breakdown.csv. The normals stage is effectively free (0.4%), which matters because it is the one every extractor here already does for nothing: all seven reference fields override Sdf::gradient, so the AreaWeightedFaces pass measured is the cost a consumer pays only when their field has no analytic gradient — and even then it is noise. The collider figure needs one qualification and keeps its force after it: what is timed is collider::readiness, which validates, not a physics engine building its own structure. A shipping game may validate once rather than per chunk. But G-005 makes welded-manifold-correctly-wound the contract, and the cost of checking that contract is the single biggest line in the budget |
| M-136 | "What fraction is the contour" has no single answer — it is 13.1% to 74.3% across seven fields, and the variable is how expensive the field is to sample, not anything about the mesher. Ordered: sphere 13.1%, box_exact 15.1%, csg_difference 16.1%, torus 16.4%, gyroid 17.5% (all at 33³), rising through thin_plate 33.0% and 44.0% to fbm_terrain 65.2% and 74.3%. A 5.7x spread on the same extractor, the same post-passes and the same machine |
M-003. fbm_terrain is the outlier because fBm noise is expensive per sample, so its contour swamps the fixed post-processing, while a cheap analytic field leaves the post-passes dominant. Consequence for every optimisation decision here: the ratio is a property of the workload, so "is it worth optimising the contour" cannot be answered in general and must be answered per field. A game on procedural terrain is in fbm_terrain's regime and should optimise the extractor; one on authored CSG is in sphere's and should not. The share also rises with resolution on every field — the contour is O(n³) while the post-passes scale with triangle count, which is O(n²) |
| M-134 | M-21's negative intercept reproduces in direction on a second machine and a third of the range, and its magnitude is 40x smaller — so the sign is the finding and the value never was. Fitting t = a + b·n³ live over 17³–89³ on a Ryzen 9 5900X, median of three timings per point, eight independent runs: Surface Nets' a is negative in 7 of 8 (range −0.133 … +0.009), Marching Cubes positive in 7 of 8 (−0.020 … 0.155), Dual Contouring positive in 8 of 8 (0.042 … 0.171). Every value is under 0.18 ms in absolute value, against M-21's committed −3.13 ms for Surface Nets over a sweep reaching 256³ |
M-002. Both halves matter. M-62 concluded from the committed CSV that there is no meaningful fixed cost; this reaches the same conclusion from a different machine, a shorter range and a different timing method, which is as close to independent replication as this repository gets. And M-21's rule — "a physically impossible fitted parameter is the model telling you it is wrong" — survives being measured at 1/40th the magnitude, because what carries the meaning is the sign, not the number. r² inverts, which is worth knowing: over this short range Marching Cubes fits worst (0.909–0.996) and the dual methods best (0.9986–0.99997), the reverse of M-21's full-sweep ordering, because MC's timings are smaller and therefore noisier relative to themselves |
| M-132 | Subgrid Marching Tetrahedra does tile across a chunk boundary — 0 open edges in 20 configurations — and the 1 that said otherwise was a wrong bound in my own instrument. Two adjacent chunks, welded, counting boundary edges in the shared plane: 0 on both fields, and 0 across six field phases at three sampling resolutions each. The mechanism holds up in the source: TETS[t] is ordered by inclusion, so a tet edge always runs from the lower cube-corner index to the higher, which makes traversal a property of the grid. M-79's warning is about a different renumbering — it says a mesh renumbering vertices per tet would crack every shared face, and chunking renumbers per chunk while leaving the within-cell corner order untouched |
B-007. The phantom edge was the block's own z wall. A chunk here is 16 cells at 0.25 — 4.0 deep — and the exclusion list gave z an upper bound of 8.0, so that wall was never excluded and one of its edges landed in the seam plane. Tenth instance this session, and the second in the same helper: B-006 fixed this exclusion once already, for omitting y entirely, and left z's bound wrong in the same edit. Both hand-written versions were wrong in different ways, so the bounds are now derived from the layout and there is nothing left to write out |
| M-133 | The dual methods are not reliably seam-closing rather than reliably open, which is a weaker and more useful claim than the one first published. With the bounds corrected, surface_nets measures 5 on waves and 0 on blobs, and dual_contouring 4 and 1. So a gap depends on how a particular surface meets the seam, and either method can come out clean on a given field — what is missing is the guarantee, not the geometry on any one frame |
B-007. ChunkSeams::Gapped now says exactly that, because "leaves gaps at every chunk boundary" — which is what B-006 shipped — is falsified by its own second field, and a consumer reading it would have concluded the opposite of the truth on half their scenes |
| M-130 | On a concave edge Dual Contouring's advantage is 3.6x in the mean and only 1.56x in the worst case — nothing like the 101x E-104 measures on a convex corner. A block with a quarter-space subtracted leaves a reflex dihedral whose position is known in closed form; the cutter orbits so the edge sweeps the grid continuously, and the distance from the exact edge to the nearest vertex is measured every frame at 41³ over thousands of frames. Mean / worst, in cells: dual contouring 0.0798 / 0.3481, surface nets 0.2895 / 0.5426, marching cubes 0.3412 / 0.5528. So the sharp-feature method is decisively better typically and converges toward the others at the extreme | E-209. This is why the sweep matters. E-104 measured one static configuration and needed a rule about which resolutions to skip to defend it; a moving feature is unaligned almost everywhere and aligned occasionally, and reporting the worst over the sweep is the only way that occasional case gets counted. A single-position measurement of a sharp feature is a measurement of that position |
| M-131 | The cell clamp does not bind on a concave edge either, which extends M-28 rather than limiting it — and the prediction that it would was registered first and falsified. The hypothesis, written into E-209's HUD before the run: a convex corner's solution is interior to its own cell so the clamp never binds (M-28), while a reflex edge's solution "wants to sit outside" and would therefore be capped by it. Measured: clamped and unclamped Dual Contouring are identical on this fixture — mean 0.0798 against 0.0801, worst 0.3481 against 0.3481. The reasoning was wrong in a simple way: a reflex edge passing through a cell has its QEF solution inside that same cell, so there is nothing for the clamp to catch | E-209. What does cap the worst case is deliberately left unestablished. It coincides with the edge lying near a sample plane — E-104's alignment trap arriving continuously rather than at chosen resolutions — but this demo does not isolate it, and the HUD says so rather than asserting a mechanism it did not test |
| M-128 | The dual methods do not tile across chunk boundaries and Marching Cubes does — measured on two fields, after the defect shipped in a README GIF. Two adjacent chunks meshed independently and welded, 16 cells at 0.25, counting boundary edges lying in the shared plane and excluding the two-chunk block's own six walls. waves / blobs: marching_cubes 0 / 0, surface_nets 5 / 0, dual_contouring 4 / 1, subgrid(4) 0 / 0 (corrected at B-007 — the figures first published here were inflated by a wrong z bound, see M-132). The mechanism is the one-vertex-per-cell rule: Marching Cubes places vertices on grid edges, which two neighbouring chunks compute from identical corner values and therefore agree on exactly, while a dual method places one vertex per cell interior and a boundary quad needs the neighbour's vertex, which the chunk does not have |
E-210, found because the user looked at the hero GIF and said the gaps were broken. It shipped. The showcase was switched to DualContouring during an unrelated aliasing investigation and never switched back, so the README's lead image was a cracked world for one commit. Switching to MarchingCubes removed every slash. Consequence: IsomeshPlugin exposes Extractor::DualContouring and Extractor::SurfaceNets on a chunked VoxelVolume with no warning, and choosing either silently produces a cracked world — B-006. Every existing streaming demo uses Marching Cubes, which is why nothing had caught it |
| M-126 | BrushOp::commutes_with is sound and tight — on eight overlapping brushes it called all seven adjacent pairs correctly, with zero unsound and zero conservative answers. Audited by swapping every adjacent pair in an edit log, re-folding the world and comparing an FNV-1a hash over every position and index against what the predicate promised: 5 pairs said commute and the mesh was bit-identical (M-36's case), 2 said no and the mesh moved (M-37's case), 0 promised commutation and moved — the only genuinely wrong answer — and 0 refused a commutation that actually held. Undo/redo round-trips bit-identically over the same hash, and the check asserts the undone state differed so it cannot pass on a no-op |
E-207. The predicate answers on operations alone and cannot see shapes, which is where its conservatism lives. The first fixture moved each brush ~3 units against radii of ~1, so every pair was disjoint — and disjoint brushes commute whatever their ops are, so the two add/subtract boundaries came back conservative: commutes_with said no, the mesh was unchanged. This refines M-37 rather than contradicting it: order matters across an add/subtract boundary when the shapes overlap, and M-37's 40,320-ordering sweep was on overlapping brushes |
| M-127 | A fixture built to demonstrate that order matters reported 0 of 7 pairs where order mattered. E-207's first scripted sequence moved each brush's centre by roughly 3 units between ops while the radii were about 1, so consecutive brushes never touched and every add/subtract boundary commuted anyway. The audit was working perfectly and had nothing to find. Fixed by lowering the path frequencies until consecutive centres sit ~1.5 apart, inside the sum of the radii, at which point 2 of 7 pairs stop commuting | E-207. Eighth instance this session of a fixture that could not exhibit the property it was chosen for (M-107, M-112, M-113, M-115, M-117, M-119, M-120's control), and the second where the demo of a defect was the thing that could not show the defect. Part 5's rule — search for a fixture that exhibits the property rather than picking one that looks like it should — is now the most-cited rule in the file |
| M-124 | The amortized cost per frame is the number a game spends, and it tracks the budget to within one chunk across a 320x range of budgets. 288 chunks re-meshed under DirtySet::mesh_within_budget, budget swept from 25 us to 8 ms, 2,360 frames each. Chunks per frame 1.00, 1.02, 3.49, 15.15, 28.80, 96.02; mean cost per frame 0.085, 0.087, 0.251, 1.016, 1.905, 6.269 ms against budgets of 0.025, 0.05, 0.2, 1, 2 and 8 ms. Above a few chunks the mean lands within 5% under the budget asked for, which is the figure a frame actually pays and the one no paper reports — papers report throughput, and a game cannot spend throughput |
E-206. The control is what makes the flat line mean anything: the identical queue through mesh_dirty costs 20.62 ms in a single frame, missing a 16.7 ms frame outright, against a budgeted peak of 2.10 ms — a 9.8x lower peak for exactly the same total work. A budget does not make meshing cheaper; it decides which frame pays |
| M-125 | The never-livelock guarantee costs one chunk, exactly, and below one chunk's cost it degrades to precisely 1.00 chunks per frame rather than to zero. mesh_within_budget consults its predicate after each chunk, which its doc prices as "overshooting by at most one chunk". Measured: one chunk here is ~0.072 ms, and the worst overshoot past the budget is 0.157, 0.172, 0.123, 0.099, 0.117, 0.122 ms at budgets from 0.025 to 8 ms — bounded by one chunk's cost and flat across a 320x budget range, exactly as claimed. At a 25 us budget, a third of one chunk, the rate is 1.00 chunks per frame: never zero, never two |
E-206. Both halves of the doc's argument are now numbers rather than assertions. The guarantee is real, its price is one chunk, and the alternative it rejects — a queue that cannot progress while it grows — never happens even when the budget is a third of the smallest indivisible unit of work |
| M-123 | Aliasing on a composed field came from the field, not the extractor — and swapping Surface Nets for Dual Contouring is what proved it. Intersecting a terrain half-space with a thickened gyroid, max(p.y − height, |g| − t), staircases badly along the rim where the two surfaces cross. The obvious suspect is the extractor rounding a crease, so Surface Nets was replaced with Dual Contouring — the crate's sharp-feature method — and the artefact was unchanged, which rules the extractor out in one run. Two field-side fixes removed it: a smooth intersection (smooth_max(a, b) = −smooth_min(−a, −b), blend 0.7) rounds the knife edge to wider than a cell, and raising the shell from 0.55 to 0.85 takes the sheet from 2.2 cells to 3.4 cells thick |
E-210. This is M-72's aliasing arriving from the other direction. M-72 measured Marching Cubes disintegrating a feature near the sampling limit and read it as a property of the extractor; the same failure is reachable purely by composing two smooth fields into one whose interesting region is sub-cell. A hard max is not a smooth field, and nothing warns you: both operands are exact distance functions and the result is not. Rule of thumb this earns: a CSG intersection's rim is a feature, and it has to clear the sampling limit like any other |
| M-120 | Transvoxel's mirrored seam works, and it had never been run — E-107 only ever meshed the fine block on the low-x side. A camera flying out and back along an LOD ladder puts coarse blocks on both sides of itself, so half the seams are inset_boundary(face_bit(0, 1)) with transition cells sampled at the fine block's first x index instead of its last. Measured across a full out-and-back over 12 blocks at levels 0–2: 0 open edges on both sides at every position, with up to 2 seams below the camera and 2 above. The mirror is the classic place for an inside-out winding, which no manifold or Euler check can see — so this is the configuration most likely to have been silently wrong, and it is not |
E-205. Proven by a negative control rather than by the zero: with ISOMESH_TRANSITIONS=0 the same worlds report 71 open edges on the low side and 102–111 on the high side, so the counter demonstrably reads failure |
| M-121 | A level change moves the surface by up to 3.14 cells, which is the pop nobody measures. Meshing a block at both its old and its new level at the instant it switches, and taking the worst vertex-to-nearest-vertex distance, over a full flight of an LOD ladder: worst 3.136 cells, typically 0.6–1.6. A pop is not a defect — a coarser mesh genuinely is a different surface — but its size is what decides whether it can be hidden by a fade, a morph, or nothing at all, and no figure for it exists in the literature review | E-205. Method note: it is only measurable at the instant of the switch, because after it the old mesh is gone; the demo therefore extracts the block twice on that frame rather than storing every block at every level |
| M-122 | Re-extracting a whole LOD ladder on every level change costs 12–23 ms and hitches; re-extracting only the blocks that changed costs 4.6–12.4 ms and does not. Twelve blocks, one or two of them changing level at a time. Caching each block's un-inset extraction and rebuilding only the changed ones takes the same world from 12–23 ms to 4.6–12.4 ms, inside a 16.7 ms frame. Validation is a further 5–7 ms and is the demo's own instrument, not a cost a game pays on a level change — timed separately for exactly that reason | E-205. What must be cached is the extraction before inset_boundary: the taper mutates positions in place and which faces need it depends on the neighbours' levels, which move independently of the block's own |
| M-118 | B-003's async tests were a wall-clock race, not a plugin defect — and the number of iterations they ran was irrelevant to whether they passed. spawning_the_work_does_not_do_the_work spun 500 app.update() calls with no yield, completing them in ~20 ms against extractions needing ~49 ms, and drained 2 chunks of 12; it failed 8 runs of 8 in isolation and the suite failed 1–3 tests per run. The discriminating probe moved wall time while reducing iterations — one millisecond of sleep per pass — and it drained all 12 in 39 iterations and 42 ms. Twelve times fewer iterations, twice the wall clock, and it passed. IsomeshPlugin was correct throughout: the pool ran (2 chunks did complete), and apply_finished_meshes polls every task each frame rather than one |
B-005. Five tests carried the same defect, not four — the_subgrid_extractor_is_reachable_through_the_component failed rarely enough to be missed in the first survey and surfaced only under 20 consecutive runs. All now wait on a deadline rather than an iteration count. Verified 0 failures in 20 consecutive full-suite runs and 20 consecutive isolated runs, which is the acceptance and is also the only evidence that would have distinguished a fix from a coincidence |
| M-119 | The obvious repair would have gutted the assertion it was repairing, and the mutation test is what proves the replacement is real. The acceptance property compared spawn_cost * 4 < total, where total was the drain loop's wall time — so any fix that let the loop wait would pad total with sleep and make a main-thread implementation pass. In the probe, 39 ms of the 42 ms total was sleep. The denominator is now the measured cost of performing one extraction synchronously in the test, which removes the scheduler from the assertion entirely: the claim becomes "queuing twelve of these cost far less than doing one." Mutation-tested by moving the work onto the main thread — let built = extract_chunk(..); pool.spawn(async move { built }) — which fails with "the frame that queued twelve extractions took 149.18 ms, against 16.43 ms to perform ONE of them here" |
B-005. The reference extraction also carries its own negative control, asserting it produced triangles: a field that was free to sample would time no work and let the comparison pass for any implementation. This is the sixth instance this session of a measurement whose denominator was the wrong quantity (M-107, M-112, M-113, M-115, M-117) |
| M-116 | Runtime convex decomposition costs 241–272 ms per fragment, which is 14–22 whole frames — so correct destruction colliders are viable, but never synchronously. Measured on a Ryzen 9 5900X, avian3d 0.7's convex_decomposition_from_mesh over 23–24 fragments per target, each fragment meshed at 21³ from the intersection of the solid with the charge: wall 23 fragments, 211 convex parts, mean 240.7 ms, worst 323.7 ms; hollow shell 24 fragments, 305 parts, mean 271.8 ms, worst 369.0 ms; spiral 23 fragments, 224 parts, mean 249.0 ms, worst 362.6 ms. A 60 fps frame is 16.7 ms, so one fragment's decomposition is 14–22× the entire frame budget, and it falls on the frame the shot lands — the worst frame available |
E-204. The shape ranking is the predicted one, which is the useful part: the hollow shell — whose convex hull is a solid ball, so a hull collider fills the cavity that makes it a shell — needs the most pieces, 12.7 per fragment against the wall's 9.2 and the spiral's 9.7, and costs the most time. Zero fragments failed to get a collider on any of the three. Consequence: this belongs on a worker with the finished collider swapped in later, exactly as G-006's budget already treats meshing; a synchronous call is a 300 ms hitch per fragment. The README's "convex decomposition — not yet" is now a measured position rather than an unexamined one |
| M-117 | A metric that reports a defect can be measuring the absence of a floor. E-204's first run accused 15 of 23 working colliders of tunnelling. The demo counts fragments that fall below a plane as having gone through something — and the scene had no ground, so every fragment eventually fell past it and the HUD read "15 fragment(s) left the world — they fell through something". Adding a static floor takes it to 1 of 23 on the wall and 0 of 24 and 0 of 23 on the shell and spiral. The one survivor is a real tunnelling case and is reported as such | E-204. Fifth instance this session of the same shape (M-107, M-112's controls, M-113's grader, M-115's mismatched windows): a number that looked like a finding was a property of the fixture. The rule that catches it is the one already in Part 5 — require every non-zero to prove it could have been zero, which here means asking what the fragment was supposed to land on |
| M-115 | A moving body is stopped harder and more often by ordinary terrain than by a chunk join — the same shape as M-106's answer, from the test M-106 could not run. A dynamic capsule driven at 7 m/s along E-203's path across the same streamed fbm_terrain, measured over 66 s and 441 m of travel: 97.0% of commanded distance actually covered, and stalls — frames where the body advanced less than half what it was asked to — split 13 at a seam against 70 inside a chunk, with worst single-frame shortfall 0.809 at a seam against 1.000 inside. So the interior of a chunk both stalls a body five times as often and stops it completely at least once, while no seam ever did |
E-206b. This is E-203's comparison re-run with a body instead of a ray, and it lands the same way: M-106 measured a worst vertical step of 0.412 cells at a seam against 0.539 within a chunk, and the honest reading of both is the ratio, not either number. A fixed stall threshold would have been measuring the landscape. What is new is that it could fail differently. A ray hits or misses; it is never caught. A seam lip that reads as a 0.2-unit step is, to a capsule, either nothing or a wall depending on the capsule, its speed and its approach angle — and nothing in E-203 could have distinguished those. Two instrument bugs found on the way, both mine: commanded accumulated from frame zero while travelled accumulated only after settling, reporting 12.8% progress on a body walking perfectly well; and the body spawned at y = 24 so most of any short run was a measurement of gravity. Both are the same error — comparing two quantities gathered over different windows |
| M-114 | HermiteCell::from_corners is public and its contract is not: the corner order it requires lives in a private module, so no consumer can satisfy it without guessing. The signature takes corner_values: &[R; 8] "in this crate's corner order"; cube is declared mod cube; in lib.rs, so corner_offset, EDGE_CORNERS and CORNER_COUNT are all unreachable from outside. The layout is [c & 1, (c >> 1) & 1, (c >> 2) & 1] and is pinned by corner_offset_matches_the_bit_layout, but that test is internal too. A public function whose precondition can only be met by reading private source is an API defect, not a documentation gap |
E-114, which is the first consumer to call from_corners from outside the crate and therefore the first to hit it. Worked around rather than papered over: the example duplicates the layout and then verifies it at startup against the crate itself, by building a cell from a plane whose crossing position is known in closed form. The check is mutation-tested, and the obvious version of it does not work: swapping x and y in the duplicated corner_offset — the likeliest transcription slip — still produces four crossings, so a check that counted them would pass; it is caught only by the position, worst x error 7.5e-1. Fixing this properly means exporting the corner order, which is an API decision and is not E-114's to make |
| M-113 | M-112's two laws reproduce in the committed example, and its fitted constant does not survive — the accuracy figure depends on how the offset sits on the f32 lattice, not on ulp/h alone. M-112 offered worst \|f\|/h ≈ 1.4 · ulp/h from a standalone probe at decimal offsets. precision_f32_vs_f64 sweeps powers of two instead, and at ulp/h = 4 it measures 4.0000 where the probe's 6e6 — same ulp/h, same ulp = 0.5, different alignment — measured 5.8564. The two agree exactly wherever the offsets agree (ulp/h = 1 → 1.3808, 2 → 3.1010), so nothing is contradicted except the formula. The law that is exact is a different one: at a fixed offset, halving h exactly doubles the error measured in cells — 3.1010 → 6.2020, 4.0000 → 8.0000, 5.8564 → 11.7128 from 33³ to 65³. The absolute error is set by ulp(offset) alone, and expressing it in cells is the entire reason a finer grid looks worse |
E-112. Both of M-112's structural claims hold in the shipped code: 33³ and 65³ are clean at 2²² and torn at 2²³ (χ 2 → 1, 42 and 78 boundary edges), so the topology threshold is absolute; and the discriminating fixture reproduces — 65³ at ulp/h = 8 is clean while 33³ at ulp/h = 8 is torn. Method: the fitted constant came from four points that all happened to be decimal, and Part 5 already says the tidy formula is usually missing a constant. Here it was missing a variable |
| M-112 | E-112's premise is wrong by an order of magnitude, and the failure it names is really two failures with two different laws. The ticket says "same field at ~1e6 offsets; f32 cracks, f64 doesn't". Measured on a unit sphere translated to offset on every axis, dual contouring, 33³ and 65³ over a ±2 box: at 1e6 f32 does not crack. Topology is perfect — same 1,160 vertices and 2,316 triangles as f64, χ = 2, 0 non-manifold and 0 boundary edges — and only accuracy moves, worst radial error 0.0362 → 0.6603 cells. What actually breaks: (1) accuracy degrades in proportion to ulp(offset)/h, measured 0.66, 1.38, 3.10, 5.86 cells at ulp/h = 0.5, 1, 2, 4, i.e. ≈1.4·ulp/h — a relative law that depends on cell size; (2) topology breaks at an absolute threshold, offset ≥ 2²³ ≈ 8.39e6, where ulp(f32) ≥ 1.0 — χ drops 2 → 1, vertices collapse 1,160 → 271, and 54 boundary edges appear at 33³ (102 at 65³). f64 is untouched at every offset tried, 0.0362 cells at 1e7, identical to its reading at the origin |
E-112 research, before implementing. The two laws are independent, and that is the load-bearing part: 65³ at ulp/h = 8 (offset 6e6) is topologically clean, while 33³ at the same ulp/h = 8 (offset 1e7) cracks — so the crack cannot be predicted from ulp/h, and the accuracy loss cannot be predicted from the absolute offset. Two controls, both run before believing any of it. Is the crack in the mesh or in the validator? validate.rs quantises with as_f32() as iN and T-008 anchors that lattice to the mesh minimum, so the same f32 vertices were re-validated after moving them to the origin in f64 — reports are bit-identical, χ = 1 and 54 boundary edges either way, so the defect is in the mesh and T-008's anchoring is not the limit. Is it the fixture's gradient? Sdf::gradient's default is a central difference with a step scaled by \|p\|, and its own doc warns that a field whose characteristic length is far from 1 should override it — so the probe was re-run with an analytic sphere normal. Bit-identical again, at every offset, which rules the gradient out entirely |
| M-111 | bevy_isomesh's four async drain tests do not pass on Linux, and one of them never passes — B-003's acceptance property is currently unverified rather than verified. Measured 2026-08-13 at 4369e3c on a 12-core Ryzen 5900X under CachyOS, with no local changes to bevy_isomesh/src, so this is HEAD's behaviour and not a working-tree artefact. plugin::tests::spawning_the_work_does_not_do_the_work fails 8 of 8 runs in isolation, meshing 2 of 12 chunks across 500 app.update() calls; the whole test returns in ~20 ms, so the updates are not blocking and the spawned extractions simply never complete. Three consecutive full-suite runs gave 1, 3 and 2 failures out of the same four drain tests, so the other three are intermittent rather than sound |
Found while running the E-110 definition-of-done checks, which is the only reason it was run at all. Not caused by E-110 — that ticket adds one file under examples/, which the lib tests do not compile. What this contradicts: the previous session's handoff reported "14 plugin" tests green, and the count is right while the result is not; a suite that passes on one platform and fails on another is exactly the rule CI already earned once (libwayland-dev). The obvious suspect is unchecked: TaskPoolPlugin::default() sizes its pools from available parallelism and cargo test builds one App per test thread, so oversubscription would explain both the total failure in isolation and the intermittency in the suite — but it is a hypothesis, and B-005 owns settling it before anything is changed |
| M-108 | The prediction was registered before the sweep and came out half right, and the half that failed is the more interesting one: the clamped residue falls with resolution on gyroid and does not move at all on fbm_terrain. Clamped dual contouring, pairs per 1,000 triangles, at 17³→49³ in steps of 4. gyroid: 7.14, 3.02, 7.14, 2.70, 3.12, 5.26, 0.72, 0.76, 1.12 — a 6.4× fall end to end, non-monotone in the middle. fbm_terrain: 25.40, 20.20, 9.82, 24.01, 13.84, 19.03, 21.87, 17.46, 20.43 — 25.40 at the coarsest and 20.43 at the finest, wandering without direction in between. The registered prediction was that both would fall, reasoning from M-29 (the residue is multi-sheet cells) plus M-15 (multi-sheet is a resolution effect, not a topological one) |
E-110, examples/qef_clamp.rs module header, which states the prediction and the falsification condition before the numbers. M-15's mechanism survives; the prediction was too broad. M-15 says "any feature thinner than one cell forces two sheets through it", and that silently assumes a fixed stock of features to resolve. gyroid has one, so finer cells retire them. fbm_terrain is fractional Brownian motion and has structure at every scale by construction, so refining the grid uncovers new sub-cell features exactly as fast as it resolves the old ones — the residue is scale-invariant because the field is. Consequence: "raise the resolution" is not a mitigation for self-intersection on procedural terrain, which is the one field in this set a game would actually ship |
| M-109 | M-61's "splitting the vertex makes self-intersection worse" is a 33³ fact, not a property — across nine resolutions it reverses three times and ties four. Clamped, pairs per 1,000, dual contouring against manifold dual contouring, 17³→49³ in steps of 4. On gyroid MDC is worse at eight of nine grids and better at 29³, 2.311 against 2.696. On fbm_terrain the two are bit-identical at 25³, 37³, 41³ and 45³, MDC is better at 29³ (23.305 vs 24.011) and 49³ (19.545 vs 20.428), and worse only at 17³, 21³ and 33³. So M-61's 1.82× and 1.12× are single-grid samples of a quantity whose sign is not stable, and on the field where it matters most MDC is indistinguishable from plain DC on four grids out of nine |
E-110's resolution sweep. What does not change: M-61's direction at the default grid reproduces here exactly — 3.118 → 5.669 and 13.837 → 15.434 — and its mechanism, that the clamp's partition argument assumes one vertex per cell, is untouched. What changes is the strength of claim those two numbers can carry. Method: the third time a figure measured at a single resolution has turned out to be resolution-dependent (V-6, M-19). A single-grid number belongs in the ledger as a single-grid number |
| M-110 | The self-intersection counter never tests 99% of the pairs on a dual contouring mesh, and the skipped count is identical clamped and unclamped — which corroborates M-29 from the counter's own bookkeeping. gyroid at 33³: 756 pairs found against 71,748 skipped for sharing a vertex with the clamp off, and 33 found against the same 71,748 skipped with it on. M-83 established the blind spot on subgrid MT's Steiner fans; on dual contouring it is larger still, because one vertex per cell means every quad shares vertices with its neighbours across every cell face. The invariant skip count is the corroboration: adjacent_pairs_skipped is a function of connectivity alone, so a clamp that changed which triangles are adjacent would move it. It does not move by one, which is M-29's "the clamp fixes placement, not connectivity" visible as an equality rather than an inference |
E-110. Also the first count of distinct offending triangles rather than pairs — 483 of 10,584 with the clamp off and 54 with it on, so the red is 4.6% of the mesh and then 0.5% of it. Nobody had counted triangles; M-28 counted pairs, and a pair-count cannot say how much of a mesh is affected |
| M-107 | λ is the sharpness/stability trade in one number, and swept over six decades it moves the runaway by a factor of 23 — but only on the fields M-30 already named. gyroid at 25³, clamp off, as λ goes 1e-6 → 7e-5 → 4e-3 → 5e-1: worst distance a vertex has to be dragged back into its own cell reads 18.03 → 8.99 → 3.41 → 0.78 cells, and worst |f|/h reads 10.54 → 3.38 → 2.24 → 0.60. On box_exact the same sweep gives 0.000 for the runaway at every λ, which is not a defect in the demo — M-30 measured the runaway at 3.18 cells on gyroid and 2.17 on fbm_terrain and said explicitly that "sphere, box_exact and thin_plate have zero vertices outside" |
E-109, which made λ configurable (solve_with, Qef::lambda, DualContouring::set_lambda) after finding the ticket named a "normal-deviation threshold" this implementation does not have. Two lessons, both about choosing the instrument before running it. |f|/h cannot see the runaway where it matters most: a flat cell is rank 1 and its unconstrained directions lie within the surface, so an unheld vertex slides along the plane and stays exactly on it — box_exact at λ = 1e-6 reads 0.000 off-surface while being several cells from where it belongs. And the field has to be chosen as deliberately as the metric: opening this demo on box_exact and sweeping λ shows exactly half the story, which is the mistake the field list is now ordered to prevent |
| M-106 | The acid test passes with a margin, and the margin is the interesting part: across 495 seam crossings the worst vertical discontinuity at a seam is 0.412 cells, against 0.539 cells within a single chunk. So the seams are measurably smoother than the terrain itself — which is the right comparison, because a fixed height threshold would have been measuring the landscape rather than the joins. Zero probes hit nothing. Measured by casting rays against the meshed triangles through parry3d, not against the field: whether two independently meshed chunks meet is decided by G-001's overlap, and only the triangles know it |
E-203. What this does not test, and the ticket asked for: a character controller. The sweep finds holes and lips; it does not find an invisible wall that only a moving capsule reveals, because nothing here slides along a surface. Named as E-206b rather than left implied |
| M-104 | A radius-based residency rule loads a ball of chunks, and for a heightfield that is 4x too many with most of them meshing to nothing — 952 resident and 606 permanently waiting, against 234 and 0 once the vertical extent is bounded. G-007's ChunkStream is radius-based because that is what a general residency rule is, and it is right. What is wrong is using it unfiltered for terrain: fbm_terrain has bounded amplitude, so every chunk more than one layer off the surface is empty air or solid rock, and each costs a full extraction to discover that. Filtering to two vertical layers in the example — which is what a real game does — takes the resident set from 952 to 234, the permanent backlog from 606 to 0, and the visible holes in the terrain to none |
E-201. The queue that never drains is the symptom to recognise: waiting pinned at hundreds while applied trickles is not a budget being respected, it is a working set larger than the budget can ever serve, and it renders as holes that never fill. A second effect, not root-caused: with the oversized set, bevy_render's slab allocator logged 704 use-after-free errors per run, and with the bounded set it logs 0 — consistent with meshes being freed while still queued for upload, but the race was not isolated, and the honest statement is that the churn was removed rather than the bug found |
| M-103 | rustdoc had never run on bevy_isomesh, and two doc links were already broken — the third time an excluded workspace turned out to be excluded from a CI step nobody noticed was missing. The root lint job runs fmt, clippy and rustdoc; the bevy job ran fmt, check, clippy and test. So cargo doc -D warnings had never been executed against that crate, and it fails immediately: a module doc linking [Mesh] with no import path, and a public function linking [triplanar_uv], a private item. Both fixed, and the step added to the job |
B-003. E-111 is the same finding and said so at the time — "a workspace that is excluded from the root is excluded from the root's CI commands too. Check each one separately" — and it was recorded after fmt turned out to be missing from exactly this job. The rule was right and incomplete: fmt was added, the list was not audited, and rustdoc sat missing for another twenty tickets. The sharper rule is to enumerate the steps rather than patch the one that bit you, because the gap is always the step nobody thinks of as linting — A-002 recorded that phrasing and this is its third instance |
| M-102 | ChunkId orders lexicographically on [x, y, z], so a residency sweep must iterate x slowest — and the natural z-outer loop produces exactly the wrong order. G-007's diff between one frame's resident set and the next is a sorted merge, which on unsorted input is silently wrong rather than loudly: it emits spurious loads and unloads and the set drifts. Caught on the first run by a debug_assert! that the swept candidates come out ascending, placed there precisely because a merge cannot detect its own precondition |
G-007. The general shape is worth more than the instance. The bug is invisible in every unit that produces a set — membership, counts, and "is chunk X resident" all pass — and only appears in the diff, which is the thing consumers act on. Asserting the precondition at the point where it is relied on cost one line and one run; discovering it downstream would have looked like chunks flickering in a demo, three abstractions away from the loop nest that caused it |
| M-101 | §3.2.3's inset cannot be reconstructed from its prose, and two attempts made the measured result worse rather than better — the missing half is where it applies, not just how to triangulate it. The point-insertion rules are fully specified ("insert the midpoints of all polygon edges contained in any edge of f, and move them a small distance in the inward normal direction"), so the first implementation applied them to every boundary-disk region: box_exact went from a clean (0, 0, 0) to (84 non-manifold edges, 84 non-manifold vertices, 180 mis-oriented). Restricting it to loops confined to a single face — the per-tet expression of "two adjacent tetrahedra sharing a face f", which needs no communication with the neighbour — still gives box_exact (42, 84, 180). Both attempts reverted |
A-014d, attempted and abandoned rather than shipped. The mechanism the failures point at: a polygon edge lying along an edge of f is shared with whatever else meets at that tet edge, and inserting a midpoint splits it — so the disk detaches from every neighbour that did not also insert one. Which polygons are duplicated, and therefore which edges may be split, is a property of a pair of tetrahedra; this implementation is strictly per-tet, and the guess that "confined to one face" captures the pair condition is what both numbers falsify. Rule 5 is the right call here and the numbers say so: a construction whose specification is a figure was guessed at twice, and both guesses produced meshes that would render fine and are measurably worse. The prose half is not enough |
| M-100 | A demo can be broken in a way that looks entirely correct: E-108's letters, centred on z = 0, are never lost by Marching Cubes at any thickness — 576 triangles at 0.45, 0.30 and 0.15 voxels, the same number every time. z = 0 is a grid plane at every odd resolution, so a sheet centred there always contains a whole plane of nodes; every vertical edge through one registers a sign change, and the extractor the demo exists to embarrass finds the letters perfectly. The constant triangle count across a 3× thickness change is the tell, and it is the kind of tell that is only visible if you look at the number rather than the picture — the render looked exactly as intended. Fixed by offsetting the mid-plane to 0.41 of a cell (off the lattice, and not a round fraction that a resolution change lands back on) and tilting it by 0.03 in y. Measured after: Marching Cubes gives 220 → 0 → 0 → 0 triangles at 0.70, 0.45, 0.25, 0.10 voxels while subgrid gives 1706 → 1380 → 1304 → 1252 |
E-108. Fifth occurrence of the fixture trap (M-32, M-38, M-44, M-94), and the first in an example rather than a test — which is worse, because a demo has no assertion to fail. The tilt earns its place separately: without it the failure is binary, every node inside or none, and M-72's middle phase — the holey remnant that is what a streamed world actually suffers — never appears at all |
| M-99 | The subgrid mesh's connectivity is provably manifold and my weld is what breaks it — the same mechanism as M-59, in a second algorithm. Unwelded: 0 non-manifold edges and 0 non-manifold vertices on every field. Welded: 3 and 6 on csg_difference, 4 and 6 on fbm_terrain. Appendix A is explicit — Theorem A.1: "In the even sum case, both the primal and dual algorithms yield manifold connectivity"; Lemma A.2: "The primal polygons constructed before Section 3.2.3 form an edge-manifold cell complex." The precondition was checked rather than assumed: over all seven reference fields at 17³, 0 of 98,304 tetrahedron faces violate the even-sum condition — so the theorem applies everywhere and the guarantee is in force. What §3.2.3 actually says is that the pair of coincident polygons "define manifold connectivity, but degenerate geometry", and a weld by position cannot tell two coincident-but-distinct polygons apart |
A-014d, measured after retrieving Appendix A through home-still, which no amount of §3.2's own text would have supplied. This re-aims A-014d. Its job is not "make the output manifold" — it already is, as a complex. It is "separate coincident geometry far enough that an indexed, welded triangle mesh can still represent it", which is exactly the inset. And M-59 is the precedent, not a coincidence: that entry recorded the same shape for Manifold Dual Contouring — a manifold complex an index buffer cannot express. Two algorithms, one representational limit |
| M-98 | Subgrid Marching Tetrahedra costs 70× classic Marching Tetrahedra and 196× Marching Cubes, and the ratio is field evaluations rather than anything algorithmic. On sphere, f32, Apple M5: at 33³ Marching Cubes 115 µs, Marching Tetrahedra 323 µs, subgrid 22.5 ms; at 65³ 965 µs, 2.68 ms, 173 ms. Other fields at 33³: torus 32.5 ms, box_exact 36.8 ms. Scaling 33³→65³ is 7.7× against 8× the cells, so it is linear in cells like the others — the constant is the whole story. The constant is not mysterious. At 16 samples per edge, a cell costs 6 tets × 6 edges × 16 = 576 field evaluations before any bisection refinement, against Marching Cubes' 8 shared corner samples; ~72× is the ratio that predicts the measured 70× against Marching Tetrahedra |
A-014c, benches/extract.rs, cargo bench --bench extract. Two consequences. This is a correctness-first implementation and says so: every cell re-finds the roots on edges its neighbours already found, deliberately, because identical endpoints through a deterministic root finder is what makes conformity hold without a cache — a grid-edge cache is the obvious optimisation and the redundancy is large, but it has a correctness precondition and is unmeasured. And the trade is real rather than a defect: 22.5 ms buys geometry no sign-based method produces at any grid resolution (M-95), so the comparison to make is not "subgrid vs Marching Cubes at 33³" but "subgrid at 33³ vs Marching Cubes at whatever resolution resolves the same feature", which for thin_plate is no resolution at all |
| M-97 | §3.2.3's immersion is not hypothetical, and it is the single cause of every violation the subgrid extractor produces: 4 of the 7 reference fields are clean, 3 are not, and both failure modes trace to the same missing inset. At 17³ with 16 samples per edge, welded, validate_indexed reports (non-manifold edges, non-manifold vertices, inconsistently oriented) of sphere (0,0,0), torus (0,0,0), box_exact (0,0,0), thin_plate (0,0,0), csg_difference (3,6,6), gyroid (0,0,138), fbm_terrain (4,6,19). The two shapes of failure look unrelated and are not. csg_difference and fbm_terrain show the non-manifold form §3.2.3 names outright — two adjacent tetrahedra each emitting an oppositely-oriented copy of a polygon bound by the same non-normal loop, whose union pinches. gyroid shows the orientation form, and the mechanism was measured rather than guessed: of its 8,088 triangles, 12 have zero area and 24 have the gradient lying exactly in the triangle's plane — worst |cos| = 0.00e0 — so the orient-against-the-gradient vote is not merely close, it is undecided, on precisely the degenerate boundary-disk triangles V-21 says are supposed to be there |
A-014c/A-014e, the_validity_suite_over_every_reference_field. Both are downstream of one fix: §3.2.3 pushes those polygons into the tet interior, which gives them area and a normal transverse to the gradient — so the union stops pinching and the orientation vote becomes decisive. Pinned as exact counts rather than asserted to zero, per the Phase 1 amendment: a known defect with a number and a ticket that owns it satisfies the gate, and A-014d now owns it with two measured fixtures instead of a hypothesis. Sharpened by M-99: the counts are not a manifoldness failure at all — connectivity is provably manifold under Theorem A.1, whose even-sum precondition holds on all seven fields, and welding is what collapses the coincident pair |
| M-96 | Orienting each triangle against the gradient at its own centroid is sufficient — the welded output is closed, manifold and consistently oriented with χ = 2 on both thin_plate and sphere. But the weld is a precondition, not a tidy-up, and the numbers before it are worthless. Unwelded, thin_plate at 17³ reports 2,240 boundary edges across 896 triangles, because the extractor emits each tetrahedron's vertices independently and no two tetrahedra share one — it is a triangle soup with no topology to check, and the orientation figure of 8 was measured only over edges interior to a single tetrahedron. Welded: 840 triangles, 0 inconsistently oriented, 0 non-manifold edges, 0 non-manifold vertices, 0 boundary edges, χ = 2, and the 56 degenerate triangles collapse away in the weld |
A-014e, the_welded_output_is_a_closed_consistently_oriented_manifold. Per triangle, not per patch: thin_plate's two faces are 0.4 cells apart and routinely land in the same tetrahedron facing opposite ways, so a per-patch decision would get one of them backwards. Second time this session that a measurement on unwelded subgrid output was meaningless — M-93 was the self-intersection count — which is why the extractor's doc comment now says it outright rather than leaving it to be rediscovered a third time |
| M-95 | A-014c's acceptance is met with a number rather than a hedge: thin_plate returns 4,328 triangles at 33³ where greedy quads returns 0 on the same grid, and every vertex is on the surface to within 1e-9. At 17³ it is 896 triangles from 2,248 vertices. The contrast is the whole point of the track — A-005 measured greedy quads' zero because no cell centre is inside a plate 0.4 cells thick, and M-72 measured Marching Cubes aliasing the same field into a resolution-dependent scatter. Sharper still, with the grid held fixed: a slab 1/20 of a cell thick gives 0 triangles at 2 samples per edge and a mesh at 256, which no sign-based method can do at any sample count |
A-014c, thin_plate_comes_back_where_greedy_quads_returns_nothing and the_extractor_resolves_a_feature_the_grid_cannot. And a determinism boundary worth having in writing. Raising samples from 16 to 32 leaves the topology identical — same vertex count, same index buffer — but moves the positions, by under 1e-12 and by more than zero. Bisection converges to an ulp of a root and which one depends on the bracket it started from. So the guarantee is "same arguments, same output", not "same field, same output", and a golden hash over this extractor must pin samples alongside the grid. The first version of that test asserted bit-equality across sample counts and failed |
| M-94 | 1D root finding resolves a slab at 1/1000 of the edge length — and the fixture that appears to demonstrate its limit passes for the wrong reason unless the slab is moved off the sample lattice. all_roots finds exactly two crossings on a slab of half-width w centred mid-edge for w = 0.25, 0.05, 0.01, 0.001, each to within 1e-12, while both endpoints read outside — which is A-005's zero-triangle result at its origin: a sign test asks the endpoints and learns nothing. The stated limit is real too: 8 samples step over a slab 2e-4 wide, and 100,000 find it, which is §1.3's "1D marching can of course miss intersections, [but] we are no worse off than classic marching" |
A-014c, a_slab_thinner_than_the_grid_still_has_two_roots and its companion. The trap: the miss-it test was first written with the slab centred at 0.5, where 8 samples put one sample exactly on the centre — it reads inside, the slab is found, and the assertion that it should be missed fails. Centring at 0.5137 fixes it. Fourth occurrence of the fixture trap (M-32, M-38, M-44) and the first where the fixture was written for this ticket rather than inherited |
| M-93 | Subdivision's output reported 30 self-intersections in 52 triangles, and every one was an artefact of vertex duplication rather than a fold. Welding first takes it to zero. Each sub-tet appends its own copy of the crossings on a face it shares with a sibling, so two triangles that legitimately meet there carry different vertex indices — and self_intersections only skips pairs sharing an index (M-83), so it compares them and finds them touching. Diagnosed by elimination rather than by inspection: all four children of (4, 2) fill to 0 self-intersections standalone (8 + 8 + 18 + 18 = 52, matching the total), so nothing was wrong inside a child; and all four children are normal curves, which ruled out the first hypothesis — §3.2.3's immersed Δ-complex, which only arises from non-normal loops on a shared face |
A-014b, every_implemented_case_emits_an_intersection_free_patch. Consequence for every future measurement on this extractor: self-intersection counts are meaningless on an unwelded multi-tet patch, and the weld must be by exact position, which is sound only because both sub-tets compute a shared crossing from the same corners and the same parameter and get bit-identical results. Same reasoning as M-32's, and the same reason a tolerance would hide the failure rather than absorb it |
| M-92 | §3.2 is complete over the tested space: 4,096 of 4,096 configurations mesh, with NoPattern and Inconsistent both zero — and 105 of them correctly triangulate to nothing. Corner type was the last of §3.2.2's three, needing the disk plus two extras: the vertex coinciding with the inside corner omitted from its polygon, and a triangle capping that corner, built from the crossings nearest it along its three incident edges. With it in, every configuration with 0–3 crossings per edge fills. The 105 is the interesting number. Those carry a non-normal loop whose inside region is a bigon — one chord and one edge piece, two nodes — and a fan over two nodes is empty. The minimal case is e = (2, 0, 0, 0, 0, 0), a single scoop pair. That is V-21 at its most extreme and it is right: the region has zero area until A-014d insets it into the tet interior |
A-014b, all_three_non_normal_types_now_have_a_spanning_disk and the_coverage_of_the_implemented_cases_is_pinned. The assertion this replaced was "every non-normal loop produces triangles", which failed — and rewriting it as a pinned count rather than deleting it is the point: a bigon disk is a real state of the algorithm, and a test that merely tolerated it would stop distinguishing "degenerate by construction" from "emitted nothing by mistake". SingleLoop and Subdivision stay at 0 here because they remain unreachable at these counts, not because they are covered |
| M-91 | The contractible spanning disk introduces no vertices at all, and coverage moves 3,394 → 3,808 of 4,096. §3.2.2's disk for corner and contractible loops is built in the tet boundary, so every one of its vertices is a crossing the tet already has — no Steiner point, no centroid, nothing new. That makes it cheaper than any of the four Steiner cases despite being the one that needed a planar arrangement to write, which is the opposite of what the case list's difficulty ordering suggests. With it wired in, the sweep over 0–3 crossings per edge moves from 3,394 filled / 702 refused to 3,808 filled / 288 refused, and every one of the remaining 288 carries a corner-type loop — the only kind left, and the only one needing §3.2.2's two extras (omit the vertex coinciding with the inside corner, add a triangle at that corner) | A-014b, the_coverage_of_the_implemented_cases_is_pinned. A Node::Corner reaching the emit is treated as [Unfilled::Inconsistent] rather than fanned over: a contractible loop marks all four corners outside so no qualifying region can contain one, and for a corner-type loop fanning over it would produce a plausible wrong disk instead of the omission rule |
| M-90 | A scoop belongs to one face, but its two endpoints lie on an edge that belongs to two — so "both endpoints are on this face" hands the same scoop to both, and a crossing ends up bounding three regions instead of two. Building §3.2.2's σ \ γ needs to know which face each of γ's segments lies in. For an ordinary segment that is determined: its two endpoints are on two different edges, and two distinct edges of a tet lie in a common face only if that face is unique. A scoop breaks it — both endpoints on one edge, and every edge is shared by exactly two faces, so the endpoint test cannot tell which one owns it. Measured on e = (2, 2, 0, 0, 0, 0), face 3: crossing (edge 1, index 1) appeared in 3 regions. §3.1 already has the answer, because face_segments builds segments per face in the first place, so the fix is to take the face assignment from there rather than re-derive it |
A-014b, a_face_split_along_a_loop_partitions_into_regions. Found only because the weaker checks passed. Edge-piece conservation and regions == chords/2 + 1 both held with the bug present — they count things without noticing which region got them. The check that caught it is order-sensitive: a crossing lies between exactly two regions and a corner belongs to exactly one. The same assertion also killed a second mutation the counting checks had survived (peeling a chord that is not innermost), so one order-sensitive property was worth more than two conservation laws |
| V-21 | The corner/contractible spanning disk is supposed to come out degenerate, and mistaking that for a bug would send A-014b chasing a non-problem. §3.2.2 builds this disk "contained mostly in the tet boundary, rather than its interior" — so its triangles are coplanar with the tet's faces by construction. Worse-looking still, a scoop (a segment joining two crossings on the same edge) realises as a straight chord lying along that edge, so the region it bounds with the edge pieces between its endpoints has zero area. Both are expected: §3.2.3 says the mesh at this point "has manifold connectivity, but may be an immersed Δ-complex rather than an embedded simplicial complex", and the repair is exactly to "push polygons into the tet interior: we insert the midpoints of all polygon edges contained in any edge of f, and move them a small distance in the inward normal direction" |
Read from 10.48550/arXiv.2606.00454 §3.2.2–3.2.3 at A-014b, before implementing, specifically to find out how the case should be judged. Two consequences for the work. A-014b's corner/contractible output must be graded on connectivity, not on area or on self-intersection — CLAUDE.md already treats degenerate triangles as a recorded metric rather than a gate, and here they are the specified output. And the arrangement should be built combinatorially rather than from straight-line geometry, since a geometric build collapses every scoop before A-014d gets the chance to inset it |
| M-89 | On thin_plate — the field this whole track exists for — 93.75% of tets already mesh, and every one of the remaining 6.25% is the contractible case. Not corner, not diagonal: contractible, all 192 of them. Sampled at 33³, decomposed into the 6-tet cube, with all roots along each edge found by dense 1D sampling: 3,072 tets carry crossings, of which 2,880 fill completely and 192 stop at a non-normal loop. The curve census is 0 open / 3,060 normal / 192 non-normal, and the non-normal breakdown is 192 contractible / 0 diagonal / 0 corner. 620 edges carry more than one root, which is the sub-voxel signal itself — the thing a sign test cannot represent, and the reason A-005 measured greedy quads returning zero triangles on this field |
A-014b, measured to decide whether §3.2.2's planar-arrangement case was on the critical path for A-014c. It is: 192 holes is not a mesh. But the useful half is that it is one construction and the simpler one — contractible loops mark all four vertices outside, so they need no distinguished vertex, no corner triangle and no vertex omission, which are the three complications the corner case adds. Provenance, resolved at A-014c: first measured with a throwaway probe carrying its own ad-hoc root finder, deleted rather than committed because a second root finder is the two-path failure the crate forbids. the_thin_plate_census_reproduces_with_the_real_root_finder now re-runs it through all_roots and gets all three numbers unchanged — 3,072, 620, and 0/3,060/192 — so the probe and the shipped root finder agree on counts, and the census is a committed test rather than a figure that only existed in a commit message |
| M-88 | §3.2.2's two labelling rules are stated separately and are checkable against each other, which turns a transcription into a verified one. The vertex rule assigns sides to the tet's four corners (corner type: the distinguished vertex inside, the rest outside; contractible: all outside; diagonal: no distinction). The edge rule walks an edge from its lower corner i, takes i's side, and flips at every crossing — and never looks at the far corner j. So the side it arrives at is a prediction, and it must equal the side j was independently assigned. The two agree only if crossing γ an odd number of times means opposite sides, which is exactly what the parity bit b_ij is defined to say — so the check couples the parity rule to the vertex rule, and nothing else does. Verified over all 4,096 configurations with 0–3 crossings per edge, every corner-type and contractible loop, every edge: no disagreement. Mutating the vertex rule so a corner loop marks nothing inside fails at e = (1, 1, 1, 2, 0, 0) |
A-014b, the_edge_labelling_closes_on_the_far_corner_it_was_not_told_about. The distinguished corner is derivable rather than given: it is the vertex whose three incident edges all have odd parity, which is consistent with the classification's p = b₀₁ + b₀₂ + b₀₃ giving 3 when it is corner 0 and 1 otherwise |
| M-87 | §3.2 as implemented meshes 3,394 of 4,096 configurations, the entire remaining gap is one construction, and Property II held every single time. Over all edge coordinates with 0–3 crossings on each of six edges: 3,394 fill completely (82.9%), 702 stop at a non-normal loop, and SingleLoop, Subdivision, NoPattern and Inconsistent are all 0. Three of those zeros mean different things and the distinction is the point. Inconsistent is a bug and never a case, so zero is a pass. SingleLoop and Subdivision are zero because they are unreachable at these counts — both need a residual pattern with ℓ > 8, which wants larger d₁, d₂ than three crossings per edge can supply — so they are covered by targeted fixtures instead, and this sweep says nothing about them. NoPattern at zero is the strong one: Property II held on Γ_normal's own residual in all 4,096 configurations, which is an empirical check of Theorem B.3 across the whole space rather than on the 27 constructed patterns of M-82 |
A-014b, the_coverage_of_the_implemented_cases_is_pinned, pinned as exact counts so a regression moves a number rather than rounding away. The useful consequence for planning: the entire 702-configuration gap is §3.2.2's corner and contractible types — one construction, not four — so what is left of A-014b is narrower than the case list suggests |
| M-86 | Conforming does not mean "no boundary at a shared face" — it means "boundary exactly where an open curve was discarded", and the difference is measurable. Two tets sharing a face, filled independently with no communication and no second pass, merged and welded: on e_shared = (1, 1, 2) with differing apex coordinates, the shared face carries one edge used by a single triangle. That is not a crack. §3.1 discards curves with a degree-1 vertex, and whether a given shared-face segment lands in an open or a closed curve depends on the whole tet — so one tet can legitimately drop a segment its neighbour keeps, which is exactly what the paper means by "such curves are discarded, but their segments may still appear in neighboring tets as part of the mesh boundary." Every one-sided shared-face edge across the fixture is accounted for by a discarded open curve, none is used by more than two triangles, and the excuse fires at least once so it is not a clause that passes by never applying |
A-014b, the_shared_face_of_two_tets_carries_no_crack, the ticket's acceptance criterion. The first version of this test asserted zero one-sided edges outright and failed — and the failure is the finding, because "conforming" had been written down as the stronger and wrong property. The right gate is the conditional one, and it is what a full grid needs: a tet interior to the grid has every neighbour present, so its open curves close through them |
| M-85 | Property II is a statement about Γ_normal's residual, not about the tetrahedron's — and taking it for the tet's silently disables §3.2.2 on every configuration that needs it. Subtracting only the corner cuts from the tet's own edge coordinates leaves in the points belonging to non-normal loops, which are in neither set, so Pattern::of fails for a reason that has nothing to do with §3.2.1 — and because that failure is an early return, the non-normal handling below it never ran. Exhibited on e = (0, 0, 2, 0, 0, 0): one non-normal loop, no normal residual at all, reported NoPattern where the loop should have been triangulated. The fix is to sum the residual coordinates from the residual normal loops directly, which cannot make the mistake, and to run §3.2.2 before §3.2.1's dispatch rather than after it — the two sections partition Γ, and one configuration can carry both |
A-014b, found by a_diagonal_non_normal_loop_fans_around_its_centre_of_mass. The paper's structure is the tell and it was there to read: §3.2.1 opens "we first consider the subset of normal curves Γ_normal ⊂ Γ" and §3.2.2 "we next consider the subset of non-normal loops Γ_nonnormal ⊂ Γ". Two subsets, two independent procedures. Implementing them as sequential stages of one pipeline, where the first can bail out, is what created the coupling |
| M-84 | The Figure-13 subdivision stencil closes: all four sub-tets it produces are themselves normal configurations, on all 27 patterns tried, and the margin is zero. The stencil is asymmetric — e_ai = 2d₂ against e_aj = d₁, e_ak = d₂, e_al = d₁ − d₂ — so the recursion is only well-founded if every tet it makes is a legal input to the same procedure, and the paper states that nowhere. Checked directly: over 1 ≤ d₁ ≤ 6, 0 ≤ d₂ ≤ d₁, every one of the 108 sub-tets satisfies both normality conditions. What makes this a real check rather than a formality is that it is tight: three of each sub-tet's four faces meet the triangle inequality with equality (2d₂ ≤ d₂ + d₂, d₁ + d₂ ≤ 2d₂ + (d₁ − d₂), d₁ ≤ (d₁ − d₂) + d₂), so there is no slack for an off-by-one to hide in — and mutating 2d₂ to either d₂ or d₁ + d₂ fails the sweep |
A-014b, the_subdivision_stencil_produces_four_normal_sub_tets. Also: the labelling is load-bearing, not cosmetic. Because the stencil is asymmetric, which corner is called i decides the entire subdivision, so Subdivision::label searches for the i, j, k, l Property II guarantees instead of trusting corner order to supply it, and returns the lexicographically smallest when d₁ = d₂ makes several equivalent |
| M-83 | T-002 is structurally blind to a fold inside a Steiner fan, and §3.2 is built entirely from Steiner fans — so "zero self-intersections" means less here than it does for Marching Cubes, and exactly how much less is now pinned. The counter excludes any triangle pair sharing a vertex index (self_intersection.rs:266), which its own docs already price as "a fold that pinches exactly at a shared vertex is not counted". A fan gives every triangle of a loop the same apex, so no two triangles within one loop are ever compared. Found by a reachability check that failed: collapsing all three Steiner points of a (3, 3) octagon pattern onto one apex — a definitively wrong mesh — reports 0 intersections, because the collapse is what creates the sharing. The boundary is sharp and the useful half survives: distinct loops share no crossing vertex and no Steiner point, so cross-loop intersections are fully visible, and reversing the innermost-to-outermost assignment on the same pattern does report a non-zero count |
A-014b, reversing_the_steiner_assignment_is_visibly_wrong. Method consequence: a mutation test on fan geometry must permute the apexes, never merge them, or it silently tests nothing. The first version of this test merged them and passed for the wrong reason — the fourth occurrence of the fixture trap (M-32, M-38, M-44), and the second caught by an assertion rather than a reviewer. Taken to its conclusion, the single-loop case's zero is entirely vacuous: m = 1 is one fan, so on a (3, 2) pattern — 20 triangles, 190 pairs — the counter skips 190 of 190 and reports zero having compared nothing. the_single_loop_zero_is_vacuous_and_this_is_what_makes_that_visible asserts that equality rather than the zero, so the green tick cannot be mistaken for coverage, and it fails loudly if the counter ever learns to see inside a fan |
| M-81 | §3.2.1's first two cases cover the whole of classic Marching Tetrahedra, and the rest of the machinery exists entirely for what a sign test cannot see. All sixteen sign patterns fill completely with corner cuts (ℓ = 3) and quads (ℓ = 4) alone — nothing reaches the octagon, single-loop, subdivision or non-normal branches, and the triangle counts come out 0 / 1 / 2 exactly as A-003's table has them. This is M-67 from the other end: the 8 classic configurations of 181 are also the 8 easiest to triangulate, so every line of §3.2 past the quad case is there to serve the 173 that a sign test reads as one of those 8 |
A-014b, every_classic_configuration_fills_completely. Useful as a staging property, not just a curiosity: the two implemented cases already subsume the extractor this crate ships today, so the remaining cases can land incrementally without a half-working path existing at any point |
| M-82 | Theorems B.4 and B.6 hold against a reconstruction that does not use them — 27 of 27 (d₁, d₂) patterns, exactly. The appendix predicts the number of boundary components as gcd(d₁, d₂) (Theorem B.4) and every component's length as 4(d₁ + d₂) / gcd(d₁, d₂) (Corollary B.6). §3.1's segment reconstruction computes neither — it pairs points face by face from the edge coordinates — yet over every 1 ≤ d₁ ≤ 6, 0 ≤ d₂ ≤ d₁ the component count and every component's length match the formulas with no exceptions, up to a single loop of length 20 at (3, 2) and two octagons at (2, 2) |
A-014b, the_appendix_formulas_predict_the_curves_section_3_1_actually_finds. Both directions are load-bearing, so the test is mutation-checked: replacing gcd with 1 fails at (2, 0), and 4(d₁+d₂)/g with 8(d₁+d₂)/g fails at (1, 0). The length formula is partly forced by arithmetic — m · ℓ must equal the 4(d₁ + d₂) total crossings — but the component count is not, and that is the part that says the curve reconstruction agrees with the topology the paper derives |
| M-80 | Every point §3.1 leaves unpaired is forced by arithmetic, not chosen — which is what makes the procedure implementable without inventing a convention. Step 2 handles an odd sum by subtracting one from each edge coordinate, "effectively creating three open endpoints", without saying which three. It does not need to: the corner cuts claim cᵢ from one end of an edge and cⱼ from the other, and on the reduced coordinates cᵢ + cⱼ = eᵢⱼ − 1, so exactly one point — the one at index cᵢ — is unclaimed. Verified over 2,875 odd-sum faces, each leaving exactly e − 1 endpoints used per edge. The same holds in step 3: the residual run on the long edge is [cᵢ, eᵢⱼ − cⱼ), of size exactly r = eᵢⱼ − eⱼₖ − eₖᵢ |
A-014b. This mattered for rule 5: an under-specified step is normally where a construction gets guessed at, and here the specification is complete once the arithmetic is done. Measured alongside: 8,424 even and 14,256 odd residual cases exercised, and over configurations with counts to 3 the curves come out 5,568 open, 3,682 normal, 771 non-normal — all three of §3.1's kinds reachable |
| M-496 | Every empty mesh this crate handed to Bevy 0.20's render world cost one allocator WARN … contains no vertices per extraction, and building it RenderAssetUsages::MAIN_WORLD removes all of them without moving a pixel. A three-path smoke (16 plugin chunks over a sphere, 8 of them empty, each with a Mesh3d; one direct meshes.add(to_bevy_mesh(&empty)); one drawn sphere overwritten in place by an empty mesh) logged 10 warnings before and 0 after; game_budget, which re-meshes 288 chunks through MeshBuilder::into_mesh and meshes.add, logged 836 in 120 frames before and 0 after. Both rendered frames of the smoke are pixel-identical before and after (max channel difference 0), and in both the in-place-emptied sphere is gone (the right half of the frame is uniform background 43/44/47). A third frame, after refilling that asset in place and moving the plugin sphere into the four empty, main-world-only chunks, draws both spheres, leaves no ghost where the sphere was, and shows no crack at the three chunk planes it crosses; the run logged 0 warnings and left 4 empty chunks, all MAIN_WORLD. Sanctuary's report — 102 warnings for 102 empty chunks of 856 per world build — is the same mechanism at scale. |
Issue #10, iteration 2, M1 Max, Metal. The smoke renders headless to an Image target: ISOMESH_SCREENSHOT window captures came back all-black (0,0,0) from a loop pass on this host, so window stills are not evidence here. Regression tests an_empty_chunk_keeps_its_chunk_mesh_but_not_the_render_world, a_chunk_that_gains_or_loses_its_surface_gets_a_fresh_mesh_with_the_matching_usage, into_mesh_keeps_… and to_bevy_mesh_keeps_an_empty_mesh_out_of_the_render_world_and_readable fail on 41e64d3 and pass after |
| M-497 | A dirty-marking rule is a claim about which points of the field an extractor reads, and mark_edit's corner rule is false for Subgrid Marching Tetrahedra: over 8 edits of a four-chunk row it missed the changed chunk on 4 (a plate thinner than a cell added and removed, a crack no corner sees cut and closed), and mark_edit_subgrid, which compares the fields at the extractor's own probe points, missed none. Soundness is judged by extracting every chunk with SubgridMarchingTetrahedra (4 samples) before and after each edit and comparing the buffers: 10 chunks changed across the 8 edits, the corner rule marked 6 of them, the Subgrid rule all 10, at 11 chunks marked, so 1 was re-meshed to the same bytes (a plate beside a sphere's surface; the corner rule over-marks the same chunk). The cost is counted, not timed: 1 + 7 (samples − 1) evaluations of each field per cell, amortised, which is the exact number of distinct points (asserted for samples 1, 2, 4 and 5 on a counting field); at samples == 1 the report equals mark_edit's counter for counter on all 8 edits. The corner rule's miss is not an edge case of carving: a crack in solid changes no corner value at all (value_changed_cells == 0) and still changes the mesh |
Issue #11, iteration 3. chunk::dirty::subgrid::tests::every_chunk_whose_subgrid_mesh_changed_is_marked (which also runs the corner rule through the oracle and fails if it ever stops catching it), a_crack_no_corner_sees_is_missed_by_mark_edit_and_found_by_mark_edit_subgrid, each_probe_point_is_evaluated_once, one_sample_per_edge_is_the_corner_rule. Sources: Baktash, Gillespie and Crane §1 and §1.3 (V); Lengyel 2010 p. 28, C4 regenerates every block in an edit's box (V). Residual: the rule is exact for the probe values, not for bisection or gradient reads between them; Dual Contouring's gradient reads are not examined |
| M-498 | A test that asserts the state a transition and its absence both leave cannot fail when the transition is dropped: an_edit_during_extraction_is_requeued_rather_than_swallowed passed against the one-line swallow it was written to catch, against a second extraction that read a stale field, and against a re-marked chunk that spawned over its running task. The plugin's contract (NeedsRemesh comes off at spawn, a running task finishes against its own Arc of the field, a re-marked chunk spawns again with the current field) was checked only by its end state: a ChunkMesh, no NeedsRemesh, no MeshingTask, which the swallow (.remove::<NeedsRemesh>() in the Ok arm of apply_finished_meshes) leaves as well. Against mutation 1 (that line) the old test passed, against mutation 2 (the second extraction handed the first extraction's field, a static cache in spawn_meshing_tasks) it passed, and against mutation 3 (Without<MeshingTask> removed from WaitingChunks, so the re-mark spawns over the running task and cancels it) it passed. The rewrite swaps the field through replace_field and mark_changed_chunks while the first task runs, sums MeshStats::spawned over the following frames, and compares what the chunk shows with extract_chunk of each field. Mutation 1 fails it with "extracted 0 times after the mark, not once" (the other 24 plugin tests still pass, so that one test is the only thing standing between the swallow and a release); mutation 2 fails it with "the chunk ended up showing a mesh the edited field did not make (45 vertices shown, 99 expected)" while its count assertion still passes (1 extraction); mutation 3 fails it with "the extraction already running should have finished against the old field (99 vertices shown, 45 expected)", again with the count at 1, because a replaced task is still one spawn. So the data assertions are not redundant with the count, and neither is the count with them. The two fixture meshes are asserted non-empty and different (45 and 99 vertices: a radius-1 and a radius-1.5 sphere in chunk [0, 0, 0]), so the comparison cannot be vacuous. On the unmutated plugin the full lib suite (46 tests) passed 3 of 3 and the test passed 40 of 40 runs on a host at load 10-12 on 10 cores: its sequence is fixed by the schedule (apply_finished_meshes only runs inside App::update, so the first task cannot land before the test's next frame however fast the worker is), not by timing |
Issue #12, iteration 4. bevy_isomesh/src/plugin/tests.rs, an_edit_during_extraction_is_requeued_rather_than_swallowed; each mutation was applied to plugin.rs alone, run once in the release profile against the new test and against the old one, and reverted. Sources: Lengyel 2010, chapter 1 (V, the mesh is regenerated from the voxel data at the moment of extraction); Lindstrom and Pascucci 2001 §3 (V, the display list is reused "until a newly refined mesh is obtained"); Saha and Kanewala 2019 (V, mutants as a proxy for real faults). Falsified by a mutant of the re-queue path this test passes. The three mutations run are the ones the issue and the code's comments name, not a census. Residual: the test runs one chunk and the default extractor |
| M-499 | A report field documented as an edit's own but computed against the caller's whole queue reports the backlog as the edit's work, and the same edit then reports differently depending on how much of the queue the frame budget had drained: mark_edit's EditReport::dirty_chunks counted the region's chunks found in the caller's DirtySet, so a no-op edit with one queued chunk in its region reported 1 dirty chunk (expected 0), and with every chunk of its 8-chunk region queued it reported 8. The three tests added in chunk/dirty/tests.rs were run against the old rule: the issue's own fixture fails with "an edit that changed nothing reported 1 dirty chunks", the whole-region fixture with 8 against 0, and a real edit (a radius-0.5 sphere carved 2 cells deeper, a 64-chunk region, 3,112 output-changed cells of 148,877 region cells, 8 chunks dirtied) reports 9 when one idle chunk of its region is queued, against 8 into an empty queue. The same mutation (the old rule put back into the shared commit) also fails the Subgrid marker's own dirty_chunks_counts_this_edit_and_not_the_queue, which only ever passed because mark_edit_subgrid had been written the right way in iteration 3 while mark_edit was left as it was. Two more mutants of commit were run against the final tests: counting only the chunks this call newly queued fails only the differential test (3 reported against 8, with half of the edit's chunks already waiting), so that test is not redundant with the other two; and counting without queueing fails 7 tests, six of them older ones that read the queue the marker fills. On the fix all 25 chunk::dirty tests pass, the two markers close through one private commit, and the queue ends as the union of what it held and what the edit dirtied, each id once. The scan removed was region_chunks × queue length equality tests per edit over a sorted Vec that supports binary search; the replacement does no test against the queue at all (derived from the code, not timed: edit_trace, extract and shootout do not call mark_edit, and no bench of marking with a backlog exists) |
Issue #13, iteration 5 (owner's review of 2026-10-30). cargo test -p isomesh --lib chunk::dirty: dirty_chunks_counts_this_edit_not_the_backlog, a_queue_holding_the_whole_region_is_still_not_the_edits_work, the_report_does_not_depend_on_what_is_already_queued; each mutant was applied to commit alone, run once in the debug profile, and reverted. Sources: Lengyel 2010 p. 28 (V, the regeneration set is a function of the edited region); Evans 2015 pp. 25 and 36 (V, edits counted per voxel against the edit list); Manning et al. 2008 §1.2 (V, a sorted contiguous array). Falsified by a caller whose queue is non-empty seeing a report that differs from the same edit's on an empty queue. Residual: DirtySet::insert is still a Vec insert, one memmove per dirtied chunk; no marking bench exists, so the cost claim is structural |
Part 3 — Verified from primary sources (tier V)
| # | Finding | Source |
|---|---|---|
| V-1 | Bevy 0.19 pins wgpu / wgpu-types / naga 29.0.3, glam 0.32.0, encase 0.12 | bevy_render/Cargo.toml @ v0.19.0 |
| V-2 | Bevy 0.19 removed RenderGraph; passes are systems in ECS schedules; non-camera work targets the RenderGraph schedule |
0.18→0.19 migration guide |
| V-3 | Marching Cubes peak: 5.42 G voxel/s, 330 M tri/s (RTX 2080 Ti). DMC costs 1.52–3.50×; FlexiCubes 2.77–3.92× | Grosso & Zint, 10.1007/s00371-021-02139-w |
| V-4 | Contouring 68 ms vs halfedge construction 58 ms — extraction is 54% of a usable mesh | same, Table 5 |
| V-5 | On unstructured grids, Delaunay/MT ratio 15.3×–81.5× — contouring is 1–2% of the pipeline | TetWeave Table 3 |
| V-6 | 73% of FlexiCubes' 64³ Marching Cubes timing is fixed launch overhead (fitted a ≈ 1.88 ms) | fit over FlexiCubes' own resolution series |
| V-7 | Cross-paper reproducibility floor is ~1.5× in opposite directions: TetWeave re-measured FlexiCubes at 128³ as 9.63/15.25 ms vs FlexiCubes' own 14.06/9.53 | both papers |
| V-8 | GPU Marching Cubes throughput has not tracked hardware: 10.7× more bandwidth bought ~1.7× more throughput (GTS 450 → 2080 Ti) | speed analysis |
| V-9 | Same Marching Cubes, compute shader → mesh shader: 114.2 → 2679.4 fps (23.4×) | Elliott MSc, Waikato 2022 |
| V-10 | CBT sum-reduction, atomics → LDS staging: 5.78 → 0.40 ms | Unity SIGGRAPH 2021 (see ✗7) |
| V-11 | Meshlet compression: 15.5 M tri in 0.59 ms (RX 7900 XTX) | 10.2312/vmv20241204 |
| V-12 | Work graphs: 79,710 instances in 3.74 ms — but 2.8–3.4× slower on classification workloads | 10.1145/3675376 + independent profile |
| V-13 | nvblox: meshing is the least GPU-accelerable stage, ×3–13 vs fusion's ×174–177 | nvblox |
| V-14 | Aokana renders 10¹⁰ voxels at 6 ms, 5% resident, RTX 3060 Ti — explicitly not editable | Aokana |
| V-15 | CoACD vs V-HACD: 49% → 80% downstream manipulation success | CoACD |
| V-16 | Dimforge migrated parry (0.26.0) and rapier (0.32) off nalgebra onto glam, citing rust-gpu support; performance "nothing changed, at all" | dimforge.com, 2026-01-09 |
| V-17 | No paper since 2020 benchmarks Marching Cubes vs Surface Nets vs Dual Contouring against each other. Surface Nets has no credible published timings at all | literature review round 1 |
| V-18 | Dual Contouring's own paper quantifies the f32 QEF failure. At 256³, bᵀb reaches ~10⁶; f32 carries six decimal digits, so E[x] evaluated on a flat region — where it should be zero — has error on the order of 1. The paper's own remedy is double precision |
Ju, Losasso, Schaefer & Warren 2002, 10.1145/566570.566586, §2.3, read this session |
| V-19 | Dual Contouring's topology is Surface Nets' topology. The paper's algorithm is literally: vertex at the QEF minimizer for each sign-changing cube, quad joining the four cubes of each sign-changing edge. Only vertex placement differs | same, §2.2 |
| V-20 | A QEF is stored as AᵀA (symmetric 3×3), Aᵀb (3-vector) and bᵀb (scalar) — 10 floats — rather than as A and b |
same, §2.3 |
| V-34 | Manifold Dual Contouring's uniform-grid criterion is one vertex per cycle of a decider-modified Marching Cubes table, and the paper claims that surface is unconditionally manifold. §3, Contouring on a Uniform Grid: "On a uniform grid, DC leads to nonmanifold vertices and edges for all of the ambiguous sign configurations in the original MC algorithm. … Nielson associates one vertex with each cycle of a modified MC table [26]. … each edge is associated with exactly one vertex. … this surface is always a manifold because the original MC algorithm always constructs a manifold and the dual preserves the topology of the surface." Reference [26] is Nielson & Hamann, The Asymptotic Decider, VIS 1991, and [13] is Nielson's Dual Marching Cubes, VIS 2004 — so the face ambiguity is resolved upstream, inside the table the cycles are read from, and the dual walk needs no rule of its own. That is the question A-022 was blocked on and could not answer. The claim itself is ✗19 | Schaefer, Ju & Warren, 10.1109/TVCG.2007.1012, read at A-022 from cs.wustl.edu/~taoju/research/dualsimp_tvcg.pdf |
| V-35 | Grosso 2017's implementation does not exist publicly, and that is now checked rather than assumed. A-002i is rule-5 stopped on §4.2's "the other two points are slightly moved towards the interior of the cell" — no distance given — and V-31 recovered the artefact both Grosso papers cite from Software Heritage, only to find it is the 2016 code, whose singular handling is the face-pairing choice rather than §4.2's construction. Three further routes, all empty: github.com/rogrosso now has one public repository and it is a lecture course; a GitHub code search for the algorithm returns nothing; and github.com/reproducibilitystamp/tmc — a live mirror, so not a deletion problem — has pushed_at 2016-06-06, which is the same artefact again. So the displacement constant is in no published artefact, and A-002i's stop is confirmed rather than merely unresolved. Recorded so the search is not repeated |
A-002i, checked 2026-08-16 against the GitHub API |
| V-36 | CoACD's intersection-free guarantee is a property of its cut, and its own default merge stage breaks it — which resolves a contradiction between two sources in this file's own corpus. ✗20 recorded VisACD's figure that "merging produces intersecting convex hulls in 35% of cases" about the hulls CoACD emits. CoACD's own §6.2 says the opposite: cutting solid meshes with 3D planes "results in flat boundaries between components. It ensures intersection-free convex hulls and avoids the defects caused by voxelization", and §6.4 repeats it — "In this way, we ensure convex hulls of the decomposed components are intersection-free." | A-026, both papers read directly. Both are true, of different stages. The recursive plane cut yields disjoint solids with flat boundaries, whose hulls cannot intersect. §6.5's post-process then "traverse[s] all pairs of adjacent components and check[s] the Concavity of the merged component. If it's within the threshold ε, we will replace the two components with the merged one" — and a merged pair's hull is the hull of their union, which can reach into a third neighbour. That is where the 35% comes from, and VisACD's sentence names the stage explicitly. The consequence for A-026 is concrete and is not a compromise. A cutting substrate needs cells that partition the interior; overlapping hulls double-count volume, which is the property that disqualified CPD (✗21). CoACD supplies exactly what is needed with merging disabled — and §6.5's merge exists solely to "further reduce the number of components", so it is an economy lever, not a correctness one, the same shape as Delaunay-ness in T-024b. It is on by default: "all of our methods include the merging stage unless otherwise noted." So the knob that makes CoACD usable here is one you turn off, and nothing in its abstract would tell you that. |
| V-52 | Bevy 0.20 never evicts a render asset whose usages drop RENDER_WORLD when it is modified, but its mesh allocator frees the modified mesh's slabs anyway — so a drawn mesh overwritten in place by a main-world-only one stops drawing instead of lingering as stale geometry. extract_render_asset queues a Modified id for extraction and then skips it for lacking RENDER_WORLD, and RenderAssets removes only on Unused, so the old RenderMesh stays. MeshAllocator::free_meshes frees every id in removed ∪ modified ∪ added, pinned by its own test "A mesh flagged modified must be freed even when it isn't re-extracted", and bevy_pbr's draw command returns Skip when the vertex slice is gone. This is what makes a content-dependent usage in MeshBuilder::into_mesh safe for callers that re-mesh in place |
bevy_render-0.20.0/src/render_asset.rs:325-367, src/mesh/allocator.rs:431-436, 627-655, 885-913; bevy_pbr-0.20.0/src/render/mesh.rs:4705-4710. Confirmed on Metal by M-496 |
Part 4 — Open questions
Each has the test that would settle it. An open question with no proposed test is a wish.
| # | Question | Settled by | Why it matters |
|---|---|---|---|
| O-1 | G-002 instrumentation; hash cell slabs, log per stroke | Unpublished, and the ceiling on every incremental-repair idea in the opportunities doc. The ceiling is high enough to be worth having: incremental re-meshing does 15–36% of the work, not 100% | |
| O-2 | gyroid and fbm_terrain drop 23× and 13.7× without reaching it, and those two are precisely the multi-sheet-cell fields — so what the clamp cannot fix is connectivity, which is A-010's problem, not placement |
A-009: measure per 1,000 triangles, clamp on vs off, all seven fields | Decided whether guaranteed intersection-free extraction is free → whether runtime convex decomposition can stop failing. Answer: free for placement, not sufficient overall |
| O-3 | Marching Cubes vs Surface Nets vs Dual Contouring vs MT — actual relative speed on one machine? | M-001 | The comparison does not exist (V-17). We'd have the only apples-to-apples measurement |
| O-4 | BrushOp::commutes_with returns that honest answer |
G-003: 8 ops × 40,320 orderings, count distinct results. Expect 1 | The coordination-free multiplayer story survives inside a run and dies at every boundary. That is a protocol's problem, not this crate's — networked editing is closed out in BACKLOG.md on exactly this evidence |
| O-5 | Do mesh shaders work on macOS/Metal? | GPU-007 capability probe | Sources contradict: wgpu's spec table lists MSL as planned; the tracking issue says the Metal HAL backend merged. Neither is trustworthy until probed |
| O-6 | What is amortized meshing cost per frame under continuous editing? | E-206 under a deliberately overloaded queue | The only number a game cares about, and no paper reports it |
| O-7 | What fraction of our pipeline is contouring vs everything else? | M-003 | V-4 says 54% for someone else's code with no physics. Ours is probably worse |
| O-8 | Does Dual Contouring's vertex placement need f64 in practice, or is f32 enough? | E-112, with the QEF condition number in the HUD | M = AᵀA squares the condition number. Half answered by V-18: the original paper measures f32 error ~1 on flat regions at 256³, and recommends f64. Partially answered by M-23: on extraction paths with no solve, f64 costs only 8–10% of wall time, so precision is cheap where there is no QEF. Still open for the vertex solve itself, and for our fields at our resolutions — which sidesteps AᵀA entirely and may not degrade the same way |
| O-9 | How much does T-003's gradient-flow chord over-estimate distance at a concave seam? | A comparison against nearest-point search over a dense surface point cloud, or E-104 once Dual Contouring lands | The chord follows ∇f to the zero set, which near csg_difference's seam can land further away than the true nearest point. The bias direction is known and safe for a "below X" gate; the magnitude is not measured, and M-001's shootout column would inherit it. csg_difference measured forward 0.0833 at 33³ — how much of that is seam bias is unknown |
| O-10 | h?gyroid 3.13% → 2.05% → 0.53% and fbm_terrain 1.70% → 0.84% → 0.77% at 17³/25³/33³, and exactly zero on the other five fields at every resolution. Still open only as the slab sweep, which would give thickness-over-h directly rather than resolution-at-fixed-field |
A-010 drove it to zero, which was the ticket's job; a sweep over a slab of shrinking thickness would give the parametrised form | M-15 established it is a resolution effect rather than a topology one, and M-4 has counts at two resolutions on two fields. It decides whether Surface Nets is usable at game resolutions or needs A-010 first |
| O-11 | (ANSWERED at R-007, M-284: the dual carries a fourth stage Marching Cubes has not — emit_quads, which walks every grid edge on all three axes and loads both endpoints before the sign test that would let it skip. It is O(n³) where the surface is O(n²), runs at IPC 0.72 against the rest of the mesher's 3.8–6.5, and is 82% of the cycles. Every other candidate was excluded by measurement first — see M-279. The remedy is A-023, and it is not a vertex rule.) Why does the dual topology go superlinear in n³ while Marching Cubes does not? (Half-answered at M-45: it is not one machine's cache hierarchy. Surface Nets degrades on Zen 3 too — 37.4 → 49.1 ns/sample — and the Surface Nets/Marching Cubes ratio is worse there than on the M5. What remains open is the mechanism, not whether the effect is real.) |
A profile or cache-miss counter at 192³ vs 256³. The cross-machine experiment is done; a second one would not add anything | The working-set hypothesis survives and is strengthened: Surface Nets gathers the four cells around each crossed edge with one stride n² cells apart, and that stride is architecture-independent, which is exactly the kind of cost that would reproduce across microarchitectures. Note both machines show a per-sample spike at 128³ (M5 Surface Nets 9.35, Zen 3 Surface Nets 53.84 against 45.6 at 96³ and 47.3 at 192³) — a working-set effect at one specific grid size on two unrelated cache hierarchies, which is itself a clue nobody has followed. Narrowed at R-005 (M-279), and the working-set hypothesis in this cell is wrong. The counters are in: the gather is O(n²) and the cost is O(n³), and a field with no surface at all costs the same to within 0.9%, so it is not the gather. Nor branches (they fall), nor allocation (0 page faults), nor the TLB. What is left is a 16% IPC decline on an instruction stream that is flat per sample — and at 16.7 M samples a 2.4× swing in misses moves the cycles by 0.4%, so the miss column is not the driver either. The 128³ spike is resolved: 127³ and 129³ are normal and only 128 has a 64 KiB plane stride, so it is conflict aliasing, and it survives on the empty field. Residue is R-007 |
| O-12 | Is Marching Cubes unconditionally manifold now? ✗15's only counterexample was the fan chord and A-015 removed it; the strict gate passes 8,000 generated cases where it used to fail on the first seed. But nothing proves a second mechanism does not exist | An exhaustive search over configurations spanning more than two cells — the two-cell sweep is exhaustive and the vertex-link case is not covered by it at all. Or a proof that a cell-local cycle triangulation plus shared face segments cannot produce a non-manifold vertex | The strict gate is now asserted, so if a second mechanism exists CI will find it on some future seed. That is the intended outcome: a failure there is a finding, not a regression, and the failing case would be the first example of whatever the mechanism is. First example found at ✗43 (M-360), and it is inside one cell. The interior rule's Contours::fan fanned every ring of a cell from one shared INTERIOR apex, so two rings longer than three glued into a bowtie: a non-manifold vertex with every edge counter reading clean, which is exactly the vertex-link case this row says the two-cell sweep cannot reach — and a two-cell sweep never could have, because both face groups live in the same cell. Found by the_interior_rule_meshes_convex_bodies on a fresh seed, fixed by a per-ring apex, pinned as a fixture and a committed seed. The third mechanism does not exist for Marching Cubes, and that half is now closed by exhaustion (M-374, P-63). Every face incident to an edge vertex comes from one of the four cells sharing that edge; those four cells are a 3 x 3 x 2 block of 18 corners, so the space is 2^18 = 262,144 sign patterns and it runs in 21 seconds. Meshed, welded and link-walked on all of them, with the interior rule off and on and at four independent magnitude draws: zero vertices with a split link, worst_link_components 1 throughout. The control is not argued either — merging a cell's interior apexes back into one reproduces ✗43's pre-fix topology and yields 5,302 link-defective vertices on 5,863 patterns in the same walk. Exhaustive over signs and sampled over magnitudes, four seeds, reported per seed; the residue is bounded by the ring structure being a function of (case, joined_mask, hexagon), which the_fan_covers_each_ring_once_and_repeats_no_index sweeps over all 16,384 pairs. Still open, and only this: the dual family. P-63's C3 tried the same block and is vacuous — a dual vertex lives at a cell centre and its link needs the cell's 26 neighbours, 4^3 = 64 corners, so the 18-corner block gives every dual vertex at most 2 incident faces and cannot host the configuration. That needs the 3 x 3 x 3 block at 2^27 = 134,217,728 patterns, which is a nightly gate and its own ticket |
| O-13 | sphere: 33³ 3.036, 49³ 3.026, 65³ 3.003 — from above, onto 3.0 |
(closed) | And M-52 supplies the mechanism the prediction did not need but turns out to have: the ratio is 4.0 in one octant and 2.0 across a sign change, so 2.992 is an average hiding a factor-of-two spread. That is why the shootout CSV carries every field |
| O-14 | (closed) | The prediction's stated counterintuitive part, "more vertices and worse accuracy", is the half that is wrong. Marching Tetrahedra buys 3× the vertices for 4% worse accuracy on smooth fields and better accuracy on sharp ones | |
| O-15 | 3.94× and a sphere 3.00× when both are locally flat at cell scale?4.0 exactly, a sign change gives 2.0, and the isotropic average is P-1's 2.992. A plane has one normal and a sphere has all of them |
(closed) | What remains is small and not worth a ticket: the mixed-sign measurement spreads 1.98–2.27 against a predicted flat 2.0, so the continuum model gets the mechanism exactly and carries a discretisation term it does not describe |
| O-16 | Can the parallel dual-edge collapse (M-59) be removed without giving up the cycle partition? The dual is a manifold complex; the index buffer is where it stops being a manifold mesh. A finer split — one vertex per face-segment adjacency rather than per cycle — would separate the endpoints, but it is not obviously topology-preserving and would cost vertices on every field rather than the two that need them | Enumerate, over all (case, joined) pairs on both sides of a shared face, the configurations where both cells put both of that face's segments in one cycle. That is a finite two-cell sweep of the same shape as ✗17's, and it would say whether the collapse is rare-and-coarse-only or merely unobserved on the seven fields |
Bounded in practice: zero on all seven reference fields at every tested resolution, one edge on the ✗15 fixture at h = 2/3, gone by h = 1/2. So it is the same "coarse grid does not resolve the surface" regime as ✗15 and ✗17, and the same answer probably applies — refine, or accept it and pin the count |
| O-19 | Which direction does the λ-medial-axis filter run — Attali's keep-r ≥ λ, or the 3D Skeletons STAR's discard-circumradius-larger-than-λ? The two surveys state it in opposite directions; one is inverted, or they describe dual constructions. R-030's instrument was insensitive to the discrepancy (M-325 measures r, not the filter), but any build on the identity picks a direction, and picking the wrong one keeps noise and discards signal. (O-17 and O-18 live in BACKLOG's deliberately-not-in-scope list; numbering is global.) |
Obtain the primary source, Chazal & Lieutier 10.1016/j.gmod.2005.01.002 — acquisition #1 in the 2026-08-17 dossier — or derive the direction from the Attali survey's own constructions, which are in the corpus and READ |
The Calibre/throat/handhold builds are gated on M-325's measured convergence and this definition; it is the last thing standing between the identity and a build ticket |
| O-20 | Why are ✗41's 216 near-surface unnecessary survivors unnecessary? They are brushes whose Lipschitz enclosure genuinely straddles the surface band over their chunk, so P-39's distance test cannot reject them, and yet removing any one of them individually leaves mesh_hash bit-identical. They concentrate in the chunks with the most surface — 29 in the 7,439-triangle chunk, 24 in the 6,177, 17 in the 4,149, 15 in the 1,527 — which is a pattern and not a mechanism. Domination in the min/max chain is the obvious candidate and it is currently unmeasured: p-59.csv's dominant_adds is 0 on all 64 rows and counts a different notion than the one the candidate names. |
A per-brush test at the cells that carry triangles: for each near-surface unnecessary survivor, count the surface cells where it attains the fold's min/max and check the count is zero. That is a definition of domination the mesh can falsify, unlike an interval comparison over the whole chunk. Register it before running — the reason this row exists is a mechanism stated without its instrument. |
It is the residue of P-39's bound after ✗41: the distance route explains 1,218 of 1,434 and something explains the other 216. A named second route is a tighter pruner; a null says the bound is already at its useful limit and closes the direction with a distribution. |
Pre-registered predictions
Registering the predicted value before running the measurement is the point. A prediction that first appears after the number is known is not evidence, and this project has already caught itself writing expectations into docs that the measurement then disproved (✗1, ✗3).
P-1 — Marching Tetrahedra / Marching Cubes vertex ratio = 3.0×. Derived, then confirmed
numerically, before implementation. Outcome at A-003: confirmed exactly, and the spread explained — sphere 3.04, torus 3.04 against a predicted 2.99, and box_exact 3.91 with a bare plane 3.94 — because the ratio is 4.0 inside one octant and 2.0
across a sign change, and 2.992 is the integral of those over the sphere. The derivation was not
just right, it was the whole answer; what it did not say out loud is that the average hides a factor-of-two
spread over individual orientations. See M-51 and M-52; O-15 is closed.
The 6-tet decomposition is the Kuhn / Freudenthal triangulation — Freudenthal 1942, Kuhn 1960, decades older than Doi & Koide 1991 and far better documented. Verified: the six monotone 000→111 paths give six tets, each of volume exactly 1/6, summing to 1, all sharing the main diagonal.
Its tet mesh uses 7 edge families per cell against Marching Cubes' 3 — 3 cube-axis (|e|=1),
3 face diagonals (√2), 1 body diagonal (√3). Weighting each by crossing probability E[|n·e|] over
uniformly random surface orientations: 4.4877 / 1.4999 = 2.992. Counted directly on a sphere SDF:
| grid | Marching Cubes (3 axis) | Marching Tetrahedra (all 7) | ratio |
|---|---|---|---|
| 33³ | 1830 | 5582 | 3.050 |
| 65³ | 7470 | 22394 | 2.998 |
| 129³ | 30078 | 89978 | 2.991 |
Falsified by a converged ratio outside ~2.95–3.05 — which would indicate the implementation is not emitting one vertex per crossed tet-mesh edge, i.e. an edge-cache or decomposition defect.
P-2 — Marching Tetrahedra is less accurate despite having 3× the vertices. Mechanism: linear
interpolation places a vertex at the zero of the linear approximation along an edge, so its error
scales with |e|². Every Marching Cubes crossed edge has |e|² = 1. Weighting Marching Tetrahedra's
seven families by crossing probability gives mean |e|² = 1.859, worst case 3 (body diagonal).
More vertices, each individually further from the true surface. Against M-10's 1.380e-3, that
predicts ≈ 2.6e-3 — above Surface Nets' 2.288e-3.
This is consistent with M-12's measured h² convergence: the error term is O(|e|²·κ), and Marching
Tetrahedra simply draws from a longer-edge distribution.
Scoping caveat — do not file this as confirming Lewiner. Lewiner et al. 2003 says tetrahedral vertices "cannot be adjusted to fit the geometrical trilinear approximation as we do with cubes" — he is comparing against his trilinear-fitted MC33, not linear-interpolation Marching Cubes. A-003 therefore tests "Marching Tetrahedra vs linear-interp Marching Cubes", the weaker half. The trilinear half needs A-002's decider plus trilinear-aware vertex placement to compare against, which A-001 does not do. Record the verdict against the comparison actually run.
P-3 — the conforming property is assertable, not just assumable. Kuhn tiles space face-to-face
only if every cell picks the same main-diagonal direction; the 5-tet decomposition needs
alternating orientation instead, which is why it is the wrong choice here. Verified: cell A's z=1
face is split by its local diagonal 001–111, cell B's z=0 face by 000–110, and those are the
same world-space segment. Assert it directly — compute the shared face's diagonal from each side and
require equality — rather than trusting the construction. Same shape as face_disagreements.
P-4 — the case table is 16 entries and needs no source paper. A tet has 4 corners, so 2⁴ = 16 sign configurations: 2 trivial, 8 one-vs-three (the isolated corner's 3 edges cross → 1 triangle), 6 two-vs-two (4 edges cross → 2 triangles). Generate it and prove it exhaustively. Doi & Koide being unobtainable costs nothing here — unlike A-001's 256 cases, this table cannot be mistyped because it is not typed.
P-5 — Manifold Dual Contouring carries Marching Cubes' Euler characteristic across exactly.
Registered before running, from the construction rather than from a paper: the output is the dual of
this crate's Marching Cubes, and a dual has V' = F, E' = E, F' = V, so χ' = χ identically.
Outcome at A-010: confirmed on every closed field at 17³, 25³ and 33³ — and the one place it fails
is what found M-59. On the ✗15 fixture at h = 2/3 the dual reports χ = 1 against Marching Cubes'
0, and the discrepancy is exactly the number of collapsed parallel edges. So the prediction held, and
its single failure localised a mechanism rather than merely being wrong.
P-7 — thin_plate welds into exactly one connected component, and orienting it as one would
not flip a face. Registered before A-014f is attempted, and before the measurement, because
A-014f's proposed remedy — orient each connected component from its most confident triangle and
propagate — is a per-patch decision, and M-96 is on record that thin_plate's two faces sit 0.4 cells
apart and land in one tetrahedron facing opposite ways. The concern raised against it is that a weld
could merge the two sheets through their thickness and let propagation silently invert one of them,
on the one field that justifies the whole subgrid track (M-95: 4,328 triangles where greedy quads
returns zero).
The prediction is that this specific failure does not occur, for two reasons that should be checked
separately because they can fail separately. (a) The validity suite welds at cell · 1e-6, six
orders of magnitude below the 0.4-cell separation, so no through-thickness merge is possible at the
epsilon actually in use — but the margin, not the outcome, is what should be recorded, since it is
the quantity that would decide a coarser weld. (b) More importantly, thin_plate is closed in
its domain and reports zero boundary edges, so its top and bottom are joined at a rim and are
already one component by topology rather than by tolerance. A closed orientable surface has a
coherent orientation across that rim, so component-wise propagation is the right answer there rather
than a risk to it.
What would falsify it: more than one component after the weld, or a component count that changes with the epsilon, or an orientable-surface check that fails on the welded plate. Any of those means the remedy is unsafe on the field it most needs to be safe on, and A-014f must find another.
Outcome — limb (a) confirmed at T-009, with the margin it asked for (M-181). The concern was that
a weld could merge thin_plate's two sheets through their thickness, and the prediction was that the
epsilon in use sits far below the 0.4-cell separation. Measured rather than argued: welding
thin_plate's subgrid output at every factor from h·10⁻⁹ to h·10⁻³ returns 422 vertices at all
seven, and the first tolerance that changes it at all is h·10⁻¹ — 1000× the one policy — where
it collapses to 128, which is the through-thickness merge finally happening. So the margin is three
orders of magnitude, not the "six orders below the separation" the prediction reasoned from, and the
quantity is now a number rather than an inference. The same test covers the second falsifier outright:
the count does not change with the epsilon, on any of the seven fields, across the whole range the
crate's four historical policies spanned.
Outcome — limb (b) confirmed too, and both remaining falsifiers fail to fire (M-182). Welded
thin_plate is one component with 0 boundary edges and χ = 2 at 17³, 25³ and 33³ — closed, genus 0,
joined at a rim, one component by topology and not by tolerance, exactly as registered. The component
count stays 1 at every epsilon from h·10⁻⁹ to h·10⁻².
So P-7 holds in full, and the remedy it was registered to de-risk is safe on the field that justifies the subgrid track. The prediction was worth making: it named its falsifiers in advance, it was checked against them, and the answer arrived before a line of A-014f was written.
The check also found something P-7 was not looking for. thin_plate's inconsistently-oriented
edges run 17³ → 0, 25³ → 8, 33³ → 6, and nobody had seen it because
the_validity_suite_over_every_reference_field runs at n = 17 alone while Phase 1's gate says three
resolutions. That is A-014f's defect on A-014e's protected field, and it supports propagation: the
surface is orientable and the local vote is failing to find the orientation that exists.
P-6 — splitting the vertex reduces self-intersection on the two multi-sheet fields. Registered
before running, reasoning from M-29 ("the residue is exactly A-010's problem"): if the clamp removed
every placement-caused intersection and the remainder is caused by two sheets sharing a vertex, giving
them separate vertices should remove the remainder. Falsified at A-010 (M-61): it goes up, gyroid
3.118 → 5.669 and fbm_terrain 13.837 → 15.434. The premise was right and the inference was wrong —
two vertices in one cell is exactly what breaks the within-cell partition the clamp's guarantee rests
on. ✗2's competing figure (ODC measuring Manifold Dual Contouring at 100% self-intersecting) was on
the record the whole time and should have been weighted against M-29 before registering this.
P-8 … P-13 — registered before anything was written, and enforced by the compiler (R-000)
The practice became a compile error. P-1 through P-7 were pre-registered in prose, and the record is good — P-6 was falsified and says so, P-7 held. The weakness was that nothing stopped an experiment from being written first and predicted afterwards, which is the exact failure the practice exists to prevent and is invisible in the artefact: a prediction recorded after the numbers came in reads identically to one recorded before.
So the predictions now live in crates/isomesh/src/experiment.rs, and isomesh::experiment!("P-n")
does not compile for an id that is not in PREREGISTERED. Registering is a commit, so git carries
the ordering that prose cannot. scripts/backlog_gate.sh checks every registered id reaches this
file — the Rust is the source, this is the elaboration, and the gate stops the two from parting
company.
Preregistration has a falsified_by field and no way to omit it, which is the other half: a
hypothesis with no stated refutation is a description in the future tense.
| id | ticket | prediction | falsified by |
|---|---|---|---|
| P-8 | R-001 | A weld gated on Lk u ∩ Lk v = ∅, leaving rejected pairs split, yields exactly 0 non-manifold edges and vertices on all eight fields × all extractors, where the unconditional weld yields N > 0 |
The gated weld still producing non-manifold output — which would prove the surface link condition insufficient for index-buffer realisation, and is the more interesting result |
| P-9 | R-002 | For buckets of ≥3 coincident vertices, at least one field yields ≥2 distinct outputs across seeded permutations of within-bucket merge order | All permutations byte-identical on every field, meaning the k-way weld is confluent and no canonical order is needed |
| P-10 | R-003 | Vertex inflation from gated-weld-plus-split is < 1%, and self-intersections per 1k are unchanged | Inflation > 1% (a real trade-off needing a stated policy), or self-intersections rising (M-93's duplication artefact returns) |
| P-11 | R-004 | With one canonical world_of_sample rather than offset-and-add, seam cracks fall to 0 for all cell sizes — not only powers of two — and M-73's hairline disappears with no change to Transvoxel |
Cracks surviving canonical reconstruction, which localises the defect back in Transvoxel |
| P-12 | R-005 | The dual's superlinear cost is the four-cells-around-a-crossed-edge gather at stride n²: cache-miss count per sample rises with n for Surface Nets and stays flat for Marching Cubes |
Flat miss rates, pointing at branch misprediction or allocation instead |
| P-13 | R-006 | M-66's non-convergent angle is bounded below by the dihedral angle of the feature, so it is a property of sharp edges rather than of resolution | The angle failing to track the dihedral prediction, which makes it a defect with a location |
Each experiment's numbers land in docs/experiments/p-n.csv, stamped with the git SHA, the machine
and the time — and flagged WORKING TREE DIRTY when the tree was not clean, because numbers that
correspond to no commit have to say so on the artefact rather than in someone's memory.
P-8 — FALSIFIED, in both clauses, and the gate makes things worse (R-001)
M. Eight reference fields × seven extractors × a 2×2×2 block of independently meshed chunks at
h = 4/35, both welds run on the same meshes in one pass. docs/experiments/p-8.csv.
These numbers replace a first run whose fixture was broken (M-274). The block was placed at
-2.0with 8-cell chunks, which spans 1.83 of the 4-unit domain and clipped a corner off every field. It produced no bucket with more than two members, so the mechanism the first write-up asserted was about a configuration the run never contained. The block is now centred and 18-cell, and P-9 reports 6–32 buckets ofk ≥ 3per configuration.
Clause one — "where the unconditional weld yields N > 0" — is false in 47 of 56 configurations.
Welder produces zero non-manifold edges and zero non-manifold vertices everywhere except nine rows,
all under dual or subgrid extractors:
| field | extractor | ungated e/v | gated e/v | rejected |
|---|---|---|---|---|
torus |
dual_contouring |
0 / 4 | 0 / 4 | 0 |
torus |
manifold_dual_contouring |
0 / 4 | 0 / 4 | 0 |
thin_plate |
subgrid_marching_tetrahedra |
4 / 6 | 0 / 135 | 143 |
fbm_terrain |
surface_nets |
1 / 2 | 1 / 2 | 0 |
fbm_terrain |
dual_contouring |
1 / 2 | 1 / 2 | 0 |
noise_cavity |
surface_nets |
276 / 536 | 276 / 536 | 1 |
noise_cavity |
dual_contouring |
277 / 539 | 276 / 537 | 8 |
noise_cavity |
manifold_dual_contouring |
66 / 145 | 65 / 143 | 9 |
noise_cavity |
subgrid_marching_tetrahedra |
222 / 301 | 218 / 1,092 | 928 |
Clause two — "yields exactly 0" — is false, and the trade is catastrophic. Across all 56
configurations the gate removes at most 4 non-manifold edges (thin_plate + subgrid, 4 → 0) and
adds up to 791 non-manifold vertices (noise_cavity + subgrid, 301 → 1,092). On every primal
extractor — where the weld was perfectly clean — it manufactures non-manifoldness from nothing:
sphere 0 → 96, torus 0 → 108, box_exact 0 → 102, noise_cavity 0 → 407.
The mechanism. vertex_delta equals rejected_merges in all 56 rows, so every refusal leaves
exactly one extra vertex — the inflation is arithmetic and harmless. The damage is that a coincidence
of k vertices is manifold only when all k merge: refusing one leaves the representative
carrying cones from some copies and not others, which is a bowtie — two cones sharing an apex, every
edge with exactly two faces, χ intact. That is precisely what validate's link walk exists to catch
and what an edge count cannot see, and it is why the damage shows up in the vertex column while the
edge column barely moves.
So the pre-registration's stated falsifier — "proving the surface link condition insufficient for
index-buffer realisation" — has the verdict right and the reason half right. The pairwise
condition is not insufficient for a pairwise merge. It is being applied greedily inside a k-way
group, and Dey, Fan & Wang's decomposition into k − 1 pairwise merges in the intermediate complex
is exactly what does not commute with rejecting one of them. Rejecting a merge is not a safe no-op —
it is a decision to split, and a split part-way through a group is worse than either whole.
Two consequences downstream. R-003 asked whether splitting the unsafe merges is free; it is not,
and the cost is not the vertex inflation it anticipated but new non-manifoldness. And the residue —
276 edges and 536 vertices on noise_cavity under surface_nets, which the gate rejects one
merge against and changes not at all — is an extractor defect rather than a weld defect.
P-9 — HELD, and the driver is not k (R-002)
M. Eight seeded permutations of within-bucket order per configuration, re-welded, compared by
byte-identity. Same fixture as P-8. docs/experiments/p-9.csv.
Nine of 56 configurations produce more than one distinct output, so H holds: the k-way weld is
not confluent and CLAUDE.md's byte-identity guarantee rests on the input order being
deterministic rather than on the weld being order-free.
But the premise is wrong about why. H said "for buckets of ≥3 coincident vertices". Measured, the correlation runs the other way:
| field | extractor | distinct | vertex spread | buckets k ≥ 3 |
|---|---|---|---|---|
sphere |
marching_cubes |
1 | 0 | 6 |
box_exact |
marching_tetrahedra |
1 | 0 | 6 |
torus |
dual_contouring |
5 | 0 | 0 |
torus |
manifold_dual_contouring |
5 | 0 | 0 |
noise_cavity |
dual_contouring |
8 | 4 | 1 |
noise_cavity |
manifold_dual_contouring |
8 | 2 | 2 |
noise_cavity |
marching_tetrahedra |
6 | 0 | 21 |
Every primal extractor has 6–32 buckets of k ≥ 3 and is perfectly confluent. torus under the
duals has none and yields five different outputs.
The driver is whether the coincident vertices are bit-identical, not how many there are. A k ≥ 3
bucket on a primal extractor comes from M-48 — a grid sample landing exactly on the isosurface, so
every cut edge meeting there places its vertex at the same computed point, within one chunk, by the
same expression. Those are bit-identical, so which survives cannot change a byte. A seam bucket spans
two chunks that computed the plane by different expressions, and M-32 measured those disagreeing by
an ulp — so which survives changes the output exactly.
And two rows change the vertex count, which is the part that matters. noise_cavity under
dual_contouring spans 4 vertices across the eight permutations, and under
manifold_dual_contouring 2. Epsilon-closeness is not transitive and Welder uses first fit, so
permuting the order changes how many representatives are elected, not merely which. The weld's own
documentation predicted this in prose ("a chain a ~ b ~ c with a and c further than ε apart
yields two representatives"); this is the first measurement of it.
What it means for a consumer, which is not what the ticket feared. R-002 worried that gating would
break determinism; gating is reverted (P-8), so that threat is gone. The live one is that a chunked
consumer appending chunks in a different order gets a different vertex count on noise_cavity,
not merely different bytes. The order is deterministic today because the loops are; nothing enforces
it.
Part 4b — Experiments run, and what happened to them
The slot this file did not have (T-013). M- records a measurement, ✗ a belief that died, O-
an open question and a P- prediction rides inside the O- row it settles. None of those is the
right home for "we built the variant, measured it, and put it back" — and with Phase 8's ablation
seam, most experiments will end that way. A reverted experiment whose numbers were never written
down gets re-run in six weeks by someone who has forgotten, which is the specific waste this section
exists to prevent.
An entry is owed whenever an ablation runs, whether it was kept or not. The verdict line is the point; the numbers are what make it re-checkable.
| E×n | **<the variant, in one line>** | H: <the hypothesis, as pre-registered> | <numbers, both arms> | **KEPT** / **REVERTED** — <why> | <ticket, harness> |
| # | Variant | Hypothesis | Both arms | Verdict | Where |
|---|---|---|---|---|---|
| E×1 | Surface Nets' centroid as Dual Contouring's vertex rule | The QEF is worth its cost on sharp fields and not on smooth ones, and pays for it in self-intersection | Hausdorff at 65³, QEF ÷ centroid: sphere 0.486, torus 0.457, csg_difference 0.255, box_exact 0.010, thin_plate 0.010. Self-intersections per 1k at 33³: QEF 3.118 / 13.837 / 29.745 on gyroid, fbm_terrain, noise_cavity against centroid's 0.000 | KEPT as an ablation, not as a default. Both arms are real answers to different questions and neither dominates — 100× accuracy on sharp features against zero self-intersections. The seam stays so the comparison can be re-run; Qef stays the default because sharp-feature recovery is what A-007 exists for |
X-002, benches/ablation.rs, M-237 |
| E×2 | A separate probabilistic-quadric solver (Trettner & Kobbelt, 10.1111/cgf.13933) |
It supersedes the Tikhonov regularizer and is more robust on near-singular cells | Never measured as a separate solver, because it was shown identical first: a direct assembly of the paper's equations agrees with solve_with at λ = Nσ² to 1.110e-16 over 296 cells |
REVERTED before it was written. In this crate's centroid-relative coordinates the paper's extra term is σ²Σrᵢ, and Σrᵢ ≡ 0 because the centroid is the mean of the crossings. A second solver would have been a second execution path computing identical numbers. Do not re-attempt for isotropic noise; the open door is anisotropic Σₙ, which needs a noise model analytic fields do not have |
X-004, the_probabilistic_quadric_is_the_existing_solve, M-238 |
| E×3 | Crossing-count-scaled regularizer (λ = Nσ², the part of E×2 that is different) |
Scaling λ with the number of planes beats one fixed λ per cell | Hausdorff at 65³, scaled ÷ fixed: sphere 1.0000, torus 0.9957, csg_difference 0.9992, box_exact 0.7519, thin_plate 0.7519. Self-intersections at 33³ fall on all three noisy fields: 3.118→2.551, 13.837→13.571, 29.745→28.749 | KEPT behind experimental, not made default. Never worse and 25% better on both sharp fields, which is a real improvement — but the default carries T-007's committed golden hashes and 112 baseline rows, and moving those for a 25% gain on two of eight fields is a decision with evidence attached, not a tidy-up. Promoting it is its own ticket |
X-004, crates/isomesh/src/experimental.rs, M-238 |
| E×21 | dot_equivariant(g, g).sqrt() in place of vec3::length, one line, one call site |
H (P-101): M-372 says the duals accumulate crossings in an order axis relabelling permutes and points at M-177, but M-177 is about negation and p-61.csv already reaches 48 on 3 of 16 rows, which a structural obstruction would not permit — so a relabelling-invariant order should take the duals from 3 of 16 to 16 of 16, at zero geometric cost |
Arm edge_slot_equivariant_normal, against the shipped path in the same binary and the same run: pure_permutation_exact 6 of 6 on 32 of 32 dual rows against the shipped 8 of 32, and 192 of 192 element-slots against 100 of 192; elements_vertex_exact Σ 492 against 392, up on 24 of 32 rows and down on none, {2: 10, 4: 2, 24: 1, 48: 3} → {6: 11, 12: 1, 24: 1, 48: 3}. Cost: 34 of 48 golden dual hashes move, 9,115 of 66,930 vertices (13.6%), max_hausdorff_delta 2.879640970121e-16 with topology_identical / counts_identical / indices_identical true on all 48 — 104× geometrically tighter than the registered key's 3.008704396734e-14 |
NOT LANDED — and this is the lead, not the registration's. dot's body is the single line a[0]*b[0] + a[1]*b[1] + a[2]*b[2], a three-term sum in axis-index order, and it is the only axis-index-ordered reduction left on the path from eight corner samples to a dual vertex; commutativity fixes {0,1} as a set, which is the identity and the x↔y swap, and ✗49 / M-372's "2 of 48, identity and the x↔y swap" is that expression measured before anyone named it. dot_equivariant already exists, is already pub, and already runs three lines away at solve.rs:228-230. What it costs to land is a 34-hash rebaseline, which the phase brief makes the owner's call and not this row's. Do not widen it to vec3::dot itself without re-pricing: 25 non-test call sites on dot, 8 on length_squared, 21 on length — 54 across 15 modules — so that variant's blast radius is the whole 216-row golden fixture, not 48 |
R-101, benches/experiment_p101.rs, docs/experiments/p-101.csv, ✗79 / M-413 |
| E×20 | Crossings accumulated as a running sum in a relabelling-invariant key order ((\|a+b\|, \|edge_offset(a,b)\|) with invariant tie-breaks) |
H (P-101): accumulating in an order keyed on the cell's geometry rather than on axis indices takes dual_contouring to 48 of 48 on at least 12 of 16 rows; it is free, no golden hash moving except through the accumulation order and Hausdorff unchanged to 1e-12; and manifold_dual_contouring does worse, because its cycle partition adds an order-dependence the key cannot reach |
Two bench-local VertexRules through the public DualContouring::with_rule, against the shipped extractor on the same rows: c1_rows_at_48 3 of 16, identical to baseline_rows_at_48_dual_contouring = 3, and worse on 9 of 16 rows, better on 0; Σ pure_permutation_exact 80 of 192 against the shipped 100 of 192, inventing a bucket at 1 exact element and putting eight rows in it; pure_sign_flip_exact moved by not one element under four accumulations. Cost measured without applying it: hashes_moved 40 of 48, positions_moved 37,764 of 66,930 = 56.4%, max_hausdorff_delta 3.008704396734e-14 against a 1e-12 bar. Instrument: the edge_slot replica is bit-identical to shipped on 320 of 320, 0 of 48 hashes and 0 of 66,930 positions moved |
NOT LANDED, and the answer is "no" rather than "not yet". R-101 was one of only two permitted source changes in Phase 24 and the harness declined the permission: golden_hashes.json is byte-unchanged and the 40 moved hashes are a priced cost of a change never applied. Nothing would make it landable — it is worse on 9 of 16 rows and better on none, for 40 hashes and 56.4% of golden dual vertices. The mechanism is in the file: the key is not total, total_unbreakable_key_ties 1,523,248 of 6,304,928 (24.16%) fall through to edge index, which is precisely what a relabelling permutes, so the "invariant" order is strictly less invariant than what A-016 already ships. M-372's premise needs correcting where it is quoted, and "make the duals octahedrally equivariant at 48 of 48" should be foreclosed as a goal |
R-101, benches/experiment_p101.rs, docs/experiments/p-101.csv, ✗79 / M-413 |
| E×19 | The barycentric (Kuhn/Freudenthal) 24-tetrahedron cell decomposition, replacing the six-tet split | H (P-100): M-372's obstruction is in the decomposition, not the extractor — a six-tet split is not octahedrally invariant and no placement rule reaches that — so a 24-tetrahedron barycentric split reaches 48 of 48 on all eight fields at both resolutions where the six-tet split reaches 12, at most 2× the six-tet split's triangles, under 6× combined against Marching Cubes, and still tiling across chunk seams at zero open edges |
Five arms × eight fields × {33³, 25³}, 3,840 extractions through P-61's equivariance instrument in one run: elements_vertex_exact 48 on 16 of 16 with worst_component_ulp 0, beside both six-tet arms at 12 on 32 of 32 and marching_cubes at 48 on 16 of 16. Price: triangles_vs_six_tet 2.3505–2.7264, mean 2.4405 against a 2.0 bar and triangles_vs_marching_cubes 6.1912–10.5579, mean 7.9353 against 6.0, falsified on 16 of 16 rows each, smallest margin 1.1801×, and it survives the non-degenerate recomputation. Vertices move by the same factor (2.3236–2.7258), so it is a finer contour and not a fanning artefact. open_edges 0 on 80 of 80 against a mismatched-diagonal control reading 80–3,765. It does buy geometry: symmetric Hausdorff lower on 13 of 16 rows, −86.0% on thin_plate/33³ and exactly 0.000000000 on box_exact/33³ |
NOT LANDED — invariance is reachable, and it prices out for a game. A player pays roughly eight triangles for every one Marching Cubes emits to gain a property no player can see, so it is not built as a shipping extractor: crates/isomesh/src/** was not touched and the split lives only in the bench, which is also where the one-path rule puts it — a second extractor with a second decomposition is the two-paths defect the crate forbids, and 8× the triangles buys no exception. It stays a CAD-only option, and what is worth keeping at zero shipping cost is the oracle: 48 independent bit-exact relations per fixture where the shipped tetrahedral extractor has 12, plus the only arm in the run that reproduces an axis-aligned box exactly. It would land on a decomposition that is octahedrally invariant and costs under 2× the six-tet split |
R-100, benches/experiment_p100.rs, docs/experiments/p-100.csv, ✗78 / M-412 |
| E×18 | The Plantinga–Vegter certificate fused into the extraction gather, replacing the standalone validate::isotopy pass |
H (P-98): M-378 measured the predicate at 21% of extraction standalone against a 5% ceiling, but the bare eight-corner gather is 0.51 ms on every arm and two thirds of the standalone cost is re-reading corners the extractor has already read — so a fused version costs at most 0.0658 of extraction at 65³ on all eight fields, certifies an identical set on all 25 rows of p-62.csv plus the 400,000-cell random arm, and is reportable per chunk at no extra pass |
Bench-local fused walk (gather_case + fused_certified) against the shipped cell_is_certified loop and the shipped isotopy_report, on the same rows: fused 0.004806–0.055328 of extraction at 65³, worst 0.055328 on box_exact, against standalone_share 0.0152–0.6082 on the same eight rows (0.293057 on box_exact). Run-independent: loads_fused_additional 0 on all twenty-four sampled rows against loads_standalone_additional of exactly 8 × cells = 2,097,152 at 65³. Same answer — set_difference 0 and unsound 0 on 25 of 25, with the mutant control at mutant_set_difference 24,252 and the degenerate control unsound_if_certify_all at 2,389 hidden-topology cells. extra_passes 0 on 25 of 25 from a counted cells_visited == cells, against the shipped API's 1, isotopy_report_ms 0.9906–1.4946 ms — 7.2× the fused marginal on csg_difference, 1.8×–9.7× across the eight 65³ fields |
NOT LANDED — crates/isomesh/src/** was read-only for the ticket and isotopy.rs still carries only the eight-value sign scan. The capability is real and priced: a certified-cell count comes out of the extraction traversal itself for one comparison on a byte the extractor already holds. Landing it means a fused entry point in the extractor that hands the case byte and the eight registers to the predicate — the one thing the standalone form cannot express — and then do not ship the standalone pass, which buys the identical set for a second 8 × cells grid read. Two conditions attach: any quotation of the 0.0658 bar must carry "at 65³", because four 17³ rows read 0.0673 / 0.0685 / 0.0708 / 0.0818; and a per-chunk pipeline must carry the (certified, active) count pair, not the fraction — IsotopyReport::certified_fraction's 1.0-on-empty is a latent 12.9-point error, noise_cavity 0.929270 against 0.800176 |
R-098, benches/experiment_p98.rs, docs/experiments/p-98.csv, M-410 |
| E×17 | A dense Checkpoint field, so undo re-folds from a snapshot instead of from the log |
H (P-95): the 08-11 doc names the gap in one line — "out-of-order arrival forces a re-fold from checkpoint; needs checkpoint cadence measured" — and M-50's 0.158 / 0.354 / 0.525 / 0.589 ms bucket curve should make the cadence derivable rather than tuned, so undoing the last edit costs strictly less than re-folding from a checkpoint whenever fewer than N edits separate them, with N measurable and stable across fields |
A bench-local impl Sdf for Checkpoint with its own trilinear sample and an incremental advance, against the shipped BrushStack fold the demo's Z key uses. Re-folding is cheaper at every separation: undo_ms 37.795 / 41.990 / 29.863 ms against the checkpoint arm at 16.29× / 15.88× / 19.03× at d = 0 and still 1.303× / 1.290× / 1.547× at d = 127 on sphere_r1_2 / gyroid / fbm_terrain; crossover_n 0 on all 18 rows, crossover_direction = none_undo_never_wins, and the fitted crossover lies 40.95 / 38.50 / 73.86 edits past the bottom of the log. The challenger is correct where it is cheap: cp_vs_log_position_mismatches 0 on all 18 rows, checkpoint_rebuild_mismatches 0, hash_mismatches 0 over 3,654 undo/redo round trips. M-50's curve predicts a cadence of 193.8 against a fit-free measured 32 |
NOT LANDED — crates/isomesh/src ships no checkpoint, snapshot or rewind path, and the row's finding is that undo is not a distinct operation to optimise. It is a re-fold at d = k − 1 and the only knob is the cadence, so any design budgeting "cheap undo of the last edit" separately from re-meshing is budgeting a path that does not exist. Two costs decide the cadence rather than the mechanism: memory — 225.30 MiB of snapshots to buy a 3.27 ms worst undo against 7.18 MiB buying 33.16 ms, 30× the memory for 10× the latency — and fidelity, because a checkpoint is a position cache and not a field snapshot: normals mismatch 93.89% → 15.53% (sphere_r1_2), 96.85% → 33.09% (gyroid), 95.05% → 25.82% (fbm_terrain) across k = 4 → 128, worst deviation 179.131°, so they must be recomputed analytically after a checkpointed re-fold. Do not use M-50 as a cadence oracle — its intercept is the base field's sample cost and its slope carries the vertex count, and neither transfers |
R-095, benches/experiment_p95.rs, docs/experiments/p-95.csv, ✗75 / M-407 |
| E×16 | A bespoke entropy coder for the edit log — LZMA's adaptive binary range coder, 11-bit probabilities and 5-bit adaptation, over a second-order linear predictor | H (P-94): brush parameters are strongly correlated along a stroke, so entropy-coding the log beats a general-purpose compressor by at least 2× — the crate owns the edit log, which is what a save file is and what undo rewinds, and Teardown's stated reason for replicating commands is that "commands are the same regardless of object size" | Both compressors see the identical quantised 17-byte record, and the coder is decoded back and asserted equal (entropy_roundtrip_ok true). compression_advantage over zstd -19: 1.418111 / 1.430490 / 1.483570 / 1.533404 / 1.534017 across the five world sizes, against a bar of 2.0. And zstd handed the same second-order residuals lands at zstd_deltas_over_entropy 1.385566–1.427941 — so 1.39–1.43 of the whole 1.42–1.53 advantage survives without the coder. The baseline was never weakened: at the smallest log bytes_zstd_level3 is 8 B smaller than level 19 (9,404 against 9,412). The predictor the clause was registered on is also wrong: bytes_entropy_first_order is 2.21–3.85% smaller than second order on every world (6,382 against 6,637; 121,001 against 123,732), because direction changes between strokes make the second difference noisier than the first |
NOT LANDED — do not write a bespoke edit-log codec. C3's own falsifier says so and bytes_zstd_of_deltas says it twice: the win is the model, not the coder. Ship the transform instead — second-difference the quantised record, then zstd — which is a fifty-line transform, not a format, and zstd is already only a dev-dependency. It would become worth writing only if zstd on the second-order residuals fell far behind the range coder on some other trace. Nothing hangs on it either way: the size question it was registered under is closed at 415,038 B for the largest measured hour and 734,400 B saturated, against a 2 MB bar |
R-094, benches/experiment_p94.rs, docs/experiments/p-94.csv, ✗74 / M-406 |
| E×15 | One write_buffer per frame through a host arena, replacing the per-chunk upload bevy_isomesh ships |
H (P-93): ✗54 measured upload at 7.3236 ms of an 8.3694 ms GPU total, 87.50%, and M-377 left the 51.6% vertex-data penalty at 4³ unpriced against it, so the weigh-off between remesh and upload is computable and has never been computed |
Uploader::upload_arena against Uploader::upload on exactly the same bytes in exactly the same frames, differing only in how many write_buffer calls it took, with the memcpy into the arena inside the timer and the round trip verified (upload_roundtrip_verified true). Streaming ms/s on gyroid, per-chunk against arena: 2³ 44.8756 / 27.8349 (1.61×, where the arm issues 38,994 writes and spends 43.6772 of 44.8756 ms/s on overhead), 4³ 28.4166 / 22.3303 (1.27×), then it reverses — 16³ 28.7316 / 29.2142 (0.983×), 32³ 13.5161 / 15.7187 (0.860×), 64³ 5.2170 / 5.9387 (0.878×). On fbm_terrain 4³ reads 26.8839 / 23.2278 (1.16×). Crossover rates agree that neither is load-bearing: crossover_edits_per_second 0.572216 / 0.177604 against crossover_arena_edits_per_second 0.410188 / 0.152020 |
NOT LANDED, and it is a bevy_isomesh renderer change rather than an extractor change if it ever is. At the granularity this crate actually ships the arena is worth 16–27%, not an order of magnitude — (the earlier "6.07 ms/s, a 6.8× cut" is withdrawn; on the clean tree the 2³ lever is 1.61×, 4.2× smaller than briefed) — and it is worse than per-chunk at 16³ and above, so it cannot be adopted unconditionally. It is only ever worth building for the write count, not the bytes, and only below 8³. Read the arm with its own caveat attached: d_stream_arena was −4.2994 ms/s on gyroid in the superseded run and is +16.391553 here, so the arena crossover is the least stable number in the file |
R-093, benches/experiment_p93.rs, docs/experiments/p-93.csv, ✗73 / M-405 |
| E×14 | A two-level chunk scheduler — coarse everywhere, fine inside every coarse chunk the trace has touched | H (P-93): a per-chunk granularity, coarse for static chunks and fine for actively-dug ones, beats both fixed choices by at least 1.5× on the eleven-edit trace with a moving camera | run_mixed at the registered 64³/4³ and a tuned 16³/4³, scored against best_fixed — the better of the two fixed arms at each rate, whose twelve raw_vertices reproduce M-377 / p-72.csv exactly — and seam-checked to zero symmetric difference in quantised surface points against the fixed reference, so both arms mesh the same world. At game_dig's 12.5 edits/s the registered pair reads 0.2376× (gyroid) and 0.1171× (fbm_terrain) against a 1.5× bar. It never wins at any of the eleven rates on either field even with the subdivision transition amortised to zero (max 0.9936×); the tuned 16³/4³ pair peaks at 1.3760×, and 1.3760× is the maximum anywhere in the file over both fields, eleven rates and four variants. On top of that it pays a hitch the fixed incumbent never pays: 24.3 ms per activation on gyroid and 84.5 ms on fbm_terrain, over 7 and 6 activations of 8 coarse chunks |
NOT LANDED — do not build a per-chunk or mixed granularity scheduler. Granularity is settled rather than a trade: 4³ wins unconditionally, and the crossover C1 predicted between 1 and 20 edits/s does not exist in 0.1–100. Nothing would buy this back at the shipped granularity — the tuned variant's 1.3760× peak lands at 0.2 edits/s, where the mixed frame already costs 21.56–27.90 ms/s, and reaching the window floor of 0.1 edits/s would need a bus 20.7× slower than this rig's. The registration's own premise is also gone: the 87.50% it was written against is the sample-grid upload on a path GPU-011a deleted, and the vertex upload C1 is actually about is 1.71% of a 12.5 edits/s frame at 4³ |
R-093, benches/experiment_p93.rs, docs/experiments/p-93.csv, ✗73 / M-405 |
| E×13 | Lipschitz brush pruning at the brick, beneath P-39's chunk-level cull |
H (P-90): Dreams' hierarchical evaluator culls over 99% of naive edit evaluations with a per-block edit list (Evans, SIGGRAPH 2015 Advances), and this crate's equivalent is P-39's 3.36× median Lipschitz pruning measured at chunk granularity — so at M-377's 4³ optimum pruning still gives at least 2× on M-50's 46–60 bucket, a per-brick survivor list costs under 8 bytes per brick, and the two culls compose rather than overlap |
Four arms interleaved inside each of 21 repetitions — full tape, chunk-pruned, chunk-then-brick-pruned, and an empty-tape floor — with meshes_bit_identical and hashes_identical true on 8 of 8. Incumbent against rival at 46–60: speedup_chunk_only 1.5799× (gyroid) and 1.8825× (ground_slab) against speedup_both 6.3916× and 10.4802×. Clock-free, which is the reading that survives a governor: eval_ratio_chunk 1.5956 and 1.8993 against eval_ratio_both 15.6941 and 18.3847, from 6,080,091 → 3,810,543 → 387,413 and 5,211,855 → 2,744,135 → 283,489 evaluations; mean survivors per re-mesh 34.3920 → 3.3216, a further 10.35× and 90.34% removed at the brick |
NOT LANDED — and the incumbent it beats is the demo's prune_into (bevy_isomesh/examples/game_dig.rs), not a crates/isomesh/src path. The 6.4×/10.5× is real and the bookkeeping is what refuses it: a per-brick surviving-brush list costs 9.398804 and 10.996338 bytes per brick, 300.8–351.9 KiB on a 128³ world, and no O(1)-indexable representation gets under 8 on both fields — the payload alone is 5.398682 and 6.996216, so the room exists only for a structure that can index a brick without a dense offset per brick. If it is ever built, materialise the survivor list lazily for the dirty bricks and discard it: one shape evaluation per brush to recompute against 2–4 bytes per brick per world to store. And do not sell the chunk pass as a cull — at 1.5799× and 1.8825× it is under its own 2× bar and provably so on any machine; it is a pre-filter that cuts the brick pass's input to a mean of 34.39 brushes |
R-090, benches/experiment_p90.rs, docs/experiments/p-90.csv, ✗70 / M-402 |
| E×12 | The classical origin-fan signed-tetrahedron integrator, against the surface form that shipped as mass.rs |
H (P-83): Hartmann & Ewougsi Tekeu, 10.1007/s00707-025-04419-1, insert T = x ⊗ x into the divergence theorem to turn the inertia volume integral into a pure surface integral evaluated analytically per triangle, and its operation count is below tetrahedral volume discretisation at equal resolution |
surface_over_tetra_ms = mass_props_ms / tetra_ms, both medians of 25 passes over the identical triangle list in the identical run and the identical build: 2.1290–2.1552 across 24 rows, median 2.1404, IQR 2.1380–2.1412. Per triangle, 18.14–18.35 ns for the paper's form against 8.47–8.59 ns for the fan — at identical accuracy on identical input, since tetra_rel_error is 1.909884e-15 to 1.682692e-13 over all 24 rows |
NOT LANDED, and the arm that shipped is the slower one. The registration's operation-count sentence is refuted for the comparison this crate would actually make: the paper's §6.1 baseline is a filled tetrahedral mesh with interior elements, and the origin fan needs no interior mesh either, consumes the same triangle list, and does 1/2.14 of the work. Do not adopt the paper's kernel over the fan on a cost argument — and do not swap the other way either: it is a one-function change buying 18.17 − 8.49 = 9.7 ns per triangle, 0.56 ms once on the largest fixture here (58,112 triangles), and it loses asymmetry, which is the only leak detector the module has. One instrument note that cost the row a re-run: hoisting the control's nine divisions per triangle moved the ratio from 1.68 to 2.14, so the fan had been under-reported by 27% while it was the flattering baseline |
R-083, benches/experiment_p83.rs, docs/experiments/p-83.csv, ✗63 / M-395 |
| E×11 | gss_min_branchy — the same golden-section search with the if left in |
H (P-81), C2: a fixed iteration count with no data-dependent branching gives bit-identical contact points across the M5 and the Zen 3 on 10⁶ queries | branch_misses_per_query_field 1.8344 against branch_misses_per_query_branchy 4.4675 — a 2.44× reduction (2.32× on the superseded dirty run, from 1.9740 and 4.5873). Digests recorded separately and both reproduced by the M5: local_digest = local_repeat_digest = 0x2be626c099a75222 against the branchy 0x4067d5c9b10dcc68. Off Linux both branch-miss columns write the literal unavailable rather than a zero |
KEPT — in the harness, as the control, never as the query. It answers no clause and exists only so that "no data-dependent branching" is a measured branch-miss difference rather than an adjective, which is why the entry books it here rather than under a clause. The two arms are not bit-equal and that is by construction: the branchless form blends with a multiplier, and 1.0·a + 0.0·c is a + 0.0, which is a for every a except −0.0 — so the branchy digest is a separate column rather than an assertion. Neither arm reached crates/isomesh/src; E×10 is the query this one instruments |
R-081, benches/experiment_p81.rs, docs/experiments/p-81.csv, M-393 |
| E×10 | Capsule-vs-field contact by branchless golden-section search, against the parry3d TriMesh query |
H (P-81): the docs cite Liu et al. 10.1016/j.cagd.2024.102305, which is SDF-vs-SDF and a determinism liability; the game's case — a small analytic proxy against one enormous static field — is Macklin et al. 10.1145/3384538, whose GSS wins the 1-D edge problem at "under 0.5 ms" against a mesh path's ~15 ms, discounted at registration to single digits on CPU — so GSS costs under 20 µs per query on the Zen 3 and beats the shipped TriMesh path by at least 3× on fbm_terrain at 33³, with ghost contacts structurally absent |
query_us_field 4.766243 µs against query_us_trimesh 38.449486 µs at 33³ — speedup 8.067043 — and 4.759963 against 118.658518 at 65³, 24.928453×; clock-free, 20,089.6 cycles per query against 160,999.4, so the 20 µs budget is met on any clock above 1.0045 GHz. Determinism: contacts_bit_identical true, differing_contacts 0 of 1,000,000, differing_blocks 0 of 64, across Zen 3 and an Apple M5 over 4 × 10⁶ folded f32s — and the same fixture shows parry3d does not have that property. Ghost contacts: 93,298 on the TriMesh path over one 495-crossing walk, 59,941 of them on active edges Jolt's default 5° threshold does not reach, against 0. And the honesty column: contact_disagreements 2,536 of 20,000 poses (12.68%) at 33³ — the field query is fast, not exact |
NOT LANDED, and the 8.067× is not spendable where the ticket aimed it. P-85 measures the collider's 45% as construction to within 3.12e-5, so the Amdahl ceiling from any query-side change is 1.0000312× on the collider stage and 1.0000141× on the pipeline: an infinitely fast query removes 0.0031% of the stage. What the number is really about is a moving body's per-frame collision budget, which is a different and previously unmeasured quantity — measuring it is the prerequisite for deciding whether to land this, and that measurement does not exist. Two conditions if it ever does: internal-edge removal is not optional on a mesh collider, and the 12.68% contact disagreement must be scored against gameplay rather than against parry |
R-081, benches/experiment_p81.rs, docs/experiments/p-81.csv, M-393 |
| E×9 | Six connectivity-weighted vertex normals, as a fourth NormalStrategy |
H (P-73): the repository's own mechanics dossier proposes the angle-weighted pseudonormal at "under 2 degrees difference on good triangles, over 15 degrees on radius-ratio under 0.15, about 40 lines", and Jin, Lewis & West 2005 (10.1007/s00371-004-0271-1) scored six connectivity weightings against the analytic normal at a median 5–20° discrepancy on marching-tetrahedra output — so every weighting is at least 3× CentralDifference's median angular error at the cell size on eight fields at 33³/65³ with thin_plate and noise_cavity worst, mean \|f(v)\| predicts the per-vertex error at ρ > 0.7 on six of eight fields, and the connectivity route moves at least one golden hash between an M5 and a Zen 3 where the gradient route moves none |
Six weightings plus CentralDifference at the cell size, every arm scored against field.gradient(vertex) over one shared vertex population in one build and one run. ratio_to_gradient is 2.469927–52.467910× on sphere/torus, 0.985–1.687× on fbm_terrain/noise_cavity, and 0/0 on box_exact, csg_difference and thin_plate, where gradient_median_deg is exactly 0.000000 — 28 of 60 testable rows under the 3× bar, and 6 of 16 cases vacuous. Against the incumbents: the connectivity route is worse on 55 of 60 testable rows and better on 5, all five on fbm_terrain at 33³ by 0.8–1.5%, with absolute median_angle_error_deg 0.309086–24.354097° where AnalyticGradient is exact by construction. C2: 0 of 7 testable fields clear ρ = 0.7 at either resolution, best anywhere 0.584622, sign inverted on fbm_terrain at −0.117851 to −0.160652. C3: hashes_moved_connectivity 0 of 18 across an Apple M5 and a Zen 3 |
NOT LANDED — do not build the dossier's ~40-line pseudonormal, and refuse it on quality rather than on determinism. The determinism objection is dead and this is where that is written down so it is not recycled: Real::acos was wired to libm at S-006, libm's acos bottoms out in a correctly-rounded sqrt, and the connectivity route moves none of the crate's 216 golden hashes — while the same sweep on std's acos moves 2 of 3, which prices the objection the registration meant. It loses to both incumbents instead: nothing beats AnalyticGradient's zero, and against CentralDifference a 1% win on one field at one resolution does not buy a fourth NormalStrategy variant. It becomes purchasable only on a field where a weighting beats CentralDifference by more than that 1.5%. Do not build the two-line off-surface canary either — mean \|f(v)\| is a strong proxy for a finite-difference error near a CSG seam (ρ 0.912948 / 0.963016) and a poor one for a connectivity error anywhere |
R-073, benches/experiment_p73.rs, docs/experiments/p-73.csv, ✗56 / M-385 |
| E×8 | A subgroup prefix scan, replacing the Hillis-Steele ladder | H (P-70): subgroupExclusiveAdd plus a short cross-subgroup scan turns 16 workgroup barriers into 2 at BLOCK 256 and subgroup 32, and the literature measures 1.33–1.49× for it on six devices |
1.0544 / 1.1113 / 1.2796 / 1.4114× at 65K / 262K / 1M / 2M elements, bit-identical to both cpu_prefix_sum and the shipped PrefixScan at every size — including on a second device opened with Features::empty(), which is C3's instrument. Applied to scan_ms 0.3657 of gpu_total_ms 8.3694 it moves the path 1.27% |
NOT LANDED. A second WGSL path in the shipped crate is what the one-path rule forbids and 1.27% does not buy an exception — and naga 29.0.4 rejects enable subgroups; outright, so the shader compiles on wgpu only by omitting a directive WGSL requires. Reopens if gfx-rs/wgpu#5555 lands and the residue moves off upload_ms, which is 87.50%. |
|
| E×7 | A staging ring, so the geometry read-back is amortised instead of waited on | H (P-71): the largest piece of a GPU extraction is the geometry copy (0.6663 of 1.1331 ms at 129³), which indirect draw arguments cannot remove because they remove it by not delivering the bytes; a depth-2 ring over read_bytes_many_deferred converts it to a per-frame cost |
120 of 120 read-backs consumed, not_ready 0 at 33³/65³/97³/129³, amortised 0.3116 / 0.4325 / 0.6059 / 0.9158 ms. Drain tail 85 / 127 / 31 / 0 frames — not monotone in the grid. Re-measured at R-071 under the scheduler it was always about: M-124's 288-chunk budget sweep, 24 cells, no_room_frames 0 everywhere, collision latency mean 1.41 frames, worst 2 at delays of 1, 2 and 4 |
THE TYPE IS LANDED (R-071, DeferredGeometry); THE DEPLOYMENT IS STILL THE OWNER'S. It had to land to be measured — the clause is about the queue under a scheduler and bench scaffolding cannot be put under one — and it ships as a third contract beside extract_buffers and extract_indirect, each stating its own guarantee, not as a fallback for either. What is still open is putting it inside IsomeshPlugin's frame-budget system, which is a latency decision on a consumer's behalf: 1.41 frames is invisible in a voxel game and a decision in a CAD tool, and P-71 records the question rather than picking. C3 came back FALSIFIED at 5 of 24 cells and that does not change this — the miss is a 1.14× premium on a pass's first chunk from extract_buffers' unindexed poll(Wait), not the queue (M-376). |
|
| E×6 | The sample loop restructured for autovectorisation | H (P-69): a pre-sliced contiguous write with the bound hoisted gives at least 2x on the marginal f32 cost, and all 216 golden hashes stay unchanged |
Marginal ns/sample, push ÷ row: sphere f32 1.231 / 1.323 = 0.9305, gyroid f32 17.793 / 18.278 = 0.9735, box_exact f32 2.681 / 2.845 = 0.9425; f64 0.977 / 0.983 / 0.899. total %ymm across all eleven monomorphisations = 0. 0 of 168 golden rows moved |
REVERTED in shape, KEPT in sharing. The shape costs 3–7% and widens nothing, so it goes back; the merge stays, because there were three copies of this loop (marching_cubes/mod.rs:240, dual.rs:356, marching_tetrahedra.rs:157) and three copies is a one-path defect whatever the shape. Do not re-attempt on this target without changing the field: the loop is 11.6% of the marginal extraction cost, so its ceiling is 1.06x, and libm's sinf/cosf have no arch selection at all |
R-067, benches/experiment_p69.rs, scripts/p69_asm.sh, docs/experiments/p-69.csv, ✗51 / M-375 |
| E×5 | The crossing stored as a signed offset from the edge midpoint | H (P-61): d = ((a + b)/2)/(a − b) is exactly antisymmetric under the simultaneous endpoint-and-sign swap by four IEEE 754 guarantees, so a mirrored grid produces a mirrored vertex bit for bit, where a parameter from the lower corner cannot |
0 mismatches on 5,800,000 straddling pairs across f32 and f64 against 1,035,808 / 2,000,000 for the lower-corner form. marching_cubes 6 → 48 of 48 on all 16 equivariance rows, worst_component_ulp 0. 135 of 216 golden hashes moved, 0 counts changed, 2,285 of 28,124 cut edges displaced (8.12%) at ≤ 268 ULP. Hausdorff and self-intersections identical to 12 digits |
KEPT, and it is the default — there is no second path: cube::edge_crossing is gone, all six placements and the WGSL shader are in the centred frame, and the 216 golden hashes are rebaselined. The cost is exactly the registered one (C2 is a cost clause) and the geometric price measured zero. Do not re-attempt the lower-corner form; its 1 − t anchor is an affine map and floating point does not respect those |
R-059, benches/experiment_p61.rs, docs/experiments/p-61.csv, ✗49 / M-372 |
| E×4 | Weld gated on the pairwise link condition, rejected pairs left split | H (P-8): exactly 0 non-manifold edges and vertices on all eight fields × all extractors, where the unconditional weld yields N > 0 | 56 configurations on a centred 2×2×2 block. Ungated is 0/0 in 47 of them. Across all 56 the gate removes at most 4 non-manifold edges and adds up to 791 non-manifold vertices — noise_cavity + subgrid goes 301 → 1,092, and sphere + Marching Cubes goes 0 → 96 |
REVERTED, and it was never merged. Strictly worse: it fixes almost nothing where there was something to fix and manufactures non-manifoldness where there was none. A k-way coincidence is manifold only if all k merge; refusing one leaves the representative a bowtie, which is why the damage is in the vertex column and the edge column barely moves |
R-001, benches/experiment_p8.rs, docs/experiments/p-8.csv, P-8 |
Part 5 — Method rules, and the failure that earned each
Rules with no incident behind them get ignored. These all have one.
| Rule | Earned from |
|---|---|
| A tool timeout is not a job failure. Check the artefact, not the call | M-415 — scribe_convert is capped at 60 seconds by the MCP client while the job keeps running server-side for 82–768 seconds, so a timeout carries no information whatsoever about the job it timed out on. The expensive case is the one where the two states look identical: one paper timed out and then silently produced no markdown, which on the wire is indistinguishable from a successful in-flight run, and catalog_read is the only thing that told them apart. Seventeen acquisitions produced several of these, and every retry decision taken from the timeout rather than from the catalogue was taken blind. The client's deadline is a property of the client |
A health endpoint reporting ok is a claim about the service, not about your job. Retry sequentially before believing a capability is broken |
M-415 — the olmocr backend fails transiently under concurrency (0 completed pages (failed=N), workspace/markdown does not exist) while scribe_health still reports status: ok, because the service is healthy: it is the concurrent job that is not. The reading that looks like "this paper cannot be converted" and the reading that means "two conversions collided" are the same bytes. Every one of those papers converted on a sequential retry, so the cost of believing the first reading is an abandoned acquisition, and the cost of disbelieving it is one serial re-run |
| A clause stated as a ratio of a total must name the share of that total it can move. A non-empty population is not enough when the clause is a fraction | ✗51 — P-69's C1 asked for 2x on the marginal extraction cost from restructuring the sample loop. The loop measures 1.23 ns/sample against an extraction marginal of 10.68: 11.6% of the quantity the clause is denominated in, so its ceiling is 1/(1 − 0.116/2) = 1.06x and the clause was unreachable however well the loop vectorised. Amdahl refuted it, not LLVM. The registration named the field population correctly (libm's sqrtf has an arch selection and sinf does not, established from source in advance) and named the machine correctly, and still missed this — because *"which rows can this fire on" is the wrong question for a ratio. Compute the share before registering, from the stage breakdown and one timing |
| A clause whose population is empty on the fixtures it will run against is not a clause. Enumerate the rows before writing the harness | Four Phase-21 clauses could not have discriminated anything, and every one was catchable a priori. P-58's C1 tested a tie-break this crate invented rather than the paper's ordering claim; its C2 had no theorem behind it, which the verdict concedes. P-59's C2 asked for a median necessary/survivors ≤ 0.75 on a fixture whose worst chunk is 0.250000, so 0.75 could not have failed. P-60's C2 predicted a Gibbs phenomenon on box_exact and csg_difference, whose restriction to the domain-centre axis is |x| − 1 — second difference exactly 0, is_step_like false on both. Each is one input→output pass over the fixture, before any code: count the rows on which the clause can fire, and if the count is zero, change the fixture or drop the clause. A HELD verdict on a clause that could not fail reads exactly like a HELD verdict on one that could |
| A ratio that chains a median onto a total is not a ratio. State both statistics or neither | ✗41's headline read "a 20.6× further reduction on top of P-39's 64 → 19" — and 1,507 → 73 is a sum over 64 chunks while 64 → 19 is the median chunk. There is no clean median counterpart because the median necessary is 0: the fixture's base sphere leaves 51 of 64 chunks needing no brush at all, 44 of them meshing non-empty from an empty list. The like-for-like figure is 9.45× over the 13 chunks where any brush matters; the world-wide total is 20.64×; the product of a median and a total is neither. Two populations, two numbers, and say which population each one is over |
| An entry that says an instrument was fixed must show the fixed instrument's values, not the old ones | ✗39 records that its first worst_component_ulp walked two sorted vertex lists positionally, reported 9.2e18, and was replaced by a sorted-merge multiset difference — and then attaches the range "(0–2,432)" to the tetrahedral rows, where the committed CSV reads ≈9.2e18 on all 32 of them. 0–2,432 is the marching_cubes span. So the number quoted as evidence that the artefact was gone was the artefact, on 55 of 112 rows, and the consumer advice built on it ("expect vertex positions to move by up to worst_component_ulp") was meaningless on half the file. After repairing an instrument, re-read the column from the artefact and quote it — a remembered range survives the repair that invalidated it |
| A parameter derived from the fixture must be pinned across the fixtures it compares | P-36 — the heat time t = h̄² was recomputed per mesh, so an 86-vertex displacement shifted the mean edge length and every entry of the edited operator moved by the t-shift: the update path read a 2.5×10⁻⁵ residual for the fixture's reason, not its own. M-333's no-op identity check could never see it, because nothing moved there. Pinned, the residual returned to 2×10⁻¹⁶ |
| A percentile trim must be checked against the size of the mode it could eat | P-29's C1 — the central-gap statistic dropped 1% tails from 8,128 edges (81 of them) while a winning wormhole path is at most ~63 edges (0.78%), so the detector trimmed away the exact mode it was registered to find, and the "unimodal" control scored a higher gap than the bimodal-expected arm. The winner-mode's minimum size was derivable from the lattice before any run — one input→output path — and never checked against the trim |
| A tolerance on a √-amplified quantity must be derived at the amplification's maximum, not at the population's comfortable middle | P-28's C1 — a 1e-9·G "float dust" tolerance held at 2.8e-17 in the band interior and lost 50–75% of rows at the band's u → 1 edge, where d r/d(radicand) = ρ/(2√(1−u²)) multiplies the same dust into 1e-9. The amplification that killed the clause is the amplification C2 measures as signal; the tolerance was derived where the function is flat and applied where it is vertical |
| A precondition claim needs the sentence from the method's own paper, and "what it requires" is a different question from "what it guarantees" | ✗20 — "every ACD method assumes closed, watertight, 2-manifold, self-intersection-free, consistently oriented input" was two conflations at once. A method that preprocesses bad input was read as one that requires clean input, when Andrews 2024 names preprocessing as an axis methods differ along; and VisACD's 35% intersecting-hull rate, which describes the hulls CoACD emits, was read as a condition on the mesh it is given. Two of the four methods audited require nothing at all, and CPD says so in one sentence |
| Verify a citation's claims and its problem separately. Three true claims do not make a method the right one | ✗21 — A-026 chose CPD as the substrate a plane-cut fracture pipeline cuts, on three claims that all survived verification against the paper: input tolerance, "guaranteed to enclose the input surface", under a third of the collider bytes. The architecture needed a fourth property nobody checked for — a disjoint partition of the interior — and CPD has none: Algorithm 1 merges the face adjacency graph, its §3.4 says "the union of all primitives covers the mesh's surface", and §3.3 concedes the primitives overlap. The abstract, which is where the three claims came from, never mentions any of this. Worse, one of the verified claims was actively disqualifying: enclosure is the right guarantee for a collider and the wrong one for a substrate, because a proxy that strictly contains the solid cannot conserve its volume. This is ✗20's rule one step out — there it was "requires" vs "guarantees"; here it is "guarantees" vs "what you need" |
| Two gates that run the same command are not the same gate if they run different tools. Compare the tool, not the command | M-304 — preflight.sh --full was green on every step and the 0.0.6 release still failed: CI's clippy was 0.1.97 and the local one 0.1.96, and question_mark exists in one and not the other. The publish step was skipped and nothing uploaded. The command was byte-identical in both places, which is exactly why nobody looked. scripts/toolchain_drift.sh now warns when local stable is behind the current release — a warning rather than a failure, because being a patch behind is normal and a gate that cries wolf gets disabled |
| A count stated in prose needs a gate, or it rots — and the second rot looks exactly like the first | The golden-hash count was wrong in the root README, fixed at 0.0.4 from 147 to 168, and was wrong again at 216. The reference-field count was wrong in six places at once. Both were found by a person reading, twice, because readme_sync.sh compared one code fence and nothing watched the prose. scripts/doc_facts.sh derives each count from its source. The gate's first version is the other half of the lesson: it matched any number before "fields" and flagged "five of the seven reference fields", which is correct prose about a subset — a gate that cries wolf is a gate somebody disables, so it now matches only phrases that can mean the total |
| Derive a measurement's bounds from the thing being measured. A hand-written bound is wrong twice before anyone notices | B-006 and B-007 — the same seam-counting helper had its exclusion list written out by hand twice. The first version omitted the y axis entirely and accused Marching Cubes of a seam defect it does not have; the fix for that left z with a bound of 8.0 on a chunk 4.0 deep, and the uncounted wall produced a phantom open edge that made subgrid look non-conforming and got shipped as Unverified in a public API. Both readings were plausible and both were the fixture. The bounds now come from layout.cell_size() * layout.cells(), which cannot disagree with the chunks it is measuring |
| A counter that is only populated on the success path cannot report the failure. Register what is being checked before the thing that fixes it | E-205 — the crack counter built its list of seam planes inside if transitions, so running with transitions off left nothing to compare against and the demo reported a confident 0 cracks on a world with 182 open edges in it. The zero was not wrong about the geometry; it was computed over an empty set. Moving the seam-plane scan out of the conditional makes the control real: 71 low and 102–111 high with transitions off, 0 and 0 with them on. Seventh instance in one session of a number that was a property of the fixture rather than of the code |
| A trap that has to be dodged by choosing a constant will be walked into again. Put the dodge in the step, not in the default | E-104 found that box_exact is exactly zero on its whole boundary, so a grid aligned to the box faces lets the sign convention decide instead of the algorithm — over the ±2 domain, whenever n − 1 is a multiple of 4. E-114 then defaulted to 13, which is one of them, and opened on the degenerate case it exists to explain: corner 7 sampled -0.0000. E-104's own note says the dodge belongs "in the code rather than left as a warning", and it was — in E-104's code. The fix that survives is arithmetic rather than vigilance: step by 4 from an odd base so n − 1 ≡ 2 (mod 4) throughout and no reachable resolution is aligned |
| Frame the camera from the field's own extent. A fixed orbit radius ships a screenshot of the inside of the mesh, and it looks like a rendering rather than a framing bug | E-110, looking at E-109's committed image for a style reference. sharp_features.rs:131 sets orbit.radius = 7.0 for every field, and the capped gyroid's domain extent is 14 — so docs/media/e109-sharp-features-gyroid.png is a picture of an inner wall, with the HUD legible over a flat beige surface and none of the geometry the demo exists to show. manifold_check.rs:256-261 already had the fix and the comment explaining it ("a fixed radius puts the camera comfortably inside the gyroid"), written one ticket earlier; E-109 did not reuse it. The image passed review because it is not obviously wrong — nothing is missing, nothing is inverted, the numbers are correct. That is the failure mode: a framing bug produces a plausible picture, so only comparing against what the field should look like catches it |
| A falsifier has to separate the hypothesis from its rivals, not merely be capable of failing | M-279 — P-12 registered "flat miss rates" as its refutation. Miss rates were not flat, so by its own falsifier the hypothesis survived, and its mechanism was false anyway: "the crossed-edge gather misses" and "the O(n³) scan misses" both predict rising misses on a growing grid, so the stated observation could never have told them apart. The control that settled it — the same sweep on a field with no surface, where the gather runs zero times and the dense state is unchanged — was not in the registration. When registering, ask what else would produce the same reading |
| A control run where it cannot discriminate reports "no effect", and reads exactly like a real negative | M-279 — the axis-order control was first run at 4.3 M samples, a 17 MB array inside this machine's 32 MB L3, where no traversal order can miss. All three orders came out within 20% and the honest-looking conclusion was "orientation does not matter". Re-run at 16.7 M it is a 2.4× spread. The fixture is now run at both sizes, the small one as a control on the control. This is G-003's rule at a different scale: there the fixture's value sat in the degenerate region, here its size did |
| Check a new harness against a committed measurement of the same thing before believing its new columns | M-279 — experiment_p12 forgot MeshBuffer::reset(), so the output buffer grew by a whole mesh every run and later runs paid reallocation the extraction did not cause. Every exotic column looked plausible; the tell was the boring one, triangles, which was not monotone in n — 145900 at 112³, 190060 at 128³, 144708 at 144³. resolution_sweep-ryzen9-5900x.csv has 5180 triangles at 48³ and the fixed harness reproduces it exactly. A new instrument's first job is to agree with the old one where they overlap |
| On a governed CPU a nanosecond is not a unit. Report cycles, and put the clock on the row | M-280 — the same binary reported Marching Cubes at 48³ as 8.13 and 14.66 ns/sample with cycles/sample unchanged at ~34, because amd-pstate-epp on powersave spans 1.96–5.62 GHz. Nothing on the face of either number said which clock it was. Every row now carries ghz, computed as cycles ÷ nanoseconds, so the artefact states it rather than inviting the inference |
| A reference implementation used as ground truth needs the same scrutiny as the thing it checks — and when a measurement is impossible, suspect the instrument before the world | M-289 — R-006 and R-008 both compared a mesh against an analytic gradient, and every control they carried was about whether the mesh was being measured fairly: rotate the fixture, offset the apex, add a no-crease case, check the vertex is on the surface. None asked whether the gradient was right, and it was wrong at exactly the points being measured — normalising a cancellation residue for any point epsilon-outside the surface, which is about half of them. Two hypotheses were reported falsified and both were true. The tell was there from the start and was misread twice: an area-weighted normal cannot leave the cone its faces span, so a past-90° reading was arithmetically impossible, and M-283 recorded the impossibility and went looking for strange geometry instead of a broken instrument |
| A fixture can exhibit the property too perfectly. Exactness is the tell, not the confirmation | M-283 — a wedge whose bisector lay on a grid axis reproduced P-13's predicted angle to four decimal places at three dihedrals and three resolutions: 75.0000, 60.0000, 45.0000. Turning the same wedge 17° or 37° about its own crease gives 20.1–128.0° for the same dihedrals. The exact agreement is a property of the symmetry between the crease and the sampling — the worst vertex is then the symmetric one — and nothing about 75.0000 at three resolutions looks like an artefact. (The numbers in this row were first taken from the run M-289 corrects; the aligned fixture's four decimals are unchanged by that correction, which is the part the rule is about.) Part 5 already says to search for a fixture that exhibits the property; this is the other half — when a measurement matches a prediction exactly, vary the fixture's orientation before believing it |
| A deliberately excluded workspace is excluded from your pre-commit loop too, and "run both" in prose is not a gate | M-293 — bevy_isomesh is out of the root workspace for a real reason (feature unification, M-190), so cargo check --workspace --all-targets does not compile it. F-001 changed a ReferenceField method and broke an example there; 58 commits went by with every local gate green, and only the full end-of-night sweep found it. CI has run the right command all along and simply had not seen the branch — 75 commits unpushed. CLAUDE.md says "run both" in two separate places, which is the evidence that saying it is not sufficient. The fourth incident from one exclusion, and the first where the CI step already existed |
| A millisecond is a property of the binary. Compare within one build and one run, or compare ratios | M-281 — two of this repo's benches measured Marching Cubes on the same field at the same resolutions with the same median rule and disagreed by a uniform 1.24–1.36×, including at 16³ where the whole run is 40 µs. Both loop shapes in one binary are identical (0.991–1.002), and adding one unrelated function to resolution_sweep.rs moved its own 256³ row from 152.5 to 130.8 ms. Layout bias, with a paper — Mytkowicz et al., ASPLOS 2009 (10.1145/1508284.1508275). benches/layout_bias is the standing check, and it asserts rather than prints |
| A generator that recognises one shape stops counting when the shape changes — and its staleness check cannot see that | M-277 — findings_index.sh matched Part 2's table rows and Part 1's ✗ headings. Measurements became ### sections at M-255 and twenty-two of them fell out of the index while --check stayed green, because a staleness check compares the file against the generator and the two agreed. The count read "249 measured" against 271 present. Check a generator against its source's own vocabulary, not against its previous output — one grep -c '^### M-' beside grep -c '^| M-' is the whole test, and it is the check that was never written |
| A file that records state drifts from the state unless something checks it. Write the check the second time, not the third | E-113 — the demo shipped at a0859e8, the README referenced it, and its row sat in BACKLOG.md for four more commits; the header counts drifted from the row counts separately. Both were found by audit, both were caused by editing one file with several scripts in one turn where a later write clobbered an earlier one. The same defect was sitting in FINDINGS.md unnoticed: O-1, O-2 and O-4 were still listed as open questions after G-002, A-009 and G-003 had all landed and answered them. scripts/backlog_gate.sh is the check, and it is mutation-tested against all eight ways the two files can disagree — because a gate that has only ever passed is indistinguishable from one that cannot fail (M-44) |
| An instrument that cannot report the failure has not reported the success. Show it producing a non-zero before trusting its zero | E-208 — the paint-drift readout measured "did the colour at this point change", and the scripted run sprayed one colour, so repainting red over red was numerically identical to paint that never moved. It printed 0.000000 at every step, which is the answer the ticket wanted, and it would have printed the same on an implementation that smeared. Cycling the palette turned the same instrument sensitive — 27 of 40 sprays register drift, up to 0.886 — and only then does the 0.000000 across both carves mean anything. This is M-75's rule in a different costume ("a test that returns the same answer when you invert the thing it is testing is not measuring that thing"), and the reason it earns its own row is that here the instrument was not inverted, it was starved: the input never varied in the dimension being measured |
| A wall-clock ratio is not a gate. Gate the count the ratio samples | ✗24 — empty_cell_rejection_is_measured_per_field asserted speedup > 1.0 on every field under a doc comment that said "recorded rather than asserted" and "not a regression gate". It failed the 0.0.7 release on a macOS runner at gyroid 0.98×, having passed at 1.10× here — the same measurement, with the sign set by the runner. The fix is not a looser threshold: what rejection can save is bounded by how many cells it proves empty, and that is an integer, identical everywhere, 16.8% on gyroid against 80.6–95.1% on every other field. Find the deterministic quantity the timing is a proxy for and assert that; print the timing. Related to M-281 (a millisecond is a property of the binary) and its sibling: a ratio survives the build, and still does not survive the machine when the true ratio is 1 |
| An area probe must sample the surface of the shape it is testing. A plane at fixed depth asks a different question, and the difference is the slope | ✗45 / M-363 — resolve_body's single-point ground probe was genuinely wrong, and the specified fix — five samples in a flat cross at that same depth — was wrong the other way: the lateral samples reach into terrain higher than the terrain under the foot, so gravity_step cuts gravity and the body hangs 12.5 cm in the air on a 0.63 gradient. Same failure at 45° on a sphere of radius R + GROUND_PROBE: 7.8 cm, because that shape still trades vertical reach for lateral. Only the chord — offset r sampled sqrt(R² − r²) below the centre, with the tolerance in −Y alone — has nothing to trade. When widening a point query to an area query, put the samples on the collider, and check the widened one against the unchanged fixtures first: the pre-existing settle test caught this on its first run |
| A test fixture that opens a driver handle must share it. N handles is N races, and the count that tips it is not the count you tested at | M-365 — wgpu_pair() built a wgpu::Instance per call, which was five instances at sixteen tests and passed. Four added tests made it twenty-three and the suite deadlocked — at --test-threads 12 and 24, clean at 8 and 16, so a race and not a threshold, and the first sighting cost 1800 s against a timeout. Neither the six device-opening tests run alone (1.35 s) nor the fifteen others alone (1.33 s) reproduce it; only the whole set does, which is why no single new test looked guilty. wgpu::Device and wgpu::Queue are Arc handles, so one LazyLock cloned per test is both the fix and what an application does — 23/23 green and 1.5 s → 0.6 s. Related to M-293 (a gate that cannot see the branch): here the gate saw it and the harness was the hazard |
| A cap checked after the work is not a cap. If the loop is guaranteed to do one more, the bound is one more per iteration — which is no bound | ✗47 / M-367 — GPU_JOBS_MAX = 16 was the second clause of mesh_within_budget's budget predicate, and that predicate is consulted after a chunk so that a too-small budget still makes progress. A frame beginning at the cap therefore added one, every frame in which no readback retired: measured 17, then 18 once the assertion was loosened to cap + 1. The loosened assertion is the tell — a bound that has to be relaxed by exactly one is usually the first term of a series. Check the counter before the push, and give the refused work back to the queue rather than dropping it or silently routing it down another path |
| A queue length read before the thing that shortens it is not the queue length | M-368 — drain_dirty seeded its in-flight count from pending.jobs.len() while running before gpu_collect in the same chained frame, so it counted every job the device had already finished and nothing had retired. With the cap enforced and the order untouched, a 256-chunk switch fell to one chunk per twelve frames with the queue pinned at its cap for 900 frames — correct backpressure against a number that was always stale. Retire first, then dispatch into the freed slots; the latency is identical either way |
| A fixed frame count in a test is an assumption about the machine. Gate progress, not speed | ✗47's fallout — key_eight_meshes_the_sandbox_on_the_gpu spun assert!(frames < 900), chosen when the drain took 135 frames on an idle device. Sharing one adapter across six tests took the same drain to thousands of frames, and the red test said "never drained" about a demo that was working exactly as designed. The replacement is a stall detector: the outstanding count must decrease within 1200 frames, which is machine-independent because a live device always retires something. Same shape as a_budgeted_drain_keeps_what_it_could_not_reach's "the drain is not making progress", and the sibling of ✗24 (a wall-clock ratio is not a gate) — a frame count is a wall clock with extra steps |
| Retiring a hostname is two steps: the platform setting and the DNS record. Leaving the record makes the failure lie | D-015 — clearing isomesh.ladvien.com from GitHub Pages left its Route 53 CNAME pointing at ladvien.github.io, which is the worst of the three states the name can be in: it still resolved, so https:// failed the TLS handshake (no certificate for that host) and http:// returned GitHub's 404 for a Host it no longer maps. Both read as an outage of the live site, and a reader with the old bookmark reported it as one. NXDOMAIN is unambiguous and takes ten seconds to interpret; a TLS error on a name that resolves takes a diagnostic session. The generalisable half: when you remove a service's address, ask what a holder of the old address now sees, and prefer the failure that names itself |
A guard downstream of an aborting command is not a guard. Under set -e, check the thing that can abort |
D-016 — publish.sh's crates.io probe has a case whose *) arm exists precisely for this: "Anything else — including a network failure — must not be read as 'not published'". Correct reasoning, unreachable code. set -euo pipefail is on, so code=$(curl …) exiting 35 (Recv failure: Connection reset by peer) killed the script before the case ran, and a docs-only commit's CI died on a bare exit status with no message. The probe is an idempotent GET, so retrying it is free of meaning-change; curl's status is now captured with || status=$? — not if ! curl, where $? inside the branch is the negation's status and not the failure you wanted to name. Both directions demonstrated: three clean probes and exit 0, and against a closed port four attempts, exit code 7 reported, script exit 1 |
| A typed error at the call site is louder than an abort — make the invalid state unrepresentable where you can, report it where you can't, and never substitute a default | The no-panic rule, reconciled with "fail loudly": ValidateConfig has private fields and one checked constructor, so the validator needs no runtime guard at all |
Corpus presence is decided by catalog_read, never by distill_search |
✗4 — 342 documents readable but unsearchable |
for_each_reference_field! looks like a closure and is not. A return in its body exits the whole test |
M-199 — the macro takes \|name, field\| and inlines its body once per field as a plain block, because each field is a different type and no single closure can take all seven. So if name != "gyroid" { return; } returned from the test function on sphere, and the test passed while running neither control nor the assertion that both had run. Use if name == … instead. The continue/break uses elsewhere in the tree are all inside genuine inner loops and are fine — a bare one would not compile, which is the only reason this trap is spelt return and nothing else. The macro's own doc now says so |
| A precondition check belongs next to the action it guards, not at the top of the job. Hoisted, it fires on every run that never reaches the action | M-198 — the publish job demanded CARGO_REGISTRY_TOKEN before running publish.sh, so a push that uploads nothing still needed a secret to stay green. publish.sh's own header had already written the rule down — it is version-driven rather than push-driven because "the alternative … would leave main permanently red and train everyone to ignore it" — and the workflow reintroduced exactly that, one layer up, where the script could not see it. The guard is not weakened by moving it: a release push with no token still fails loudly, and now it says which crate and version it was about to upload. Both directions were checked, because a guard nobody has watched fail is decoration |
| When two paths are timed in one process, the one that runs second pays. Re-order before believing either number | M-197 — batching extract's read-backs appeared to make extract_buffers 75% slower (0.54 → 0.95 ms at 129³), consistently across four runs, on a path the change does not touch. Collapsing the two staging buffers into one allocation did not move it, so it was not allocation count. Swapping the order of the two measurements in gpu_vs_cpu put extract_buffers back at 0.553 and made the read-back path slow instead — whichever runs second pays, because the first leaves the device allocator warmed to a different peak. The real comparison was sound (both builds measured the read-back path first) and the apparent regression was the harness. A one-line reordering is the cheapest way to find out, and it is worth doing before writing any number down |
| A property that holds on every fixture you have is a property of the fixtures until one of them can fail it | M-208 through M-213 — five pre-registered claims (Manifold Dual Contouring's manifoldness, P-5's dual-χ identity, the weld's never-adds-a-defect, P-7's weld plateau, orientation's monotonicity) were all true on seven reference fields and all false on the eighth. Not one was wrong about the seven; every one was narrower than it was stated, and the missing precondition was the same in every case: no field in this crate could produce a cell with an interior ambiguity (M-208). The tell was available in advance and nobody looked: each claim is about what happens on a hard configuration, and no one had asked whether any fixture reached it. Before trusting a green suite as evidence for a property, ask what the fixtures cannot express |
| A deleted repository is not a missing source. Ask an archive before taking a rule-5 stop | V-31 — github.com/rogrosso/tmc, cited by both Grosso papers, 404s. Software Heritage had a full git snapshot, and mc/MarchingCubes.cpp reads out of it intact by content hash. The Wayback Machine had only the root page and would have answered nothing, so "I checked the archive" has to name which — Wayback archives pages, Software Heritage archives repositories. This mattered rather than being tidy: the paper's own listing of the inner hexagon is corrupt in the copy held here, and the program is the only surviving source for it. Sibling of the rule below, and the same failure one ticket later: the question was never "does the text say it" but "does any artefact say it" |
| An acquisition status is a measurement with a date on it. Re-check it before it justifies a decision | V-29 — meshing-library-target.md recorded Grosso 2016 and 2017 as PAYWALL. Both were in home-still, converted and indexed, acquired by the same sweep that supplied the papers A-002c was built on. The stale row was trusted for four days and it had sized a ticket: A-002b's largest single piece, a grid-subdivision preprocessing pass, exists only on the route the unread paper replaces. A PAYWALL row is evidence about one attempt, not a property of the paper |
| A paper is not only its text. Check its ancillary files before concluding it does not state something | V-28 — A-014d sat rule-5 stopped for two tickets on "the triangulation patterns appear nowhere in the text", which was true and not the question. The arXiv abs page lists anc/ files in its HTML; this paper ships a supplement and a standalone JS implementation with a "Simplicial Embedding" checkbox — §3.2.3, from its authors, executable. One curl at any point would have found it. The stop was correctly taken — inventing a case table is the failure rule 5 exists to prevent — and incorrectly maintained, because "the prose does not say" was never checked against "the artefact does not say". Figures and code are sources; only text had been searched |
| Sample the pixels rather than trusting the eye. A figure read by eye is a measurement with no error bar | V-28 — Figure 15's whole meaning hangs on which edges are drawn blue, and at a glance the pentagon's bottom edge looks navy against a blue-tinted fill. Sampling the rendered PPM along each edge gives blue-excess +109 on the two real chords and +14 on the one that merely looked it — a 7× separation that settles in one command what staring at the panel could not. The same read also caught a segment sampling as fill rather than as a line, which is how the boundary was shown to bend at an inserted vertex |
| Search home-still before believing a doc that says a paper is missing | M-63 — docs/research/ lists Manifold Dual Contouring and the Transvoxel dissertation as "genuinely absent, blocking"; both are in the corpus and both were read in one session. A-010's ticket named the wrong paper for its own algorithm because nobody had opened the right one |
| A test that gives the same answer when you invert what it tests is not measuring it | M-75 — two winding tests on a zero-width transition patch reported the identical count in both fan orders, because the patch was exactly perpendicular to the gradient they were dotted against. Flipping the code and re-running is the cheapest check that a test has any power at all |
| Assert the property you believe, not the one that is easy — and when the assertion fails, the counterexample is usually the finding | M-64, and M-59 before it. "A lateral link always crosses the resolution boundary" was false, and the case that broke it is precisely what transition cells exist to do. "Manifold Dual Contouring is manifold" was too strong, and the case that broke it is a second mechanism nobody had named |
| Never guess a DOI or arXiv ID. Look it up or stop | A subagent guessed an ID from memory and downloaded an unrelated condensed-matter physics paper under a meshing DOI |
| Verify the source separately from the number | ✗7 — right figure, wrong attribution |
| "Nobody measured X" needs the same evidence as any other claim | ✗9 — asserted twice, false twice |
| No performance number without the benchmark that produced it, in the repo | The corpus contains several published figures that failed verification |
| A doc comment the test suite disproves is worse than no doc comment | ✗3 |
| Assert the identity, not the inequality — a weak assertion hides a strong fact | ✗1 |
| Verify that a property test can actually fail. Corrupt an input and confirm red | A test that cannot fail is decoration, not evidence |
| Record an assertion's break conditions next to it | ✗1 — G-001 chunking will break it correctly, and it will look like a regression |
| A command queued against a streamed entity must tolerate the entity being gone | M-171 — one example panicked on every run for want of try_insert, and three more were one busy frame away from it |
| An accepted CI failure is indistinguishable from a new one. Encode the acceptance — skip, gate, or split the job — and keep the checkmark green, or the checkmark stops meaning anything | M-174 — the ubuntu test job's known GPU red concealed a broken release gate, a false MSRV claim and a rule-2 gate that had been failing since GPU-001, for the whole GPU series |
| A deliberate exclusion buys something and costs a gate. Write down which gates it exempts, or rediscover them one incident at a time | M-190 — bevy_isomesh is excluded from the root workspace for a good reason, and rustfmt, rustdoc and MSRV each had to be patched in separately after the gap was found. Three incidents, one cause |
| A suite that samples one point of a stated range is reporting on that point, not on the range. Check that each gate is run everywhere it claims to be | M-182 — the subgrid validity census runs at 17³ while Phase 1's gate says three resolutions, and 17³ is exactly where thin_plate is clean. 25³ and 33³ carry 8 and 6 flipped edges, on the one field the whole subgrid track exists for |
| Before implementing a remedy, measure the ceiling it could reach. A remedy whose maximum is known to fall short is a re-scope, not a task | M-180 — A-014h's rule was implementable in an afternoon and would have removed 234 of box_exact's 924 duplicates while its acceptance asked for all of them. One HashSet of bit patterns, written before the code, said so |
| A claim that a property "needs no special case" is a prediction, and it gets a test like any other. Write the test that would fail if it did | M-175 — "ties need no tie-break" sat in a doc comment for the whole of ✗12 and was false the entire time. It survived 9600 measured trials because those trials were the one case where it happened to be true, and it fell to the first test written about the tie itself |
| A shipped artifact is not evidence that the pipeline shipped it. Check the pipeline's own record, not the outcome it was supposed to produce | M-174 — 0.0.3 and 0.0.4 were on crates.io, which is precisely what a working publish job would look like from outside. It had been skipped on every run since it was written, and both versions went up by hand. The finding that said so was itself wrong the first time in the opposite direction ("never uploaded"), from reasoning about the gate instead of asking the registry |
| Pin known defects as non-zero assertions rather than excluding them | M-4 — the numbers only move when someone means them to |
| Single-grid timings measure dispatch latency; sweep resolution and report the fixed cost | V-6 |
| Treat any published cross-paper ratio below ~2× as noise | V-7 |
| A green local run on one platform is not a green build. CI is the first real test of anything platform-shaped, and it will find things a local pass structurally cannot | First push: every job passed except bevy_isomesh on Linux, where Bevy 0.19's default Wayland backend needs libwayland-dev / libxkbcommon-dev. No such package exists on macOS, so no amount of local verification could have caught it |
| A ticket's acceptance criterion is itself a claim about the code. Check it against the code before starting the ticket, not after. | ✗11 — A-002 carried an L-sized acceptance criterion that the existing test suite had already made unsatisfiable. Nothing flagged it, because acceptance criteria are read as instructions rather than as assertions to verify |
| A property that falls out of how a table was constructed outranks folklore about the algorithm the table implements | ✗11 — "Marching Cubes produces holes" is true of a transcribed table and false of a derived one; the distinction is invisible if you reason about "Marching Cubes" rather than about this code |
| When a ticket paraphrases a research doc, re-read the doc. A paraphrase can invert the property that made the technique worth adopting | ✗12 — "branch-free, handles all degeneracies" became "falls through when the triple product is near zero" across three documents, turning the rule's central guarantee into its opposite |
| When an acceptance criterion passes by two orders of magnitude, it is not the test — find the one that fails. Ship it anyway, and ship the real one beside it | M-11 — T-003's stated criterion passes with 80× margin, so a constant-returning harness satisfies it. The convergence-order test and the closed-form fixtures are what actually constrain the code |
| Estimate a count from the geometry, then measure it before writing it down — the tidy formula is usually missing a constant | M-13 — A/h² under-predicted the triangle count by 1.47×, because a surface crosses 3/2 cells per unit area, not one |
| A test double is evidence only if it is pinned to the thing it stands in for. Write the equivalence test first, and make it bit-exact | T-005b — the case-table mutation check runs a corrupted table through a local marcher. Without the_double_reproduces_marching_cubes comparing the two bit-for-bit on the uncorrupted table, a corrupted-table failure would be indistinguishable from the double having drifted |
| Before waiving a property in a gate, check what else was resting on it. Derived checks fail with their premise | M-16 — a gate that waived manifoldness kept the even-χ assertion, which is a corollary of manifoldness. It failed on the first non-manifold mesh it saw, and the assertion was the bug, not the mesh |
| When a mutation test passes for the wrong reason, the message tells you: check where the panic came from, not just that there was one | M-17 — the wrong-edge corruption first tripped edge_crossing's precondition deep inside the crate, so the validity gate under test was never reached. should_panic alone would have called that a pass |
| Write the prediction into the benchmark before the first run, in the file, committed. Then the result cannot be rationalised afterwards | M-19 — T-006 predicted a ≈ 0 on the CPU path from the fact that V-6's 73% figure is GPU dispatch overhead. It came out at 0.61%. Had it come out large, the prediction being on record is what would have forced the awkward question instead of a tidy story |
| A fitted coefficient means nothing until it is compared to the data's own range. Report it against both ends | M-19 — Marching Cubes' a is 0.61% of the largest run and 543% of the smallest. Either number alone tells a different and misleading story; the pair says "negligible at scale, do not extrapolate below the range" |
| A physically impossible fitted parameter is the model telling you it is wrong. Do not report it as a value | M-21 — Surface Nets' fitted fixed cost is negative. Reported as "there is no fixed cost" it would be nonsense; read correctly it says the cost grows faster than n³ and the whole two-term model does not apply |
| A property that has held in every measurement so far is still a hypothesis, not a mechanism. Say which condition it depends on | ✗15 — "Marching Cubes is manifold" held on seven reference fields at every resolution ever tried, and the mechanism offered for it (vertices on edges, not one per cell) was real but insufficient. The true condition is "the grid resolves the surface", which nothing had stated |
| A fixture chosen by intuition can sit in the degenerate region where the property being tested does not apply. Search for one | G-003 — the smooth-min associativity fixture used values 0.5 apart with k = 0.4; past |a − b| ≥ k the blend saturates and smooth-min is just min, which is associative. The test asserting non-associativity was exercising the associative case. This is the second time in two tickets (M-32 was the first), which is why it is now a rule rather than an anecdote. Fourth occurrence at ✗129, on a registered experiment rather than a test: M-490 graded the Gaussian-kinematic formula on the full noise_cavity box, where 86% of the values are the sphere cap's, and P-180's inscribed cube — chosen by geometry, not by search — still carries 12%, because the cube's corners lie on the sphere |
| Count what changes in the output, not what changes in the input. They can differ by an order of magnitude | M-34 — E1 first counted cells whose samples moved and read 100%, which says incremental meshing is pointless. Counting cells whose triangles move gives 15–36%, which says the opposite. An SDF edit perturbs a whole solid; it re-shapes only a shell |
| Choose a test fixture by searching for one that exhibits the property, not by picking one that looks like it should. | M-32 — the non-power-of-two seam test first used h = 4/33, which looks irregular and lands in the 78% of cases that happen to agree exactly. It passed while proving nothing about the case it was named after. A search over (origin, h, cells, chunk) found the 22% that disagree, and the fixture now comes from that search with an assertion that the two expressions still differ |
| A workspace that is excluded from the root is excluded from the root's CI commands too. Check each one separately | E-111 — the lint job runs cargo fmt --all --check from the root, which excludes bevy_isomesh, so that crate's formatting had never been checked in 20 tickets and an example was committed unformatted. cargo check/clippy/test had their own steps in the bevy job; fmt was the one nobody noticed was missing |
| Count what the claim is about, not what is easy to count. A bitwise "did it move" is not a measure of "was it wrong" | A-009 — the clamp box is the cell shrunk by ε, so a vertex sitting exactly on a cell face is nudged by 5e-5 cells and a bitwise count calls it clamped. On a grid-aligned box_exact that read as 1176 of 1352 vertices displaced; the honest count, against a 1e-3-cell threshold, is zero. The first number would have gone into a commit message and been wrong |
| A remedy stated for one operation does not cover the pipeline. If a property is claimed end-to-end, check every reduction in it | M-24 — the audit's "magnitude-sorted dot products" is real and insufficient; the determinant needed the same treatment, and nothing said so. The equivariance test caught it because it asserted bit-equality rather than a tolerance |
| Read a dependency's API before believing what it is for. Reputation is not a type signature | ✗16 — glam is "the" Rust math library and was written into four documents as A-007's dependency. It has no generic scalar, so it cannot serve a crate generic over f32 and f64 |
| Before believing a performance verdict, ask how many machines it has run on. One is a hypothesis | ✗14 — Surface Nets loses to Marching Cubes by 2.76× at 256³ on an Apple M5, and the mechanism is probably cache. That is a strong result and a weak generalisation until it runs somewhere else (O-11) |
| When a new feature shows a defect, check whether the old one has it too before attributing it. The cheapest version of that check is usually an exhaustive small search | ✗17 — the decider produced 2 non-manifold edges where plain Marching Cubes produced 0, which reads unambiguously as "the decider broke it". An exhaustive sweep over all 4,096 two-cell sign patterns found 12 affected under each rule — the defect is A-001's fan, and the decider only changes which patterns are reached. Attributing it to A-002 would have put the fix in the wrong ticket and left Marching Cubes' own version of it undiscovered |
| A measurement that comes back zero has to prove it could have come back non-zero. Put the reachability check in the test | M-44 — the first chunk-seam sweep reported 0 decision flips and 0 ambiguous seam faces, which is a pass that means nothing. The assertion ambiguous_faces > 100 failed and forced the sweep to be retuned until it actually reached the configuration. Third occurrence of the fixture trap (M-32, M-38), and the first where a test caught it rather than a reviewer |
| Run every step of a CI job locally, not the ones you remember it having. Name them in the definition of done so the list is not held in memory | A-002 — a public doc comment linked to a pub(crate) item, which cargo doc under -D warnings rejects and which clippy and fmt both pass. Two of the lint job's three steps were run locally and the third was not, so a green local run pushed a red CI. Same shape as E-111's missing fmt on the excluded workspace: the gap is always the step nobody thinks of as linting |
| Implement the expensive fix, measure it, and only then look for the cheap one. The measurement is what tells you a cheap one is worth hunting | A-015 — the ticket was written expecting to re-baseline ✗1, M-2, M-22 and all 84 golden hashes, and the naive centroid fix duly cost +73% vertices. That number was so much worse than the "a vertex and two triangles per long cycle" estimate that it forced the question "which chords can actually collide?", whose answer is local and made the fix free. Estimating the cost instead of measuring it would have shipped the expensive version or abandoned the ticket |
| Record the margin, not just the verdict. "It did not happen" and "it came within an ulp of happening" are the same count | M-44 — zero seam decisions flipped, but the number that makes that trustworthy is the closest observed margin, 1.535e-2, against a perturbation of ~1e-16. Without it, the zero could have been luck |
In a no_std crate that links std under #[cfg(test)], never call a float method on a concrete f32/f64 — go through Real or name libm:: — because under test the inherent std method shadows the trait and the platform's libm leaks into whatever the test writes down |
✗130 — prescribed.rs's ring() computed a bore ring with a.cos() on an f64; golden hashes blessed under test on Linux/glibc, and macOS read 48 of 378 differing in the last ULP of cos(2π/3) and sin(4π/3) — every combination of the two three-point-ring fields. glibc, Apple's libm and pure-Rust libm each gave a different value; naming libm::cos made both platforms use the third. M-31's 216 cross-platform hashes had held only because no earlier field put a trig call on a concrete float |
| A filter that skips work must be stated against what the consumer reads, not against what the first consumer read. Name the points, and pick the filter from the extractor | M-497 — mark_edit skipped every cell whose eight corners sat on one side, which is the whole input of Marching Cubes and a strict subset of Subgrid's, so a Subgrid volume kept a thin wall that had been cut and never drew one that had been added (issue #11), with nothing reporting it. The plugin now picks the rule from Extractor by a match with no wildcard, so adding an extractor forces a decision about what it reads |
| A test that claims a transition must observe the transition, and must have been seen to fail against the mutation it names. A check on the end state passes when the transition happened and when it was skipped, if both leave that state | M-498 — an_edit_during_extraction_is_requeued_rather_than_swallowed asserted a ChunkMesh and no NeedsRemesh and no MeshingTask, and the swallow it names leaves exactly that, so it passed with the edit dropped (issue #12). The fix counts the second extraction (MeshStats::spawned summed across frames) and compares the mesh shown with a direct extraction of the field it should have been built from. Run the named mutation before trusting the test, and keep the output with the entry |
| A counter documented as an operation's own must be computed from what the operation built, and its test must call it with the shared object already holding something. A fresh container is the one state in which "this call's" and "everything in it" agree | M-499 — EditReport::dirty_chunks was documented as the chunks the edit dirtied and computed as the region's chunks found in the caller's whole DirtySet; every test built a fresh set per call, so none could see the difference (issue #13). The sibling marker, written later, built a local set and was right; the two were never compared. Count from a set the call built, route both siblings through one function, and give the test a queue with a chunk in the region the edit does not touch |
Part 6 — Adding an entry
### <tier><n> — <one-line claim>
**Believed because:** <where it came from — and be specific, "folklore" is a real answer>
**Tested by:** <the command, test name, or source read. Must be repeatable.>
**Result:** <the numbers>
**Consequence:** <what changed as a result — a decision, a ticket, an assertion>
**Would be shown wrong by:** <the observation that would falsify this>
An experiment that was reverted still gets an entry. Part 4b is the slot, and the verdict line is the load-bearing part — a variant that was built, measured and put back is the single most expensive thing to rediscover, because nothing in the tree records that it was ever tried.
Two things that make this file worth keeping rather than a chore:
Re-tier rather than rewrite. When an R becomes an M, leave the R text and add the measurement below it. The gap between what was reported and what was measured is itself data.
Record the ones we got right for the wrong reason. ✗10 is in the falsified section even though the outcome was fine, because the reasoning was wrong and the reasoning is what generalizes.
M-255 — naive reinitialisation moves the zero set, measured before it was fixed (S-004)
M. Sussman & Fatemi's warning is not folklore and not small. A narrow-band reinitialiser that
seeds from the interpolated crossing, solves, and keeps the solved value everywhere drifts the
surface 0.152 of a cell over twenty applications on Sphere at 33³, h = 0.125, band = 3 —
tracked as the crossing fraction along all 386 cut x-edges, none of which appeared or vanished.
At roughly 0.0076 cells per application that is invisible per edit and visible after a hundred. In a destructible game it is a wall changing shape while nobody edits it.
Freezing the seeds inside one call does not fix it, which was the first thing tried and the
reason this entry exists: the next call recomputes the seeds from the previous call's output, so
the freeze holds for one round and the drift resumes. The fix is to restore the input values at
every sample adjacent to a sign change, which makes the crossing fraction bit-identical rather than
close — measured drift is then exactly 0.0, and the assertion is assert_eq!(worst, 0.0) rather
than a tolerance.
Why a tolerance would have been the wrong assertion. A per-application bound of 0.01 cells is satisfied by a steady creep of 0.0076. The bound has to be on the total after many applications, which is why the test runs twenty and not one.
construct::tests::reinitialisation_does_not_move_the_zero_set.
M-256 — the narrow band's cost claim needs the march, not the sweep (S-004)
M. The ticket's premise is that reinitialisation should cost edited surface area rather than
chunk volume. Delegating to signed_distance_field_swept and discarding what falls outside the band
satisfies every accuracy assertion and none of that premise: fast sweeping visits every sample on
every one of its eight passes regardless of value, so bounding it saves the update and not the
visit.
Fast marching bounds exactly. It finalises in increasing order of distance, so the first dequeued
value above the limit proves every remaining one is too, and break there is exact rather than a
heuristic cutoff. Measured on Sphere at 33³, band = 3: 4,802 of 35,937 samples finalised —
13.4%, against 100% for both unbounded constructors.
So march() takes a limit and signed_distance_field_marched passes far(). One implementation,
one path; the bound is a parameter, not a second algorithm.
The test asserts the share stays below 25% for the same reason M-255's assertion is on the total: a solve that quietly touched the whole grid would pass the drift check and defeat the ticket.
M-257 — the approximate GPU method beats both exact CPU ones (S-005)
M. Jump flooding (Rong & Tan 2006, 10.1145/1111411.1111431) against construct::
signed_distance_field (S-001, "exact") and construct::signed_distance_field_swept (S-002), on the
four reference fields whose analytic value is a distance, at 17³/33³/65³. Worst error against the
analytic field, at 65³:
| field | jump flood | swept | exact transform |
|---|---|---|---|
sphere |
0.02048 | 0.09271 | 0.06250 |
torus |
0.02370 | 0.10527 | 0.06233 |
box_exact |
0.08839 | 0.15861 | 0.10825 |
thin_plate |
0.06250 | 0.19221 | 0.08927 |
The flood wins all twelve rows. docs/measurements/jump_flood.csv.
Why, and why it is not a paradox. "Exact" in S-001 means exact to the nearest sample, so it
quantises every distance to the grid — its error is pinned at exactly h/4 on sphere and
box_exact at every resolution, which is the signature of quantisation rather than of algorithm.
The sweep is exact in the limit but its Godunov update is first-order. The flood is seeded from the
same sub-cell crossings the sweep uses and then measures a true Euclidean distance to that seed,
so on these fields the sub-cell seeding buys more than the 27-offset lattice restriction costs.
So the ticket's stated acceptance was the wrong assertion, and it took two failures to see it. S-005 asks for "error against S-001". Written literally, the gate asserts the flood agree with a CPU constructor — which asserts it reproduce that constructor's error. Both attempts failed on that basis while the flood was the most accurate of the three:
- against S-001:
sphereat 17³ disagreed by a full cell (0.250) while sitting 0.082 from truth against the transform's 0.250. - against S-002:
thin_plateat 17³ disagreed by 0.523 cells while sitting 0.250 from truth against the sweep's 0.407.
The gate is flood_err <= xform_err && flood_err <= swept_err, against the analytic field. The
agreement figures stay recorded, because how far the GPU and CPU paths drift apart is a real
question for a consumer meshing on one and colliding on the other — it is just not a correctness
bound.
Rule 5 note. The seeding is a deliberate departure from the paper, stated rather than slipped in: Rong & Tan seed each boundary sample with its own position. Seeding the interpolated crossing is what makes the comparison measure the flood rather than the seeding, and it is why these numbers do not transfer to a textbook JFA implementation.
M-258 — a u32 followed by vec3<u32> is 32 bytes, not 16 (S-005)
V + M. std140 aligns vec3<u32> to 16, so struct { stride: u32, pad: vec3<u32> } puts the pad
at offset 16 and the struct is 32 bytes. Sizing the uniform buffer at 16 produced
"the buffer bound at binding index 1 is bound with size 16 where the shader expects 32" — caught by
wgpu, but only at dispatch, not at pipeline creation. struct { stride: vec4<u32> } with .x used
is 16 and says the same thing. The existing GridParams shader header already carried this rule in
prose ("two vec4s rather than a struct of scalars so std140 and std430 agree"); it was not followed
in the new file.
M-259 — the round trip the crate did not have (S-006)
M. Sphere → Marching Cubes → signed_distance_from_mesh → Marching Cubes, on a 33³ grid at
h = 0.125. Vertex and triangle counts are identical across the trip (1,158 vertices, 2,312
triangles), χ is 2 both times, boundary and non-manifold edges zero both times, and the worst
|analytic field| over the output vertices goes from 0.001701 to 0.003803 — 2.2× degradation,
against a bound of half a cell (0.0625).
The sign agrees with the analytic field at every sample more than half a cell from the surface — zero disagreements out of 35,937. That is Bærentzen & Aanæs Theorem 1's whole claim, tested rather than trusted, and it is the assertion that catches a pseudonormal read from the wrong feature: a face normal where a vertex one was needed is correct for most samples and wrong near a crease.
This is the first end-to-end test in the crate. It exercises the extractor, the pseudonormal sign, the closest-point classification and the acceleration structure against each other — a fault in any one shows up as geometry that moved.
It needed a piece that did not exist. Every constructor in construct returns a Vec<R> and
every extractor consumes an Sdf, so there was no way to mesh what had just been built.
construct::SampledField is that adapter, and it interpolates trilinearly rather than by nearest
sample because Marching Cubes' case table is derived from the trilinear interpolant — a field
wrapping the same samples any other way disagrees with the mesher about where the surface is.
M-260 — a uniform grid over the sample cells lost to a flat box reject, 3.9× (S-006)
M. Mesh-to-SDF needs a closest-triangle query per sample. The first implementation binned triangles into the sample grid's own cells and searched expanding shells, stopping when the shell's own lower bound exceeded the best distance found. It measured 3,457 ms against an unaccelerated scan's 892 ms on 9,261 samples × 872 triangles — 3.9× slower than the thing it was accelerating.
Why, and it is not an implementation detail. Reaching radius k costs O(k³) bins. A sample at
the corner of a 21³ grid around a unit sphere is twelve cells from the surface, so it walks
essentially the whole grid before it finds anything — and most samples in any grid are far ones.
Fixing the shell iteration from O(k³) to O(k²) per shell does not change the conclusion, because
the total over all shells is O(k³) either way.
Replaced with a two-level axis-aligned box reject: a box per triangle, and a box per block of 64
consecutive triangles. 394 ms — 2.3× faster than brute force, and the whole from_mesh test
module dropped from 31.6 s to 3.0 s.
The reject is exact — a box whose nearest corner is beyond the current best cannot contain a closer point — so the accelerated and unaccelerated paths are asserted bit-identical, not merely close.
What makes the blocks work is a property of the input, stated rather than assumed: Marching Cubes
emits triangles in grid order, so 64 consecutive ones are spatially close and their block box is
tight. A mesh whose triangles arrive in arbitrary order degrades to the unaccelerated scan and stays
correct. This is not a BVH, which is what the paper uses and what would make the query O(log m)
rather than O(m).
M-261 — Real gained acos, and libm is why (S-006)
V. The angle-weighted pseudonormal weights each face normal by the incident angle, which needs
an arc cosine Real did not have. Added as libm::acosf / libm::acos, unconditionally, for the
reason in CLAUDE.md's libm justification: std's acos is the platform's and differs between
macOS and Linux, and T-007's 63 golden hashes are committed. A platform-dependent angle would make
this crate's mesh-to-field path produce different geometry on the dev machine and in CI.
M-262 — the winding number beats the pseudonormal on holed meshes, by a widening margin (S-007)
M. A meshed sphere at 17³ with a cap removed, scored against the analytic sphere on the 4,491 samples more than one cell from the surface. Four hole sizes:
| cut | triangles removed | boundary edges | pseudonormal wrong | winding wrong | mean \|w−½\| |
|---|---|---|---|---|---|
| 0.6 | 104 | 24 | 5 | 0 | 0.0000 |
| 0.3 | 212 | 28 | 131 | 27 | 0.0674 |
| 0.0 | 268 | 28 | 327 | 50 | 0.1225 |
| −0.5 | 396 | 28 | 1,435 | 88 | 0.2650 |
The margin widens from 5-versus-0 to 16×. On the closed mesh the winding number is exactly
1.000000000 inside and 0.000000000 outside — the correction term is identically zero when there
are no boundary edges, so that case reduces to plain ray parity and calibrates the intersection code
separately from the construction.
The one-hole version of this test was not evidence. At cut = 0.6 the two methods differ by five
samples out of 4,491, which is indistinguishable from noise in a discretisation. The sweep is what
makes it a finding rather than an anecdote.
Why the winding number is not perfect either, and why that is correct. The mean |w−½| column
grows with the hole. That is not the measure becoming confidently wrong — it is the question
becoming wrong. Once half the sphere is deleted the mesh no longer encloses the points under the
hole, so calling them outside is the right answer for the surface that actually exists, and scoring
against the analytic sphere is scoring against geometry that was removed. Jacobson et al.'s framing
is that a GWN measures "how confident we can be that a point is inside"; the column is that
confidence at exactly the samples this counts as wrong. So the assertion is a 3× margin over the
pseudonormal at every hole size, plus exactness on the smallest hole, not zero errors everywhere.
Sources checked rather than assumed. Xie, Hafner & Wojtan (10.1145/3811339) give the
construction verbatim: w_M(q) = Σᵢ sgn(r·nᵢ) − (1/4π) Σⱼ Ωⱼ, with the cone apex "directly behind
the ray" so the cone contributes no forward intersections. They are also the source for not
citing Barill et al. 2018 as state of the art: Barnes–Hut summation "trades off accuracy for
computational speed… the resulting values are merely approximations." Martens & Bessmeltsev supply
the grid optimisation used here — "to compute voxelizations of resolution N³, we only need to shoot
N² rays" — which is why this casts one ray per row and sums the intersections beyond each sample.
M-263 — the boundary must be counted with multiplicity, not as a boolean (S-007)
V. The closing cone needs one triangle per net directed boundary edge. Treating "is this a
boundary edge" as a boolean is correct on a manifold mesh with boundary and wrong on the triangle
soup this exists to handle: an edge with three incident faces has a net of one and needs one closing
triangle, while a boolean either drops it (if any partner exists) or double-counts it. The net is
also what makes the sign right without a separate orientation pass — a net of +n for u → v means
n copies of the triangle (v, u, apex), the reverse edge, which is what makes M + C consistently
oriented.
Real gained atan2 for van Oosterom & Strackee's solid angle. The four-quadrant form is
load-bearing: the denominator goes negative for a triangle subtending more than a hemisphere, and a
plain atan of the quotient loses the half-turn.
M-264 — the uncertified set is a curve, not a resolution failure (T-015)
M. Plantinga & Vegter's per-cell condition evaluated on all eight reference fields at 17³, 33³ and 65³. Share of active cells carrying the isotopy guarantee:
| field | 17³ | 33³ | 65³ |
|---|---|---|---|
sphere |
100% | 100% | 100% |
torus |
100% | 100% | 100% |
thin_plate |
100% | 100% | 100% |
fbm_terrain |
100% | 100% | 100% |
box_exact |
72.97% | 86.98% | 93.62% |
csg_difference |
69.26% | 85.66% | 92.75% |
gyroid |
84.84% | 92.94% | 96.36% |
noise_cavity |
35.89% | 48.59% | 80.02% |
docs/measurements/isotopy.csv.
The interesting number is not the fraction, it is how it scales. Halving h multiplies a
d-dimensional set's cell count by 2^d, so two doublings give 2^(2d) and
d = log₂(growth) / 2. Measured 17³ → 65³:
| field | active d |
uncertified d |
|---|---|---|
box_exact |
2.14 | 1.10 |
csg_difference |
2.17 | 1.13 |
gyroid |
2.07 | 1.04 |
noise_cavity |
2.33 | 1.49 |
The active set is two-dimensional, because a surface is. The uncertified set is one-dimensional. So those cells are not scattered failures of an under-resolved field — they trace a feature curve: the box's edges, the CSG seam, the gyroid's high-curvature ridges. No spacing will certify them, because the feature is genuinely not smooth, and the fraction climbing toward 100% is just the 1-D set thinning against a 2-D one rather than the problem going away.
noise_cavity at 1.49 sits between the two, which is the honest reading of a field that is both
under-resolved at 17³ and creased: its fraction jumps 36% → 49% → 80%, far faster than the others.
That is consistent with M-244, where its gradient was measured at 7.73 against a first draft's
declared 2.598.
The certificate is exact here, and the reason it can be is worth recording. The general condition
needs interval arithmetic over an arbitrary F, which this crate cannot do — an Sdf returns point
values, and a sampled gradient hull underestimates variation, so the predicate would pass where the
truth fails. That is the one direction a certificate must never err in. But the surface Marching
Cubes approximates is the trilinear interpolant, and for that the bounds are exact and
closed-form: ∂F/∂x is bilinear in (y, z), hence a convex combination of the four x-edge
differences, so its exact range is their min and max. F is a convex combination of the eight
corners, so 0 ∉ □F(C) is exactly "the cell is inactive" — the first clause is free and the
predicate reduces to the inner product. No interval library, no sampling, and h² factors out of the
sign test on isotropic cells.
Two configurations this crate already cares about are refused, and correctly. The paper's own Figure 1 — alternating corner signs — is refused, which is the ticket's "engineered violator". So is a face-ambiguous cell: a configuration whose topology depends on a tie-break is by definition not determined by the corners, and A-002's entire series exists because of it.
M-265 — decimation is re-sampling on a nested grid, so the literature's rule has no bite here (T-016)
M. Four downsampling operators against re-sampling, on all eight reference fields, 65³ → 9³ in
four levels. docs/measurements/downsample.csv.
Decimation matches re-sampling bit-for-bit — every triangle count, every vertex position, every error figure, on every field at every level. Asserted as an equality, not a tolerance. The reason is elementary once stated: a grid that was sampled from the field, decimated, keeps a subset of those same points, and decimation composes, so level 3 is still a subset of the field's own samples.
That falsifies the framing this ticket inherited. "You do not downsample, you re-sample" (Frisken,
Koschier) is sound advice about filtering operators; for decimation on a 2ᵏ + 1 nested grid it
is a distinction with no difference, and the free operator is already the recommended one. It stops
being free the moment a level is edited rather than sampled — which is the case a destructible
game is in, and is where the rule earns its keep.
The filters are strictly worse, both ways at once. Mean (box, [1,1,1]/3) and Tent
([1,2,1]/4) produce fewer triangles and larger geometric error at every level — worst
|analytic| on sphere at level 3 is 0.07196 for the mean against re-sampling's 0.01430, 5×.
And at level 3 the mean deletes the entire torus: 0 triangles against 128. A filter that removes
a whole object one level before the grid stops resolving it is not "correctly discarding a sub-cell
feature".
Min behaves exactly as designed and the price is now known. It never loses anything — more
triangles at every level on every field — because taking a minimum can only pull values negative, so
solid grows and never shrinks. The cost is a systematic dilation of about one fine cell per level:
worst error reaches 4.02 on fbm_terrain at level 3 against re-sampling's 0.93, and 0.75 on
sphere against 0.014.
Recommendation, with the number behind it: decimate. It is free, it is identical to re-sampling
while the fine level is field-derived, and both alternatives trade accuracy for something that is not
worth it — the filters for smoothing that deletes objects, min for a conservatism that costs
several cells of dilation.
M-266 — M-72's aliasing is alignment, not chance (T-016)
M, and it refines M-72 rather than contradicting it. M-72 recorded thin_plate at
4,088 → 1,016 → 248 → 56 triangles across LOD 0–3 and explained the survival as "whichever edges
happen to straddle a thin slab still register a sign change" — which reads as chance.
It is not chance. The plate is 0.4 × h thick and centred at y = 0; every level here has an odd
sample count (65, 33, 17, 9), so y = 0 is a sample plane at every level and the feature is exactly
aligned with the sampling. Shifting the plate by half a cell produces zero triangles at every
level, including the finest, where it is still only 0.4 cells thick.
So the sequence is not a sub-cell feature disintegrating; it is a perfectly aligned one being found
every time, and the falling counts are just its x/z extent being sampled more coarsely.
And the ticket's attribution was backwards. It predicted that 4,088 → 1,016 → 248 → 56 is what box-filter averaging produces, and that re-sampling would make the plate "correctly disappear". Measured: that sequence is re-sampling's, and the box filter is what makes the plate vanish — completely, from level 1. Both halves inverted.
The mechanism is clear once separated: re-sampling asks a point question, so a corner inside the plate registers a sign change however thin it is; a filter asks a neighbourhood question, so a thin negative sliver averaged against a large positive surround comes out positive. Neither is "correct" — they answer different questions, and which one a consumer wants depends on whether a feature that vanishes at a known distance is better than one that survives by luck of alignment.
This also makes ThinPlate::THICKNESS_IN_CELLS's doc comment wrong. It reads "Below 1.0 so
that no grid phase can ever put a corner inside the plate, with margin", and the canonical grid puts
a whole plane of corners inside it. Thin enough is not the same as off-lattice.
M-267 — the sampled gradient supremum is not even monotone in sampling density (T-017)
M. sup ‖∇f‖ re-measured at 8³, 16³, 32³ and 64³ samples over each field's own domain:
| field | n=8 | n=16 | n=32 | n=64 | still climbing |
|---|---|---|---|---|---|
sphere, torus, box_exact, csg_difference, thin_plate |
1.00000 | 1.00000 | 1.00000 | 1.00000 | no |
gyroid |
1.54383 | 1.72726 | 1.73003 | 1.73131 | no |
fbm_terrain |
2.35846 | 2.84980 | 2.90822 | 3.04828 | yes |
noise_cavity |
8.84299 | 7.74791 | 9.37619 | 9.72480 | yes |
noise_cavity goes down and then up. M-244 recorded its gradient reaching 7.734 and used that to
justify declaring the field Unbounded; the figure was measured at n = 16, and at n = 8 it was
already 8.84 — higher. So 7.734 was not a lower bound that later runs merely improved on. A
sampled maximum over one point set is not nested inside a sampled maximum over a denser one, because
the denser set is not a superset — F-002's grid is offset by a fixed nudge and rescaled with n.
That is a sharper argument than M-244's for the same conclusion. M-244 said a sampled maximum is a lower bound on a supremum and so cannot be declared as a Lipschitz constant. This says the sampled maximum is not even a stable lower bound: no single run establishes anything, and taking the max over several runs is the least one would have to do to claim a number.
The five exact fields read exactly 1.00000 at every density, which is the eikonal property
holding to five figures across four independent samplings — a stronger confirmation than any one run.
The gyroid's declared bound is loose by 2×, and that is now recorded rather than suspected. It
declares Lipschitz { l = 2√3 ≈ 3.4641 }, derived at M-244 from |∂g/∂x| ≤ 2. Measured supremum
converges to 1.731 — bound_gap = 0.4994. The derivation is sound and the bound is therefore
correct; it is not tight, because the three terms of ∇g cannot be extremal simultaneously.
Sampling cannot settle whether 2√3 is attainable, which is why the declaration stands. The cost is
paid in F-005's empty-cell rejection, where a loose constant inflates the rejection radius and
disqualifies cells a tighter one would skip — M-248 measured exactly that, at 1.5× against
thin_plate's 11.8×.
M-268 — field quality is now in the regression gate, and every column is exact (T-017)
M. docs/measurements/field_quality.csv, baselined per machine and diffed by
scripts/regress.sh field_quality. Columns: sup_grad, inf_grad, eikonal_pct, bound_gap,
certified_pct, keyed on (field, samples).
All five are compared exactly, with None tolerance, and the reason is structural rather than
optimistic: every one is a max, a min, or a ratio of counts over deterministic libm arithmetic.
None is a sum, so there is no accumulation order to differ across architectures — unlike hausdorff
and self_intersections_per_1k, which carry stated tolerances for exactly that reason. A field is
not supposed to move at all; if one of these shifts, either a field's definition changed or a
constant it depends on did, and both should require an acknowledgement.
Unbounded fields write empty cells for declared_bound and bound_gap rather than zeros.
regress.sh skips an empty value, and a literal 0 would read as "the gradient is nowhere near the
bound" — the opposite of "there is no bound".
M-269 — a grid-aligned ray double-counts shared edges, and the constructor shootout is what found it (T-018)
M, and it is a defect in S-007 that S-007's own tests missed. T-018 put the pseudonormal and the
winding number side by side on the same mesh for the first time. Their magnitudes are computed by
the same code, so any difference is a sign difference — and on torus the winding number read a
worst error of 1.223 against the pseudonormal's 0.014, and 1.168 against 0.004 at 65³.
The cause: intersect_x_ray tested u ∈ [0,1] and u + v ∈ [0,1] inclusively on both sides,
while its own doc comment claimed a half-open convention. A ray passing exactly through an edge
shared by two triangles is therefore counted twice, which flips the parity and so the sign.
And a grid-aligned ray hits shared edges constantly, not rarely. The samples lie on grid lines,
and Marching Cubes places every vertex on a grid edge, so a +x ray from a sample runs along a
line that triangle edges also lie on. This is not a floating-point near-miss; it is exact
coincidence, by construction.
A half-open barycentric rule does not fix it in 3D: two triangles meeting at an edge do not agree on
which of their own u, v, w that edge is, so there is no local rule that makes exactly one of
them own it. The fix is Plantinga & Vegter's device, and they state the licence — "We can take ε
arbitrarily small using a symbolic perturbation" — so the ray line is nudged off the lattice by
~1e-5 of a cell, with different fractions on y and z so it cannot land back on a cell diagonal.
The perturbation has to move the query point too, and getting that wrong is a second bug the tests
caught immediately. The first attempt nudged only the line and left q and the cone apex on the
sample: χ was then counted along one line while the correction was subtracted for a cone whose apex
sat on another, which is not the construction. It turned 0 misclassifications into 12 on the
smallest hole. With the query point moved with the line, torus matches the pseudonormal to the last
digit at both resolutions and the hole sweep is unchanged.
The method note is the point. S-007 shipped with four passing tests including a closed-sphere
calibration that read exactly 1.000000000 and 0.000000000. A sphere is convex, so a grid-aligned
ray leaves through one triangle and the double-count has nothing to double. It took a second
constructor computing the same magnitudes by different means to expose it — which is what a
head-to-head harness is for, and is the argument for T-018 existing at all.
M-270 — a benchmark that hands a repair algorithm perfect input measures the benchmark (T-018)
M. The first version of this shootout ranked all four field-based constructors in one table and
put band first on both speed and accuracy — 5.02 ms against the exact transform's 5.11, and a
worst error of 0.0729 against 0.1206, 0.1623 and 0.1453.
That was an artefact and the algorithm deserved no credit for it. S-004 keeps the input outside its band by design; the harness fed it the analytic field, so most of its output was ground truth it had merely copied. The other three read only signs and sub-cell crossings and discard magnitudes, so they gained nothing from the same input — which is exactly why the comparison was unfair without looking unfair.
Refed with the analytic field scaled by two — same zero set, twice the gradient, the shape a CSG scale or a careless composition produces — the honest numbers are:
| worst | worst near surface | |
|---|---|---|
| degraded input | 2.26132 | 0.18740 |
| after reinitialisation | 2.26132 | 0.11325 |
It repairs the near band and leaves the far field exactly as it found it. That is what a narrow band is, and stating it as a number rather than as a design intent is the difference between a measurement and a description.
The taxonomy is the fix, not a tolerance. Three families now: signs → field (exact, swept, marched), field → field (band, on degraded input), mesh → field (pseudonormal, winding). A constructor may only be ranked against ones answering the same question.
M-271 — the exact transform is the hungriest constructor, and the mesh-based pair are free (T-019)
M. Peak resident set per constructor, measured out of process — one process per constructor via
--only, reading its own VmHWM from /proc/self/status, minus a baseline run that builds the
input and stops. sphere, KiB above baseline:
| constructor | 33³ | 65³ | growth |
|---|---|---|---|
swept |
376 | 4,228 | 11.2× |
marched |
404 | 4,616 | 11.4× |
exact |
608 | 6,212 | 10.2× |
band |
784 | 6,704 | 8.6× |
pseudonormal |
292 | 0 above the mesh | — |
winding |
208 | 0 above the mesh | — |
Eight times the samples costs 8.6–11.4× the memory, so every one is essentially linear in sample count with different constants.
The ordering is the finding. signed_distance_field is the exact transform and the only O(n)
one, and it is the most memory-hungry of the three — 47% more than sweeping. Felzenszwalb &
Huttenlocher's separable algorithm needs per-row envelope state and a squared-distance staging array
on top of its output, and none of that is visible from the complexity class. "Exact and linear" does
not mean lean, and a chunked consumer choosing a constructor by asymptotics would have chosen wrong.
band is the most expensive of all, which is the opposite of what a narrow-band method sounds
like. It runs the bounded march and additionally holds the input it is repairing and an on_surface
flag array — M-256 measured it finalising only 13.4% of samples, and that is a saving in work, not
in footprint.
The two mesh-based constructors cost nothing above the mesh they were handed at 65³. Meshing allocates more transiently than either of them does, so their own peak sits underneath it. That is the honest reading of a zero here, not a measurement failure — and it means a consumer already holding a mesh pays only for the output buffer.
On the instrument. T-018 declared this gap because a counting GlobalAlloc needs unsafe impl
and the workspace sets unsafe_code = "forbid". Reading /proc/self/status is a plain file read and
needed no such thing; what it needed was leaving the process, since VmHWM is a high-water mark
over a whole process life and would otherwise attribute every constructor's peak to whichever ran
first. So the rule cost a process boundary, not a measurement. Linux only — macOS publishes no
/proc and its ru_maxrss needs libc — and CI runs Linux, which is where the figure is checked.
M-272 — the pre-registration gate is a const assertion, and that is the whole of it (R-000)
V. R-000 asked for "the feedback loop is currently a discipline; make it a compile error", with
the acceptance "an experiment without a pre-registered P- fails to build".
It needs no proc macro and no build script. experiment!("P-n") expands to
const _CHECK: () = assert!(isomesh::experiment::is_preregistered("P-n"), "…");
and is_preregistered is a const fn doing a byte-wise str comparison, because str's
PartialEq is not const and neither is <[u8]>::eq. A const item is evaluated whether or not its
value is read, so an unregistered id cannot reach a run. The acceptance is proved by a
compile_fail doctest, which is the only kind of test that can assert a compile error and is
therefore the only honest way to check this ticket.
Preregistration is #[non_exhaustive], so a consumer crate cannot construct one. The harness takes
&'static Preregistration and there is no other way to obtain one, which makes the macro the sole
entrance rather than the polite one.
Two smaller things the design gets for free. falsified_by is a required field, so a hypothesis
with no stated refutation is unrepresentable rather than discouraged. And records names the columns
in advance, with Run::record panicking on any other set — so a metric that was predicted and then
quietly not measured is a failure, not a silence. That is F-002's one-sidedness in another costume:
the instrument has to be able to report the bad news.
The one thing it cannot enforce is that the registration was written first. Nothing in a source
file can. What it does is make registering a commit, so git carries the ordering, and
scripts/backlog_gate.sh fails if a registered id never reaches FINDINGS.md.
P-14 — registered for R-003, before it was measured
The residual non-manifold output under the dual extractors is the one-vertex-per-cell rule meeting a cell with more than one surface component. Almost all of it should sit in cells where Manifold Dual Contouring emits more than one vertex, and MDC's own count should be strictly lower on every field where either is non-zero.
Falsified by a substantial share of non-manifold vertices sitting in cells where MDC emits exactly one vertex — which would mean the defect is not the one-vertex-per-cell rule and is somewhere else entirely.
Records: non_manifold_vertices, non_manifold_edges, multi_vertex_cells,
nm_vertices_in_single_vertex_cells, worst_link_components. Answered above — falsified on its
first clause.
M-275 / P-14 — FALSIFIED on its first clause, and the residue is an edge defect (R-003)
M. One 49³ grid per field, one extraction per dual rule, no chunking and no weld anywhere — so a
seam cannot be a second explanation. docs/experiments/p-14.csv.
| field | extractor | nm vertices | nm edges | cells MDC split | nm vertices in unsplit cells | link components | worst link degree |
|---|---|---|---|---|---|---|---|
gyroid |
surface_nets |
99 | 48 | 54 | 45 | 2 | 4 |
gyroid |
manifold_dual_contouring |
0 | 0 | 54 | 0 | — | — |
fbm_terrain |
surface_nets |
38 | 19 | 19 | 19 | 1 | 4 |
fbm_terrain |
manifold_dual_contouring |
0 | 0 | 19 | 0 | — | — |
noise_cavity |
surface_nets |
597 | 314 | 290 | 307 | 2 | 4 |
noise_cavity |
dual_contouring |
597 | 314 | 290 | 307 | 2 | 4 |
noise_cavity |
manifold_dual_contouring |
106 | 53 | 290 | 106 | 1 | 4 |
sphere, torus, box_exact, csg_difference and thin_plate are clean under all three.
Clause two held. Manifold Dual Contouring's count is strictly lower on every field where either is non-zero — 99 → 0, 38 → 0, 597 → 106. Splitting multi-component cells removes the defect entirely on two of three fields.
Clause one is false, by about half. "Almost all of them sit in cells where MDC emits more than one vertex" — measured, 45 of 99, 19 of 38 and 307 of 597 sit in cells MDC did not split, and MDC's own residual 106 are 106 of 106 in unsplit cells. So the one-vertex-per-cell rule explains roughly half the defect on the dual rules and none of what survives its own remedy.
What the other half is, and it reframes the ticket. The vertex-to-edge ratio is 597/314, 99/48, 38/19 and 106/53 — exactly two to one, on every row. Every non-manifold vertex is an endpoint of a non-manifold edge. So there are not 597 defects plus 314 defects; there are 314 defects, each counted twice more by the vertex walk. The residue is an edge with three or more incident faces, which is a different failure from a vertex whose link falls apart, and no amount of cell splitting addresses it — MDC splits the cells and the edges remain.
A second shape of vertex defect, which the first run of this experiment could not see.
worst_link_components = 1 on a vertex validate flagged looks like a contradiction and is not: a
link can be connected and still not a simple cycle, with one link vertex reached by four link
edges instead of two. That is a pinch, not a bowtie. The added worst_link_vertex_degree column
reads 4 on every non-clean row, and separates them: fbm_terrain and MDC's residue on
noise_cavity are purely pinches (components 1, degree 4); gyroid and noise_cavity under
Surface Nets and Dual Contouring carry both (components 2 and degree 4).
The instrument was wrong before the hypothesis was. link_components alone would have reported
fbm_terrain as having non-manifold vertices with one-component links and left that unexplained.
Adding a column rather than editing the registration is what M-273's relaxation made possible.
M-273 — the first thing done with the pre-registration mechanism was amend a registration to fit the code (R-002)
✗ against my own practice, caught by the mechanism itself. R-000 shipped a harness whose
Run::record demanded the row's keys be exactly the registered records. The first experiment
needed a field column to identify its rows — and the path of least resistance was to edit P-8's
registration and add it. Which is amending a prediction to fit the code, one commit after building
the thing whose entire purpose is to stop that.
It was caught on the next experiment, when P-9 panicked with "field is not one of the records this
experiment registered" and the same edit beckoned again.
The design was wrong, not only the act. records is a list of metrics that must be reported,
not a schema for the file. Row keys are not anybody's hypothesis. Run::record now panics only on a
missing metric and permits extra columns, which are written after the registered ones, sorted —
so identifying a row never requires touching a prediction. Both amendments were reverted to what
R-000 committed.
The general rule, which is Part 5 material. A gate that is stricter than the thing it protects creates pressure to weaken the gate, and the weakening is indistinguishable from the abuse it was built to stop. Check exactly the property you mean: "every registered metric appears" was the property; "the columns are exactly these" was a stronger claim nobody needed and could not keep.
M-274 — the fixture never contained the configuration both experiments were about (R-002)
✗. P-8's first run used a 2×2×2 block of 8-cell chunks at h = 4/35 anchored at -2.0. That
spans 16 × 4/35 = 1.83 units of a 4-unit domain, so the block covered a corner of every
reference field and never reached the origin. P-8 recorded numbers, they were internally consistent,
and the write-up asserted a mechanism about k-way merges.
P-9 measured the same fixture and reported buckets_of_three_or_more = 0 in all 49 rows it produced. There
was no k-way merge anywhere in it. The mechanism was a description of something the run did not
contain, arrived at by reasoning from the algorithm rather than from the data — which is the failure
mode this file exists to catch, committed while writing an entry for this file.
Centring the block and taking 18-cell chunks — 36 × 4/35 = 4.11, covering [-2, 2] — puts the
eight-chunk corner at the origin and the four-chunk edges through the surface. k ≥ 3 buckets appear
immediately: 6–32 per configuration on every primal extractor. Both experiments were re-run and
P-8's entry replaced; the conclusion survived and got much stronger (the gate's damage went from
"up to 42 non-manifold vertices" to "up to 791"), which is luck rather than vindication.
The rule. A fixture that produces zero of the thing being studied looks exactly like one that
produces some, because every other column is populated. Count the phenomenon, not just the
outcome — P-9's buckets_of_three_or_more column is what exposed this, and it existed only because
the pre-registration demanded it.
M-276 — the dual methods' non-manifold edges are the ambiguous face, all 314 of them (A-021)
M + V. noise_cavity at 49³ under Surface Nets, no chunking and no weld. For each non-manifold
edge, the grid face its two cells share, and how many of that face's four boundary edges carry a sign
change:
| population | crossed boundary edges | count |
|---|---|---|
| non-manifold edges | 4 | 314 |
| manifold (2-face) edges | 2 | 30,891 |
| manifold (2-face) edges | 0 | 8 |
Every one. No exceptions, and no overlap between the populations. Zero non-manifold edges join cells that are only diagonally adjacent, so the quad's triangulation diagonal is never the culprit either.
The mechanism, derived from the code and then confirmed by a control. DualMesher::emit_quads
winds a quad as (0,1,2) and (0,2,3), so each quad side lands in exactly one triangle and only
the diagonal 0–2 lands in two. The mesh edge between two face-adjacent cells is a side of the quad
of every crossed boundary edge of their shared grid face. So the face count on that mesh edge
equals the number of crossed boundary edges: two is manifold, four is not.
A square whose four boundary edges are all crossed is one whose corner signs alternate — and that
is the literature's ambiguous face, verbatim (10.1145/195826.195828):
"Each cell face has four edges, an even number of which will contain intersection points. If two edges of a face contain intersection points, then the only choice is to connect them with an edge… However, if a cell face has intersection points in all four of its edges, there are choices of how to connect up pairs… which justifies the name ambiguous face."
So this is the A-002 series arriving from the dual side. Grosso's trilinear work, the asymptotic
decider, FaceAmbiguity::AsymptoticDecider — all of it exists to make one choice on an ambiguous
face in the Marching Cubes path. The dual path makes both choices at once: it emits a quad for
each of the four crossed edges, and all four pass through the same mesh edge.
It is therefore not inherent to "one quad per crossed edge". The ambiguous face has a choice by definition, and a decider that picked one pairing would emit two quads there instead of four. That is a specific remedy with a precedent inside this crate, and it is A-022 rather than a claim made here — the dual path has no face-ambiguity setting today, and asserting what MDC's own criterion is without reading it would be rule 5's failure.
It also closes P-14's loose end exactly. P-14 found MDC's residual 106 non-manifold vertices sitting 106 of 106 in cells MDC did not split. Now explained: MDC splits cells with more than one surface component, and an ambiguous face between two cells that each hold a single component does not meet that criterion. The two measurements interlock — one says the residue is not about cells, the other says what it is about.
Method note: the reasoning was wrong before it was right, and the probe is what caught it. Reading
emit_quads first produced "a mesh edge gets a quad per crossed boundary edge, and a face with a sign
change has two, so every dual mesh is non-manifold everywhere" — which contradicts every measurement
in this file. The error was treating a quad as contributing two faces to each of its sides. Printing
the face-count histogram for a plain half-space ({1: 8, 2: 8} — no edge above two) settled it in
one run and cost less than the third attempt at the algebra.
M-277 — the index generator was blind to the shape its own file had moved to (R-004)
M. scripts/findings_index.sh matched exactly two things: table rows | M-n | … | in Part 2, and
### ✗n headings in Part 1. Measurements stopped being table rows at M-255 — the entries had
outgrown a cell — and the generator never noticed. Counted directly:
| count | |
|---|---|
^\| M-n \| table rows |
249 |
^### M-n — heading sections |
22 |
| what the index said | "319 entries — 249 measured" |
So every measurement from S-004 onward, twenty-two of them including all of R-001, R-002, R-003 and
A-021, was in FINDINGS.md and absent from the index a reader is told to consult first.
--check was green throughout, and correctly so. A staleness check compares the artefact against
what the generator produces, so it cannot see the generator's own blind spot: both agreed, and the
one gate guarding the index was structurally unable to report this. The script's own header says an
index that is allowed to drift "answers confidently and wrongly"; it was doing that about itself.
Found while adding R-004's entry, by going to copy the row format and finding that the last twenty-two entries do not use one.
Fixed by also matching ### (M|V|O)-n — … headings, with M-275 / P-14's two-id form resolved to
the first id and a table row winning over a heading for the same id. P- headings stay unindexed
deliberately — ### P-8 … P-13 names six predictions in one heading and would collide with each of
their own outcome sections. Index after the fix: 341 entries, 271 measured.
M-278 / P-11 — HELD, and the crack budget is not where the ticket assumed (R-004)
M. benches/experiment_p11.rs, docs/experiments/p-11.csv, 40 rows: sphere and torus ×
five level-0 spacings × two LOD pairs × two arithmetics. A fine block meets a half-resolution one
across a seam, stitched with Lengyel transition cells at zero width, and every block starts twelve
cells from the grid origin so that both arithmetics can differ at all.
| arm | sample position |
|---|---|
canonical |
o + h·(base + local) — one multiply from a global integer index |
offset |
(o + h·base) + h·local — a step added to the block's own corner |
Both come from the shipped functions. TransitionCell::sample already takes (origin, base), so
handing it the face's own world origin with a zero base is the pre-M-73 code. Marching Cubes has no
integer base, so its canonical arm roots the extraction at the grid origin and clips to the block's
cells; clip_agrees_with_the_block checks that clip at every power-of-two spacing, where the two
arms compute identical positions and a difference could only be the clip.
The result, in one table — seam-plane boundary edges
| pipeline | canonical |
offset |
|---|---|---|
| weld + transition cells (what the crate ships) | 0, all 20 rows | 0, all 20 rows |
| bit-identity + transition cells | 0, all 20 rows | 0 at h = 0.125 and 0.0625; 63–348 at 0.1, 1/12, 1/14 |
| weld, transition cells removed | 32–184 | 32–184, differing from canonical in 5 of 20 |
P-11 HELD, in both clauses. Canonical reconstruction gives zero seam cracks at every cell
size — not only the powers of two — under both merge policies, and every one of the fine block's
seam vertices is bit-identical to its partner (shared == pairs, 20 of 20 rows, up to 124/124). The
registered falsifier — "cracks surviving canonical reconstruction" — did not fire anywhere, so the
defect does not localise back into Transvoxel.
What the ticket assumed, and what is actually true
R-004 is titled "quantify the crack budget: arithmetic vs algorithm", and the split is sharper than expected but on a different axis:
- The algorithm owns the whole of the visible budget. Remove the transition cells and the seam opens to 32–184 boundary edges with a widest hole of 1.03–3.01 cells — a hole you can see the sky through. Put them back and it is 0. Arithmetic changes none of that.
- The arithmetic owns the whole of the invisible one. Its worst positional disagreement is
1.440e-15world units, and the weld epsilon ish · 1e-4. So under the shipped pipeline the offset arm is indistinguishable from the canonical one, and under bit-identity it is 63–348 cracks wide. That is ✗18.
Three things the sweep found that were not predicted
1. The seam plane is the wrong unit of analysis, which sharpens M-32 rather than falsifying it.
M-32 is confirmed where it speaks: at h = 0.125 and 0.0625 the two arms are bit-identical
everywhere and every crack column is 0, so "recommend power-of-two cell sizes for chunked worlds"
holds. But at h = 0.1 and 1/12 the seam plane's own coordinate agreed bit for bit
(seam_plane_delta = 0) while only 24 of 92 vertices did. The disagreement is not confined to
the coordinate along the seam normal; it is every coordinate that two blocks with different bases
reach by different groupings — the fine block's (o + h·12) + h·i, the patch's
(o + h·(12 + 2j)) + h·s, the coarse block's (o + 2h·6) + 2h·j. Only h = 1/14 disagreed on the
plane itself, at 4.441e-16.
2. Bit-exact sharing degrades continuously, and one spacing loses it entirely. Partners that are
bit-identical, offset arm: 0.125 and 0.0625 → 100%; 0.1 → 26/76, 14/48, 6/36, 4/24;
1/12 → 24/92, 13/56, 12/44, 9/24; 1/14 → 0 of 108, 0 of 72, 0 of 52, 0 of 40. There is no
threshold here to sit above — a spacing either happens to keep the grouping exact or it does not.
3. An ulp of coordinate can be a cell of geometry. The bit-identity crack is a hairline
(~1e-14 cells) in 8 of the 12 non-power-of-two offset rows, 8.1e-3 and 1.7e-2 cells in two
more, and 1.053 and 2.076 cells on torus at h = 1/12. A sample perturbed in its last bit
crossed zero, the two sides disagreed about whether an edge was cut, and a patch that should have
been emitted was not. The same effect shows in the control: with transition cells removed, the offset
arm's crack count differs from the canonical one in 5 of 20 rows (68→81, 44→48, 37→41, 152→160,
72→80). So "the arithmetic only moves things by an ulp" is true on average and false in the tail.
The consequence for the crate, which is a ticket rather than a claim
ChunkLayout::world_of_sample's doc calls itself "the single place a sample's world position is
defined. Everything else routes through it" — and no extractor does. Extractor::extract_into
takes origin: [R; 3] and computes origin + h·local, so a chunk at a non-zero base gets the offset
arithmetic by construction and there is no argument a caller can pass to avoid it. That is why this
experiment had to reach the canonical arm by clipping an over-extended extraction. X-005 owns it;
it is an API change to the crate's central trait and therefore a decision, not a fix.
P-15 — registered for R-007, before it was measured
The residue M-279 leaves, stated so it can fail. Surface Nets executes 207 instructions per sample at IPC 1.22 where Marching Cubes executes 132 at 4.04 — 1.57× the instructions and 5.24× the cycles — and none of the obvious candidates survived: not the crossed-edge gather (a field with no surface costs the same), not branches (they fall), not allocation (zero page faults), not the TLB, and not, at 16.7 M samples, the misses (a 2.4× swing moves cycles by 0.4%).
H. More than half of the dual mesher's cycles per sample are spent in
emit_quads, which is three unconditionalO(n³)sweeps over the sample grid rather than work proportional to the surface.
The reasoning, so the prediction is a claim and not a shrug: place_vertices reads the same eight
corners per cell that Marching Cubes' march does, and sample is identical, so the dual's extra ~75
instructions per sample have to come from emit_quads — which walks every grid edge on all three
axes and loads two samples before the sign test that would let it skip. Two of its three passes
have their innermost loop on the wrong axis (v = (axis + 2) % 3), giving strides of nx and
nx·ny. Whether that is where the cycles go rather than merely the instructions is exactly what is
not known.
Falsified by emit_quads accounting for half or less, which puts the cost in sample or
place_vertices — work Marching Cubes does too, at four times the IPC — and means the dual's IPC is
lost to something other than its extra traversal.
Records stage, cycles_per_sample, instructions_per_sample, ipc, samples.
A note on the instrument, because the obvious one is unavailable. STALLED_CYCLES_BACKEND would
answer this directly and AMD does not map it (perf_event_open → ENOENT). An intra-extractor
breakdown therefore needs either an ablation seam in DualMesher or per-stage counter windows inside
it, and which of those is acceptable under the one-path rule is part of R-007.
M-279 / P-12 — the mechanism is FALSIFIED, and the registered falsifier could not have caught it (R-005)
M. benches/experiment_p12.rs, docs/experiments/p-12.csv, 90 rows on the Ryzen 9 5900X.
Six hardware events and one software event through perf_event_open; every counter ran the whole
window (counter_time_ratio 1.0 on all 90 rows) and the clock held at 4.148–4.188 GHz, which the
rows carry rather than imply (M-280).
What P-12 predicted, and what the numbers say
sphere, f32, the resolution sweep's own grid:
| n | MC cyc/sample | MC instr | MC IPC | MC miss | SN cyc/sample | SN instr | SN IPC | SN miss |
|---|---|---|---|---|---|---|---|---|
| 48 | 33.7 | 138.8 | 4.12 | 0.104 | 144.0 | 210.5 | 1.46 | 1.635 |
| 128 | 32.4 | 133.2 | 4.11 | 0.022 | 178.4 | 207.7 | 1.16 | 5.465 |
| 256 | 32.5 | 131.5 | 4.04 | 0.020 | 170.2 | 206.8 | 1.22 | 4.258 |
Both of P-12's observable clauses came out its way. Marching Cubes' miss rate stays flat (0.104 → 0.020, falling); Surface Nets' rises 2.6× (1.635 → 4.258), though not monotonically — 112³ and 144³ sit below 64³.
The mechanism clause is false, and one control settles it
P-12 says the cost is the four-cells-around-a-crossed-edge gather. That gather runs once per
crossed edge, which is O(n²); the cost is O(n³). So the sweep is run a second time on a field
with no surface at all — a sphere of radius 10 over a domain of half-extent 2, every sample
negative, no edge crossed, no vertex placed, no quad walked — while the dense per-cell state is
allocated, filled and scanned exactly as before.
At 256³, Surface Nets: 168.6 cycles/sample and 4.277 misses/sample with 0 triangles, against 170.2 and 4.258 with 153,552. A difference of 0.9%. Removing every gather the hypothesis blames changes nothing, so the hypothesis is false. Dual Contouring, which shares the engine, lands on the same number (167.4 cycles, 4.240 misses, 0 triangles).
The other two candidates the registration named are excluded too
Branch misprediction cannot produce a rising cost because it falls: Surface Nets 0.0436 → 0.0267
misses per sample across the sweep, Marching Cubes 0.0343 → 0.0115. Allocation is not it either:
page faults after the two warmup runs are 0 on all 90 rows. And a candidate the registration did
not name, added because "the working set grew" and "the page walk grew" have the same symptom:
dTLB read misses peak at 0.104 per sample and are typically ~1e-3, transparent huge pages being
always on this host.
What it actually is: IPC, on an instruction stream that does not grow
Surface Nets executes 1.57× Marching Cubes' instructions and takes 5.24× the cycles. Its instruction count per sample falls across the sweep (210.5 → 206.8) while its cycles rise (144.0 → 170.2), so the whole of the superlinearity is a 16% decline in IPC (1.46 → 1.22) on a constant instruction stream. Marching Cubes' IPC is flat at 4.04–4.28.
And the miss column does not explain the cycles either
Three grids of 16.7 M samples, no surface, same code, differing only in axis order:
| shape | SN misses/sample | SN cycles/sample |
|---|---|---|
68×496×496 |
3.274 | 151.49 |
496×68×496 |
1.362 | 151.74 |
496×496×68 |
3.360 | 151.14 |
A 2.4× spread in misses buys 0.4% of cycles. At this size the misses are streaming and the prefetcher hides them, so the LLC-miss column tracks the dual's cost without accounting for it.
The one place misses do cost is the 128³ spike, and it is a stride effect. 127³ / 128³ / 129³ on
sphere: 152.5 / 178.4 / 152.1 cycles and 2.468 / 5.465 / 2.413 misses. Their working sets
differ by 2%; only 128 has a plane stride of exactly 64 KiB. The same spike is on the empty field
(149.1 / 176.4 / 148.8 cycles), so it is not the surface. These misses are conflict misses and cost
about 10 cycles each; the streaming ones above cost nothing. That is the clue M-45 recorded on two
machines and nobody had followed.
The registered falsifier was insufficient, which is the method finding
falsified_by was "flat miss rates, pointing at branch misprediction or allocation instead." Miss
rates were not flat, so by its own stated falsifier P-12 survives — and its mechanism is
still false. The falsifier named an observation the hypothesis could fail, but not one that could
separate it from its rival: "the gather misses" and "the O(n³) scan misses" both predict rising
misses on a growing grid. The control that settled it — a field with no surface — was not in the
registration and was added while writing the harness.
O-11 is narrowed rather than closed
It asked for "a profile or cache-miss counter at 192³ vs 256³" and hypothesised the stride-n²
gather. The counters are in and the gather is out. What remains is where the dual's IPC goes —
not the gather, not branches, not allocation, not the TLB, and not, at this size, the misses.
STALLED_CYCLES_BACKEND is the event that would name it and AMD does not map it;
perf_event_open answers ENOENT. R-007 owns the residue.
M-280 — this harness's nanoseconds are not a unit, and the committed Zen 3 sweep is 1.45× stale (R-005)
M. Two runs of the same binary at the same commit reported Marching Cubes at 48³ as 8.13 and
14.66 ns/sample while cycles/sample held at ~34 both times. This host runs amd-pstate-epp on the
powersave governor over 1.96–5.62 GHz, so that is a 1.8× clock excursion and nothing about the
code. experiment_p12 now leads with cyc/samp and carries a ghz column — cycles ÷ nanoseconds —
so a row states the clock it was taken at instead of leaving it to be inferred from a number that
looks like a measurement.
Two full 90-row runs after that change: ns median |Δ| 0.43%, cycles 0.31%, clock 4.15–4.20 GHz throughout. The nanosecond is fine when the clock is; the column is what says which.
Which then found something bigger. Re-running benches/resolution_sweep at the current commit,
with the clock sampled every five seconds and steady at 4.20 GHz, five times:
committed resolution_sweep-ryzen9-5900x.csv |
measured now | ||
|---|---|---|---|
| Marching Cubes 256³ | 221.363 ms | 152.2–153.3 ms | 1.45× faster |
| Surface Nets 256³ | 823.442 ms | 693–721 ms | 1.18× faster |
Consequences for what is written down. ✗14's Zen 3 ratio was SN/MC = 3.72× at 256³; measured in
one binary and one run it is 5.43× (M-282), so ✗14's conclusion is strengthened and its number is
wrong. M-45's "the M5 is 2.76× faster than the Ryzen on Marching Cubes at 256³ (80.2 vs 221.4 ms)"
cannot be quoted at all: its Ryzen half is superseded by a real code change and its M5 half was
not re-run, so the figure is unmeasured rather than merely stale.
One excursion in six runs, unexplained. One of the six gave 264.714 ms for Marching Cubes at 256³ at the same steady 4.20 GHz and the same binary — 1.74× the other five, which cluster within 0.7%. Surface Nets did not move in that run (697.8 against 693–721). No cause identified; recorded so that a single ms figure from this host is not read as a measurement.
Corrected the same night, and the correction matters (M-281). The table above attributes the gap
to the code, and that attribution was not earned when it was written: the "measured now" column came
from the current resolution_sweep binary, and adding one unrelated function to that binary moves
its own Marching Cubes 256³ row from 152.5 to 130.8 ms. So 152.5 is a property of a build, not of
the algorithm.
Settled by re-running the old commit rather than by arguing. A worktree at d2ab82a — the commit
M-45 cites — built and run on this machine tonight reproduces its committed CSV to within 1.8%:
Marching Cubes 256³ 222.649 ms against 221.363, Surface Nets 813.964 against 823.442, Dual
Contouring 861.370 against 877.359. The committed Zen 3 figures are sound and reproducible, so
the difference is a real code change and not the clock and not the machine — but its size is
222.6 → 127.8, 1.74×, measured against M-282's family run rather than against a binary whose
layout costs it 17%. Read the direction from this entry and the magnitude from M-282.
The CSV was restored rather than overwritten. ✗14, M-19, M-20, M-21, M-22 and O-11 all quote
exact figures from it, and the archive says three separate times that re-measuring the family belongs
to M-001. M-001 is referenced nineteen times across FINDINGS.md and BACKLOG_ARCHIVE.md
and had no ticket row in either file — so the designated home for this re-measurement did not
exist and it could never have been taken off the queue. Now filed.
M-281 — a timing here is a property of the binary, not only of the code (M-001)
M. benches/family and benches/resolution_sweep measure Marching Cubes on the same field, the
same resolutions, the same warmup and median rule, on this machine with the clock held at 4.18 GHz —
and disagreed by a uniform 1.24–1.36× at every resolution:
| n | resolution_sweep ms |
family ms |
ratio |
|---|---|---|---|
| 16 | 0.047 | 0.038 | 1.24 |
| 64 | 2.681 | 2.011 | 1.33 |
| 128 | 20.972 | 15.461 | 1.36 |
| 256 | 172.477 | 127.605 | 1.35 |
A uniform ratio at 16³, where the whole run is 40 µs and nothing is under memory pressure, rules out cache, TLB and allocation at a stroke.
What it is not. benches/layout_bias puts both loop shapes in one binary — the sweep's single
drained loop with black_box(triangle_count()) against family's split loops with
black_box(&mesh) — in both orders, so M-197's "whichever runs second pays" cannot apply. They come
out identical, ratio 0.991–1.002, and the file asserts that rather than printing it. Nor is it the
counters (family without them: 127.6 ms against 127.1 with), nor extractor lifetime (rebuilt per
resolution: 127.1 against 131.6 carried).
What it is. Adding one unrelated function to resolution_sweep.rs — a copy of the probe,
called once before the sweep — moved that binary's own Marching Cubes 256³ row from 152.5 ms to
130.8 ms. Same measured code, same loop, same machine, same clock; 17% from linking something else
in beside it. This is layout bias, and it has a paper: Mytkowicz, Diwan, Hauswirth & Sweeney,
Producing Wrong Data Without Doing Anything Obviously Wrong!, ASPLOS 2009
(10.1145/1508284.1508275), whose finding is that link order and environment size move measurements
by enough to invert a conclusion.
The consequence for this repository, which is the point. A millisecond figure is comparable only against other figures from the same binary and the same build. Ratios measured side by side in one run survive; absolute numbers quoted across benches do not. That is precisely M-001's design — one bench, one process, one run — and it is now measured rather than asserted.
M-282 — the whole family, in one binary and one run (M-001)
M. benches/family, docs/measurements/family.csv. sphere, f32, the sweep's resolution set,
median of 5 after 2 warmups, clock 4.17–4.25 GHz on every row, Ryzen 9 5900X, single thread.
| algorithm | 256³ ms | × MC | ns/sample | cycles/sample | IPC | triangles |
|---|---|---|---|---|---|---|
marching_cubes |
127.8 | 1.00 | 7.62 | 31.8 | 4.13 | 153,548 |
marching_cubes+decider |
130.8 | 1.02 | 7.80 | 32.6 | 4.16 | 153,548 |
marching_tetrahedra |
261.8 | 2.05 | 15.60 | 65.3 | 4.19 | 458,568 |
surface_nets |
693.8 | 5.43 | 41.35 | 172.7 | 1.20 | 153,552 |
dual_contouring |
751.1 | 5.88 | 44.77 | 187.0 | 1.35 | 153,552 |
manifold_dual_contouring |
771.0 | 6.03 | 45.96 | 192.0 | 1.42 | 153,552 |
subgrid_marching_tetrahedra |
budget | — | 1575.0 | 6583.2 | 3.69 | 113,568 (at 128³) |
The strongest pattern in the table is the IPC column, and it is a clean partition. Everything
table-driven runs at 3.7–4.2 instructions per cycle; everything built on DualMesher runs at
1.20–1.42. Three algorithms with three different vertex rules — a centroid, a QEF, a QEF with
cell splitting — land within 18% of each other and a factor of three below the rest, which says the
cost is the shared scaffolding rather than any of the rules. That is R-007's target, arrived at from
a second direction.
Four things nobody had priced.
- The asymptotic decider costs 2.4% — 130.8 against 127.8 ms, same 153,548 triangles. ✗11 and the whole A-002 series argue about what it fixes; this is what it costs.
- Marching Tetrahedra is 2.05× Marching Cubes in time and 2.99× in triangles (458,568 against 153,548). P-1 predicted the 3.0× ratio and it lands at 2.99 — but the time ratio is only 2.05, because Marching Tetrahedra has the highest IPC in the family. Three times the triangles for twice the time.
- Manifold Dual Contouring's guarantee costs 2.6% over Dual Contouring — 771.0 against 751.1 ms. Given A-010 and M-59, this is the price of the entry that takes the manifold zero, and it is approximately free.
- Subgrid Marching Tetrahedra is 100.7× classic Marching Tetrahedra and 215× Marching Cubes, at 128³ on Zen 3. M-98 measured 70× and 196× on the Apple M5 at 33³/65³, and said "the constant is the whole story" — so the constant is also machine-dependent, by 1.44× between these two hosts. It is the one entry the 2000 ms budget stops, at 128³, which the CSV records rather than omitting.
✗14's ratio has widened and its numbers are superseded. surface_nets / marching_cubes at 256³
is 5.43× here against the 3.72× on record, and 3.19× at 16³ against M-45's "2.46× behind even
at 16³". Both are within-binary ratios, which M-281 says is the comparison that survives.
M-283 / P-13 — FALSIFIED, and the fixture that confirmed it agreed to four decimal places (R-006)
⚠ THE VERDICT IN THIS ENTRY IS WRONG. P-13 HELD — see M-289. The reference gradient this experiment compared against was normalising a cancellation residue at points epsilon-outside the surface, so roughly half the vertices near a face were measured against a random unit vector. The corrected numbers are in M-289: 6,959 past-90° vertices become 472, the worst angle tracks
(180° − θ)/2and is bounded by it in 136 of 168 rows, and it is resolution-invariant to four significant figures. The entry is kept whole because what it got right — theθ = 180°control, the median of zero, the four-decimal fixture — it got right for the right reasons, and because a falsification that was itself falsified is the most useful kind of thing this file can hold.
M. benches/experiment_p13.rs, docs/experiments/p-13.csv, 384 rows: an exact convex wedge of
controllable dihedral × 4 resolutions × 2 apex alignments × 3 rotations × Marching Cubes and Dual
Contouring. The metric is M-66's: the angle between a vertex's area-weighted face normal and the
field's own gradient there, over vertices more than one cell from the domain boundary.
The prediction, and the fixture that appeared to confirm it exactly
Across a crease of dihedral θ the surface normal turns by 180° − θ, so a vertex given the average
of the two faces should sit at most (180° − θ)/2 from either. With the wedge's bisector on a grid
axis — the obvious way to build the fixture — that is what comes out, to four decimal places:
| θ | predicted | 17³ | 33³ | 65³ | 129³ |
|---|---|---|---|---|---|
| 30° | 75.0 | 75.0000 | 75.0000 | 75.0000 | 75.0000 |
| 60° | 60.0 | 60.0000 | 60.0000 | 60.0000 | 60.0000 |
| 90° | 45.0 | 45.0000 | 45.0000 | 45.0000 | 90.0000 |
Four significant figures, three resolutions, three dihedrals. It is wrong.
Rotate the wedge by 17° and the agreement is gone
Same dihedrals, same resolutions, apex off the lattice, wedge turned 17° about its own crease (129³, and the p99 is there because one vertex should not set a conclusion):
| θ | predicted | MC worst | MC p99 | MC median | DC worst | DC p99 | DC median |
|---|---|---|---|---|---|---|---|
| 30° | 75.0 | 90.96 | 89.04 | 0.000 | 75.00 | 75.00 | 0.045 |
| 45° | 67.5 | 85.93 | 85.93 | 0.000 | 98.46 | 41.88 | 0.036 |
| 60° | 60.0 | 92.13 | 60.00 | 0.000 | 60.05 | 60.00 | 0.035 |
| 90° | 45.0 | 71.57 | 71.57 | 0.000 | 90.00 | 71.57 | 0.028 |
| 120° | 30.0 | 93.43 | 60.00 | 0.000 | 75.12 | 74.95 | 0.048 |
| 150° | 15.0 | 90.96 | 78.43 | 0.000 | 78.43 | 78.14 | 0.019 |
| 170° | 5.0 | 87.88 | 87.88 | 0.000 | 91.91 | 91.42 | 0.396 |
| 180° | 0.0 | 0.0000 | 0.0000 | 0.000 | 0.0028 | 0.0000 | 0.000 |
A five-degree crease produces an eighty-eight-degree disagreement. Across all 168 non-control rows, Marching Cubes' worst runs 5.00°–128.00° and 149 of them are at or above 60° whatever the dihedral. The registered falsifier — "the angle failing to track the dihedral prediction, which makes it a defect with a location rather than a property" — fires.
One clause of P-13 held, and it is the one the θ = 180° control settles
With the crease removed entirely the disagreement is 0.0000° worst and 0.0000° mean for Marching Cubes at every resolution, and 0.0028/0.0003 for Dual Contouring. Marching Cubes is exact on a linear field — every crossing lands on the plane — so this is not a floor, it is zero. So the error does require a sharp feature and does not require a coarse grid, which is P-13's first clause. What is false is the second: the magnitude is not a function of the dihedral and is not predictable from the field.
And it reconciles the two halves of M-66 that looked contradictory
M-66 reported a mean that falls with resolution and a worst that does not. The median here is 0.000° in every row — the disagreement is confined to the crease, which is a one-dimensional set in a two-dimensional mesh. So refining the grid adds smooth vertices that are exactly right and dilutes the mean, while leaving the crease's own error untouched. Both halves, one mechanism.
Dual Contouring does not fix it, and on one axis is worse
A-007 exists to recover sharp features, so the dual is the natural remedy. It is not one. At θ = 90°
its worst rises with resolution where Marching Cubes' does not, and so does its mean:
| 17³ | 33³ | 65³ | 129³ | |
|---|---|---|---|---|
| Marching Cubes worst / mean | 90.00 / 13.28 | 90.00 / 8.51 | 90.00 / 9.13 | 71.57 / 8.45 |
| Dual Contouring worst / mean | 36.17 / 2.52 | 44.96 / 3.33 | 71.57 / 5.06 | 90.00 / 6.79 |
The dual starts three times better and converges toward Marching Cubes from below. Its median stays an order of magnitude worse than Marching Cubes' exact 0.000, which is the QEF placing vertices off the plane in the smooth region — the trade ✗12 and E×1 already describe, now visible in the normals.
The past-90° vertices are real, and they are on the surface
6,959 vertices under Marching Cubes and 4,868 under Dual Contouring, over the non-control rows, have an area-weighted normal more than 90° from the field gradient — pointing into the solid. Worst 128.00° and 125.30°.
That should be impossible: an area-weighted normal is a convex combination of incident face normals,
so it lies in the cone they span, which for two planes is (180° − θ)/2 ≤ 75° wide. The obvious
escape is that the vertex is not on the surface — Marching Cubes interpolates linearly and a wedge is
not linear near its apex. Measured rather than assumed, and the escape is closed: over the rows
that have one, the median |f(v)| / h at those vertices is 0.0000 and the largest is 0.28. They
are on the isosurface.
So the incident faces are not confined to the two planes' cone: the crease is bridged by triangles that face somewhere else, and for an acute wedge a whole band along it is thinner than a cell, which is M-15's "any feature thinner than one cell forces two sheets through it" arriving on a sharp field. Whether that is inherent to one vertex per crossed edge or a defect with a fix is R-008.
R-008 answered it and this reading is narrowed (M-288): the crease accounts for 20% of them.
536 of 2,657 past-90° vertices sit under a cell from the crease; the other 2,121 are 11 to 94 cells
away. The counts are exact multiples of n − 2 and the wedge is extruded along z, so there are
one to three offending locations in the whole cross-section and neither classifier found them.
R-009 owns that.
The method finding, which is the one worth keeping
The fixture agreed with the prediction to four decimal places and was wrong. A wedge whose
bisector lies on a grid axis puts its crease in a symmetric relationship to the sampling, and the
worst vertex is then exactly the symmetric one — the average of two faces, at exactly half the turn.
The number is a property of that symmetry, not of the dihedral, and nothing about 75.0000 at three
resolutions looks like a fixture artefact. Only turning the fixture 17° showed it. Part 5 already
carries "choose a fixture by searching for one that exhibits the property"; this is the harder
version — a fixture can exhibit the property too perfectly, and exactness is the tell rather than
the confirmation.
M-284 / P-15 — HELD, and the dual's IPC wall is one function (R-007)
M. benches/experiment_p15.rs, docs/experiments/p-15.csv, 16 rows, Ryzen 9 5900X, f32,
Surface Nets, no surface. P-15 predicted more than half the cycles; the answer is 82%.
The instrument, which needed nothing from the library
R-007 offered two ways into a private function and asked which was allowed: counter windows inside
DualMesher::extract, or an ablation seam. Neither was used. The first is impossible before it is
undesirable — isomesh is no_std and cannot make a Linux system call — and the second is public
API for one experiment.
The third way is that the stages have different iteration counts, and the counts depend on the
grid's shape rather than only its size: sample runs S = ∏ size, the two resizes and
place_vertices run C = ∏ (size − 1), and emit_quads runs
Q = Σ_axis (size[axis] − 1)(cells[u] − 1)(cells[v] − 1). On a cube Q/C = 2.97; on a slab two
samples deep it is 1.00; on a rod two samples deep on both minor axes the inner loops are empty
and it is exactly 0, while S/C runs 1 → 4 across the same shapes. Thirteen shapes make the design
matrix separable and least squares reads the stages off it.
| shape | cells | S/C |
Q/C |
cycles/cell | instructions/cell |
|---|---|---|---|---|---|
| 193×193×193 | 7,077,888 | 1.02 | 2.97 | 156.04 | 205.29 |
| 513×513×9 | 2,097,152 | 1.13 | 2.74 | 153.21 | 199.29 |
| 1025×1025×3 | 2,097,152 | 1.50 | 2.00 | 126.06 | 179.88 |
| 1449×1449×2 | 2,096,704 | 2.00 | 1.00 | 66.63 | 145.92 |
| 500001×2×2 | 500,000 | 4.00 | 0.00 | 31.32 | 145.88 |
The decomposition, and the number that answers R-007
| per iteration | instructions | cycles | IPC |
|---|---|---|---|
sample |
16.31 | 2.51 | 6.49 |
place_vertices + resizes |
95.82 | 24.99 | 3.83 |
emit_quads |
31.24 | 43.26 | 0.72 |
r² = 0.9954 on instructions and 0.9990 on cycles, and the model predicts rather than
describes: a shape held out of the fit entirely, 385×385×17, comes in at +0.12% on instructions
and +0.50% on cycles.
At 193³, emit_quads is 45% of the instructions and 82% of the cycles. So P-15 held, and by more
than it claimed.
The punchline is the IPC column. place_vertices — the dual's cell loop, which reads the same
eight corners Marching Cubes' march does — runs at 3.83, which is Marching Cubes' own 4.04 (M-282).
sample runs at 6.49. Only emit_quads is slow, at 0.72, and it is slow enough to drag the whole
mesher to 1.20. The dual does not have an IPC problem; one of its four stages does, and that
stage is 45% of the instructions and 82% of the time.
The fit-free cross-check, and where it disagrees
1025×1025×3 and 1449×1449×2 have cell counts agreeing to 0.02% and Q/C differing by exactly
1, so their difference in cost per cell is one emit_quads iteration with only a small S/C
correction. It gives 60.8 cycles and 42.2 instructions against the fit's 43.3 and 31.2.
That is a 40% disagreement and it is reported rather than smoothed: 60.8 × 2.97 = 181 cycles per cell
would exceed the cube's measured 156, so the two-row estimate over-attributes — the two slabs
differ in more than Q/C. The fit is the conservative reading and the one with a validated
out-of-sample prediction, so 82% is a floor.
A limitation the sweep found in itself
500001×2×2 and 2×2×500001 have identical S, C and Q and differ by 62% in instructions
(145.88 against 236.88). The model has no term for loop overhead, which dominates when the innermost
trip count is 2 — and sample iterates x innermost, so which axis is short decides how many times
the loop preamble runs. It does not affect the conclusion (both rods anchor Q = 0 and the two
500001×2×2-shaped rows agree exactly at 145.88), and it bounds how far the coefficients should be
trusted on degenerate shapes.
O-11 is answered
"Why does the dual topology go superlinear in n³ while Marching Cubes does not?" — asked at T-006,
half-answered at M-45, narrowed at M-279, and closed here. The dual carries a fourth stage Marching
Cubes does not have, emit_quads, which walks every grid edge on all three axes and loads both
endpoint samples before the sign test that would let it skip. It is O(n³) where the surface is
O(n²), it runs at one sixth of the rest of the mesher's IPC, and it is 82% of the cost. The
superlinearity M-21 saw is that stage's working set growing past the caches while the other three
stay flat — and the remedy is A-023, not a vertex rule.
A-023 landed and O-11 is now a smaller question rather than a closed one (M-285, M-286). The constant is gone: the dual is 2.5–3.1× faster, byte-identically, and Surface Nets beats Marching Cubes at 48³. The curve is not: per-sample cost still rises 7.92 → 13.37 ns over 16³…256³, and that residue is now visibly the cache — misses and cycles track at 8.4 cycles per miss where before they did not track at all. What is left of O-11 is A-024, and specifically the 2.6× penalty at exactly 128³ that a 64 KiB plane stride buys.
A-024 landed and O-11 is closed (M-287). Forcing the row length odd removed the aliasing at every size — 128³ against its neighbours goes 3.37× → 1.01× — and Surface Nets' per-sample cost across 16³…256³ is now 8.71 → 9.70 ns, +11%, against the +40% this question was raised about. Two causes, both removed, and neither of them a vertex rule or an algorithm: a dynamically indexed coordinate array and a power-of-two row stride.
M-285 — the dual's axis had to be a constant, and that was 82% of its cycles (A-023)
M. benches/family, benches/experiment_p15, benches/experiment_p12, all re-run at one commit
with the clock at 4.14–4.26 GHz.
DualMesher::emit_quads took axis, u and v as runtime values, so p[axis] = a was a
dynamically indexed store and p could not live in registers: every iteration wrote three coordinates
to the stack and linearize read them straight back — a store-to-load chain the scheduler cannot
break. R-007 had already priced the stage at 82% of the dual's cycles at IPC 0.72 (M-284), beside
a cell loop doing more work per iteration at 3.83.
It is now three monomorphisations of one function with the axis a const generic. Same three
passes, same order, same bounds, same triangles in the same sequence.
| before | after | |
|---|---|---|
emit_quads per iteration |
43.26 cycles, 31.24 instructions | 3.33 cycles, 12.02 instructions |
emit_quads' share at 193³ |
82% of cycles | 27–32% |
| the whole mesher at 193³ | 156.0 cycles/cell | 37.1 cycles/cell |
At 256³, one binary, one run:
| algorithm | before | after | speedup | IPC | × Marching Cubes |
|---|---|---|---|---|---|
surface_nets |
693.8 ms | 224.4 ms | 3.09× | 1.20 → 2.77 | 5.43 → 1.72 |
dual_contouring |
751.1 ms | 279.5 ms | 2.69× | 1.35 → 2.88 | 5.88 → 2.14 |
manifold_dual_contouring |
771.0 ms | 305.6 ms | 2.52× | 1.42 → 2.90 | 6.03 → 2.34 |
Marching Cubes, its decider variant, Marching Tetrahedra and subgrid Marching Tetrahedra are
unchanged to within noise, which is the control: the change is inside DualMesher and only
DualMesher's three entries moved.
The mesh is byte-identical. golden_hashes_are_unchanged passes untouched, and every triangle
count across the family matches the run before it. That was the acceptance: an optimisation that
changes the mesh is a bug in the optimisation.
And Surface Nets is now faster than Marching Cubes at 48³ — 30.7 cycles per sample against 33.1,
at IPC 5.29 against 4.19. ✗14 said Surface Nets "never wins on Zen 3, at any resolution: 2.46×
behind even at 16³". That is no longer true, and the reason it was true was one missing const.
M-286 — the misses M-279 measured as free were hidden behind the stall, and now they cost (A-023)
M. M-279 measured, on the pre-A-023 dual, that a 2.4× swing in cache misses moved cycles by
0.4% — three grids of 16.7 M samples differing only in axis order — and concluded that the LLC-miss
column tracked the dual's cost without accounting for it. That conclusion was true of that code and
is false of this code, because the store-to-load chain in emit_quads was stalling the loop deeply
enough to cover every miss underneath it.
The same control, re-run: misses 2.12 / 1.35 / 1.95 and cycles 37.4 / 33.4 / 35.7. They now track, at about 5 cycles per miss.
And the cubic sweep, which before showed cycles rising while misses did nothing useful:
| n | Marching Cubes cycles | Surface Nets cycles | Surface Nets IPC | Surface Nets misses |
|---|---|---|---|---|
| 48 | 33.1 | 30.7 | 5.29 | 0.612 |
| 96 | 30.8 | 36.8 | 4.28 | 1.658 |
| 127 | 31.0 | 33.2 | 4.72 | 1.496 |
| 128 | 31.2 | 84.3 | 1.86 | 4.724 |
| 129 | 31.2 | 33.0 | 4.75 | 1.483 |
| 192 | 31.6 | 43.1 | 3.60 | 2.540 |
| 256 | 32.0 | 56.7 | 2.73 | 3.720 |
Cycles and misses now move together: 48³ → 256³ is +26.0 cycles for +3.11 misses, 8.4 cycles per
miss; 129³ → 128³ is +51.3 for +3.24, 15.8 cycles per miss.
So the residue of O-11 is now, and only now, a cache story. What A-023 removed was a constant, not
the curve: Surface Nets' per-sample cost still rises with n, from 7.92 ns at 16³ to 13.37 at 256³,
and that rise is the dense per-cell state outgrowing the caches exactly as M-279's working-set
reasoning said — the reasoning was right and the evidence for it was masked.
The 128³ spike is now the largest single feature of the curve and is unambiguous. 127³ and 129³
cost 33.2 and 33.0 cycles per sample with 1.50 and 1.48 misses; 128³ costs 84.3 with 4.72 —
a 2.6× penalty at one resolution, on working sets 2% apart, because n²·4 is exactly 64 KiB and
that is a cache-set aliasing period on this machine. Before A-023 the same spike was 1.24× and looked
like noise on a curve. A-024 owns it, and it matters more than its size suggests: 128³ is the
canonical chunk size in voxel engines.
A-024 has since landed and removed it (M-287). 128³ now costs 36.65 cycles per sample against 127³'s 36.01 and 129³'s 36.20, and the miss rate at 256³ falls from 3.72 to 1.56 per sample — so the residual cache term this entry identifies was, at every size and not only at 128, largely the same aliasing.
Method note, and it is the third time tonight. M-279's null result — "misses do not cost" — was a correct measurement of a machine whose bottleneck was somewhere else. A null measured under a dominant confound is a statement about the confound. The confound has to be removed before the null means what it says.
M-287 — one bit of the row length was a 3.4× tax at the chunk size everybody uses (A-024)
M. benches/a024_aliasing, docs/measurements/a024-aliasing.csv, plus family,
experiment_p12 and experiment_p15 re-run.
DualMesher::values was laid out by the caller's shape, so its row stride was size[0]·4 bytes
and its plane stride size[0]·size[1]·4. At 128 those are 512 bytes and exactly 64 KiB —
a cache-set aliasing period twice over on this machine.
Diagnosed before anything was changed, by letting the caller arrange the pad
The aliasing depends only on the shape, and the shape is an argument. So adding one sample moves the stride while changing the work by under 1%:
| plane bytes | cycles/sample | vs 127³/129³ | |
|---|---|---|---|
| 127³ | 64,516 | 33.10 | — |
| 128³ | 65,536 = 2¹⁶ | 108.51 | 3.37× |
| 129³ | 66,564 | 31.39 | — |
129×128×128 (pad x) |
66,048 | 31.48 | 0.98× |
128×129×128 (pad y) |
66,048 | 36.45 | 1.13× |
128×128×129 (pad z, control) |
65,536 = 2¹⁶ | 107.89 | 3.35× |
| 128×131×131 (512-byte rows only) | 67,072 | 36.74 | 1.14× |
| 256³ | 262,144 = 2¹⁸ | 54.07 | 1.39× vs 255³/257³ |
The z control is what makes this a measurement rather than a story. It adds the same 0.8% of
work and does not touch either stride, and it keeps the entire penalty. And the two periods separate
cleanly: 512-byte rows alone cost 1.14×, the 64 KiB plane costs the remaining ~3×, and only padding
the fastest axis fixes both because size[0] appears in both.
The fix is size[0] | 1
Unconditional, because a pad applied only when the stride looks bad is a second layout reachable from
one call — the shape the one-path rule forbids. And idempotent, which is the part that matters: a
fixed pad of one would be worse than nothing, since it maps every size[0] = 2ᵏ − 1 onto the stride
it is trying to avoid. | 1 has no such image.
It cannot reintroduce either period: 4·odd is never a multiple of 512, and 4·odd·size[1] is a
multiple of 65,536 only if size[1] is a multiple of 16,384. The cost is one float per row when the
row is even — 0.8% of values at 128³ — and nothing at run time, because the multiply is by a
different constant rather than an extra one.
After
| before | after | |
|---|---|---|
| 128³ against its neighbours | 3.37× | 1.01× |
| 256³ against its neighbours | 1.39× | 0.92× |
| Surface Nets at 128³ | 48.51 ms | 18.35 ms (2.64×) |
| Surface Nets at 256³ | 221.4 ms | 162.7 ms (1.36×) |
| Surface Nets IPC at 256³ | 2.80 | 4.09 |
| cache misses per sample at 256³ | 3.72 | 1.56 |
Marching Cubes and Marching Tetrahedra move 1.02× and 1.01×, which is the control: the change is
inside DualMesher. Triangle counts across the family are identical and
golden_hashes_are_unchanged passes.
Taken with A-023, and this is the headline
| this morning | now | |
|---|---|---|
| Surface Nets at 256³ | 693.8 ms | 162.7 ms — 4.26× |
| Surface Nets IPC | 1.20 | 4.09 |
SN / MC at 256³ |
5.43× | 1.26× |
| per-sample cost, 16³ → 256³ | 29.63 → 41.35 ns (+40%) | 8.71 → 9.70 ns (+11%) |
Not one triangle changed. And Surface Nets is now faster than Marching Cubes on small grids:
| n | 16 | 24 | 32 | 48 | 64 | 96 | 128 | 192 | 256 |
|---|---|---|---|---|---|---|---|---|---|
| Marching Cubes ns/sample | 9.37 | 8.87 | 8.29 | 8.03 | 7.74 | 7.41 | 7.48 | 7.62 | 7.67 |
| Surface Nets ns/sample | 8.71 | 8.59 | 8.05 | 8.24 | 8.42 | 8.53 | 8.75 | 9.53 | 9.70 |
| ratio | 0.93 | 0.97 | 0.97 | 1.03 | 1.09 | 1.15 | 1.17 | 1.25 | 1.26 |
O-11 is closed. "Why does the dual go superlinear where Marching Cubes does not?" Two reasons,
both now removed: a dynamically indexed coordinate array that stalled emit_quads on store-to-load
forwarding (A-023), and a power-of-two row stride that put the sample array on one cache set
(A-024). What is left is +11% across four octaves of grid, against Marching Cubes' own −18% then
flat. The question was asked at T-006 on 2026-08-13 and it took the counters to answer, but the answer
was two keywords.
And it re-opens a design question rather than settling one. ✗14 exists to say Surface Nets is not
the cheap default. Its triangle-count half (✗1, 2χ more triangles) is untouched; its cost half is
now 1.26× at the largest grid and a win below 48³. Whether that changes the default is not a
measurement, and this file does not decide it.
P-16 — registered for R-008, before it was measured
What M-283 left, stated so it can fail. 6,959 vertices under Marching Cubes and 4,868 under Dual
Contouring, on an exact convex wedge, carry an area-weighted normal more than 90° from the field
gradient — worst 128.0°. An area-weighted normal is a convex combination of incident face normals,
so it lies inside the cone those faces span, and for two planes meeting at θ that cone is at most
(180° − θ)/2 ≤ 75° wide. The obvious escape was measured and closed: the median |f(v)|/h at those
vertices is 0.0000, so they are on the isosurface.
H. Every such vertex lies on a grid edge at least one of whose incident cells straddles the crease — its eight corners do not all have the same nearer plane — so the phenomenon is two faces meeting inside one cell rather than a winding or ordering defect.
If that holds, it is M-15's "any feature thinner than one cell forces two sheets through it" arriving on a sharp field, and it is inherent to one vertex per crossed edge rather than fixable.
Falsified by more than 5% of past-90° vertices whose incident cells all lie on one side of the crease — which would make it a defect with a location and a fix, and a much better outcome.
Records dihedral_deg, samples, past90_vertices, past90_in_straddling_cell,
offending_faces_per_past90_vertex.
The threshold is 5% and not 0% on purpose. A cell is classified by its eight corners' nearer plane, and a corner sitting within rounding of the bisector can be classified either way; a hard zero would make the hypothesis fail on arithmetic rather than on geometry. 5% is far above that noise and far below "a substantial share".
M-288 / P-16 — FALSIFIED, and the registered definition did not implement the registered claim (R-008)
⚠ THE VERDICT IN THIS ENTRY IS WRONG. P-16 HELD, at 0% — see M-289. Every number below is counted over vertices whose reference gradient was noise. Corrected: 442 offenders in 6 rows, 100% of them on the crease, only at
θ = 30°and60°. What survives is the observation about the registered definition — it splits by the bisector rather than the crease, and it still agrees with the corrected classifier on every row.
M. benches/experiment_p16.rs, docs/experiments/p-16.csv, 63 rows: an exact convex wedge ×
7 dihedrals × 3 rotations × 3 resolutions, Marching Cubes, area-weighted normals.
23 rows contain a past-90° vertex, 2,657 in total, and 536 of them — 20% — are on the crease. The registered falsifier was "more than 5% whose incident cells all lie on one side". It is 80%.
| rows | median distance to the crease | |
|---|---|---|
| offenders on the crease | 6 | 0.69–0.90 cells |
| offenders elsewhere | 17 | 11.14–93.81 cells |
So the mechanism P-16 named is real and is a minority. Two faces meeting inside one cell does produce past-90° normals — the six rows where it happens are unambiguous, the offenders sit under a cell from the crease, and the control (vertices under 90°) is on the crease only 0–12.8% of the time, so the classification is not vacuous. It is simply not what most of them are.
The registration's operational definition was wrong, and it did not matter
P-16 reads "straddles the crease — its eight corners do not all have the same nearer plane". The
clause after the dash does not implement the claim before it: d0 ≥ d1 splits by the bisector
plane, which runs from the apex through the interior of the solid, not by the crease. A cell deep
inside the wedge and nowhere near the surface straddles the bisector; a cell holding the crease need
not.
The registered test was kept and reported anyway, because a registration is not edited after its experiment runs, and a corrected test — does the cell hold the crease line, which rotation does not move — was reported beside it and labelled post-hoc. They agree on the verdict of every one of the 23 rows. The error was real and changed nothing, which is worth knowing in both directions: the result does not depend on the mistake, and a wrong definition can survive a whole experiment undetected because it happened to correlate.
What the counts localise, which is more than either classifier managed
Offender counts are 31, 62 at n = 33; 63, 126 at n = 65; 127, 254, 381 at n = 129 — every one an
exact multiple of n − 2. The wedge is extruded along z, so the sampling is identical in every
layer and any feature of the two-dimensional cross-section repeats once per layer. There are
therefore one, two or three offending locations in the entire cross-section, and they are 11 to 94
cells from the crease.
That is a small, specific, reproducible configuration rather than a diffuse effect — the same shape as A-021's 314 non-manifold edges before M-276 named them. Finding it wants a constructed minimal fixture, not a wider sweep, and that is R-009.
What R-008 concludes
The question was "is the crease bridged by triangles that face somewhere else, and is that inherent?" The answer is that the crease does that and accounts for a fifth of it; the other four fifths are somewhere else, at one to three points per cross-section, and this experiment did not find them. M-283's reading — that the bridging is M-15's thin-feature mechanism on a sharp field — is narrowed rather than falsified: it is one of at least two causes and not the main one.
M-289 — the reference gradient was noise, and it falsified two hypotheses that were true (R-009)
M. benches/r009_locate.rs, docs/measurements/r009-locate.csv, and experiment_p13 and
experiment_p16 re-run.
This entry reverses M-283's and M-288's verdicts. Read it before either of them.
How it was found, which is the method and not an accident
R-008 left 80% of the past-90° normals unlocated and two classifiers saying only where they were not.
What it had bounded was tight: the counts were exact multiples of n − 2 and the wedge is extruded
along z, so there were one to three offending locations in the entire cross-section. A-021 is
the model for that situation — it found its answer by printing a face-count histogram for a plain
half-space, not by widening a census — so R-009 dumped one configuration.
The answer was in the first six lines. Two cells per cross-section, six incident faces each,
every face lying exactly on a plane (worst face 0.00°), no slivers, and a stored vertex normal
exactly equal to a plane normal. The mesh was correct in every respect. And the gradient it was
being compared against came back [-0.5156, 0.8568, 0], which is neither plane normal.
The bug
Wedge::gradient's exterior branch computes away = q − dir·t and normalises it. On a point lying
on a ray those two vectors are equal, so away is not zero — it is a cancellation residue of
order ε·|q| — and normalising it returns a random unit vector. The guard was e > 0.0.
Every Marching Cubes vertex is on the surface to within an ulp, and about half of them land
epsilon-outside, so half the vertices near a face were compared against noise. The fix is a
threshold relative to |q|, falling back to the plane normal, which is what the exterior gradient
converges to approaching a ray along the surface — the right answer rather than a tolerance.
What it reversed
| as reported | corrected | |
|---|---|---|
| past-90° vertices, Marching Cubes | 6,959 | 472 |
| past-90° vertices, Dual Contouring | 4,868 | 232 |
| rows containing one (of 168) | 75 | 8 |
| P-13 | FALSIFIED | HELD |
| P-16 | FALSIFIED at 4× its threshold | HELD at 0% |
P-13 holds. With the corrected gradient the worst angle tracks (180° − θ)/2 and is bounded by
it in 136 of 168 rows, falling monotonically with the dihedral — at rotation 17°, n = 129:
θ = 30° → 58.0 against 75 predicted, 45° → 50.5 against 67.5, 90° → 33.3 against 45, 120° → 25.3
against 30, 150° → 10.3 against 15, 170° → 2.8 against 5, and 180° → 0.00. And it is
resolution-invariant to four significant figures — 58.00, 58.00, 58.00, 58.00 across 17³…129³ —
which is M-66's non-convergence, reproduced cleanly and now predictable from the field. That is
exactly what P-13 claimed.
P-16 holds, at 0%. Its falsifier was "more than 5% of past-90° vertices whose incident cells all lie on one side of the crease". The corrected measurement is 442 offenders in 6 rows and 100% of them on the crease, median 0.69–0.73 cells from it — and they occur only at θ = 30° and 60°, the acute wedges, where the wedge is thin enough for two sheets to share a cell. That is M-15 on a sharp field, exactly as registered.
What survives from M-283 unchanged
The θ = 180° control (0.0000° worst and mean at every resolution, because Marching Cubes is
exact on a linear field), the median of 0.000° everywhere (the disagreement is confined to a
one-dimensional crease, which is what reconciles M-66's falling mean with its flat worst), and the
grid-aligned fixture reporting the prediction to four decimal places — 75.0000, 67.5000, 60.0000,
45.0000 — while rotated ones give 20.1 to 128.0. The fixture is still too perfect; what changed is
that the rotated values now bracket the prediction instead of contradicting it.
The rule
A reference implementation used as ground truth needs the same scrutiny as the thing it checks.
Every control in R-006 pointed at the mesh: rotate the wedge, offset the apex, add a no-crease case,
check the vertex is on the surface. All of them were about whether Marching Cubes was being measured
fairly. None of them asked whether the gradient on the other side of the comparison was right,
and it was wrong at precisely the points being measured — which is the only place a reference is ever
wrong in a way that matters.
The tell was available and was misread twice: an area-weighted normal cannot leave the cone its faces span, so a past-90° reading was arithmetically impossible from the start. M-283 recorded that impossibility, chased the one escape it could think of (the vertex being off-surface), measured it closed, and concluded the geometry must be strange — rather than concluding that one of the two quantities in the comparison had to be wrong. When a measurement is impossible, suspect the instrument before the world.
M-290 — the ambiguous face in the dual path, with the source read at last (A-022)
M. benches/a022_decider.rs, docs/measurements/a022-decider.csv, 144 rows: eight reference
fields × three resolutions × six extractor configurations, f64, no chunking and no weld (matching
A-021, because the weld can create a non-manifold edge — M-226).
The block was a lookup failure, not a paywall
A-022 sat blocked on "the source is paywalled and not in the corpus", with paper_download
reporting "No open-access PDF found" for 10.1109/TVCG.2007.1012. The paper is at
cs.wustl.edu/~taoju/research/dualsimp_tvcg.pdf — Tao Ju's own publications page, and the exact
filename A-022's own text already named. One web search found it.
Two obstacles were in the way and neither was the publisher. paper_download resolves a DOI through
arXiv, Unpaywall and provider resolvers; an author's personal copy is indexed by none of them. And the
server presents a valid InCommon certificate without its intermediate, so every TLS client refuses
it — fetched by supplying the missing intermediate from the certificate's own AIA URL, with
verification left on.
It is still not in the corpus, and paper_download still answers "No open-access PDF found" —
re-checked after reading it. So the recipe is recorded rather than left to be rediscovered:
curl -sSo inter.crt http://repository.emsign.com/certs/EEEMIncommonDVG2C.crt
openssl x509 -inform DER -in inter.crt -out inter.pem
cat /etc/ssl/certs/ca-certificates.crt inter.pem > chain.pem
curl -sSL --cacert chain.pem -o dualsimp_tvcg.pdf \\
https://www.cs.wustl.edu/~taoju/research/dualsimp_tvcg.pdf
--cacert adds the missing intermediate to the system bundle; nothing is disabled, and the root
(emSign Root TLS CA - G1) is one the system already trusts.
What it says, and it answers the question A-022 could not
V-34 has the quotations. The criterion is one vertex per cycle of a table whose ambiguous faces the asymptotic decider has already resolved, each edge owned by exactly one vertex. So A-022's framing — "whether MDC's own criterion is face-based or component-based decides whether this is a new rule or a bug in the existing one" — has a third answer: it is component-based over a face-resolved table, and the dual walk needs no rule of its own because the ambiguity is settled upstream.
A-022's acceptance was unreachable, and the paper says so
It asked for M-276's 314 non-manifold edges to go to zero under Surface Nets and Dual Contouring. Those are one vertex per cell, and §3 says "DC leads to nonmanifold vertices and edges for all of the ambiguous sign configurations". Measured here: 1,128 edges across the 24 configurations, against Marching Cubes' 0. The 314 is the literature's own prediction and not a defect to remove — removing it means splitting the cell's vertex, which is Manifold Dual Contouring, which this crate already has.
The decider helps by a fifth and does not eliminate
manifold_dual_contouring defaults to FaceAmbiguity::Separate, which is not the table the paper
specifies. Switching to the decider-modified one takes it from 143 to 114 non-manifold edges over
the 24 configurations — noise_cavity at 33³ from 64 to 40, at 49³ from 53 to 49, at 65³ from 26 to
25. Better, sourced, and still not zero, which is ✗19.
And the residue is one field. Manifold Dual Contouring is manifold on seven of the eight
reference fields under both rules; every one of the 143 is noise_cavity. That is the field A-002e
added precisely because none of the other seven produces a cell with an interior ambiguity
(M-208), which a face decider cannot see by construction. That is the next question and it is
A-025, not this ticket.
The rule
A paywalled DOI is not a missing paper. Check the author's own page before taking a rule-5 stop.
V-31 earned the sibling of this — "a deleted repository is not a missing source; ask an archive, and
say which archive" — one ticket earlier, and this is the same failure with a different resolver:
paper_download answers a question about DOI resolvers, not about whether the paper is readable.
A-022 was blocked for a day on a file that a search engine returns first, under the filename the
ticket had already written down.
P-17 — registered for A-025, before it was measured
What ✗19 leaves. Manifold Dual Contouring's uniform-grid surface is not always a manifold, and the
step that fails is "the dual preserves the topology" rather than its Marching Cubes premise (M-290).
Every one of the 143 residual non-manifold edges is on noise_cavity — the field A-002e added
because none of the other seven produces a cell with an interior ambiguity (M-208) — and a face
decider cannot see an interior one by construction.
H. The residue is an interior ambiguity: the cells sharing an offending ambiguous face report
Interior::Joinedon at least one axis sweep at a rate far above the same measurement over non-offending ambiguous-face pairs.
The crate already predicts the count from the grid alone —
the_defect_count_is_predicted_from_the_grid_alone gets 30 and 64 under Separate and 8 and 40 under
the decider, with no mesh involved. What it does not say is which pairs, or why those. This adds
the interior test to the same predicate and a control beside it.
Falsified by offending pairs reporting Interior::Joined at about the same rate as the control —
which would mean the residue is not the interior ambiguity and one-vertex-per-cycle fails for a reason
nothing in the A-002 series has named.
Records samples, face_rule, offending_pairs, offending_with_interior_join,
control_with_interior_join.
The control is the whole design. "Offending cells have an interior join" is worthless if every ambiguous-face cell does — and ambiguous faces are where interior ambiguities live, so that is the likely null rather than a remote one. The comparison is against ambiguous-face pairs that are not offending, measured in the same pass.
M-291 / P-17 — FALSIFIED, and the sharper form of it points the other way (A-025)
M. benches/experiment_p17.rs, docs/experiments/p-17.csv, 8 rows on noise_cavity at four
resolutions × two face rules.
The predicate is the crate's own and it reproduces its pinned numbers first. Offending pairs come
out 30 and 64 under Separate and 8 and 40 under the decider at 17³ and 33³, which is
the_defect_count_is_predicted_from_the_grid_alone exactly. Extended: 53 and 26 under Separate
at 49³ and 65³, 49 and 25 under the decider — and those match M-290's counts, which came from the
mesh with no grid involved, where these come from the grid with no mesh involved.
P-17 is falsified by the null its own control was built to catch
| offending, any axis | control, any axis | |
|---|---|---|
| all 8 rows | 1.0000 | 1.0000 |
Every ambiguous-face pair on noise_cavity reports Interior::Joined on some sweep — offenders and
non-offenders alike, at every resolution, under both face rules. The registered falsifier was
"offending pairs reporting Interior::Joined at about the same rate as the control", and the rates
are not merely close, they are identical and saturated.
The registration predicted this failure mode in its own text — "'offending cells have an interior join' is worthless if every ambiguous-face cell does, and ambiguous faces are where interior ambiguities live, so that is the likely null rather than a remote one" — which is what a control is for and why it was there.
The sharper form, and it runs against the hypothesis
A disjunction over three sweeps is nearly always true, so the sweep across the shared face was measured separately; Custodio's criterion is about a specific pair of opposite faces, and for an offending pair that is the one whose endpoints include the shared face.
| n | rule | offending | control |
|---|---|---|---|
| 17 | Separate |
0.700 | 0.980 |
| 33 | Separate |
0.578 | 0.953 |
| 49 | Separate |
0.679 | 0.992 |
| 65 | Separate |
0.731 | 0.973 |
| 17 | decider | 1.000 | 0.911 |
| 33 | decider | 1.000 | 0.852 |
| 49 | decider | 1.000 | 0.928 |
| 65 | decider | 1.000 | 0.949 |
Under the crate's default rule the offenders have the interior join less often than the control — 0.58–0.73 against 0.95–0.99 — so on that arm the interior ambiguity is mildly anti-correlated with the defect. Under the decider the offenders are at 1.000, but so is nearly everything else (0.85–0.95), which is a lift too small to build on.
What A-025 now knows, and what it does not
Excluded: the residue is not the interior ambiguity, in any of the three forms tried — the
any-axis disjunction (no discriminating power at all), the shared-face sweep under Separate (points
the wrong way), and the shared-face sweep under the decider (saturated on both arms).
Newly established, and it is about the fixture rather than the defect: on noise_cavity
100% of ambiguous-face cell pairs carry an interior join. That is A-002e's field doing exactly
what it was built to do (M-208), and it is why this field and no other produces the residue — but it
is a property of the whole population, so it cannot be the thing that picks out 26 pairs from 322.
Still unnamed: what distinguishes the offending pairs. A-025 stays open for it, and the next step is A-021's method rather than a wider census — the offending set is 26 pairs at 65³ and their sign configurations can simply be printed.
M-292 — no two-cell configuration forces Manifold Dual Contouring's defect (A-025)
M. benches/a025_configurations.rs, docs/measurements/a025-configurations.csv. All
2¹² = 4,096 sign patterns of two cells stacked along one axis — ✗17's method — with every
consistent assignment of the joined bits enumerated on top: 16,384 combinations, the two cells
required to agree about the shared face because a face rule evaluates the face and both cells see
the same four corners.
| patterns | |
|---|---|
| share an ambiguous face | 512 |
offend under mask 0, which is exactly FaceAmbiguity::Separate |
18 |
| offend under some consistent mask — what any face rule could reach | 476 |
| offend under every consistent mask — what no face rule could fix | 0 |
Zero. For every one of the 512 configurations there is a consistent choice of joined bits under
which the four cut edges do not all land in one cycle on both sides. The defect is never forced
by the sign configuration, which is the question A-025 asked and which sampling noise_cavity could
never have answered — a field says which configurations it reaches, not which exist.
What that does and does not license
It does not say a face rule can fix it. A rule reads the face's values, and the values that make
a face ambiguous also determine what the rule answers — the freedom this enumeration has, a real rule
does not. The evidence that it cannot is already in: the asymptotic decider is the canonical
value-determined rule and it still leaves 25 to 49 offending pairs per resolution on
noise_cavity (M-290, M-291).
So the two halves fit together. Combinatorially the defect is always avoidable; with a rule that is a function of the shared face alone, it is not. Anything that fixes it needs strictly more context than the face — the two cells' other faces, or a second vertex, which are the two alternatives A-017 recorded and rejected.
Two structures in the table, both sharp
The default's 18 are exactly the (1, 1) bucket. Every configuration where both cells resolve to
a single cycle offends under mask 0, and there are exactly 18 of them. That is the whole of
Separate's combinatorial exposure, and it is why the default's count on a real field tracks how
often two one-cycle cells meet across an ambiguous face.
(1, 2) and (2, 1) are the only buckets that are not saturated — 42 offending against 18 not,
a share of 0.700, where all fourteen other cycle-count buckets are 1.0000. So a cell with one cycle
meeting a cell with two is the only pairing whose outcome the mask does not always control, and the
36 patterns no mask can make offend are all there. Both facts are exact over the full enumeration
rather than estimated from a field.
M-293 — the excluded workspace's fourth gate incident, and this one is local (A-025 follow-on)
M. Found by running the whole gate list at the end of the night rather than the part that is fast.
cd bevy_isomesh && cargo check --all-targets fails at HEAD, and has since F-001 — 58 commits.
The example precision_f32_vs_f64.rs implements ReferenceField::is_exact_distance, which F-001
replaced with bound() -> FieldBound because "a bool could not hold both". Three errors: a method
that is not a member of the trait, a missing required one, and a call to a method the bound no longer
provides.
It never reached CI, and that is the finding. .github/workflows/ci.yml has a bevy job that runs
exactly this command, so a push would have gone red immediately. The branch is 75 commits ahead of
origin and F-001 is not among the pushed ones. So this is not M-174's "an accepted CI failure is
indistinguishable from a new one" — CI would have caught it on contact. It is the other thing:
Nothing local compiles
bevy_isomesh.cargo check --workspace --all-targets, which is what anyone runs before committing, excludes it by design — that is the whole point of the exclusion (feature unification, M-190) — so a change to acrates/trait can break every example in the other workspace and the pre-commit loop stays green.
M-190 called it three incidents, one cause: rustfmt, rustdoc and MSRV each had to be patched into
the bevy CI job after the gap was found. This is the fourth, and it is the first where the CI step
already existed. The three before were missing steps; this one is a present step that local work
never runs. So the remedy is not another CI line — it is one local command that covers both
workspaces, and CLAUDE.md already says "run both" in two places, which 58 commits show is not
enough. I-008 owns making it mechanical.
Fixed here: the wrapper forwards bound() instead, which is exactly right and the example's own
doc comment already argued it — "a translated field is still the same field: same topology, same
Euler characteristic, same distance property". f(p − by) has f's Lipschitz constant, and if |f|
was the distance to the zero set then |f(p − by)| is the distance to the translated one. The full
bevy job — fmt, check, clippy, rustdoc, test — passes.
M-294 — the defect in 48 samples, and the same signs give the decider two answers (A-025)
Tier M. crates/isomesh/src/manifold_dual_contouring/tests.rs,
a_constructed_ambiguous_face_makes_the_dual_non_manifold and
the_decider_fixes_the_constructed_case_only_when_the_magnitudes_break_the_tie.
M-290 measured ✗19 over eight fields, M-291 falsified the first mechanism, M-292 bounded the mechanism over all 4,096 two-cell sign patterns. All three are censuses, and a census names a rate. This is the constructed case A-025 asked for — 48 samples, no field — and it names the mechanism.
Twelve of the 48 carry it. A 2×2×3 column of ±1 in a 4×4×3 lattice, trilinear between the
samples, the rest outside. Its middle plane is out, in, in, out — the face saddle. It is one of
M-292's 18 patterns that offend under the mask FaceAmbiguity::Separate produces, and all 18 are
exactly the ones where both cells resolve to a single cycle. One cycle is one vertex, so the four
quads — one per cut edge of the shared face — connect the same pair of vertices:
| on the same 48 samples | triangles | non-manifold edges |
|---|---|---|
| Marching Cubes | 40 | 0 |
| Dual Contouring | 20 | 1, carrying four distinct faces |
| Manifold Dual Contouring | 20 | 1, carrying four distinct faces |
That is ✗19 in one fixture. Schaefer, Ju & Warren's premise — "the original MC algorithm always constructs a manifold" — holds on these samples, and their conclusion — "the dual preserves the topology of the surface" — does not. It also prices the manifold construction on this configuration at nothing: splitting a cell by cycle cannot split a cell that has one cycle, so MDC and plain DC measure the same defect, which is what §3 predicts for DC in as many words.
Why the block is 3×3×2 cells and not 1×1×2. A quad exists only where all four cells around its
grid edge do, and the shared face's four edges reach one cell out in x and in y on both sides. The
two cells alone produce no quads at all. Mutation-tested: moving the column into the lattice corner
takes the defect to zero, which is the claim.
The sharper half — one sign configuration, two answers. The asymptotic decider does not read
signs. It reads the ambiguous face's four corner magnitudes and asks where the bilinear saddle sits,
s = (v₀₀·v₁₁ − v₁₀·v₀₁) / (v₀₀ + v₁₁ − v₁₀ − v₀₁) (Nielson & Hamann, Visualization '91). Scaling the
face's two inside corners, with every sign held fixed, walks s across zero and the defect goes
with it:
| inside corners | saddle s |
the face | non-manifold edges | triangles |
|---|---|---|---|---|
−0.25 |
+0.375 |
separated | 1 | 20 |
−1 — the fixture |
0, an exact tie |
separated | 1 | 20 |
−4 |
−1.5 |
joined | 0 | 20 |
Three things fall out.
- The tie is resolved, not undefined. At
s = 0this crate answers separated (ambiguity::face_is_joined), so the perfectly symmetric saddle — the first thing a hand-built fixture reaches — is precisely the case the decider declines to fix. - The triangle count never moves. Twenty either way: a face rule changes which vertices the quads connect, not how many there are. So the defect is pure connectivity, and so is its removal.
- The offending set is not a set of sign configurations. M-292 found no pattern that offends under
every consistent mask; this is that result from the other side. One configuration, two answers,
chosen by the field rather than by the rule — which is why the decider still leaves 25–49
offending faces per resolution on
noise_cavity(M-291) while being combinatorially capable of avoiding all of them.
Mutation-tested, four ways, because a test that has only ever passed is indistinguishable from one that cannot fail (M-44): flipping one bit of the pattern (the table stanza fires), moving the column to the lattice corner (the defect vanishes), pointing the "Marching Cubes is manifold here" arm at Dual Contouring instead (fires), and running the decider sweep with the magnitudes never scaled (the row assertion fires). Each went red on the named test and only there.
What this does not settle, and deliberately: whether ManifoldDualContouring should default to
AsymptoticDecider instead of Separate. That re-baselines every golden hash and is the crate
owner's call — A-025 says so explicitly, and it stays open on exactly that.
M-295 — the documentation drifted in thirteen places, and one number rotted twice (docs)
Tier M. A full audit of every documentation file on 2026-08-16, against the source.
Thirteen drifts, and the distribution is the finding: none of them is in the algorithms, all of them are in prose that describes the algorithms. Ranked as found —
| where | said | was | |
|---|---|---|---|
| 1 | crates/isomesh-gpu/src/lib.rs |
shaders are GPU-002…004, still to come | shipped — and this is the docs.rs landing page |
| 2 | root README | 168 golden hashes | 216 |
| 3 | README + six sites in docs/demos/ |
seven reference fields | eight |
| 4 | two sites | six-algorithm shootout | seven |
| 5 | docs/measurements/README.md |
three resolutions | two |
| 6 | isomesh-gpu README |
wgpu 29.0.4 | manifest and lib.rs say 29.0.3 |
| 7 | README hero | alt text "eight examples", caption "six" | one image, two captions |
| 8 | README hero | 1,348 seam crossings | 495, in four other places |
| 9 | isomesh-gpu README |
the export list | omitted eight public types and six shader constants |
| 10 | bevy_isomesh README |
names ChunkSeams::Gapped |
not re-exported — unreachable by that name |
| 11 | README | — | a heading separated from its own prose by two unrelated sections |
| 12 | examples catalog | 31 examples | 34 |
| 13 | README | — | six public modules mentioned nowhere |
The one that matters is #2, because it is the second time. CHANGELOG.md 0.0.4 records fixing
that exact number from 147 to 168. It then rotted to 216. A number that has rotted twice will rot a
third time, and the reason is structural rather than careless: scripts/readme_sync.sh was the only
doc-content check in CI and it compares one code fence.
scripts/doc_facts.sh now derives the counts that keep rotting from their sources and fails on a
document that states a different one. Mutation-tested six ways.
The gate's first version is half the finding. It checked any number-word before fields or
extractors and flagged "five of the seven reference fields go to exactly zero" — correct prose
about a subset. Twenty-odd false positives on the first run. A gate that cries wolf is a gate
somebody disables, so the patterns were narrowed until only a phrase that can mean the total
matches. Note what survives: in that same sentence the subset "five" is fine and the total "seven
reference fields" is wrong, and the narrowed gate catches the second without touching the first.
A second structural finding, from the same audit: readme_sync.sh compared every Rust fence.
Its awk collected all of them concatenated, so adding a second Rust snippet to either README failed
the gate with a diff pointing at the new snippet rather than at drift in the quickstart — a gate
failing for a reason it is not about, which is the other way gates get switched off. Fixed to take the
first fence, which is what its own header always claimed.
And an unspent-work finding. Seven examples carry a capture-driven animation sweep that exists
only to be recorded — dual_contouring_cube steps around grid-aligned resolutions on purpose so a
clip cannot show the comparison inverting, qef_clamp flips the clamp on a fixed dwell "so the GIF
is the same GIF on any machine", sharp_features ping-pongs λ logarithmically so it loops. Not one
of them had ever been recorded. The code was written, commented, committed and never run. Nothing
detects that; a capture hook has no test that fails when nobody calls it.
Would be shown wrong by: a document stating one of these counts correctly while doc_facts.sh
reports drift, or the reverse — a drift the gate does not see. The second is expected and bounded: the
gate checks five counts, not every number in the tree.
M-296 — the README answered "is the GPU faster" with no, and its own CSV said 37× (docs)
Tier M. Found by a reader asking the obvious question of the demo page: does this tell me whether the GPU is faster?
README.md's "Is this for you?" table read:
GPU extraction to make CPU meshing faster — no — with readback the GPU path measures slower than the CPU at every resolution tried; it pays off only when you render from GPU memory and never read back.
docs/measurements/gpu_vs_cpu.csv, committed, in the same repository:
| samples/axis | CPU ms | GPU, uploaded field | GPU, field on the GPU | |
|---|---|---|---|---|
| 17³ | 0.059 | 0.300 | 0.219 | CPU ahead 3.7× |
| 33³ | 0.340 | 0.418 | 0.225 | GPU ahead 1.5× |
| 49³ | 1.049 | 0.780 | 0.265 | GPU ahead 4.0× |
| 65³ | 2.444 | 1.349 | 0.272 | GPU ahead 9.0× |
| 97³ | 8.618 | 3.715 | 0.327 | GPU ahead 26× |
| 129³ | 20.141 | 8.369 | 0.536 | GPU ahead 37.6× |
The claim was true once and nothing re-read it. It describes the state before GPU-010a moved the prefix scan onto the device (M-150) and GPU-011a moved field evaluation there (M-155) — three tickets that took the 129³ path from 15.01 ms to 0.54 ms, none of which made the extractor faster. Every one of those findings is in this file, each with the number, and the README kept saying "no" for as long as they took to land.
And I propagated it. Rewriting crates/isomesh-gpu/src/lib.rs earlier the same day, I carried
"with a readback, this is slower than the CPU… measured, at every resolution tried" into the crate's
docs.rs landing page — a fresh assertion of a falsified claim, written while holding the CSV that
disproves it, because it was inherited from prose rather than checked against data. This is M-149's
lesson recurring exactly: "the error being recorded is an overclaim in prose that the repo's own
committed CSV contradicted. Checking a claim against data already in the repository costs one query."
What is true, and now stated in all four places:
- The GPU wins above about 33³ and loses below it, on roughly 0.22 ms of fixed cost.
- The GPU column is nearly flat — 0.22 → 0.54 ms across a 420× rise in cells — because
extraction was never the cost.
count + emitis 0.045 ms at 129³ and does not move. - Where the field is evaluated decides the rest. Uploading CPU-sampled data makes the upload 87% of the path (2.4× ahead instead of 37×), and it does not take field evaluation off the CPU's budget — it adds a copy to it.
Why nothing caught it. doc_facts.sh (M-295) gates counts with one mechanical source. A
directional claim — "slower", "faster", "never" — has no such source, so no gate of that shape can
see it. What would have caught it is the rule M-149 already earned and this repository failed to
apply twice.
Would be shown wrong by: a re-run of gpu_vs_cpu on this hardware showing the crossover somewhere
other than ~33³, or gpu_field_total_ms losing its flatness with resolution.
M-297 — no published convex decomposition runs at interactive rates, so this crate's own 241 ms was not an outlier (O-2)
V. M-116 measured runtime convex decomposition at 241–272 ms per fragment on avian3d 0.7 —
"14–22 whole frames" — and left open whether that was the implementation or the problem. A sweep of
the decomposition literature says it is the problem, and by a wide margin.
| method | per PartNet-Mobility model | hardware | source |
|---|---|---|---|
| VisACD | 16.97 s | OptiX + CUDA | its own Discussion, 10.48550/arXiv.2604.04244 |
| CoACD, as VisACD measured it | 36.31 s | — | the same sentence |
| CoACD, as CoACD measured itself | 194.4–253.4 s | one CPU thread | Table 1, 10.48550/arXiv.2205.02961 |
Against a 16.67 ms frame that is 1,000× at the very best and 15,000× at the worst, and the
ordering survives whoever's harness you believe. The fastest figure in the sweep is a GPU method with
OptiX and CUDA under it.
Every method labelled "real-time" precomputes, and each says so in its own words. Müller,
Chentanez & Kim (10.1145/2461912.2461934) — the source usually reached for on real-time destruction
— state that the "pre-computed convex decomposition is independent of the fracture pattern exposed at
real-time." Sellán et al. (10.1145/3549540) grant that their fracture modes are "slower to compute
than geometric-only procedural prefracture" and that "this cost is added only at the offline
precomputation stage." What runs at frame rate in both is pattern selection, never decomposition.
Consequence. Reporting collider::readiness() per shard, and decomposing offline or not at all,
is the position the literature supports rather than a holding pattern waiting on a faster library. Two
independent measurements now agree from opposite directions: 241 ms measured here, seconds-per-model
published there.
And the precondition list turns out to be this crate's validator output. Every method in the sweep
assumes closed, watertight, 2-manifold, self-intersection-free, consistently oriented input. VisACD
preprocesses "using SDF remeshing to make the meshes watertight" before it will run, and declines to
evaluate CoACD's merging step at all because "merging produces intersecting convex hulls in 35% of
cases" — disabling merging in its own algorithm "for the same reason." So T-001's checklist is not
mesh hygiene for its own sake; it is the entry condition for anything downstream that decomposes.
R-011 is open on the single gap this exposes: ColliderReadiness does not fold in
SelfIntersectionReport, so the one precondition that a 35% failure rate is actually about is the one
readiness() cannot currently report.
Would be shown wrong by: a published method decomposing a game-scale mesh inside a frame budget with no precomputation step, or a closer read of VisACD's Table 1 showing 16.97 s is not the best figure it reports.
M-298 — orientation catches a fan that reverses, not a fan that folds, and a star polygon is invisible to both counters (T-020)
M. The proposed equivalence was fan-fold ⟺ inconsistently_oriented_edges > 0, tolerance-free
and needing no narrow phase, for fans whose winding is fixed per triangle to face a chosen outward
normal. Half of that is exactly right and the other half is too strong. The counter is an exact test
for a fan that reverses its sweep. A fan can fold without reversing, and then nothing sees it.
The mechanism, derived rather than measured. Adjacent slices of a fan share the spoke
{apex, p_i}. Writing T_i unflipped as (c, p_i, p_{i+1}) and flipped as (c, p_{i+1}, p_i), the
four cases collapse to one rule:
T_i |
T_{i+1} |
spoke traversed | verdict |
|---|---|---|---|
| unflipped | unflipped | p→c then c→p |
consistent |
| flipped | flipped | c→p then p→c |
consistent |
| either mixed pair | the same way twice | inconsistent |
So inconsistently_oriented_edges on a fan is precisely the number of flip-state changes around
it — and the flip state is sign((p_i − c) × (p_{i+1} − c) · outward), the sign of the slice's
signed area. It fires on a sign change, which is a reversal of sweep direction. Nothing else.
Measured, on two synthetic fans in validate/tests.rs:
| fan | boundary winding | inconsistently_oriented_edges |
self-intersections | pairs tested |
|---|---|---|---|---|
| convex hexagon (control) | 1 | 0 | 0 | 0 |
| four CCW points then one that backtracks | 1 | 2 | 0 | 0, 10 skipped |
| pentagram, every second vertex of a pentagon | 2 | 0 | 0 | 0 |
The reversing fan gives exactly two, one spoke entering the reversal and one leaving it, matching the derivation before it was run. The pentagram is the counterexample: every slice spans +144°, so every slice has the same sign, so no triangle is flipped and no spoke changes state — while the boundary winds twice, which means the cap covers its disk twice. Both counters report zero on a cap that is definitively wrong.
And self-intersection cannot cover the gap, which is M-83 again. Every fan triangle shares the
apex, so every pair is skipped: 10 of 10 skipped, 0 tested on a five-slice fan. The zero is
vacuous in the precise sense M-83 established, and the test asserts tested_pairs == 0 alongside it so
the green tick cannot be misread as coverage.
Why the counterexample was looked for at all. QEx (Ebke, Kobbelt, Bommes & Campen,
10.1145/2508363.2508372) records the analogous failure for their own fold-over detector — "this
assumption fails in one special case: around a vertex-q-vertex we can arrange the fold-overs in such a
way that the entire triangle fan spans an absolute range of less than 180°." Different detector,
different domain, same shape of claim. Taking that as a prompt rather than asserting the equivalence
was total is what found the pentagram.
Consequence. The claim is worth having and must be stated with both qualifiers attached: it holds for fans wound per-triangle against an outward normal, and it detects reversal, not folding. A fan built with uniform winding produces no signal at all, and a fan that folds monotonically produces none either.
Would be shown wrong by: a fan that reverses its sweep and reports zero inconsistently oriented edges, or a per-triangle-outward construction under which a star-polygon cap does flip a slice.
M-299 — the on-demand split is free for the pseudonormal and costs a factor of N for the winding number (S-008)
V. S-008 was scoped to put both mesh-to-field backends behind one
Sdf-implementing type. Only one of them fits, and the reason is a property of the published method
rather than of this implementation.
The pseudonormal path decomposes exactly. Its per-sample work is self-contained — nearest triangle
by the blocked box reject, then Theorem 1's sign from that triangle's feature pseudonormal — so
lifting it into MeshField::sample and rewriting signed_distance_from_mesh as that method in a loop
leaves the batch path running the same instructions in the same order.
the_grid_path_is_this_field_in_a_loop asserts the two agree on identical bits, not within a
tolerance, across all 35,937 samples of the M-259 round trip. A tolerance there would have been an
allowance for the two to become different code without the test noticing.
The winding path does not decompose, because its efficiency is a row amortisation.
winding_numbers casts one ray per grid row and shares that hit list across every sample in the
row — Martens & Bessmeltsev's construction as M-262 recorded it, "to compute voxelizations of
resolution N³, we only need to shoot N² rays." A per-point query cannot share a cast with points it
has not been given, so an on-demand winding field would cast one ray per query: N³ rather than N², a
factor of N. At the round trip's 33³ that is 35,937 casts against 1,089.
So MeshField is the pseudonormal backend and there is deliberately no on-demand winding twin.
Building one anyway would have put two implementations of the same formula in the crate on two
different cost curves, which is the shape of thing that ends up giving two answers to one question.
No timing was taken and none is needed for this decision — the ray counts are structural, not
empirical. Would be shown wrong by: a per-point winding formulation that reuses casts across
queries. A persistent per-row cache keyed on (y, z) is the obvious attempt, and it would make the
field stateful and its cost order-dependent, which is why it was not the default.
P-20 — registered for R-010, before the harness was written
What E×4 leaves. The link-condition gate was measured and reverted: over 56 configurations it
removed at most 4 non-manifold edges and added up to 791 non-manifold vertices, taking
noise_cavity + subgrid from 301 to 1,092 and sphere + Marching Cubes from 0 to 96. The
mechanism is named there and it is the whole reason this ticket is a different object: a k-way
coincidence is manifold only if all k merge, and a pairwise test refuses one member of the
set, leaving its representative a bowtie. That is why the damage was in the vertex column while the
edge column barely moved.
What changes here is the shape of the refusal, not its strictness. Equality on a key is an
equivalence relation: it partitions each coincidence class into complete sub-classes, every
member of a sub-class merges with every other, and no proper subset is ever refused. The API takes
&[u64] rather than impl Fn(u32, u32) -> bool precisely so that E×4's shape is unrepresentable
rather than merely discouraged.
H. Splitting on a caller-supplied key moves no topology metric relative to the unconditional weld beyond the splits the key itself names: with a constant key every metric is identical, and with a varying key the only change is the vertex count rising by the number of sub-classes the key creates. All eight reference fields, every extractor.
Falsified by any topology metric moving where the key is constant — which would mean the hook itself, not the key, is doing something. And separately by a non-manifold vertex count that rises by more than the split count under a varying key, which would be E×4's failure reappearing through a different door.
Records field, extractor, key, vertices_after, splits, non_manifold_edges,
non_manifold_vertices, boundary_edges.
Note what the constant-key arm actually tests. It is a control on the mechanism, not on the hypothesis' interesting half: if a constant key changes anything at all, the plumbing is wrong and no result from the varying arm can be trusted. It is registered as an arm rather than assumed because M-279's rule says a falsifier must separate the hypothesis from its rivals — and "the hook perturbs the weld" is exactly the rival that a varying-key-only experiment could not tell apart from "the key does what it says."
P-19 — registered for S-009, before the harness was written
What ✗23 leaves. S-009's original justification is gone: Manifold Dual Contouring does not query
where it needs to, it pre-samples all N³ points at dual.rs:257, so the dense path is the right price
for extractors. What survives is the question for a genuinely sparse consumer — F-005's empty-cell
rejection by sphere tracing, a collision query, a point probe. But M-299 already measured the thing
that decides it, and it makes the obvious prediction the wrong one.
The batch winding path casts one ray per grid row, not per sample. winding_numbers shares each
+x ray across every sample on it, so an n³ grid costs n² casts — Martens states the same
reduction, "to compute voxelizations of resolution N³, we only need to shoot N² rays." An on-demand
field cannot share anything: it casts one ray per query. So the two paths differ by a factor of N in
ray count, and the naive crossover — "on-demand wins below N³ queries, because that is how many the
batch path answers" — charges the batch path for work it does not do.
H. The crossover is set by the row sharing, not by the point count: on a nearly-closed mesh the crossover query count
Q*is of orderN²rather thanN³, landing within0.5×to4×ofN²for grids from 17³ to 65³.
Falsified by Q* reaching a tenth of N³ or more on a nearly-closed mesh, which would put the
cost in the per-point boundary-edge correction rather than in the per-row ray, and mean the row
sharing is not what sets the crossover. Also falsified if no crossover exists above a single
query — which would say the on-demand field has no regime at all, and S-009 should be closed rather
than built.
Records samples_per_axis, triangles, boundary_edges, batch_total_ns,
on_demand_ns_per_query, crossover_queries, crossover_over_n_squared, crossover_over_n_cubed.
Why "nearly-closed" is in the hypothesis rather than left implicit. The two terms scale
differently: the ray cost is O(N²·T) for the batch and O(Q·T) on demand, while the boundary
correction is O(N³·B) against O(Q·B), with B the boundary-edge count. On a mesh with many
holes the correction term dominates and Q* really should approach N³ — so the hypothesis is
specifically that the row sharing governs, and it is only testable where B is small. A
hole-punched fixture is the control that should push Q* up, and if it does not, the mechanism named
here is wrong even if the number on the nearly-closed fixture comes out right. That control is part
of the registration, not an afterthought — M-279's rule, that a falsifier has to separate the
hypothesis from its rivals rather than merely be capable of failing.
P-18 — registered for R-011, before the count was taken
What M-297 leaves. Every decomposition method in the sweep assumes closed, watertight, 2-manifold, self-intersection-free, consistently oriented input, and two of them say so in operational terms rather than in passing: VisACD SDF-remeshes its inputs "to make the meshes watertight" before it will run, and refuses CoACD's merging step because "merging produces intersecting convex hulls in 35% of cases." That reframes this crate's validity checklist — it is not mesh hygiene for its own sake, it is the entry condition for anything downstream that decomposes. Which raises a question the crate can answer about itself.
H. Every precondition a published convex decomposition method requires of its input mesh is already reported by
ColliderReadiness, so a caller holding a readiness report has everything it needs to decide whether a mesh can be handed to a decomposer.
Falsified by any precondition required by a method in the audit that no ColliderReadiness field
reports.
Records method, precondition, required, readiness_field, covered.
This one is registered expecting to die, and that is why it is registered.
SelfIntersectionReport is a separate type that ColliderReadiness does not fold in — visible by
reading collider.rs:78-108 — so self-intersection-freedom is the standing candidate for the gap, and
R-011's ticket text already says so in the backlog. Writing the expectation down before taking the
count is the difference between a prediction and a rationalisation, and this project has already
caught itself putting expectations into docs that measurement then disproved (✗1, ✗3, ✗14, O-14). If H
survives, the surprise is the finding; if it dies where predicted, the audit is still the product,
because "which field covers which precondition" is not currently written down anywhere.
✗20 — "Every ACD method assumes closed, watertight, 2-manifold, self-intersection-free, consistently oriented input"
Believed because: a literature sweep summarised the ACD line's preprocessing steps as a shared requirement, and this repository accepted it as the bridge from T-001's checklist to downstream colliders — "isomesh's verification checklist isn't mesh hygiene, it's the precondition list for whatever decomposes downstream."
Falsified by: R-011's audit of the four methods' own papers. Two of the four require nothing.
V-HACD "addresses this by voxelizing the input, guaranteeing a solid input for decomposition at the
cost of some accuracy" (Andrews 2024, 10.1145/3641519.3657479 §2.1.3). CPD — the method the sweep
singled out as the best fit for plane-cut shards — states it outright: "Unlike prior work, our
approach handles non-manifold, non-watertight meshes directly without preprocessing"
(10.48550/arXiv.2602.07369 §4), and its Figure 1 is "a complex non-manifold mesh with boundaries."
Root cause: two conflations, in the same sentence.
- Preprocessing read as requirement. CoACD and VisACD both clean their input, so their papers describe watertight meshes — but Andrews 2024 names "whether to perform preprocessing or discretization of the input" as one of the three axes methods differ along. Clean input is a quality lever, not a gate: what it buys is skipping the repair pass and the accuracy it costs — V-HACD's voxelization error, CoACD's "slightly offset version of bad inputs", VisACD's SDF remesh.
- Output read as input. VisACD's "merging produces intersecting convex hulls in 35% of cases" is about the hulls CoACD emits, in a sentence explaining which methods VisACD will benchmark: "We do not evaluate methods that produce decompositions with intersecting convex hulls." Read as an input condition, it put self-intersection-freedom on the precondition list. No audited method requires a self-intersection-free input. CoACD guarantees intersection-free output instead — "In this way, we ensure convex hulls of the decomposed components are intersection-free."
Consequence for this crate. Self-intersections per 1,000 triangles stays a recorded metric and does not become a gate. The conditional that would have promoted it — "if decomposition ever enters the pipeline" — does not fire.
Method rule earned: in Part 5. A precondition claim needs the sentence from the method's own paper, and "what it requires" is a different question from "what it guarantees."
Would be shown wrong by: a decomposition method that refuses, rather than repairs, an input failing one of these five properties.
✗21 — "Convex Primitive Decomposition is the cutting substrate a plane-cut fracture pipeline wants"
Believed because: A-026 (as written in the 2026-08-16 brief, and as ✗20's aside above already
repeated — "the method the sweep singled out as the best fit for plane-cut shards") selected CPD
over the V-HACD/CoACD line on three claims. All three are true and all three were verified here,
in 10.48550/arXiv.2602.07369: the input tolerance quoted in ✗20 (§4, verbatim), "guaranteed to
enclose the input surface" (abstract), and "less than one-third of the complexity as measured by
total bytes" against V-HACD and CoACD (abstract). The ticket then built an architecture on top of
them: decompose a shell, plane-cut the cells, call a fragment a set of cells on one side, and
predicted the fragments would be closed, manifold, χ=2 and volume-conserved to 1e-3.
Falsified by reading the method rather than the results (A-026, before any code was written). CPD does not produce cells, and it does not partition a volume. Algorithm 1 operates on the face adjacency graph: it starts at one primitive per face and greedily merges topologically adjacent primitives under an excess-volume cost, QEM-style. Its own §3.4 says what comes out — "Each primitive covers all vertices of each face it subsumes, allowing vertices to be covered by multiple primitives and the union of all primitives covers the mesh's surface." And the primitives overlap by design and by admission: §3.3 titles a paragraph "Overlapping Primitives" and states that the cost function "does not account for double-counted volume of intersecting primitives", declining the exact computation because it is "at least 30× the wall-clock time" for "minuscule improvement" — "in practice, primitives do not overlap much." Not zero. Not a partition.
Root cause: the third conflation in this family, and ✗20 named the first two. ✗20's rule was that "what it requires" differs from "what it guarantees." This one is a step further: "what it guarantees" is not "what you need."
- Enclosure is the wrong guarantee for a substrate. A collider may be a conservative superset of the solid — that is what makes it safe. A cutting substrate must approximate the solid from both sides, ideally equal it, because the fragment volumes are read off it. A proxy guaranteed to strictly contain the input yields fragments that are systematically too large, so volume conservation to 1e-3 is unreachable by construction — the predicted acceptance measure is falsified by the choice of decomposer, not by any implementation of it.
- Overlap makes "a fragment is a set of cells on one side" ill-defined. Disjoint cells that tile the interior are what makes that sentence mean something; overlapping covers double-count every shared region.
- A surface cover has no interior to cut. plane ∩ convex polyhedron = convex polygon still holds per primitive, but the union of overlapping primitives is neither convex nor a manifold solid without a boolean union — and that union is precisely the operation CPD avoids paying for.
The tension is structural, not an oversight in the paper. The property that makes CPD tolerant of non-manifold, non-watertight input — it never needs an interior, only faces and their adjacency — is the same property that denies it an interior partition. CPD's own §2 describes what the alternatives do instead: prior ACD work "remesh or voxelize the input to make it manifold, then partition the manifold mesh top-down along cutting planes." Partitioning is the property the substrate needs, and it belongs to the line A-026 rejected.
Consequence. A-026 is blocked on a decomposer choice, which is a design decision and not a measurement — recorded on the ticket rather than settled here. Nothing is owed to CPD as a collider: ✗20 stands, the three verified claims stand, and AG-007-shaped "colliders from the proxy" work is unaffected. What does not survive is CPD as the thing you cut.
Method rule earned: in Part 5. Verify a citation's claims and its problem separately. Three true claims about collider quality were carried into an architecture that needed a fourth property nobody had checked for, and the paper's abstract — which is what the claims came from — never mentions it.
Amended 2026-08-16 with the ticket author's own account, which is sharper than the reconstruction above. "I read a virtue for collision as a virtue for cutting without checking what the method actually produces. Same shape as the MDC mistake earlier: a property lifted from a summary, not from the thing itself."
That names the family. Three premises have now failed the same way, and none of them failed because a source was wrong:
| Premise | Lifted from | The thing itself said |
|---|---|---|
| "Manifold Dual Contouring queries where it needs to" (D-011) | a summary of the paper | dual.rs:257 pre-samples all N³ |
| CPD's three virtues make it the substrate (this entry) | the abstract | Algorithm 1 merges the face graph; §3.4 covers the surface |
"MeshReport applies a closed-solid test to render meshes" (✗22) |
a downstream symptom | is_manifold is already "the gate for open fields" |
In each case the summary was accurate and the inference from it was not. So the rule is not "distrust summaries" — it is that a summary states what a thing is for, and every one of these questions was about what it does. Read the artefact when the question is mechanical.
Would be shown wrong by: a construction that recovers a disjoint interior partition from CPD's output at a cost below decomposing with a partitioning method directly. The boolean union of the primitives is the obvious candidate and is what CPD measured at 30× for a related computation.
✗22 — "MeshReport applies a closed-solid test to render meshes, so it must be split into two report types"
Believed because: T-023 (2026-08-16 brief) read a downstream "2/12 manifold" figure as a measurement category error inside this crate, and prescribed "two report types with distinct assertion sets."
Falsified by reading validate.rs and property.rs (T-023, before any code was written). The
distinction the ticket asks for already exists, and it is older and finer than what was proposed:
MeshReport::is_manifoldis documented "The gate for open fields" and does not look atboundary_edges.is_closedis "The gate for closed fields" and adds the boundary and χ-parity checks.has_structural_errorsis the third. The type's own doc comment already says why: "'Valid' is not one thing, so there are three predicates rather than one."violations()deliberately excludesdegenerate_triangles,duplicate_verticesandunreferenced_verticesbecause "a correct extractor produces non-zero counts of all three for perfectly ordinary reasons" — recorded-not-asserted, which is exactly T-023's ask.SurfaceGateis a three-case enum, not the two the ticket assumes, and is "deliberately an enum rather than abool" because "a blanket gate is unsatisfiable for at least one field and at least one algorithm." The third case,ClosedPossiblyNonManifold, covers a grid that may not resolve the field — which no two-type split expresses.- The choice is driven by field metadata, never by the caller:
ReferenceField::closed_in_domain()gates it in seven test modules, andassert_extracted_mesh_is_valid's doc says "gatecomes from the field and the algorithm, never from the caller's intuition."
So the proposed fix would have added a second path to a question already answered once — two report
types where three predicates and a three-case enum exist — and re-baselined every golden hash, since
MeshReport's Display block is hashed.
But there is a real defect underneath, and it is a visibility bug, not a type bug — and it is worse
than "private". mod property; is #[cfg(test)] (lib.rs:129), so SurfaceGate is not merely
pub(crate), it does not exist in a release build at all: the gate-selection rule is test-only
scaffolding that no consumer can reach under any feature. MeshReport and
ReferenceField::closed_in_domain are both public. A consumer therefore receives the report and
its three predicates with no reachable statement of which one to call, and re-derives the rule —
badly. That is precisely the downstream symptom: calling is_closed() on a render mesh that was never
a solid.
Correction, made on closer reading before the fix was written. This entry first claimed
bevy_isomesh/examples/manifold_check.rs:379-381 "does the same thing" by hand-rolling
if report.is_closed() … else if report.is_manifold(). That was overstated and is withdrawn. The
example is a descriptive cascade — it answers "what is this mesh", printing MANIFOLD, CLOSED
or MANIFOLD, WITH BOUNDARY — and reading the three predicates in that order to classify is a
correct use of them. It never judges a mesh against a gate it was not meant to meet.
What the example does lack is the other half: it cannot say whether the boundary it found is
expected. On gyroid, MANIFOLD, WITH BOUNDARY is the right answer and not a defect; on a closed
field the same string is a bug. Without the field's gate the example reports the observation and
withholds the verdict. That is a smaller and more accurate statement of the gap, and it changes
T-023's acceptance: the if/else is kept, and the expected-gate verdict is added beside it.
Consequence. T-023 is re-scoped from split the report to publish the gate, and that is a
promotion of test-only code into the shipped API rather than a one-word visibility change — which
makes it a larger M than it looked, not a smaller one. The acceptance clause worth keeping is its
last one — the docs state which artefact each belongs to — because that was always the part that
bites.
Source-reliability note, which is the durable half. This is the third premise from the
2026-08-16 brief to fail against this codebase, and the three fail the same way. Its claims about the
external literature have held up under checking every time — CPD's three claims (✗21), Shewchuk's
PSLG flood fill, Müller's architecture, ✗20's input-tolerance audit. Its claims about this
codebase's internal state have been wrong three times running: "Manifold Dual Contouring queries
where it needs to" (false at dual.rs:257, retired by D-011), "decompose and cut the cells" (✗21),
and this one. Read the brief as a literature review, and verify every sentence it writes about
crates/ against crates/.
Would be shown wrong by: a consumer requirement that the three predicates genuinely cannot express — a report where solid and surface assertions must coexist on one mesh rather than being selected between.
✗23 — "Manifold Dual Contouring queries where it needs to, so it wants an on-demand field"
Believed because: S-008 needed a motivating consumer for MeshField and named one. The sentence
reads like a summary of Schaefer, Ju & Warren — dual methods place one vertex per cell, so it is
plausible that such a method evaluates the field at scattered points rather than sweeping a grid.
It went into the S-008 archive note, into S-009's justification, and — the part that mattered — into
the shipped doc comment on MeshField, a public type, where it told every reader of docs.rs that
MDC is "exactly that consumer".
Falsified by reading this codebase (D-011, S-009). ManifoldDualContouring::extract calls
self.sample(sdf, shape, origin, cell_size) at dual.rs:257, which loops every one of the N³ grid
points into a buffer before any cell is visited. MDC reads a grid exactly like Marching Cubes does.
There is no scattered evaluation anywhere in it.
What survives, and it is most of the work. MeshField itself is not in question: S-008's own
the_grid_path_is_this_field_in_a_loop makes it the implementation of the query and pins
signed_distance_from_mesh to identical bits across all 35,937 samples of the round trip. T-025 then
made the winding path use it too. The type was right and its stated reason was wrong — which is
why this is a ✗ and not a revert.
What it changes. S-009 is re-parented: the on-demand-versus-batch question is real but belongs to
a genuinely sparse consumer — F-005's empty-cell rejection by sphere tracing, a collision query, a
point probe — and it owes a pre-registered crossover Q* rather than an appeal to MDC. Nothing else
in the crate acted on the premise.
Family. This is the first of the three failures ✗21's amendment tabulates, and the cleanest example of the shape: the summary was accurate about what the method is for, and the inference was about what it does. It is also the only one of the three that reached shipped documentation, which is why it earned a ticket of its own rather than a line in someone else's.
Would be shown wrong by: a dual method in this crate that evaluates the field per-cell rather than pre-sampling — which is a legitimate thing to build, and would make the premise true of that extractor rather than of MDC.
M-300 / P-18 — FALSIFIED, and not where it was predicted: the gap is non-manifold vertices, not self-intersections (R-011)
M. P-18 predicted that every precondition a published convex decomposition method requires is
already reported by ColliderReadiness, and was registered expecting to die on
self-intersection-freedom. It died, and that candidate was not the reason — self-intersection-freedom
turned out not to be an input precondition of anything (✗20).
7 required preconditions across the four methods. 5 covered. 2 not, and they are the same field
twice. docs/experiments/p-18.csv, sources row by row in
docs/research/2026-08-16-decomposition-preconditions.md.
| precondition | ColliderReadiness field |
covered |
|---|---|---|
| closed / watertight | boundary_edges |
yes |
| 2-manifold edges | non_manifold_edges |
yes |
| consistent orientation | inconsistently_oriented_edges |
yes |
| 2-manifold vertices | — | no |
MeshReport computes non_manifold_vertices with the link walk and collider::from_report does
not copy it across. Ten fields are forwarded; that one is not. So a bowtie — two cones sharing
an apex — reports boundary_edges = 0, non_manifold_edges = 0,
inconsistently_oriented_edges = 0, and passes supports_inside_outside(). CLAUDE.md already
states why edge counts cannot see it: "two cones sharing an apex have 2k of each, every edge has
exactly 2 faces, and χ can come out right." A bowtie is not a 2-manifold, and CoACD's plane cutting
is stated over manifold meshes.
The omission looks deliberate and is not. ColliderReadiness's doc comment explains, field by
field, which validator numbers a collider cares about and which it does not — a duplicate vertex is
argued about at length, a degenerate triangle is argued about at length. non_manifold_vertices is
not argued about; it is simply absent, and no test names it. That is the signature of a field
forgotten rather than excluded. Tracked as T-021.
What the audit is worth independently of the verdict. "Which readiness field covers which decomposition precondition" was written down nowhere, in this repo or in the papers, and the four methods disagree so widely — two requiring nothing — that the mapping is not derivable from any one of them.
Would be shown wrong by: a fifth method requiring an input property none of these four does, or a demonstration that a bowtie vertex is harmless to plane-cut decomposition — which would make the omission correct and the doc comment merely silent about it.
M-301 — the bowtie that passed: a closed, edge-manifold, consistently oriented surface that is not a 2-manifold (T-021)
M. M-300 found non_manifold_vertices missing from ColliderReadiness. This is the fixture that
shows what it cost, built as two tetrahedra point-reflected through a shared apex — they touch at
exactly one vertex and share no edge.
| counter | value |
|---|---|
euler_characteristic |
3 |
boundary_edges |
0 |
non_manifold_edges |
0 |
inconsistently_oriented_edges |
0 |
non_manifold_vertices |
1 |
Every edge has exactly two faces, the surface is closed, both cones are wound outward, and it is not a
2-manifold. Before T-021 supports_inside_outside() returned true on this mesh — the arbitrary-
answer case its own doc comment warns about, at the one point on the surface where it is guaranteed
rather than possible.
χ = 3 is the tell, and nothing was reading it. Two closed surfaces glued at a point give
V − E + F = 7 − 12 + 8 = 3, and an odd χ is impossible for a closed orientable surface, where
χ = 2 − 2g is always even. MeshReport::is_closed already folds in that parity check —
CLAUDE.md says so explicitly — so the validator could always see this. The collider view could not,
because the field it needed was not forwarded to it.
The three-line fix and the one-line behaviour change. from_report now copies
non_manifold_vertices across, and supports_inside_outside() requires it to be zero. That last part
makes a mesh that passed yesterday fail today, which is correct and is still a semver-visible change
on a struct whose fields are public.
Why it was missing is worth recording. Every other MeshReport number the collider view drops is
argued about in the doc comment — a duplicate vertex gets a paragraph on why it is a correctness
fault rather than a structural one, a degenerate triangle gets one on why a collider is the consumer
that has to care. non_manifold_vertices got no paragraph. An omission with a rationale and an
omission without one look identical in a struct definition, and only the doc comment distinguishes
them; this one had no doc comment because it had no field.
Would be shown wrong by: a physics engine answering an inside/outside query correctly at a bowtie apex, which would make the tightened predicate too strict rather than newly right.
M-305 / P-20 — the weld key does what it says, and H's wording was wrong anyway (R-010)
M. cargo bench --bench experiment_p20 → docs/experiments/p-20.csv. 51 configurations × 3 arms:
none (the unconditional weld), constant (every vertex keyed 0), normal (the vertex normal
quantised to 1/16).
Both registered falsifiers held.
- Constant key moves nothing, anywhere. 0 of 51 configurations differ from
noneon any of vertices, non-manifold edges, non-manifold vertices or boundary edges. The hook is inert when the key is; nothing in the third arm is the plumbing. - No E×4 reappearance. Non-manifold vertices rise by more than the split count in 0 rows. The equivalence-relation argument survives contact: a key partitions each coincidence class into complete sub-classes, and no class is ever left with a lone representative. Contrast E×4's pairwise gate on this same fixture shape, which added up to 791 non-manifold vertices.
The pre-registered fixture could not test the interesting half, and that was found mid-experiment.
On all 50 field × extractor pairs the normal key produced 0 splits. At a chunk seam the two
copies of a vertex come from the same field evaluated at the same point, so their normals agree far
inside the quantum — there is no attribute discontinuity for the key to preserve. A key that never
fires is a control that cannot discriminate, and it reads exactly like a real negative (M-279). So a
creased_cube fixture was added: 6 quads, 24 vertices, every corner shared by three vertices with
three different face normals. This was not in the registration and is disclosed rather than folded
in. On it: none and constant both collapse 24 → 8; normal keeps all 24, 16 splits,
non-manifold edges and vertices 0.
H's wording is contradicted even though neither falsifier fired, and this is the finding. H said the only change under a varying key is "the vertex count rising by the number of sub-classes." Boundary edges go 0 → 24 on the crease fixture. That is not a defect and not an independent effect — it is the split, seen from the edge column instead of the vertex column. Keeping a cube's faces apart necessarily opens the edges between them; a position-welded cube is a closed solid and a normal-split one is six disconnected quads.
Which makes this the exact mirror of E×4. There, a pairwise refusal did its damage in the vertex column while the edge column barely moved. Here an equivalence refusal does its intended work in the boundary-edge column while the vertex column shows only the splits. Same fixture family, same two columns, opposite readings — and the column that moves tells you which kind of refusal you built.
It also needs T-023's gate to read correctly, which is why that ticket landed first without either
being planned against the other. A normal-split render mesh is a surface, not a solid: its 24
boundary edges are a recorded number under SurfaceGate::Manifold, and asserting Closed on it would
report correct output as broken — ✗22's failure, arriving from a new direction.
H is amended rather than marked falsified, because both of its stated falsifiers are the load-bearing claims and both held: the only change beyond the splits the key names is the boundary opened between sub-classes, which is the same event counted on a different edge.
Would be shown wrong by: a key whose sub-classes are not separated by any edge — two coincident vertices in the interior of a face — where the vertex count should rise with no boundary change at all. Untested here; the crease fixture puts every split on an edge by construction.
M-304 — a green preflight.sh is not a green CI, because the toolchains differ (0.0.6 release)
M. The 0.0.6 release ran with preflight.sh --full green on every gate and failed. The lint
job raised clippy::question_mark twice in crates/isomesh/src/predicates.rs — at 188:13 and
231:9, both match … { Some(x) => …, None => return None } where ? now suffices — the job exited
101, and the publish to crates.io step was skipped. Nothing uploaded; crates.io stayed at 0.0.5.
Five other jobs passed, including both test matrices and the packaging dry run.
Cause: version drift, not a missing gate. preflight.sh runs cargo clippy and CI runs cargo
clippy; the command is identical and that is exactly why it was invisible. Local was clippy
0.1.96 (rustc 1.96.0, 2026-05-25). CI installs whatever stable is on the day it runs, which was
0.1.97 (rustc 1.97.1, 2026-07-14). question_mark fires in the newer and not the older.
rustup update stable reproduced the failure locally in seconds, and the fix — *h.first_mut()? = g0;
and *h.get_mut(written)? = q; — is shorter than what it replaced.
This is M-293's shape with a different mechanism, and that is the point. There the gap was a
target the local command did not compile (bevy_isomesh, excluded from the workspace). Here the
command covers everything and the compiler differs. Both produce the same reading: a fully green
local run, and a red CI. A gate that runs the right command with the wrong tool is not a weaker gate,
it is a silent one.
Rule earned, and it is a script rather than a note: scripts/toolchain_drift.sh, wired into
preflight.sh immediately before the clippy step. It compares local stable against the current
release via rustup check and prints a warning naming both versions. Deliberately a warning and not
a failure — being a patch behind is normal, and blocking every local run on it is the
gate-that-cries-wolf Part 5 already has a rule about. What it must not do is stay quiet, because quiet
is what made this invisible.
Cost, recorded because it is the argument for the check. One failed release, ~31 minutes of CI, and a stretch where several commits were deliberately held back to avoid cancelling a run that was never going to publish.
Would be shown wrong by: a CI configuration that pins its toolchain, which would make local and remote agree by construction and turn this check into noise. That is a real option and it was not taken — pinning would also stop CI seeing new lints, which is the thing that caught this.
M-303 / P-19 — HELD: the winding crossover is N², not N³, and the per-point cost is linear in boundary edges (S-009)
M. cargo bench --bench experiment_p19 → docs/experiments/p-19.csv. The batch cost is decomposed
into setup, per-ray and per-point terms by timing three grid shapes — (2,2,2), (2,N,N) and
(N,N,N) — where T_full − T_thin isolates the per-point term exactly, because the two shapes cast an
identical number of rays.
| fixture | N |
boundary edges | per-ray ns | per-point ns | Q* |
Q*/N² |
Q*/N³ |
|---|---|---|---|---|---|---|---|
| sphere, closed | 17 | 0 | 3,740 | 104.0 | 414 | 1.43 | 0.084 |
| sphere, closed | 33 | 0 | 15,886 | 151.3 | 1,418 | 1.30 | 0.040 |
| sphere, closed | 65 | 0 | 73,172 | 153.4 | 4,791 | 1.13 | 0.017 |
| holed control | 17 | 420 | 3,043 | 10,005 | 3,835 | 13.27 | 0.78 |
| holed control | 33 | 1,702 | 16,020 | 39,681 | 25,914 | 23.80 | 0.72 |
| holed control | 65 | 6,794 | 86,130 | 157,363 | 178,978 | 42.36 | 0.65 |
H held on both arms. Q*/N² is 1.13–1.43 against a registered band of 0.5×–4×, and Q*/N³ stays
below the 0.1 falsifier at 0.017–0.084. The second falsifier — no crossover at all — did not fire
either: Q* is below N³ on every row, so an on-demand field always has some regime.
The control did its job, and it is the part worth keeping. Punching holes moves Q*/N² from ~1.2
to 13–42, so the hypothesis was genuinely at risk rather than unfalsifiable. And the mechanism is
confirmed quantitatively, not merely directionally: from N = 17 to N = 65 the holed fixture's
boundary-edge count rises 16.2× and its per-point cost rises 15.7× — the correction term is
linear in boundary edges, exactly as the derivation says. The per-ray term meanwhile tracks
triangle count (16.2× more triangles, 19.6× the ray cost), and barely moves between the closed and
holed fixtures at fixed N. Two terms, two different drivers, both as predicted.
What this decides for S-009: build it, but the regime is narrower than the ticket assumed. The
naive reading — an on-demand field wins below N³ queries — overstates the win by a factor of N.
At 65³ on a closed mesh the real crossover is 4,791 queries against 274,625 samples, so
on-demand pays only below about 1.7% of the grid. That is a real regime for a point probe or a
collision query, and F-005's sphere-traced empty-cell rejection is plausibly inside it — but it is not
the general-purpose win "queries where it needs to" implied, and ✗23 already retired the consumer that
sentence named.
Incidental, and it is not small. The holed mesh at 65³ takes 43.6 seconds to batch. The
correction is O(N³·B) and both factors are growing, so the winding backend's cost on genuinely
damaged input — which is the input it exists for — is far worse than the closed-mesh figures anyone
would benchmark with. Nothing currently warns about that.
Would be shown wrong by: a boundary correction whose cost is not linear in boundary-edge count —
which would break the O(N³·B) model the crossover is derived from, even though the crossover numbers
themselves came out inside the band.
M-302 — the naive orient2d fails by reporting collinear, not by reporting a false crossing (T-024a)
M. T-024a's acceptance asked for "a degenerate fixture (three collinear points, two coincident within ε) that the float path misclassifies and the exact path does not." Two constructions built to that description cannot exist, and finding out why sharpened what the predicate is actually for.
Exactly collinear input does not break the naive determinant, provided the differences are exact.
fl(x · y) is a function of the real product x · y alone. So if u₁v₂ = u₂v₁ exactly as reals —
which is what collinearity means for the difference vectors — then fl(u₁v₂) and fl(u₂v₁) are the
same float, and their difference is exactly 0.0. Rounding cannot manufacture a disagreement
between two equal real quantities. Measured, not argued: a first fixture of three points on y = x
gave the naive form exactly 0.0, and a search over 3,000,000 near-collinear integer triples at
coordinates up to 2³⁰ found zero sign disagreements.
So the error lives in the subtractions, and the failure mode is the opposite of the expected one.
The reachable defect is a false zero: points that are not collinear reported as collinear. The
committed fixture is a = (2147483647, 2147483645), b = (−1073741823, −1073741822), c = (0, 0) —
an extended-Euclid pair whose exact determinant is 1, the smallest nonzero value integer input
admits, while both products land near 2⁶¹ where one ulp is 512. The naive form returns exactly
0.0; orient2d returns positive. Coordinates stay below 2⁵³, so every one is exactly
representable and the i128 oracle is exact.
Why this matters more than the symmetric case would have. A false crossing is self-correcting — downstream code sees an inconsistency. A false collinear is the reading a triangulator trusts: it is the answer that says "no decision needed here", so it silently drops a constraint rather than producing a visible contradiction. T-022's flood fill halts at constrained edges, and an edge the predicate calls degenerate is an edge the fill walks straight through.
Method note. Both dead fixtures were written from a plausible description of the failure — the one in the ticket, which came from the same 2026-08-16 brief as ✗21 and ✗22 — and neither was tested against an oracle before being believed. The search that replaced them took minutes. A fixture that "obviously" exercises a path is a hypothesis about the path.
Would be shown wrong by: a collinear configuration where the difference vectors themselves round,
making u₁v₂ and u₂v₁ unequal as reals even though the original points are collinear. That is
reachable — it needs coordinates far enough apart that a − c is inexact — and would mean the
false-nonzero mode exists too, at coordinate ranges this fixture does not reach.
✗24 — "Empty-cell rejection benefits every field, however little"
Believed because: the sentence sitting in empty_cell_rejection_is_measured_per_field as a code
comment — "a cell the surface does not reach exists in every one of them" — which is true and
does not imply what was inferred from it. Every field does have unreached cells. What decides whether
rejection pays is not whether such cells exist but what fraction of the grid they are, and nobody
counted.
Falsified by the 0.0.7 release, on a macOS runner, at gyroid 0.98×. The assertion was
speedup > 1.0 per field, and the test's own doc comment said in the same breath "recorded rather
than asserted" and "not a regression gate". The prose was right and the code was the gate. The
publish step was skipped and nothing uploaded — the second release in this repo stopped by a green
local suite and a red CI one (M-304 was the first).
What's true instead, counted rather than timed (M-306). The rejected-cell share at 17³ is
16.8% on gyroid and 80.6–95.1% on every other field that offers a constant. gyroid is
triply periodic; its surface reaches nearly every cell in any finite box, so there is almost nothing
to prove empty and the one extra evaluation per cell is close to pure overhead. A 1.10× ratio on the
Ryzen and 0.98× on a contended runner are the same measurement, and which side of 1.0 it lands on is
set by the runner rather than by the code.
So this was never a threshold problem. Loosening > 1.0 to > 0.9 would have bought a release
and kept a gate whose subject is the runner. The gate is now the rejected count, which is an
integer, identical on every machine, and bounds the saving that the ratio can only sample. The ratio
stays printed.
Would be shown wrong by: a field with a low rejected share that nonetheless shows a large speedup, which would mean the saving is not bounded by the count and the mechanism is something else.
The residual, named rather than fixed. the_reject_agrees_with_brute_force_and_is_faster in
construct/from_mesh asserts fast_ms < brute_ms and is the last wall-clock gate in the suite. Its
margin is 2.4× on this machine in a debug build, against gyroid's 1.10×, and the asymmetry it
tests is algorithmic (O(samples × triangles) against a two-level box reject) rather than a per-cell
constant. Left as-is with the margin on record; if it ever flakes, the same treatment applies —
assert the rejected-triangle count, print the ratio.
M-306 — what empty-cell rejection can save is bounded by a count, and that count is a property of the field (✗24)
M. cargo test -p isomesh --lib empty_cell_rejection_is_measured_per_field -- --nocapture, 17³
(4,096 cells), SubgridMarchingTetrahedra at 16 samples per edge, Ryzen 9 5900X, debug build. The
rejected count is cell_is_provably_empty over every cell — deterministic, and the same integer on
any machine. The ratio is best-of-three each way in one process.
| field | rejected / 4,096 | share | speedup |
|---|---|---|---|
thin_plate |
3,896 | 95.1% | 7.2–7.7× |
torus |
3,768 | 92.0% | 3.8× |
sphere |
3,752 | 91.6% | 3.9× |
box_exact |
3,312 | 80.9% | 2.6× |
csg_difference |
3,300 | 80.6% | 2.7× |
gyroid |
688 | 16.8% | 1.1× |
The spread is 5.7× in the count and it is the whole story. gyroid is the only field below a
quarter and the only field whose ratio is near 1; every other field is above four fifths and every
other ratio is comfortably above 2. F-005's claim — one evaluation deletes the 576-evaluation constant
for every cell the surface does not reach — holds exactly as stated and is silent about how many
such cells there are, which is the quantity that decides whether the technique is worth switching
on.
Rejection moves no triangle on any field, asserted rather than sampled, and that half is unchanged from the original test: it is the only property of rejection that has to hold, and it is the one a consumer is entitled to rely on.
Note the ratio is not monotone in the share at the top end — sphere 91.6% / 3.9× against torus
92.0% / 3.8×, and box_exact 80.9% / 2.6× against csg_difference 80.6% / 2.7×. Both pairs are
within the run-to-run spread of each other, so the count separates the regimes and does not predict
the ratio to a decimal. That is exactly why the count is the gate and the ratio is a print.
V-37 — the instrument R-024 needs is published and in this corpus; the question it asks is not
V. R-024 is written as "nobody has established this, and every paper treats the two as interchangeable." Half of that needs narrowing, and the narrowing is worth more than the original sentence.
The instrument exists and has been shipping since 2010. Wojtan, Thürey, Gross & Turk,
Physics-inspired topology changes for thin fluid features (10.1145/1778765.1778787, in corpus as
eth-cgl-sim_anim-Woj10) defines exactly the test R-024 needs, verbatim:
"we determine the complexity of a cell edge by counting the number and orientation of its intersections with triangles in the surface mesh and comparing the result with a single line segment (0-sphere). If there are too many components, or if the surface is oriented the wrong way at any of the intersection points, then the edge is complex."
They call it the complex edge test, run it over every edge of the signed-distance grid, and state
its coverage precisely: it "is guaranteed to identify any topological flaws that are well-resolved in
at least two dimensions", with complex-face and complex-cell tests above it for thinner defects. The
2024 multi-material surface-tracking paper (sig2024_Multi-Material_Mesh-Based_Surface_Tracking…)
reuses the same hierarchy — complex edge, complex face, complex cell — so this is a standard
instrument, not a one-off.
What they use it for is a different question, and that is the part that leaves R-024 standing. Their mesh is advected by a velocity field and the SDF is rebuilt around it; disagreement between the two is expected, is the thing they are detecting, and is then repaired. Their sentence says so directly: "We detect disagreements between the explicit surface mesh and the fluid grid." Nobody in that line asks whether a mesh freshly extracted from a field agrees with the field that produced it, per extractor — because in their setting the mesh never was extracted from that field.
An independent search returned nothing for the question itself — does an extracted isosurface preserve the connected components of the sublevel set — across arXiv, OpenAlex, Semantic Scholar and CrossRef. The nearest hits are persistent-homology reviews and volume-rendering work, neither of which is this.
So the claim R-024 may make is narrower and still unoccupied: the test is borrowed prior art and must be cited as such; what is new is running it as a correctness audit of extraction itself, across a family of extractors on a shared fixture, and reporting which of them seal and which do not. Claiming the instrument would be the third instance of ✗21's family — reading a method's purpose off its mechanism.
Would be shown wrong by: a paper that runs an edge-crossing or equivalent audit on a freshly-extracted isosurface and reports per-algorithm agreement with the field's own sign. That is the exact thing being claimed as absent, and finding it closes R-024's novelty rather than its result.
P-21 — registered for R-024, before the harness was written
What is being asked. The crate validates a mesh against itself — manifoldness, orientation,
Euler characteristic, self-intersection — and against the field's geometry, in validate::accuracy.
It has never checked the mesh against the field's partition of space. Those are different claims:
a mesh can be closed, manifold, correctly oriented and Hausdorff-close while sealing a passage the
field leaves open, or opening one it seals.
The discrete form, and why the probe is a grid edge. The extractor never sees the field anywhere
but at the samples, so the air sublevel set as the extractor could know it is the 6-connected graph
on samples with !is_inside. Probing along the grid edges keeps both sides on the same lattice and
keeps the test local, which is what lets it run on gyroid and fbm_terrain — fields whose
surface leaves the domain, where any global inside/outside test is undefined at the boundary. The
instrument is Wojtan et al.'s complex-edge test and is cited as theirs (V-37).
H. For every 6-adjacent pair of grid samples, the mesh crosses the segment between them an odd number of times when the two samples straddle the surface and an even number when they do not — so the air sublevel set's components and the same samples' components under mesh-cut adjacency agree in count and in partition. Marching Cubes achieves this on all eight reference fields, because its vertex is the root of the interpolant along the very edge being probed. At least one dual method does not, because it places its vertex by solve.
Falsified by universal agreement — every extractor sealing every field at every resolution, which would be a stronger correctness statement than this crate currently makes and would be worth stating as one. And separately, more interestingly, by Marching Cubes disagreeing: the crossing on a sign-changing edge is on the interpolant by construction there, so a failure would locate the defect in triangulation rather than in vertex placement, and would invert the mechanism this hypothesis rests on.
Records field, extractor, samples_per_axis, field_air_components, mesh_air_components,
unsealed_walls, spurious_walls, mixed_regions.
The degeneracy this has to get right, stated before the numbers arrive. A Marching Cubes vertex lies exactly on the probed segment and is shared by every triangle in its fan, so counting triangle hits would report 4 where the surface crosses once, and every sign-changing edge in the crate's flagship extractor would read even. Crossings are therefore counted as distinct points, deduplicated at the crate's own weld tolerance, and the number of raw hits that collapsed is reported so the mechanism is visible rather than assumed. A harness that got this wrong would falsify H in the loudest possible way while measuring nothing but its own convention — which is M-279's rule, applied before the fact for once.
M-307 / P-21 — HELD: the primal family seals every reference field, and all three duals leave the domain boundary open (R-024)
M. cargo bench --bench experiment_p21, docs/experiments/p-21.csv. Eight reference fields ×
seven extractors × [17, 25, 33] = 168 rows, 9,151,296 probes. Ryzen 9 5900X. The instrument is
validate::sealing; it is Wojtan et al.'s complex-edge test and is cited as theirs (V-37).
P-21 held in both clauses, and its stated falsifier — universal agreement — did not occur.
| extractor | sealed | where it fails |
|---|---|---|
marching_cubes |
24 / 24 | — |
marching_cubes+decider |
24 / 24 | — |
marching_tetrahedra |
24 / 24 | — |
surface_nets |
21 / 24 | fbm_terrain, all three resolutions |
dual_contouring |
21 / 24 | fbm_terrain, all three resolutions |
manifold_dual_contouring |
21 / 24 | fbm_terrain, all three resolutions |
subgrid_marching_tetrahedra |
18 / 24 | fbm_terrain and noise_cavity |
The three duals report the identical count — 92 at 17³, 138 at 25³, 190 at 33³ — and
unsealed_on_domain_face equals unsealed_walls in every one of those nine rows. Three
independent implementations agreeing to the unit, all of it on the boundary, is what says the
mechanism is one vertex per cell rather than any particular solve or face rule.
The mechanism. A dual emits one quad per sign-changing grid edge and that quad needs all four
cells around the edge. On a face of the sampled domain only one or two exist, so no quad is emitted
and the wall is left open. A primal method emits per cell, meshes every cell it has, and seals the
same edge. fbm_terrain is the only reference field whose surface leaves through the sides, which is
why it is the only field where this is reachable — gyroid is capped and the other six are closed in
the domain.
For a chunked world the domain face is the chunk seam, so this is the measured statement of why a
dual chunk's collider is not watertight on its own. It is adjacent to M-4 (Surface Nets' pinned
non-zero boundary_edges) and is a different claim: that one is about the mesh's own topology, this
one is about whether the mesh separates what the field separates.
The split is not primal versus dual. It is whether the method puts its crossing on the probed grid
edge. subgrid_marching_tetrahedra is primal by family and is the worst performer here,
because it samples along tet edges inside the cell and its crossings are nowhere near the grid
edges. Its fbm_terrain failures are mostly not on the domain face — 1 of 4, 1 of 3, 0 of 4 — and
its noise_cavity failures are entirely interior, 0 of 3, 0 of 3, 0 of 4.
That interior residue is recorded and is not attributed to subgrid MT as a defect. This harness compares against the sign pattern at the grid corners, because that is all the other six extractors ever see. Subgrid MT deliberately looks between the corners, so where it disagrees it may be the more faithful of the two — a sub-cell feature the corner signs cannot represent is exactly what it exists to find. Deciding which is right needs a probe of the analytic field along the edge and is not this ticket.
The two degeneracies, and both had to be resolved before any number above means anything.
- A sample exactly on the surface.
sphereat 17³ passes through its six axis intercepts, and a primal method places its vertex att = a/(a − b)— soa = 0puts it at the sample, and its fan then touches all five same-sign probes there. Before the exclusion, all four grid-edge primal methods reported exactly 30 spurious walls (6 samples × 5 edges) and every dual reported 0. The first reading of this experiment was that Marching Cubes fails and the duals are clean — the exact inverse of the truth, produced entirely by the instrument. - One rounding away from that, which the exact test misses.
sphereat 25³ carries a sample at−1.11e−16: solid byis_inside, and the surface to within one ulp.value == 0does not catch it; the crossing att = 1.0does. This is A-002i's lesson in a second place — "the exact test undercounts the phenomenon" — and the fix is to detect the degeneracy from the mesh side as well as the field side.
159,816 of 9,151,296 probes (1.7%) are set aside as undecidable, and the exclusion is symmetric:
both graphs lose the same edges, so field_air_components and mesh_air_components are equal in all
168 rows including every failing one. The component counts are R-024's own wording and they agree
everywhere; it is the edge-level columns that carry the result, which is itself worth knowing —
holes at a boundary do not always change a component count.
Would be shown wrong by: a dual method that seals fbm_terrain's domain face — which is buildable,
by emitting a partial quad where the ring is incomplete, and would be a change to the extractors rather
than to this finding.
M-308 — the family comparison's headline conclusion was overturned by optimising one member of the family, not by a better measurement (R-026)
M. docs/measurements/family.csv, Ryzen 9 5900X, f32, sphere, one binary, one run. Read
against docs/research/2026-08-13-measured-comparison.md §4 and against M-45, which that section
quotes.
What §4 says, and it is this repo's own published conclusion:
"On Zen 3 there is no crossover at any resolution — Surface Nets is 2.46× behind even at 16³. So the crossover is a property of one machine's cache behaviour, and the degradation is a property of the algorithm."
Both halves of the observation are now false on that same machine.
| samples per axis | marching cubes | surface nets | SN / MC |
|---|---|---|---|
| 16³ | 9.24 ns | 8.63 | 0.93× |
| 24³ | 8.68 | 8.32 | 0.96× |
| 32³ | 8.11 | 7.96 | 0.98× |
| 48³ | 7.86 | 8.10 | 1.03× |
| 64³ | 7.64 | 8.41 | 1.10× |
| 128³ | 7.56 | 8.78 | 1.16× |
| 256³ | 7.60 | 9.80 | 1.29× |
The crossover exists on Zen 3, at about 40³, where §4 says it does not exist at any resolution. And
SN/MC at 256³ has gone 5.43× (M-282) → 1.29×, against the 3.72× M-45 recorded and the 2.65× it
attributed to the M5.
Nothing about the machine changed. A-023 made the dual mesher's loop axis a const-generic parameter and A-024 forced the row length odd; together 4.26× on the dual path with byte-identical output (M-285, M-287). The comparison's most-quoted conclusion inverted because one member of the family got optimised, not because anything was measured better or measured elsewhere.
So the published claim was never about the algorithms. "Surface Nets is slower than Marching Cubes" was a measurement of one implementation of Surface Nets at one moment, and it read as a statement about the method — including to us, who wrote it. ✗14 was folklore that measurement falsified; §4 is measurement that our own optimisation falsified, which is the same failure one level up.
What survives, and it is the part worth keeping. Surface Nets' per-sample cost still rises with resolution — 7.96 ns at 32³ to 9.80 at 256³, a 23% rise — while Marching Cubes' falls and then flattens, 9.24 → 7.60. That shape is unchanged by the 4.26× and is what M-21 and M-286 identify as a cache term. The shape is the finding; the ratio never was.
Scope, stated rather than implied. family.csv is sphere, f32, one machine. §4's wording is
"on every field measured, on both machines", and neither half of that is currently re-derivable: the
eight-field authority is shootout.csv, whose timing column the document itself disclaims as noisy,
and the Apple half is stale and blocked on a quiet machine (M-005). The honest current statement is
one field, one scalar, one machine — which is a weaker claim than the one being retired, and is the
point.
Incidental, and it is a large number nobody has quoted. subgrid_marching_tetrahedra runs at
1,553–1,704 ns/sample across the same sweep — 200× Marching Cubes, and roughly 100× classic
Marching Tetrahedra. M-98 measured 70× against classic MT at a different sampling resolution; this is
the same constant seen on the current binary.
Would be shown wrong by: a re-run in which the crossover is absent again, which would mean 40³ is noise rather than a crossing — the two curves are within 4% of each other from 16³ to 48³, so the location is soft even though the inversion at 256³ is not.
✗25 — "Marching Cubes is the only one of the family in the good corner of manifold × intersection-free"
Believed because: M-53 measured it, and it is the headline of
docs/research/2026-08-13-measured-comparison.md §1 — "the algorithm the folklore treats as the crude
baseline is alone in the good one." It was a real measurement, faithfully transcribed, and it was
already wrong when the document quoted it.
Falsified by the detector it was measured with (R-026). 99415af, 2026-08-14 — one day after the
document was written — rewrote validate::self_intersection's straddle test, and its own commit
message says what that cost: "A triangle merely touching another's plane was being counted as a
transverse intersection, which inflated a metric this repo quotes." all_above/all_below became
one straddles, requiring vertices strictly on both sides of the other's plane, and the coplanar
branch moved ahead of it.
Marching Tetrahedra's 3.405 per 1k on csg_difference was that false positive, and it is the whole
of M-53's case against MT. The mechanism fits the method exactly: MT splits each cell into six
tetrahedra that share faces, so tangential triangle-plane contact is not an edge case for it, it is
the common case. Measured now, and also in the CSV committed at T-011 on 2026-08-15, Marching
Tetrahedra has zero self-intersections on every field at every grid.
The good corner has three occupants, not one. Eight fields × two grids, docs/measurements/shootout.csv:
| algorithm | non-manifold edges | worst self-int / 1k |
|---|---|---|
| marching cubes | 0 | 0 |
| marching cubes + decider | 0 | 0 |
| marching tetrahedra | 0 | 0 |
| surface nets | 747 | 0 |
| dual contouring | 747 | 29.745 (noise_cavity) |
| manifold dual contouring | 90 | 45.232 (noise_cavity) |
| subgrid marching tetrahedra | 446 | 0 |
Two further things the eighth field changed, neither of which the document carries. noise_cavity
is the worst field in every column for every method — it was added at A-002e precisely because
the other seven cannot reach an interior ambiguity (M-208). And manifold_dual_contouring is no longer
the entry that takes the zero: 90 non-manifold edges, all of them noise_cavity, which is ✗19.
Self-intersections appear only at 33³ and never at 65³ — all six non-zero rows are the coarse grid, for both duals. Refining removes them, which is M-15's mechanism (any feature thinner than one cell forces two sheets through it) seen in a third place after M-60's falling manifold-split rate.
The method failure is the retrievability one, and this repo has a rule for it. The defect was found, fixed, and its consequence for a quoted metric was written down — in a commit message. M-53 was never amended and the research document went on saying it for two days. "A result only in a commit message is not retrievable in six weeks" is the definition-of-done clause that exists for exactly this, and it was applied to the result of a ticket and not to the fallout of a fix.
Would be shown wrong by: a transverse self-intersection in Marching Tetrahedra output that the current straddle test misses — which would mean the fix over-corrected and the metric is now deflated rather than inflated. The tangential-contact exclusion is the module's stated contract, so that would be a contract question rather than a bug.
V-38 — the published AR>4 and sliver figures are not a baseline this crate can be measured against, and one of them is misattributed (T-026)
V. Read directly from FlexiCubes (Shen et al., 10.48550/arXiv.2308.05371), Fig. 15, against
docs/research/2026-08-10-meshing-algorithm-catalog-v2.md §10 and against T-026 as this repo first
wrote it.
The misattribution first. The catalog's table has a row "Aspect ratio >4 | MC 11.46%" and
"Slivers <10° | MC 11.82%". In the paper those two numbers are on the row labelled MC + Reg.
— Marching Cubes with the equilateral-edge regularisation loss applied. That is not plain Marching
Cubes, and the paper's own Fig. 16 exists to show what the regulariser does: "MC and DMTet lose details
in the local geometry."
The deeper problem, and it is the one that matters. Every figure in that table comes from a
differentiable-rendering optimisation loop — Source A is 79 Myles shapes under depth + silhouette +
SDF loss for 1000 iterations; Source B is 75 ThreeDScan shapes under mask + depth + normal loss. The
mesh is extracted from a learned signed distance field that the loop has been bending for a thousand
steps. This crate meshes analytic fields on a uniform grid. A learned SDF's level set is far less
regular than sphere's, so the triangle-shape statistics are properties of that field, not of
Marching Cubes.
So T-026's premise as first written is wrong and is corrected here before anything was built on it.
It said "without these two columns this crate's comparison cannot be read beside any of those tables."
Matching the definition makes the column readable; it does not make the values comparable, and
publishing this crate's sphere AR>4 next to FlexiCubes' 2.93% would be exactly the
one-scene-number error this repo has now catalogued five times (M-56, M-60, M-136, ✗14, M-308).
What is still worth having, unchanged: AR>4 and min-angle<10° are the two quantities that line of work reports, so emitting them in the same definition lets a reader convert rather than guess. The comparison T-026 can honestly make is within this crate — seven extractors on one fixture — which is the same shape as every other table in the head-to-head.
The definition is pinned to a tool rather than to a formula, and that is the lead to follow. FlexiCubes' Fig. 15 names PyVista as the measurement tool, which wraps VTK's Verdict library, so the definition to match is Verdict's triangle aspect ratio rather than any of the three plausible textbook forms (longest edge ÷ inradius, circumradius ÷ inradius, longest edge ÷ shortest altitude). Confirm it from Verdict before implementing — rule 5, and the whole point of the ticket is that a differently computed ratio is an incomparable column.
Would be shown wrong by: a plain-Marching-Cubes AR>4 figure in either paper, measured on a non-optimised field, which would restore the baseline this entry withdraws.
V-39 — the comparable triangle-quality baseline is Grosso & Zint's, not FlexiCubes', and it comes with a prediction (T-026)
V. Read from Grosso & Zint, A parallel dual marching cubes approach to quad only surface
reconstruction (10.1007/s00371-021-02139-w, in corpus), §5 and Table 7 — found while looking for the
Verdict aspect-ratio definition V-38 said to pin.
The metric is one line and it is cited rather than invented. "Quality of triangles is computed using the mean ratio metric"
q_tri = 4√3 · A / Σᵢ lᵢ²
"where A is the area of the triangle, and lᵢ is the length of their incident edges [13, 33]." It is
1 for equilateral and 0 for degenerate, so it is a normalised distribution rather than a
threshold count — no > 4 cutoff to match, which is exactly the fragility V-38 flagged.
This baseline is comparable where FlexiCubes' is not, and the difference is the whole point of V-38: Grosso & Zint mesh uniform grids of synthetic, CT and MRI volumes with no optimisation loop and no learned field, and they report MC, TMC and DC by name — three of this crate's seven extractors.
| dataset | DMC | DMCS | DC | TMC | MC |
|---|---|---|---|---|---|
| Skull | 0.83 | 0.82 | 0.82 | 0.69 | 0.69 |
| Body | 0.81 | 0.78 | 0.80 | 0.67 | 0.67 |
| Skeleton | 0.83 | 0.81 | 0.81 | 0.67 | 0.67 |
| iWP | 0.84 | 0.82 | 0.86 | 0.65 | 0.65 |
| gen2 (64³/128³/256³) | 0.87 | 0.82–0.83 | 0.84 | 0.71 | 0.71 |
The sharpest thing in the table is a column pair, and it is a prediction this crate can test
directly. MC and TMC are identical to two decimals on every one of the seven rows —
0.69/0.69, 0.67/0.67, 0.67/0.67, 0.65/0.65, 0.71/0.71/0.71. The paper gives the mechanism in its own
words: both "place their vertices also on the trilinear interpolant but along the voxel edges not
within the voxel cells." Topological correction does not move triangle shape, because it changes
which crossings are joined and not where they are. This crate has that exact pair — marching_cubes
and marching_cubes+decider — and the shootout already shows them emitting identical vertex and
triangle counts on most fields.
A second axis comes free and this crate has never measured it: irregular vertices, valence ≠ 6 for a triangle mesh, reported as a percentage. MC sits at 44–60% across their datasets and DMC at 24–54%.
gen2 is the row to compare against, because it is synthetic rather than scanned and MC scores
0.71 at 64³, 128³ and 256³ alike — a resolution-independent constant, which is what a comparison
against this crate's analytic fields wants.
So T-026's metric is decided by evidence rather than taste, and it is not the one the ticket was written around. Mean ratio, from a uniform-grid isosurfacing paper covering three of our extractors, beats AR>4 from a differentiable-rendering paper whose values V-38 already withdrew. The Verdict definition remains worth having only if someone wants to cross-read the neural line's tables, which V-38 says is a conversion aid and not a comparison.
Would be shown wrong by: this crate's Marching Cubes measuring a mean ratio far outside 0.65–0.71 on a smooth analytic field, which would mean the metric is not implementation-independent and the baseline is not usable after all — a real possibility, since their MC is somebody else's code and the field is not ours.
P-22 — registered for T-026, before the metric was implemented
What V-38 and V-39 leave. The ticket was written around FlexiCubes' AR > 4, and that baseline is
withdrawn: those figures come from a differentiable-rendering loop on learned fields, and the
11.46% attributed to Marching Cubes in this repo's own catalog is the paper's MC + Reg. row (V-38).
V-39 replaced it with Grosso & Zint's mean ratio, from a paper that meshes uniform grids and
reports MC, TMC and DC by name:
q = 4√3 · A / Σᵢ lᵢ² 1 for equilateral, 0 for degenerate
The prediction is theirs, not ours, and that is what makes it worth registering. Their MC and TMC columns agree to two decimals on all seven rows — 0.69/0.69, 0.67/0.67, 0.67/0.67, 0.65/0.65, and 0.71/0.71/0.71 — and they state the mechanism: both "place their vertices also on the trilinear interpolant but along the voxel edges not within the voxel cells." This crate has that exact pair.
H, clause 1.
marching_cubesandmarching_cubes+decidermeasure the identical mean ratio on every reference field, because a face rule changes which crossings are joined, not where they are.H, clause 2. This crate's Marching Cubes lands inside 0.65–0.71 on a smooth analytic field — the band their MC occupies, and their
gen2figure is resolution-independent at 64³, 128³ and 256³.
Falsified by the two Marching Cubes entries differing at all, which would mean the face rule moves geometry rather than only connectivity and would contradict the mechanism the paper states for its own two columns. Or a mean ratio outside 0.65–0.71 on a smooth analytic field, which would mean the metric is not implementation-independent and the published baseline cannot be compared against.
Clause 2 is the one expected to be interesting, and it is registered as a real risk rather than a
formality. Their MC is somebody else's code, measured on somebody else's fields — gen2 is a
synthetic volume this repo has never seen. Every cross-source comparison this project has attempted
has needed an amendment (✗7, ✗8, M-45's withdrawn cross-machine figure, M-51, M-55). A band borrowed
from another implementation is exactly that shape again, and registering it as the prediction is the
only way the borrowing gets tested rather than assumed.
Records field, extractor, samples_per_axis, mean_ratio, irregular_vertices,
referenced_vertices, triangles.
Both metrics are recorded, never gated — the standing degenerate_triangles already has, and for
the same reason: Marching Cubes emits slivers wherever a grid corner sits near zero, and that is the
algorithm rather than a defect.
One caveat carried in before the numbers. Irregular means valence ≠ 6, which is their definition
and is written for closed medical volumes. Every boundary vertex on an open field is irregular by
construction, so gyroid and fbm_terrain will read high for a reason that has nothing to do with
triangle quality. The count is reported raw to match their definition, and the caveat belongs on the
column rather than in a correction later.
M-309 / P-22 — FALSIFIED on both clauses, and the first one fails for a reason sharper than the hypothesis (T-026)
M. cargo bench --bench experiment_p22, docs/experiments/p-22.csv. Eight reference fields × seven
extractors × [17, 25, 33], Ryzen 9 5900X. Metric: Grosso & Zint's mean ratio
q = 4√3·A / Σᵢlᵢ², verified in validate::tests against closed forms — exactly 1 for an
equilateral triangle and exactly √3/2 for a right isosceles one — before any mesh was measured.
Clause 1 — "the two Marching Cubes entries measure identically" — FALSIFIED, 9 of 24 pairs differ. The 9 are not scattered.
| field | MC vs MC+decider |
|---|---|
sphere, torus, box_exact, csg_difference, thin_plate |
bit-identical, all three resolutions |
gyroid |
differs, max 0.0030 |
fbm_terrain |
differs, max 0.0014 |
noise_cavity |
differs, max 0.0292 |
The mechanism H proposed is right and its conclusion does not follow from it. The asymptotic decider genuinely moves no vertex — both entries place the crossing at the root of the interpolant along a grid edge, and five of the eight fields come out bit-identical, which is that half of H confirmed exactly. Note what bit-identity proves and what it does not: it says the decider resolved every ambiguous face on those fields the same way the default table does, which is implied by having no ambiguous faces but does not require it. But the rule changes which triangles exist, and mean ratio is a property of triangles, not of vertices. Same points, different triangulation, different shape statistics. H conflated "does not move geometry" with "does not change the mesh", and the five identical fields are what make the distinction visible rather than arguable.
The published table is reconciled rather than contradicted, and the arithmetic is the reconciliation.
Grosso & Zint report MC and TMC agreeing to two decimals on all seven rows. gyroid's 0.0030 and
fbm_terrain's 0.0014 round away at two decimals. Only noise_cavity's 0.0292 would show at
their precision — and that is the field A-002e added because none of the others produces a cell with an
interior ambiguity (M-208). Their datasets are medical scans and a synthetic volume; nothing says any
of them is as ambiguity-rich as noise_cavity. Two-decimal agreement is evidence of a small
difference, not of no difference, and this is the second time in two days that a published agreement
turned out to be a rounding window (after ✗25's inflated metric).
Clause 2 — "our Marching Cubes lands inside their 0.65–0.71" — FALSIFIED, 3 of 6 rows outside, all above.
| 17³ | 25³ | 33³ | |
|---|---|---|---|
sphere |
0.7785 | 0.6920 | 0.7131 |
torus |
0.7039 | 0.7510 | 0.6884 |
And the resolution-independence does not reproduce either. Their gen2 is flat at 0.71 across 64³,
128³ and 256³; sphere here goes 0.7785 → 0.6920 → 0.7131, non-monotone. So the borrowed band fails in
both of the ways P-22 registered as the risk, and this is the sixth cross-source comparison in this
project to need an amendment.
What does transfer is the ordering, and only partly. Their DC (0.82–0.86) beats their MC (0.65–0.71) on every dataset. Here, averaged over the three resolutions:
| extractor | sphere |
torus |
box_exact |
thin_plate |
gyroid |
fbm_terrain |
noise_cavity |
|---|---|---|---|---|---|---|---|
| marching cubes | 0.728 | 0.714 | 0.858 | 0.866 | 0.687 | 0.691 | 0.688 |
| surface nets | 0.814 | 0.797 | 0.863 | 0.743 | 0.795 | 0.770 | 0.758 |
| dual contouring | 0.815 | 0.736 | 0.845 | 0.743 | 0.727 | 0.600 | 0.621 |
| marching tetrahedra | 0.674 | 0.675 | 0.250 | 0.499 | 0.652 | 0.652 | 0.637 |
Surface Nets beats Marching Cubes on all eight fields. Dual Contouring beats it on the smooth ones and
loses on the rough ones — 0.600 against 0.691 on fbm_terrain, 0.621 against 0.688 on
noise_cavity. The QEF places a vertex to fit planes, and where the field has no feature to fit it
places it badly; Surface Nets' centroid does not have that failure mode. The published claim that the
dual is better is a claim about smooth data.
The largest number in the table is the one nobody was looking for. Marching Tetrahedra measures
0.250 on box_exact and 0.322 on csg_difference — against Marching Cubes' 0.858 and subgrid
Marching Tetrahedra's 0.862 on the same field. A 6-tetrahedron decomposition of a cube cuts an
axis-aligned flat face along tet diagonals, and the triangles that result are needles. Its accuracy on
that field is the best of the primal methods (M-55, box_exact 5.103e-2 against Marching Cubes'
7.217e-2), so this is a case where accuracy and triangle quality point in opposite directions by a
factor of three.
Would be shown wrong by: a field on which the decider changes the mean ratio while changing no triangle, which would mean the difference is arithmetic rather than combinatorial and would break the mechanism stated above. The five-versus-three split itself is not at risk — it is the measurement.
V-40 — Open SciVis Datasets is HTTP-only, and the publisher's own SHA-512 is what makes that fine (M-006)
V. Measured, not assumed. klacansky.com resolves (178.63.98.254), answers on port 80 with 200,
and refuses the connection on port 443 — openssl s_client reports connect:errno=111, a refusal
rather than a timeout or a certificate error. Egress from this machine is not the cause: github.com
and google.com both answer 200 over HTTPS in the same run.
So there is no HTTPS URL to prefer and nothing to fall back from, which is the one-path rule satisfied by the world rather than by a decision.
The integrity guarantee comes from the data, not the transport, and it is stronger than a
self-computed hash. Each dataset page publishes a SHA-512. scripts/fetch_volumes.sh verifies
against those, and both files matched on the first fetch:
| file | bytes | published SHA-512 verified |
|---|---|---|
fuel_64x64x64_uint8.raw |
262,144 | yes |
bonsai_256x256x256_uint8.raw |
16,777,216 | yes |
The distinction matters and the script says so: a hash computed from the file it had just downloaded would verify nothing at all.
Two format statements from the site, both load-bearing: "All datasets are in little-endian byte
order" and "Dimensions are width x height x depth (e.g., array[depth][height][width] in C)" — so
x is fastest, which is exactly SampledField's documented layout and Shape3::linearize's
definition. No transpose is needed and none is done.
No blanket licence exists. The site asks "Please, cite individual datasets to support authors", and each dataset carries its own acknowledgement. That is an attribution request, not a redistribution grant, which is the concrete reason the volumes are fetched rather than vendored.
M-310 — on real scanned volumes, Marching Cubes lands inside the published quality band that analytic fields put it outside of (M-006)
M. ./scripts/fetch_volumes.sh && cargo bench --bench volumes,
docs/measurements/volumes.csv. Two Open SciVis uint8 volumes, fuel 64³ and bonsai 256³, isovalue
32, one world unit per voxel, Ryzen 9 5900X. Read through construct::SampledField as f = iso − value,
since the datasets are densities and this crate's convention is negative inside.
| volume | extractor | ms | triangles | non-manifold edges | mean ratio |
|---|---|---|---|---|---|
fuel |
marching cubes | 6.2 | 6,338 | 0 | 0.7006 |
fuel |
surface nets | 6.4 | 6,352 | 8 | 0.7976 |
fuel |
dual contouring | 10.9 | 6,352 | 8 | 0.7228 |
fuel |
manifold dual contouring | 11.5 | 6,352 | 0 | 0.7233 |
bonsai |
marching cubes | 506 | 1,061,042 | 0 | 0.6888 |
bonsai |
marching cubes + decider | 601 | 1,061,438 | 0 | 0.6884 |
bonsai |
marching tetrahedra | 903 | 3,271,492 | 0 | 0.6375 |
bonsai |
surface nets | 608 | 1,057,710 | 1,776 | 0.7957 |
bonsai |
dual contouring | 1,518 | 1,057,710 | 1,776 | 0.6649 |
bonsai |
manifold dual contouring | 1,619 | 1,057,710 | 85 | 0.6650 |
bonsai |
subgrid marching tetrahedra | — | refused | — | — |
This partially rescues P-22's clause 2, and locates why it failed. M-309 recorded our Marching Cubes
outside Grosso & Zint's 0.65–0.71 on analytic fields — 0.7785, 0.7131, 0.7510. On real scanned
volumes it is inside: bonsai 0.6888 and fuel 0.7006. Their band was measured on CT and
simulation data, and it reproduces on CT and simulation data. The band is a property of the input class,
not of the implementation, and M-309's falsification was measuring the wrong kind of field — which is
this project's own recurring lesson (M-56, M-60, M-136, ✗14) arriving for the eighth time, now about a
borrowed number rather than one of ours.
Their Dual Contouring does not reproduce, and the asymmetry is unexplained. Grosso & Zint put DC at
0.82–0.86 against their MC's 0.65–0.71; here DC measures 0.6649 on bonsai, below Marching Cubes.
The entry that lands near their DC figure is Surface Nets, at 0.7957. This is M-309's finding on real
data — the QEF places a vertex to fit planes and does badly where there is no feature to fit — and CT
data is rough everywhere. Whether their "DC" is this DC is not established.
Marching Cubes emits zero non-manifold edges on a million-triangle CT surface, as do the decider variant and Marching Tetrahedra. ✗25's three-occupant good corner holds on real data.
The manifold construction earns its keep here in a way the reference fields never showed. Manifold
Dual Contouring takes bonsai from 1,776 non-manifold edges to 85 — a 95% reduction — where on the
analytic fields it was 0 extra vertices on five of seven (M-60). Real scanned data is the input that
construction was designed for, and this is the first measurement in this repo on that input.
The decider fires on real CT data and not on fuel. bonsai gives 533,221 vertices plain against
533,270 with the decider, and 1,061,042 triangles against 1,061,438; fuel is identical on both. That is
M-309's five-versus-three split in a third place: a face rule changes the mesh exactly where ambiguous
faces occur, and quantised CT data has them.
⚠ NO LONGER TRUE — A-028 fixed it (M-317). bonsai meshes: 1,572,901 vertices, 3,138,925 triangles, 232 s, with 483 tetrahedra declined around 33 singular points and reported rather than fatal. What follows is the original observation.
Subgrid Marching Tetrahedra refuses bonsai — "vertex 1 has no normal to derive: a zero gradient,
or no incident area" — while meshing fuel fine at 3.9 s. The error names two possible causes and this
measurement does not separate them. ⚠ SEPARATED AND HALF-FIXED at A-028 (M-316): it is the
zero-gradient branch, the cause is not the plateau guessed below but a local extremum — steep and
exactly symmetric, because u8 quantisation put both neighbours on the same integer — and
SampledField now supplies an exact trilinear gradient instead of inheriting a central difference. The
refusal moved to vertex 3 on a second, one-sided mechanism. Two figures in the table below moved with
it: Dual Contouring on bonsai is now 529,383 vertices / 1,770 non-manifold edges / 0.6443, and on
fuel 0.6876. Manifold Dual Contouring's 85 and Marching Cubes' 0 are unchanged. What is measured: 0.3% of bonsai's voxels within 8 of the
isovalue sit on a 6-neighbour plateau, against 0.0% of fuel's, which is consistent with the
zero-gradient branch and does not establish it. Settling it needs the failing cell printed, which is a
ticket rather than a line here. The refusal is the crate behaving correctly — one path, fail loudly —
and it also means this extractor is unusable on the input class M-006 exists to test.
Would be shown wrong by: a third real volume on which Marching Cubes lands outside 0.65–0.71, which would make the two agreements here a coincidence of two files rather than a property of scanned data.
V-41 — R-022's hypothesis is two problems with different costs, and a voxel lattice is the easy case for one of them (R-022)
V. Read from Durfee, Dhulipala, Kulkarni, Peng, Sawlani & Sun, Parallel Batch-Dynamic Graphs
(10.48550/arXiv.1908.01956, in corpus) §Connectivity, and Acar, Anderson, Blelloch, Dhulipala &
Westrick, Parallel Batch-dynamic Trees via Change Propagation (10.48550/arXiv.2002.05129, the paper
R-022 names).
The asymmetry is stated plainly by Durfee et al. and R-022 does not carry it:
"An insert can cause at most two trees in
Fto be joined to form a single tree.""A delete may split a tree into two, but if there exists another edge between these two resulting trees, they should then be connected together to ensure that the forest is maximal."
An insertion is a union. A deletion needs a replacement-edge search, and that is what the whole sketching apparatus in that paper exists for — "Handling a set of edge deletions, however, is more complex."
Mapped onto what a game actually does, that split is the whole ticket:
| player action | air sublevel set | structure needed |
|---|---|---|
| digging — removing solid | air nodes and edges appear | insertion only; a union-find is enough |
| filling — adding solid | air nodes and edges vanish | deletion; replacement search, the expensive half |
R-022's H — "batched dynamic connectivity sustains a brush-sized edit under 1 ms at 128³" — does not
say which, and the two are not the same measurement. Digging is the common case and is the cheap one;
validate::sealing already builds exactly the union-find that answers it. Filling is where the
polylogarithmic machinery is actually needed, and where the constant factors live.
And the lattice is a good fit for the structure, which is not obvious. The 2025 follow-up
(10.48550/arXiv.2506.16477) records the standing awkwardness of RC-trees: "RC-trees, however, only
directly support trees with constant vertex degree. Prior work has had to apply ad-hoc techniques to
simulate trees with higher degree." A 6-connected voxel air graph is bounded degree, so the
restriction that forces ad-hoc work on social and web graphs costs nothing here — and it makes the
bounds deterministic rather than randomized, per that paper's Theorem 1.1. R-022's claim that
nobody has run these structures on a voxel lattice is a claim about a case that suits them better than
the ones they were benchmarked on.
The bound to measure against, from the paper R-022 names: a batch of k edge insertions or deletions
in O(k log(1 + n/k)) work and O(log² n) span. At n = 128³ ≈ 2.1M and a brush-sized k ≈ 10³, the
log(1 + n/k) factor is about 11, so the predicted work is ~10⁴ units — which is what makes the
1 ms target plausible and is the number the harness should be read against rather than a bare stopwatch.
Consequence for the ticket: it needs splitting before measuring, and the pre-registration must name which half it predicts. Measuring digging and reporting it as "dynamic connectivity" would be the easy half wearing the hard half's name.
P-23 — registered for R-022a, before the harness was written
What V-41 leaves. R-022 asked whether batched dynamic connectivity sustains a brush-sized edit under
1 ms at 128³, and V-41 found that is two questions. Digging removes solid, so air samples appear —
insertion only, and Durfee et al.'s "an insert can cause at most two trees in F to be joined" means a
union-find is the entire structure. Filling makes them vanish, needs a replacement-edge search, and is
R-022b.
This registers the easy half, and says so. Measuring digging and reporting it as dynamic connectivity would be the easy half wearing the hard half's name.
H. At a fixed brush radius, the number of union operations an incremental insertion-only update performs is constant as the lattice grows through 33³, 65³ and 129³ — so unions per newly-air sample stays inside a narrow band and never exceeds 6, the degree of the lattice — while a full rebuild's union count grows as
n³.
Falsified by the incremental union count growing with n³ at fixed brush size. That is R-022's own
stated falsifier, and it would close the whole direction rather than only this half. And separately
by unions per dirty sample exceeding 6, which would mean the harness is visiting something other than
the six incident lattice edges and is measuring its own traversal rather than the repair.
The second falsifier is the one that earns its place, and it is E-208's rule in a new costume: the
first arm can only fail if the world is a certain way, while the second fails if the instrument is.
A harness that walked a 26-neighbourhood, or re-visited each edge from both ends, would produce a
beautifully flat curve against n³ and would still be wrong — flat is the answer H wants, so a flat
reading is exactly where a bug would hide.
Counted, not timed. Union calls are integers and identical on every machine, so the gate is a count and the wall-clock is printed beside it — ✗24's rule applied before the fact for once, rather than after a release failed on it.
Records samples_per_axis, dirty_samples, incremental_unions, rebuild_unions,
unions_per_dirty.
The number to read the result against is the paper's, not a stopwatch. Acar et al. bound a batch of
k updates by O(k log(1 + n/k)) work; at n = 128³ ≈ 2.1M and a brush-sized k ≈ 10³ the logarithmic
factor is about 11. H is the stronger claim that for insertions alone the factor is a constant
under 6 rather than logarithmic — which is what a union-find buys and what a general dynamic-trees
structure has to pay for because it also supports the deletions R-022b needs.
M-311 / P-23 — HELD on both clauses that were about the world, and the clause about the comparison was wrong (R-022a)
M. cargo bench --bench experiment_p23, docs/experiments/p-23.csv. A solid lattice at 33³, 65³
and 129³; one spherical brush of radius 6, identical at every resolution; isomesh::connectivity::Air.
Ryzen 9 5900X. Union calls are integers, so every count here is machine-independent.
| n | samples scanned | dirty | incremental unions | rebuild unions | per dirty | incr ms | rebuild ms |
|---|---|---|---|---|---|---|---|
| 33 | 35,937 | 925 | 4,872 | 2,436 | 5.27 | 0.028 | 0.2 |
| 65 | 274,625 | 925 | 4,872 | 2,436 | 5.27 | 0.032 | 1.3 |
| 129 | 2,146,689 | 925 | 4,872 | 2,436 | 5.27 | 0.051 | 5.3 |
Clause 1 held exactly. The lattice grows 59.7× and the incremental union count does not move by one: 4,872 three times. Repair after a dig is a function of the edit, and of nothing else.
Clause 2 held. 5.27 unions per newly-air sample, under the lattice degree of 6 at every resolution. The instrument is visiting the six incident edges and not a wider neighbourhood, which is what that falsifier existed to check — and it is the arm that would have caught a bug hiding behind the flat curve clause 1 wants.
Clause 3 — mine, and false. P-23 says "while a full rebuild's union count grows as n³." It does
not. It is flat at 2,436, because a union-find build unions only air-air edges and the air volume
is the brush, which is fixed. The comparison the hypothesis proposed does not exist, and one minute of
arithmetic before registering would have found that.
What actually grows is the scan, and that is the real result. A rebuild must visit 2,146,689
samples to discover that 925 changed — 2,321 samples touched per sample that mattered. The union work
was never the n³ term; the search for what to union is. In wall-clock: 0.051 ms against 5.3 ms at
129³, a 104× advantage, and the gap widens with the lattice while the incremental side stays flat.
The 2× between the columns is the two traversals, and it is not a defect. build visits three
forward edges per air sample so each lattice edge is seen once; dig visits all six, because a
newly-air sample's backward neighbours are not in the dirty set and will never visit it. 4,872 = 2 ×
2,436 exactly.
What this does and does not establish. It establishes the digging half — R-022's "most digging does not alter connectivity" is now measured rather than asserted, and edit-proportional repair is real in the insertion direction. It establishes nothing about filling, which needs deletion and a replacement-edge search (V-41), and is R-022b. A union-find has no deletion at any price, so the structure that answers this half cannot be extended to the other one — R-022b is a different data structure, not a longer version of this.
Would be shown wrong by: a brush that straddles two existing components at a scale where the
union-find's path compression matters — the counts here are all from a single connected cavity in solid
rock, and merges is therefore close to unions. A field with many small pre-existing cavities would
exercise the find path harder without changing the union count, which is a different measurement rather
than a contradiction.
AMENDED 2026-08-17 (R-022b, ✗26). The claim survives; the instrument does not. Adding fill forced
the union-find to go flat — every sample pointing directly at its component id — because a
path-compressed forest cannot absorb deletion (✗26). Under flat labels there is no such thing as a
"union call": the quantity this row reports stops naming anything that exists, and Repair.unions
and Repair.merges become relabel counts.
The finding itself is unharmed. This row's claim is that repair is proportional to the edit and not to the lattice, and its benchmark digs a brush into a solid lattice — one component growing, so the flat-label cost is one write per newly-air sample and the edit-proportionality is exactly as measured. What changed is the unit, from union calls to relabels.
What is genuinely new, and is not measured here. Flat labels give dig a worst case this row never
exercised: breaking through into a large cave relabels the smaller side. Union by size bounds that
to log₂ n relabels per voxel amortised — but amortised is the wrong statistic for the frame the
breakthrough lands on (M-124), which is why repair became budgeted rather than synchronous. This row
does not measure a breakthrough and should not be read as bounding one.
The row is kept rather than restated because the gap between what was measured and what the quantity turned out to be is itself the data. A silently vanished metric is the thing that gets rediscovered in four months.
V-42 — R-023's quantity does not exist as stated, and the one that does is a decision margin rather than a persistence (R-023)
V. Read from this crate's own marching_cubes::interior, against Edelsbrunner, Letscher &
Zomorodian (10.1007/s00454-002-2885-2, in corpus) and Kissi, Pont, Levine & Tierny
(10.48550/arXiv.2407.12399, in corpus, the paper R-023 names). Done before registering, which is
the P-23 lesson applied.
The good news first, and it is better than the ticket hoped. Interior::test() is not a table
lookup. It is a sign test on a value: Joined iff saddle(t) > 0 for some t in the sweep. So a
thresholded version is not a replacement for the decider — it is a one-parameter family containing
it, with ε = 0 recovering the published test exactly. R-023's H says a persistence threshold
"reproduces MC33's topology on the fields where MC33 is agreed correct"; on this construction that
clause is true by construction rather than by measurement.
The bad news, and it is the arithmetic the ticket did not do. saddle(t) = numerator(t) /
denominator(t), and pole() exists precisely because the denominator has a root in (0, 1) on
some configurations. So max_t saddle(t) is unbounded — +∞ — on exactly the cells Custodio's
correction is about, which are exactly the cells R-023 exists to resolve. The naive margin does not
exist where it is needed. This crate's own doc comment says why: "as the sweep approaches pole the
saddle runs off to infinity and returns from the other side. A point that leaves [0, 1]² has left the
face, which is why the value there can change sign without the numerator doing anything."
What is bounded and meaningful is the body-saddle value of the trilinear interpolant. F(s) at an
interior body saddle is a genuine critical value, has the field's units, and is the value at which
this cell's topology changes as the isovalue sweeps — which is the quantity a filtration is about.
BodySaddles::of already locates s and reports which saddles are interior; only a trilinear evaluator
is missing, and that is eight terms.
Now the honest scoping the ticket demanded, and it is a narrowing. Persistence pairs a creator
with a destroyer, both critical points, and reports the lifetime between them. |F(s)| pairs a
critical value with the isovalue, which is not a critical point. It is therefore not a persistence
pair and calling it persistence without qualification would overclaim — the third such overclaim this
phase has caught before it shipped, after V-38 and V-39.
What it is instead: the decision margin — how far the isovalue would have to move for the interior ambiguity to flip. It has the shape of a persistence (a function-value difference at a topology change) and inherits the reason persistence is worth having (stability under perturbation), and it is a distance-to-a-critical-value rather than a critical-pair lifetime. That is exactly the claim to make, and R-023's own instruction was to claim exactly what is true: "This does not remove the modelling choice — it relocates it." It relocates it into a margin, not into a persistence.
Consequence for the ticket, and it survives intact. Everything R-023 wants — a computable scalar, a
tunable threshold, a stability argument, retiring a disputed 730-entry table in favour of one knob — is
available from F(s). What changes is the name and one line of the pitch.
Would be shown wrong by: a bounded reformulation of max_t saddle(t) that stays finite through the
pole — restricting t to where saddle_position(t) lies inside [0, 1]² is the obvious candidate and
was not pursued, because the body-saddle value is simpler and is already a critical value.
P-24 — registered for R-023, before the harness was written
What V-42 leaves. R-023 proposed thresholding a tunnel's persistence. That quantity does not exist
as stated — max_t saddle(t) is unbounded through the pole, on exactly the cells the ticket is about —
and the quantity that does exist is the body-saddle value F(s), a genuine critical value of the
trilinear interpolant. It is a decision margin, not a persistence pair, and V-42 says why the
distinction is worth keeping.
The claim is structural, and deliberately carries no tuned constant. Interior::test() is
saddle(t) > 0 for some t. If F(s) is the quantity that test is a sign of, the two must agree
wherever Chernyaev's construction is exact — and Custodio's whole correction is that it is not exact
when the sweep's denominator has a root inside (0, 1), because the tracked saddle has left the face.
H.
sign(F(s))agrees withInterior::test()on every ambiguous cell whose sweep has no pole in(0, 1), and every disagreement between them has a pole inside the sweep.
Falsified by a disagreement on a cell with no pole. Chernyaev's quadratic is exact there, so a difference would mean the body-saddle value is not what the interior test is a sign of, and the reframing collapses rather than needing a tolerance. There is no percentage band to hide in, which is the point: after M-309's clause-2 band failed for being pointed at the wrong input class, a structural claim is worth more than a tuned one.
And separately falsified by universal agreement, including on the poled cells. That would mean Custodio's correction is unreachable on this crate's fields and the census cannot discriminate — a null that indicts the fixture rather than the hypothesis, and would send this to constructed cells the way A-021 and M-294 went. Registering that arm is E-208's rule: an instrument that cannot report the interesting case has not reported its absence either.
Records field, samples_per_axis, ambiguous_cells, agreements, disagreements,
disagreements_with_pole, disagreements_without_pole.
What holding buys, stated so it cannot inflate later. Not "persistence resolves Marching Cubes
ambiguity". It buys: the interior decider is the ε = 0 member of a one-parameter family, the
parameter is a margin in the field's own units, and a caller who wants tunnels below a size suppressed
gets a knob instead of a fork. A-002b, A-002i and A-020b are not retired by that on its own — they are
about which topology to emit, and this is about how confidently the cell was classified. The ticket's
"retires three tickets" is the thing most likely to be overclaimed here, and it is not what H says.
M-312 / P-24 — FALSIFIED before it ran, on arithmetic; and the margin that replaces it is bounded by half the field's scale (R-023)
M. Two measurements. cargo test -p isomesh --lib -- the_interpolant_is_zero_at_every_body_saddle
and cargo bench --bench interior_margin, docs/measurements/interior_margin.csv. Ryzen 9 5900X, and
every number here is a count or a ratio of field values, so none of it is machine-dependent.
P-24 is dead and it never reached a fixture. It registered sign(F(s)) at a body saddle as the
decision margin for the interior ambiguity. F is zero at every body saddle by construction — 2.3e-15
worst case over the interior saddles of 200,000 random cells — so the registered quantity is sign(0).
BodySaddles says so in its own doc comment ("the zero level set is assumed") and
BodySaddles::coefficients solves its quadratic "at the zero level set": these are points where the
level set is singular, not where ∇F = 0. A critical point of F has a critical value; a singular
point of F = 0 has value zero.
This is the second clause in this phase registered without checking its arithmetic, after P-23's clause 3, and the second time the check would have taken a minute. The rule earned at P-23 was stated and then not followed, which is worth more than the rule was: a rule that has been written down once has not been applied once. The invariant is now a committed test rather than a hazard, and the test's own doc says which registration it killed.
What replaces it is structural rather than hypothesised. SweptFaces::margin() returns the largest
saddle value the sweep reaches over the candidate points test() already walks, and test() is now
literally margin() > 0 — it calls it. So "the interior decider is the ε = 0 member of a
one-parameter family" is true by construction and cannot drift, which is the strongest form R-023's
first clause could take and needs no census at all.
The open question was whether that parameter means anything, and it does. saddle(t) is a ratio
whose denominator vanishes at the pole, so the margin had no a priori bound — and a threshold on an
unbounded quantity measures the pole rather than the tunnel. Measured over 400,000 random cells per
population, corner values in [-1, 1]:
| population | ambiguous cells | joined | poled | max |margin| | over scale | over half scale | |margin| < 1e-6 |
|---|---|---|---|---|---|---|---|
| continuous | 6,348 | 5,608 | 3,150 | 0.4338 | 0 | 0 | 0 |
| quantum 1/255 | 6,366 | 5,605 | 3,154 | 0.4333 | 0 | 0 | 1 |
| quantum 1/16 | 6,377 | 5,432 | 3,184 | 0.4356 | 0 | 0 | 27 |
| quantum 1/4 | 5,994 | 4,267 | 3,040 | 0.4355 | 0 | 0 | 371 |
Never above half the corner scale, in 25,085 ambiguous cells, and never infinite. The mechanism is
that ambiguity itself supplies the bound: on an ambiguous face one diagonal is strictly negative and the
other is not, so the denominator's four terms add rather than cancel, and AM-GM on the numerator
gives |saddle| ≤ max|corner| / 2. Observed maximum 0.436 against that 0.5. The pole is not exotic —
it is present on half the ambiguous sweeps, 3,150 of 6,348 — and the margin stays bounded through it,
which is the result that makes a threshold in the field's own units meaningful and portable.
Near-degenerate cells are a quantisation phenomenon, which is the third sighting of that pattern.
Margins under 1e-6 go 0 → 1 → 27 → 371 as the quantum coarsens from continuous to 1/4. A
threshold has almost nothing to act on in continuous data and something real to act on in quantised
data, exactly as M-220 and M-232 found for singular faces, and exactly where M-310's real u8 volumes
live.
What this does not establish, stated because the ticket invites the overclaim. Nothing here says a
threshold reproduces MC33's topology, retires A-002b, A-002i or A-020b, or resolves any ambiguity. It
says the decider is the sign of a bounded scalar, and that the scalar is bounded by half the field's
scale on the configurations it is defined for. R-023's remaining half — what a non-zero ε does to the
emitted topology, and whether the differences land only where published algorithms disagree — is
unmeasured and is a hypothesis that can now be registered against a quantity known to exist.
Would be shown wrong by: an ambiguous sweep whose margin exceeds half the corner scale, which would break the AM-GM reading and mean the bound is empirical rather than structural.
M-313 — R-023's hypothesis is falsified: a margin threshold acts away from where the published algorithms disagree (R-023)
M. cargo bench --bench interior_margin, docs/measurements/interior_margin.csv and
docs/measurements/interior_margin_epsilon.csv. 400,000 random cells per population; the disagreement
set is SweptFaces::test() != chernyaev_numerator_test(), which is the set on which the corrected
and uncorrected published constructions differ.
R-023's H, verbatim: "a persistence threshold reproduces MC33's topology on the fields where MC33 is agreed correct, and differs only on cells where the published algorithms disagree with each other." The second clause is false, and not marginally.
| ε (relative to corner scale) | flipped by the threshold | disagreeing | both | expected if independent |
|---|---|---|---|---|
1e-1 |
1,818 | 1,005 | 156 | 287.8 |
1e-2 |
81 | 1,005 | 2 | 12.8 |
1e-3 |
3 | 1,005 | 0 | 0.5 |
1e-4 |
0 | 1,005 | 0 | 0.0 |
The overlap is smaller than chance at every ε — 0.54×, 0.16×, 0 against independence. A threshold does not act on the disagreement set; it acts away from it. H predicted the two sets would coincide; they are anti-correlated.
The mechanism is geometric and makes the anti-correlation obvious in hindsight. A small margin is a near-tangency: the swept saddle barely crosses zero, so the interior decision is nearly a coin toss. A disagreement is a pole phenomenon: the sweep's denominator vanishes, the saddle position leaves the face, and Chernyaev's numerator-only test reads a value at a point that is no longer on the surface. Those are different conditions — and a poled sweep's margin is set by the large excursion near the pole, which pushes it away from zero rather than toward it. Measured directly: the largest margin on a disagreeing sweep is 0.406, against a maximum of 0.436 over all sweeps. Disagreeing cells have among the largest margins there are.
Disagreement is common, which is the other thing worth recording. 1,005 of 6,348 ambiguous sweeps —
16% — and 1,342 of 5,994 at quantum 1/4, 22%. Custodio reports the misread "once in 10,000
random 5×5×5 fields"; that is a rate over fields, and this is the rate over the configurations
that can exhibit it at all. The two differ by three orders of magnitude and must not be confused,
which this crate's own how_often_the_correction_changes_the_answer already warned about and is now
quantified over random cells rather than a magnitude grid.
So R-023 is closed by measurement rather than by effort, and the phase's own note applies: "Do not
treat a null as a wasted ticket." What survives is real and shipped — SweptFaces::margin(), the
interior decider being the ε = 0 member of a one-parameter family by construction, and the bound
|margin| ≤ max|corner|/2 (M-312). What dies is the reason the ticket gave for wanting it: thresholding
this scalar is not a route to resolving the cells the published algorithms fight over, and cannot
retire A-002b, A-002i or A-020b. Those cells are decided by the pole, and the margin is largest
exactly there.
What the margin is still good for, stated so the surviving claim is not inflated: suppressing
tunnels whose interior decision is numerically marginal — a knob for a game that would rather have a
closed cell than a coin toss. 371 of 5,994 cells at quantum 1/4 have a margin under 1e-6, against
0 in continuous data, so that knob has something to act on exactly where quantised input lives
(M-220, M-232, M-310).
Would be shown wrong by: a field-driven census — these are random corner tuples, and the eight reference fields might populate the joint distribution differently. The anti-correlation is strong enough at three ε that a reversal seems unlikely, and the mechanism does not depend on the population.
V-43 — R-020's "unobtainable" prior art has been in the corpus since the day before the ticket was written, and it narrows the novelty claim (R-020)
V. R-020 flags its own biggest risk: "the closest prior art — Acar's own Dynamic Well-Spaced Point
Sets (10.1145/1810959.1811011) and Kinetic Mesh Refinement in 2D (10.1145/1998196.1998254) — is
unobtainable through the pipeline and does output-sensitive incremental meshing. Read before
claiming novelty."
Both are obtainable and both are already read into the pipeline. Downloaded 2026-08-13,
converted, and embedded 2026-08-15 with 25 and 23 chunks — the phase spec that calls them
unobtainable is dated 2026-08-16. A third copy is there too: 10.1016/j.comgeo.2012.11.007 is
the 2013 Computational Geometry journal version of the first paper, independently in the corpus. This
is V-29's incident in a second place — "recorded as PAYWALL and in fact indexed in home-still since
2026-08-10" — and the rule it earned is unchanged: check the corpus before recording a source as
unavailable.
What they actually prove, which is more than the ticket allowed for:
| Dynamic Well-Spaced Point Sets | Kinetic Mesh Refinement in 2D | |
|---|---|---|
| update cost | O(log Δ) per insert/delete |
O(log Δ) per certificate failure and per insert/delete |
| optimality | proved time-optimal, Ω(log Δ) lower bound; size-optimal output |
events O(n² log³ Δ), "optimal up to a polylogarithmic factor" |
| self-adjusting | keyword | keyword, and stated: "inspired by recent advances on self-adjusting computation" |
Δ is the geometric spread — diameter over closest-pair distance.
So "self-adjusting computation applied to meshing" is occupied territory, by the author R-020 proposes to build on. The novelty claim cannot be "the first incremental meshing bound". What is genuinely unoccupied is narrower and survives: their input is a point set whose points move, appear or vanish, and their output is a quality mesh of the domain. R-020's input is a scalar field on a fixed lattice whose values change, and its output is an isosurface — a codimension-one object whose combinatorics are decided by sign changes, not by Voronoi cells. Those are different problems and the transfer is not mechanical.
And their lower bound does not bind R-020, for a reason worth stating before anyone reconciles it
wrongly. Ω(log Δ) is proved by exhibiting inputs where an update "require[s] Ω(log Δ) Steiner
points to be inserted to the output". A fixed sampling lattice inserts no Steiner points — the
sampling is given and does not adapt — so the mechanism that forces their lower bound is absent, and
R-020's O(|edit|) with no logarithm is not in tension with it. This crate already has one measured
instance of exactly that: M-311's connectivity repair is O(|edit|) on a lattice with no log factor,
because a union-find is α(n) and the lattice never grows a vertex.
On a lattice log Δ is log n, not a constant — diameter ≈ n√3·h over closest pair h — so had
the bound bound, it would cost a factor of about 11 at 128³. That is the arithmetic, done here rather
than left as a reassurance.
What R-020 may claim after this: the first incremental bound for isosurface extraction from a scalar field. What it may not: priority over self-adjusting computation in meshing, an unqualified "first proved incremental bound", or novelty for change propagation as a technique.
Would be shown wrong by: a paper applying self-adjusting computation or change propagation to a scalar-field isosurface specifically, which is the exact gap this narrows to and which the ticket's own five-database sweep reports as empty.
M-314 — the computation after a local edit is edit-proportional; the output buffer throws that away, and the culprit is a counter (R-020)
M. cargo bench --bench edit_trace, docs/measurements/edit_trace.csv. A sphere sampled at 33³,
65³ and 129³; one spherical brush of radius 5 carved at its equator, identical at every resolution;
Marching Cubes. Every column is a count.
No P- id, and that is deliberate. This phase registered two clauses whose arithmetic died on
contact (P-23 clause 3, P-24 entirely) and got one right by measuring first (M-313). This measured
first. R-020's H — "the recorded trace changes proportionally to the number of cells touched, not to
grid size" — was written in the phase spec before any of this ran, so it is a prediction in prose; it
was never in experiment.rs, so it has no compile-time guarantee and should be read as the weaker
thing it is.
| n | cells | dirty cells | case changed | vertices | buffer moved | geometric moved | first moved |
|---|---|---|---|---|---|---|---|
| 33 | 32,768 | 792 | 432 | 1,758 | 1,348 (77%) | 330 | 414 |
| 65 | 262,144 | 792 | 412 | 6,918 | 4,257 (62%) | 322 | 2,609 |
| 129 | 2,097,152 | 792 | 500 | 27,822 | 15,706 (56%) | 346 | 12,257 |
The computation side holds, and holds exactly. The lattice grows 64× — 32,768 cells to 2,097,152
— and the dirty set does not move by one: 792 cells at every resolution, from 515 changed samples.
That is comfortably inside the 8k = 4,120 bound arithmetic gives, since each sample is a corner of at
most eight cells. Cells whose case index actually changed stay at 412–500 throughout. R-020's
hypothesis is confirmed on this half.
The output side is not edit-proportional and the gap grows with the grid. Vertices that genuinely
appeared or vanished — compared as a set of positions, not by index — are 330, 322, 346: flat,
edit-proportional, and about the size of the dirty set. Vertices whose buffer slot changed are
1,348, 4,257, 15,706: growing, and 56–77% of the entire buffer. The ratio between them goes
4.1× → 13.2× → 45.4×, tracking the vertex count, which is O(n²) for a surface.
So more than half the output is rewritten for an edit that touches 0.038% of the cells, and the
cause is identified rather than inferred: first moved is 12,257 of 27,822 at 129³, and essentially
everything from there on differs. Vertices are appended in scan order and indices name buffer
positions, so a cell emitting a different number of triangles shifts every index after it. A
sequential counter is the classic instability in Acar's sense, and the field's locality does not protect
against it.
The control is what makes both numbers mean anything (E-208). An index-wise diff cannot tell the surface moved from the buffer was reshuffled, and it reports the same large number either way. The set-difference column separates them, and it is the column that turns this from "re-meshing is expensive" into "re-meshing is cheap and the encoding is expensive".
What this says R-020 can claim, with V-43's narrowing already applied. The dependency structure of
Marching Cubes is stable under a local field edit — measured, at three grid sizes, with the dirty set
constant. What is not stable is the crate's output encoding, and that is a fixable property of the
implementation rather than of the algorithm: the crate already names vertices stably internally — the
edge cache is keyed on (lower sample, axis) — and then discards that naming when packing the buffer.
Would be shown wrong by: an edit that changes the case of cells far from the brush, which would
break the 792 constant. The sphere is smooth and the brush is compact; a field with long-range structure
through one cell — a thin sheet, noise_cavity — is the case that could differ, and was not run.
M-315 — R-025's 20% is above the ceiling on any vertex placement, measured before a placement rule was written (R-025)
M. cargo bench --bench placement_ceiling, docs/measurements/placement_ceiling.csv. The two
smooth reference fields that publish an exact distance — sphere and torus — at 17³/33³/65³/129³,
Marching Cubes and Dual Contouring. Distances are closed form for both surfaces, so nothing here
depends on a projection converging.
No P- id. R-025 was not registered, and this is why: the run exists to check its arithmetic
first. Third time this phase, after M-313 and M-314, and against two registrations that died on
contact when the check was skipped.
The method. The reported Hausdorff is the worst mesh sample, and the harness samples vertices and
triangle centroids, so it is max(vertex, centroid). Project every vertex exactly onto the true
surface and the vertex term goes to zero, leaving the centroid term recomputed on perfect vertices.
That residue is the floor no placement rule can go below, because a flat triangle inscribed in a
curved surface deviates at its interior whatever its corners do.
The ceiling is 1.5% to 21.5% across 16 rows, median 12.3%, and exactly one row reaches 20%.
| sphere 17³/33³/65³/129³ | torus 17³/33³/65³/129³ | |
|---|---|---|
| dual contouring | 9.2, 17.4, 10.7, 12.3 % | 12.2, 16.8, 1.5, 8.0 % |
| marching cubes | 21.5, 14.5, 13.8, 9.0 % | 16.0, 12.1, 12.3, 5.7 % |
R-025 predicts ">20% better Hausdorff on smooth fields". That is above the ceiling in 15 of 16 measurements, and the one exception is the coarsest grid of the pair. The hypothesis is falsified by arithmetic, before implementation — and not for the reason the ticket anticipated. It expected Aamari & Levrard's minimax bound to bite, i.e. curvature estimation too noisy at game resolutions. Something more basic is true: there is not 20% of placement error to win.
A structural fact fell out, and it is crisper than the ceiling. Which term is the Hausdorff:
- Dual Contouring: the vertex term, in 8 of 8 rows. Its accuracy is placement-limited.
- Marching Cubes: the centroid term, in 8 of 8 rows. Its accuracy is tessellation-limited.
So curvature-aware placement is aimed at Dual Contouring and cannot help Marching Cubes at all — which the ticket does not distinguish, and which halves the target before the ceiling is even applied.
And the QEF is already trading in the direction a placement rule would want to. Dual Contouring's
centroid error is better than the floor — better than it would be with vertices placed perfectly
on the surface — at 7 of 8 rows, by 2.9–3.6× on sphere and 1.2–1.5× on torus. The QEF does not
try to put a vertex on the surface; it minimises distance to the tangent planes, and that produces
better-centred facets at the cost of worse-placed vertices. Pushing vertices onto the surface would
make the triangles fit worse.
One limit, stated rather than discovered later. This measures the mesh → field direction only.
It reproduces docs/measurements/shootout.csv exactly wherever that direction dominates — Dual
Contouring on both fields, Marching Cubes on sphere, matching to every published digit — and comes out
5% under on torus + Marching Cubes, where the symmetric metric's field → mesh half is larger.
Placement is a mesh → field property, so the ceiling is unaffected; the absolute numbers for that one
row are a slight underestimate.
Would be shown wrong by: a smooth field where the vertex term dominates and exceeds the centroid
term by more than 25%, which would leave room a placement rule could take. Neither of the two fields
that publish an exact distance is such a field, and gyroid — the third R-025 names — publishes none,
so this crate cannot currently produce that counterexample even if it exists.
V-44 — R-021's caveat is contradicted by the paper R-021 is built on, and the cheap half is already delivered (R-021)
V. Read from Agarwal, Arge, Mølhave, Revsbæk & Yang, Maintaining Contour Trees of Dynamic Terrains
(10.48550/arXiv.1406.4005, in corpus), §1.1–1.2, against R-021's own text.
What the ticket says: "Edelsbrunner's 3-manifold Reeb maintenance is O(n) per certificate failure,
asymptotically no better than rebuilding", and "the two 3D results the question hinges on — Tarasov &
Vyalyi 1998 and Safa & Wang 2014 — are both unobtainable."
What the paper says, in its related-work paragraph:
"…of time varying piecewise linear 2-manifolds. This algorithm handles certificate failures in
O(log(n))time, however, they need to process a much larger number of certificate failures since a certificate fails each time any two vertices ofMlie on the same contour. Their algorithm also works for simple 3-manifolds where the Reeb Graph is a contour tree."
Both halves of the caveat are in trouble. A prior algorithm is O(log n) per certificate failure,
not O(n); and it already covers simple 3-manifolds. Its weakness is not the per-event cost the
ticket names — it is the event count, because certificates fail whenever any two vertices share a
contour rather than only on adjacent-vertex swaps. That is a different objection with a different
remedy, and it is the one the 2014 paper's contribution is aimed at.
One thing not resolved, and stated rather than glossed. The quoted sentence is a related-work
paragraph and does not name its subject inside the chunk read, so whether it describes the Edelsbrunner
result the ticket attributes the O(n) to cannot be pinned from here. What is certain is that the
paper R-021 uses as its reframe asserts a prior O(log n)-per-failure algorithm that extends to
3-manifolds, and that is incompatible with "asymptotically no better than rebuilding" however the
attribution resolves.
The 2-manifold restriction on the 2014 paper itself is confirmed, which is the half of the caveat
that holds: its abstract is explicit that h : ℝ² → ℝ and M is a triangulation of ℝ².
Tarasov & Vyalyi is findable. 10.1145/276884.276892, "Construction of contour trees in 3D in
O(n log n) steps", 1998, 60 citations — via CrossRef, with no open download link, so paywalled is
the accurate word rather than unobtainable. Note also what its title says: it is construction, not
maintenance, so it is weaker support for a maintenance claim than the ticket implies.
And the scoping point that matters more than any of this. R-022 called itself "the cheap half of
R-021", and that half is delivered and measured: M-311 has connectivity repair on a lattice at
O(|edit|) with no logarithm, 792 dirty cells constant across a 64× lattice. R-022's own framing is
that the questions a game asks — is this sealed, did I break through, is this a chokepoint — are
single-threshold. A contour tree answers all thresholds, which is strictly more, and nothing
in this phase establishes a consumer that needs it.
Together with M-314 — the extractor's dependency trace is already edit-proportional and the bottleneck is the output encoding (R-027) — the marginal value of contour-tree maintenance for this crate is unestablished rather than small. R-021 is not blocked on evidence about the algorithm; it is blocked on a consumer, and that is a different and more honest reason than the one it carries.
Would be shown wrong by: a game mechanic in this project's own backlog that needs the topology of more than one threshold at once. None is written down.
M-316 — a central difference is identically zero at a local extremum, and quantised data manufactures them (A-028)
M. cargo bench --bench a028_diagnose on bonsai (Open SciVis, uint8, 256³, iso 32), plus the
full suite. The subgrid extractor's refusal of that volume (M-310) is diagnosed and half of it is
fixed.
Which branch fired is decided by the call site, not by the message. Error::DegenerateNormal reads
"a zero gradient, or no incident area" and is raised from two places with different causes —
normals.rs, where a vertex has no incident triangle area, and subgrid/extract.rs:548, where
vec3::length(sdf.gradient(p)) is not positive. Only the subgrid extractor refuses bonsai, so it is
unambiguously the zero-gradient branch. The message obscured what the code already determined.
The cause is not a plateau, and that is the interesting part. M-310 guessed plateaus, on 0.3% of near-isovalue voxels sitting on a 6-neighbour plateau. The three failing corners are steep:
| corner | axis | neighbour / value / neighbour | slopes |
|---|---|---|---|
[24, 19, 35] |
x | 1.0 / −1.0 / 1.0 | −2 / +2 |
| y | 18.0 / −1.0 / 18.0 | −19 / +19 | |
| z | 0.0 / −1.0 / 0.0 | −1 / +1 |
Every failing corner is a local extremum in all three axes, and a central difference is identically
zero at a local extremum however steep the field is around it. The field there is not flat — it is
symmetric, and it is exactly symmetric because u8 quantisation put both neighbours on the same
integer. Steep and symmetric is a sharper failure than flat, and it is the one an eight-corner
analytic form cannot have.
The fix is a bug fix rather than a workaround: SampledField had a closed-form gradient and did not
provide one. It implemented sample only, so it inherited Sdf::gradient's central difference — the
very substitution sdf.rs's own doc comment warns about for &S forwarding, "six times the cost,
O(h²) instead of exact, and nothing anywhere would fail". It now returns the exact trilinear
gradient, checked against a central difference inside cells to 1e-6 on a random field, and the
18 / −1 / 18 shape is a committed fixture.
Counted properly, against the denominator that matters. The extractor evaluates a gradient at a
corner only where the surface passes exactly through it, which corners_on_surface selects. On
bonsai: 16,284 of 529,508 surface-cell corners have value exactly zero — 3%, because u8 data
with an integer isovalue lands on the isosurface constantly, and 16,284 is not an edge case. 33 of
those 16,284 also have a zero gradient, so the isosurface passes through a critical point of the
field and the surface is singular there. Over all surface-cell corners, 1,071 of 529,508 have a zero
gradient; the 33 are the subset the extractor actually asks about.
That reframes what is left. At a point that is both on the surface and critical, there is no normal — not a missing one, an absent one. The extractor is right to refuse; what is in question is only whether 33 singular points should refuse a 16 MB volume, which is a granularity decision rather than a correctness one.
It moved the failure and did not remove it: vertex 1 → vertex 3. A second mechanism, distinct
and now characterised: at a cell corner frac = (0, 0, 0), so the analytic gradient reduces to the
three forward differences alone — c₁₀₀ − c₀₀₀, c₀₁₀ − c₀₀₀, c₀₀₁ − c₀₀₀ — and is zero whenever
those three neighbours match the corner. On quantised data that is common, and it is not a plateau
either: the +-side cell is not uniform at all three residual failures. The subgrid extractor asks
for a gradient at a cell corner, where the interpolant's gradient is one-sided by construction, and
that is where A-028 now sits.
What changed downstream, recorded because M-310's numbers move. Dual Contouring uses gradients in its
QEF, so an exact gradient changes its output on real volumes: on bonsai, 529,488 → 529,383
vertices, 1,776 → 1,770 non-manifold edges, mean ratio 0.6649 → 0.6443; on fuel, mean ratio
0.7228 → 0.6876. M-310's headline is unaffected — Manifold Dual Contouring still takes bonsai
from 1,770 to 85, and Marching Cubes still emits 0 non-manifold edges on a million-triangle CT
surface.
All 688 lib tests pass, golden hashes included, which is the check that this touched nothing on the reference-field path: those fields carry their own analytic gradients and never used the default.
Would be shown wrong by: a failing corner whose three forward neighbours differ from it, which would mean the residual zero has a third cause and the one-sided reading is incomplete.
M-317 — the volume meshes: 483 tetrahedra declined around 33 singular points, reported rather than fatal (A-028)
M. ./scripts/fetch_volumes.sh && cargo bench --bench a028_diagnose, plus cargo bench --bench
volumes. Ryzen 9 5900X. A-028's acceptance, answered.
bonsai meshes. 232.3 s, 1,572,901 vertices, 3,138,925 triangles, 879 non-manifold edges, mean
ratio 0.6770. It previously produced nothing at all.
What was declined, and the split is not decoration:
| tetrahedra skipped | 483 |
of those, Degenerate (gradient exactly zero) |
475 |
of those, IllConditioned (non-zero, below the floor) |
8 |
| sites at a cell corner the surface passes exactly through | 475 of 483 |
The 8 would have been invisible inside a single count. They are a precision problem — a normal exists and its direction is dominated by rounding — where the 475 are a topology one, where no normal exists at all. Different remedies, and folding them together would have let one hide inside the other. Note that 475 is also the on-surface-corner count; this run did not cross-tabulate the two, so their equality is a coincidence of totals until someone checks it.
483 tetrahedra is 33 places, not 483. The scan finds 33 distinct corners that are both on the surface and critical, and a grid corner is incident to at most 8 cells × 6 tetrahedra = 48; 483 / 33 = 14.6 tetrahedra per corner. So the mesh has 33 small clusters of holes, not 483 scattered ones — which is what makes them repairable, and is visible only because the report carries positions.
The design, and the reason each part is there. Sites carry positions: a count can stay at 483
while the sites move, so a count alone is not a regression test, and a caller repairing the mesh needs
to know where. The floor for IllConditioned is relative to the tetrahedron's own slope — its
corner-value spread over the cell size — because an absolute floor on a gradient means a different thing
at every field magnitude and grid spacing, the same reasoning ValidateConfig's thresholds use.
Nothing is substituted: a wider stencil returns the gradient of a smoothed field, which is a
different field, and at a saddle there may be no correct normal at all.
The guidance that means most callers never reach any of this. Integer samples against an integer
isovalue land exactly on the surface constantly — 3% of bonsai's surface-cell corners (M-316) — and a
corner the surface passes through is where this extractor asks for a normal at a grid point. Contour
at a half-offset isovalue (127.5, not 127) and no sample can sit on the isosurface at all, because
a half-integer is unattainable by integer data. It does not remove ill-conditioning and the critical
points are still in the field; it removes the exact zero that fires. Standard practice in volume
rendering, now in the extractor's docs with a test.
A regression the pinned counts caught, and it is the reason they are pinned. Splitting emission into
resolve-then-emit moved shared.insert into the second pass, so two tetrahedron edges meeting at an
on-surface corner stopped collapsing to one vertex (A-014h). The zero-area sliver between them then
stopped looking degenerate and got emitted — the index buffer M-185 says this crate's own validator
calls invalid. It surfaced as the orphan count going 46 → 0, and a falling defect count reads as an
improvement. Without M-203's pinned 46 it would have shipped. Fixed by resolving the within-tetrahedron
repeat before anything reaches the sink.
Two cross-checks that the instrument is measuring what it claims. fuel's output is byte-identical
to before — 9,517 vertices, 18,946 triangles, 8 non-manifold edges, 0.6622 — so the change is a no-op
on data that already worked. And 232.3 s against Marching Cubes' 0.49 s on the same volume is 471×,
against M-308's ~200× on sphere; the constant is larger on real data, which is worth knowing before
anyone plans to use this extractor on a scan.
Would be shown wrong by: a volume where the skipped tetrahedra are not clustered — many distinct singular corners rather than a few — which would make the holes scattered and much harder to repair, and would change the advice this entry gives.
M-318 — a grid-edge naming would close the whole edit-proportionality gap, and the obstacle is not the encoding (R-027)
M. cargo bench --bench edit_trace, docs/measurements/edit_trace.csv. The counterfactual computed
from the value arrays alone, with no API changed and no extractor involved — measure the ceiling
before pricing the break, which is the order that closed R-025 and P-24 cheaply.
The counterfactual, and why it is not circular. A Marching Cubes vertex lives on a grid edge, and
(lower sample, axis) names that edge globally — the crate already keys its edge cache that way and
discards the name when packing. Under such a naming an entry changes only when its edge's crossing
appears, vanishes, or moves, and a crossing moves only when one of the edge's two samples does. So
the column counts edges. It is deliberately not keyed on position: position-keying makes the
answer equal geometric_moved by construction and would measure nothing.
| n | dirty cells | vertices | buffer moved | geometric moved | keyed |
|---|---|---|---|---|---|
| 33 | 792 | 1,758 | 1,348 | 330 | 318 |
| 65 | 792 | 6,918 | 4,257 | 322 | 310 |
| 129 | 792 | 27,822 | 15,706 | 346 | 346 |
Flat, and equal to the true geometric change. 318 / 310 / 346 against 330 / 322 / 346 — the small gap is a definitional one, since a vertex that moves counts twice in the set difference (vanished plus appeared) and once as an edge. At 129³ they are identical, so nothing merely moved there.
So the break would buy the whole gap: 15,706 → 346 at 129³, a 45× reduction, and flat in n where the
packed buffer grows with the O(n²) vertex count. M-314's split — computation edit-proportional,
output not — has no residue once the naming changes. There is nothing else in the way.
But the encoding is not the hard part, and this is the thing to know before scoping. Three shapes, and only the third works:
- Stable order — emit in grid-edge order rather than cell-scan order. Does not help. A
crossing appearing still shifts every index after it; the churn is
O(n²)again. - Index is the edge id, with holes. Stable, and 230× the memory: 3·129³ ≈ 6.4 M slots for 27,822 vertices.
- A persistent edge → slot map, allocating on first use, never reusing, compacted occasionally.
This is the one an incremental engine actually runs — and it is state carried across extractions,
which is a larger change than the index encoding.
extract_intois currently a pure function of its inputs, and this makes it not one.
So R-027 is an architecture question wearing an encoding question's clothes, and X-005's 294 call sites are the smaller half of its cost. The measurement says the prize is real and undiminished; it does not say the shape is cheap.
Would be shown wrong by: a field whose edits change crossings far from the dirty set — the keyed
column is flat here because a brush is compact, and a field with long-range coupling through one cell
would break that. noise_cavity is the candidate and was not run.
M-319 — filling disconnects the air region about one time in six, so R-022b's cheap escape does not exist (R-022b)
M. cargo bench --bench fill_disconnect, docs/measurements/fill_disconnect.csv. noise_cavity
sampled at 33³/49³/65³ — the reference field with real cave structure, which is why it exists (M-208) —
then 200 spherical brush fills of radius 4 at random positions, with the air component count rebuilt
after each rather than maintained. Rebuilding is the point: a maintained count cannot be used to judge
whether maintenance is needed.
The question this was built to answer. V-41 split R-022, and M-311 settled the digging half at
O(|edit|). Filling deletes, and a deletion may split a component and then needs a replacement-edge
search — the expensive half. But that machinery is only earned if deletions actually disconnect
things. R-022's own framing is that "most digging does not alter connectivity"; if filling were the
same, the ticket would collapse from implement dynamic connectivity to detect the rare split and
recompute, which is a much smaller thing.
| n | air samples | fills | changed | split | emptied | changed | air left |
|---|---|---|---|---|---|---|---|
| 33 | 30,120 | 200 | 82 | 49 | 33 | 41.0% | 29.3% |
| 49 | 97,830 | 200 | 38 | 32 | 6 | 19.0% | 67.2% |
| 65 | 227,567 | 200 | 32 | 27 | 5 | 16.0% | 84.5% |
Read the 65³ row and discount the others, for a reason the table makes visible rather than hides. The fills accumulate, so a run that consumes most of the domain is measuring a vanishing field rather than a steady one: 33³ has 29.3% of its air left at the end and its 41% is largely the domain being eaten. 65³ ends with 84.5% and is the least confounded.
So about one fill in six changes connectivity, and the cheap escape does not exist. A
detect-and-recompute design would rebuild once every six edits at O(n³) — which is precisely the cost
R-022 exists to avoid, and at 65³ that is 275,000 samples scanned to repair a brush of a few hundred.
This validates R-022b rather than closing it, which is a different outcome from R-023 and R-025 and
worth saying plainly: three exploratory measurements in this phase killed their tickets, and this one
does not.
Two structures in the change, not one. Splits outnumber emptyings 27:5 at 65³, but both happen: a fill can sever a component in two, or consume a small pocket entirely. A deletion structure has to handle both, and the second is the easy one — a component that vanishes needs no replacement edge.
The rate is a property of the brush-to-feature ratio, not a constant. Radius 4 in a 65³ domain is a large brush — about 6% of the domain per axis — and a smaller one would sever less often. 16% is not universal; what is established is that the rate is tens of percent rather than the fraction of a percent that would justify recomputing.
Would be shown wrong by: a fill sequence on a field with fewer, larger caves, where a brush is small
relative to a passage and severs almost nothing. noise_cavity is deliberately near its own feature
size, which is the adversarial end; a game's caves are usually wider than its brush.
M-320 — the median split sheds one voxel, so the replacement search the literature is built around is answering a question this lattice does not ask (R-022b)
M. cargo bench --bench replacement_search, docs/measurements/replacement_search.csv. Same field,
same brush, same seed and same 200 fills as M-319, so the two tables are the same run seen two ways. The
spanning forest is rebuilt by BFS before each fill and the component labelling rebuilt after it —
M-319's discipline, for M-319's reason: a structure that maintained either could not be evidence about
whether maintaining it is worthwhile.
Two clauses, and only the first had a prediction. M-319 established that R-022b is real. It did not say which deletion structure the lattice needs, and two numbers from the literature decide that.
| n | air | edges deleted | tree edges | free | splits | min side | median side | max side |
|---|---|---|---|---|---|---|---|---|
| 33 | 30,120 | 64,327 | 24,980 | 61.2% | 72 | 1 | 1 | 19 |
| 49 | 97,830 | 105,184 | 38,025 | 63.8% | 33 | 1 | 1 | 47 |
| 65 | 227,567 | 119,179 | 41,966 | 64.8% | 29 | 1 | 1 | 120 |
Clause 1 held, with the deviation explained by the same arithmetic that predicted it. Deleting a
non-tree edge cannot change connectivity, and HDT separates the cases in O(1) from a hash table —
10.48550/arXiv.2411.11781 names this as why HDT stays practical "on dense graphs where most of the
deletions target non-tree edges". For a 6-connected lattice |E| = 3n²(n-1) against a forest of about
|V| = n³, predicting 1 - n/(3(n-1)) — 65.6%, 66.0%, 66.1%. Measured 61.2 → 63.8 → 64.8: below,
and rising toward it. The gap is the air region's own surface, where every voxel touching solid is
missing that edge and so has degree below 6; as the lattice grows the region's surface-to-volume ratio
falls and the measurement climbs toward the closed-form value. So about two thirds of the deletion
work is free, and that is a constant factor of 3 rather than an asymptotic win.
Clause 2 was deliberately left unpredicted, and it is the one that resizes the ticket. D-Tree finds a
replacement edge by running BFS on the smaller component of the split, with "no theoretical
guarantees" and good measured behaviour (10.48550/arXiv.2509.14433, describing [13]). Its cost is
therefore exactly the size of the smaller side. That size is 1 at the median, at every resolution.
The largest observed anywhere is 120 voxels against 227,567 air samples — 0.05% of the domain.
The mechanism is the brush's shape, not the field's. A sphere advancing into a cave mostly strands single fringe voxels — voxels whose only surviving neighbours were themselves inside the brush — rather than severing a passage cleanly in two. The split is real and the search is real; what is absent is the large smaller side that HDT's levelled scheme exists to amortise.
So the structure R-022b needs is not HDT. The O(log n) levels, the pushing of non-replacement edges
down a level, the whole amortisation argument, all exist to bound a search whose cost can otherwise be a
constant fraction of the graph. On this lattice it is one voxel at the median. What that leaves is the
much older technique HDT also uses: alternating BFS outward from the two endpoints of the deleted tree
edge, stopping when either side exhausts, which costs O(smaller side) without needing to know in
advance which side is smaller. No levels, no edge demotion, no amortisation scheme.
The split counts here and in M-319 differ, and that is a different denominator rather than a disagreement. M-319 counted fills whose component count changed; this counts split events — pre-fill components that map to two or more post-fill components. One fill can split twice, and a split coinciding with a pocket vanishing leaves the net count unmoved. Hence 72 against 49 at 33³, where the air is most fragmented, and 29 against 27 at 65³, where it is barely different.
Do not read a growth law off the maxima. 19 → 47 → 120 is an extreme-value statistic over 29–72 samples and more fills would find larger ones. The median is the robust column and it is flat at 1.
Would be shown wrong by: a field whose caves are wide relative to the brush, where a fill can sever a
passage mid-span and shed half a component. noise_cavity at radius 4 is the adversarial end for
frequency (M-319) and may well be the friendly end for size — a brush comparable to the passage width
consumes a junction whole instead of cutting across it. Measuring one wide-cave field would settle it.
P-25 — registered for R-022b, before the structure was written
Pre-registration. crates/isomesh/src/experiment.rs, id P-25. Recorded here and compiled into the
crate before the harness exists, which is the only thing that makes the result falsifiable rather
than narrated.
H. Repairing the air sublevel set's connectivity after a brush fill costs work proportional to
the shed volume — the air samples that leave their component — and not to the surviving component,
nor to the lattice. At a fixed brush radius the voxels the replacement search visits stays flat as
the lattice grows through 33³, 49³ and 65³, while a rebuild's visit count grows as n³.
Two mechanisms, and both are already measured rather than hoped for.
A union-find can absorb deletion. This module's own docs say it cannot — "a union-find cannot do
deletions at any price" — and that is right about the general operation and wrong about the one needed
here. A parent pointer only has to reach the correct root; a filled sample sitting mid-tree is never
queried, because connected gates on air before it walks. So a fill does not have to rebuild a
component: it has to re-root the shed pieces and leave the surviving side untouched. The pieces are
what get re-rooted, and the pieces are small.
And M-320 measured how small. The smaller side of a split is 1 voxel at the median and 120 at the
observed maximum, against 227,567 air samples. That is what makes the levelled HDT scheme — O(log n)
levels, non-replacement edges demoted a level to amortise a failed search — unnecessary on this lattice.
Lockstep search outward from every seed, stopping when all but one frontier exhausts, costs
O(shed) and needs none of it.
Falsified by: visited voxels growing as n³ at a fixed brush size, which would mean the search is
exploring the surviving component rather than the shed pieces — the lockstep stop condition wrong,
and the structure walking exactly the thing it exists not to walk.
Separately and more seriously falsified by any disagreement between the incrementally maintained
components and a full rebuild over the same values: the component count, or any connected answer.
That would mean the structure is fast and wrong, which is worse than slow and right, and it is the
failure a measurement of cost alone cannot see. It gets its own assertion rather than its own benchmark.
Records: samples_per_axis, fills, dirty_samples, seeds, visited, splits,
shed_components, vanished_components, rebuild_visited.
M-323 — the chunk is the bound; the cost is the edited chunk's share of the severed component, and the two differ by 35× (R-028)
M. cd bevy_isomesh && cargo run --example sealed_cave --release, and reproduced as a standalone
check while writing it. Three chunks of 16 cells, two chambers in chunks 0 and 2, a tunnel through
chunk 1, a plug filled at the world origin:
components before = 1 A<->B before = true
plug: 179 samples, 83 dirty (96 already solid), 34 seeds, 138 visited, 1 split
components after = 2 A<->B after = false
one chunk = 4,913 samples
138 visited is 0.028× a chunk. M-322 measured the same operation — sever a passage by filling one plug — at 0.970× a chunk. Same structure, same kind of edit, 35× apart, and nothing about the structure changed between them.
The difference is where the severed component's mass lives. M-322's fixture pinched a cavern that filled the edited chunk, so lockstep separated two large halves within that chunk and walked both. Here the chambers are in chunks 0 and 2 while the plug is in chunk 1, so the pieces the local search separates are two short tunnel stubs. The split between the two large components is then resolved by the boundary graph, whose nodes are components rather than samples, and which costs nothing proportional to the caverns at all.
So M-322's headline needs a distinction it did not draw. "Chunking bounds the search by the chunk" is structural and stands. "A bisect costs about a chunk rebuild" is not a property of chunking — it is a property of M-322's fixture, which deliberately put both halves inside one chunk to be adversarial. The general statement is:
the search costs the edited chunk's share of the severed component, bounded above by the chunk.
This is the second time in this phase that a fixture's own shape was mistaken for a structural property — M-320's one-voxel median was the first, and P-26 carried the correction by predicting separately per fixture. The pattern is now three-for-three with ✗14, M-51, M-56, M-60 and M-40, and it argues for the same remedy each time: run the adversarial fixture and a representative one, and never quote one number for both.
Found by building an example, not by benchmarking. The example exists because AirWorld shipped
with no consumer, and its first consumer immediately produced a number no fixture in the suite did.
That is the argument for CLAUDE.md's "prefer adding an example over adding prose" being about
correctness rather than presentation.
Would be shown wrong by: a chunking where a component's mass concentrates in the chunk being edited — which is exactly M-322's fixture, so this is not a disagreement between the two rows but a statement of what varies between them.
M-322 — chunking makes the bisect bounded rather than cheap, and the advantage is exactly the chunk count (R-028)
M. cargo bench --bench chunked_bisect, docs/measurements/chunked_bisect.csv. Comparative, and
deliberately without a P- id: the bound is not a hypothesis. A lockstep search runs inside one Air
and therefore cannot visit more samples than that Air holds — a property of the construction, asserted
by connectivity::world::tests::a_bisect_visits_no_more_than_one_chunk. What was not settled by
construction is the size of the gap against the unchunked structure, which is what this measures.
The fixture is M-321's: one cavern spanning the world, pinched to a single air voxel at the midplane, and that voxel filled. 32 cells per chunk, so a chunk is 33³.
| arm | chunks | world air | visited | its own rebuild | ratio | × a chunk |
|---|---|---|---|---|---|---|
| single | 2 | 69,696 | 69,696 | 70,785 | 0.985 | 1.94 |
| single | 4 | 139,392 | 139,392 | 140,481 | 0.992 | 3.88 |
| single | 8 | 278,784 | 278,784 | 279,873 | 0.996 | 7.76 |
| single | 16 | 557,568 | 557,568 | 558,657 | 0.998 | 15.52 |
| chunked | 2 | 69,696 | 34,848 | 35,937 | 0.970 | 0.97 |
| chunked | 4 | 139,392 | 34,848 | 35,937 | 0.970 | 0.97 |
| chunked | 8 | 278,784 | 34,848 | 35,937 | 0.970 | 0.97 |
| chunked | 16 | 557,568 | 34,848 | 35,937 | 0.970 | 0.97 |
The single grid visits every air sample it has. 69,696 visited against 69,696 air is not a coincidence: lockstep stops when all but one frontier exhausts, and when the two halves are the same size they exhaust together, so the walk covers both. That is why M-321 measured 1.1× a rebuild and why this arm sits at 0.985–0.998 — the incremental structure buys nothing on this edit, at any world size.
The chunked arm is flat at 34,848 while the world grows 8×. The advantage over the single grid is exactly the chunk count — 16× at width 16 — and it grows linearly with the world, without bound, because one number is constant and the other is not.
What this does not do, stated plainly: it does not make a bisect cheap. 34,848 is 0.970× a chunk rebuild. Inside the middle chunk the pinch still splits it into two equal halves and lockstep still walks both. Chunking converts an unbounded cost into a bounded one, and the bound is "rebuild one chunk" — which is a cost the mesher already pays per edit, so it is now proportional to something the engine has already budgeted for rather than to the size of the world.
So the remedy M-321 named was the right one, and for the reason it gave. HDT's levels bound a replacement-edge search; on a genuine bisect there is no replacement edge, and no search strategy can avoid discovering which side is smaller. Decomposition does not make the discovery cheaper — it makes the thing being searched smaller.
Would be shown wrong by: a component that spans many chunks and is pinched inside one of them, where the split has to propagate through the global graph to many chunks' labels. The graph handles that — its nodes are components, not samples — but this measurement does not stress it, because the fixture's pinch severs a component that only ever needed relabelling within one chunk.
AMENDED 2026-08-17 (M-323). One sentence here is about the fixture, not the structure. "Chunking
converts an unbounded cost into a bounded one" stands. "34,848 is 0.970× a chunk rebuild" is what
this fixture costs, because it deliberately pinches a cavern that fills the edited chunk so both
halves are walked. The sealed_cave example severs a passage between chambers in other chunks and
the same operation costs 0.028× a chunk — 35× less — because the local search separates two tunnel
stubs and the boundary graph resolves the rest. The general form is the edited chunk's share of the
severed component, bounded above by the chunk.
M-321 / P-26 — HELD on the measured distribution, and the adversarial fixture it demanded costs 1.1× a full rebuild (R-022b)
M. cargo bench --bench experiment_p26, docs/experiments/p-26.csv. Two fixtures, because P-26
predicted differently for each and a harness running only the first would have measured M-320's fixture
rather than the structure.
| fixture | n | dirty | seeds | visited | per seed | vs 200 rebuilds |
|---|---|---|---|---|---|---|
| distribution | 33 | 21,299 | 19,019 | 58,837 | 3.09 | 122× |
| distribution | 49 | 32,123 | 32,428 | 96,950 | 2.99 | 243× |
| distribution | 65 | 35,381 | 37,244 | 126,030 | 3.38 | 436× |
| bisect | 33 | 1 | 2 | 28,830 | 14,415 | 1.2× |
| bisect | 49 | 1 | 2 | 101,614 | 50,807 | 1.2× |
| bisect | 65 | 1 | 2 | 246,078 | 123,039 | 1.1× |
HELD on the distribution — but the raw column is not the claim, and saying so is part of the result.
visited grew 2.14× across the sweep, which read alone looks like the first falsifier firing. It is not:
the edit itself grew. The same radius-4 brush removes more air at 65³ than at 33³ because there is
more air to remove, so seeds grew 1.96×. P-23 could legitimately say "flat" because its fixture held
the edit constant; this one cannot, and P-26 inherited that phrasing without inheriting the fixture
property that made it true. The quantity the hypothesis is actually about — work per unit of edit — is
visited/seed, and that is 3.09 → 2.99 → 3.38 while the lattice grows 7.6×. Flat, and the advantage
over rebuilding widens from 122× to 436×.
The bisect fixture behaves exactly as P-26 predicted, and the number is worse than "grows". Filling
one voxel — the midpoint of a tunnel joining two equal caverns — visits 246,078 voxels at 65³ against a
274,625-sample rebuild. That is 1.1×. Lockstep buys essentially nothing on this edit: both frontiers
are half the component, so "stop when all but one exhausts" stops only after walking half of it. The
per seed column makes the gap between the two regimes plain — 3.38 against 123,039, four orders of
magnitude, for the same structure on the same lattice.
So "the levelled HDT scheme is unnecessary here" is now conditioned by measurement rather than by
caution. It is unnecessary for the measured edit distribution and it is not the remedy for the bisect
either — HDT's levels bound a replacement-edge search, and here there is no replacement edge to find:
the component genuinely split, and the cost is the unavoidable one of discovering which side is smaller.
The remedy is decomposition, not a better search. A per-chunk Air bounds any walk by the chunk,
so bisecting a tunnel costs 33³ rather than the world — which is why Air::label_of ships now, as the
one accessor a stitching layer needs (R-028).
One implementation defect, caught by the falsifier rather than by a test. The first run reported
887,123 visited at 33³ — 15× the corrected figure — and grew 5.44×. Cause: search rederived its
seeds as "any air sample adjacent to solid", which in a cave field is the entire cave surface, so it
ran thousands of frontiers instead of a handful and lockstep explored nearly the whole component. The
correct seed set is the air adjacent to this fill's own removals, which fill already computed and
threw away. Two further O(n³) scans (any_member, and a member-collection pass) were removed with it.
Every one of the 15 unit tests passed both before and after that fix, including the pairwise rebuild-agreement test — because the defect made the structure slow, not wrong. A correctness suite cannot see a cost defect, which is the argument for a pre-registered cost falsifier existing at all.
Would be shown wrong by: a field whose caves are wide relative to the brush, where the distribution's
own splits start shedding large pieces and visited/seed climbs. noise_cavity at radius 4 is the
adversarial end for split frequency (M-319) and, per M-320, the friendly end for split size.
✗26 — P-25's mechanism clause is false, and P-25's own falsifier is what named it (R-022b)
Falsified by analysis, before the harness ran. P-25 claimed a union-find can absorb deletion: "a parent pointer only has to reach the correct root, and a filled sample sitting mid-tree is never queried." The first half is true. The second half is true of the filled sample and of nothing hanging off it, and that is the whole error.
Parent pointers encode union history, not spatial adjacency. Q → P → A records that Q was merged
in via P at some point in the past. It says nothing about whether Q touches P in the lattice. So a
filled sample can be an articulation point of the tree while being nothing of the kind in the
graph:
component {A, B, P, Q}, union-find tree: A root, B → A, P → A, Q → P
a fill sheds {P} spatially, so P is re-rooted
find(Q) now walks Q → P → P = P
connected(Q, B) returns false while Q and B are still genuinely connected — Q may even be
adjacent to A directly. The queries that break are the descendants', not the filled sample's own.
What caught it is the thing worth recording. P-25's second falsifier says: "any disagreement
between the incrementally maintained components and a full rebuild over the same values: component
count, or any connected() answer." That is exactly the failure above. The mechanism clause and the
falsifier clause contradicted each other inside a single pre-registration, and writing both down is
what made the contradiction visible before a line of the structure existed.
This is the practice paying for itself, and it is the reason this row is kept in full rather than quietly replaced by its successor: the reasoning generalises where the fact does not. A registration that names a strong falsifier can refute its own mechanism at zero cost. One that only asserts a mechanism cannot.
What survives. Only the mechanism dies. P-25's cost prediction was never in doubt and is re-registered unchanged as P-26 — flat labels fix the representation, not the search. The lockstep replacement search was always required; the union-find was falsely promising it could be skipped.
P-26 — P-25 with one clause replaced, registered for R-022b
Pre-registration. crates/isomesh/src/experiment.rs, id P-26. This is P-25 minus its mechanism
clause, and it is registered as a new id rather than as an amendment because experiment.rs's own
docs require it: "Amending a Preregistration after its experiment has run is a rewrite of the
prediction, and the only honest way to do it is to register a new id and record why the first one was
inadequate." ✗26 is the why.
Unchanged from P-25 — the cost claim. Repairing the air sublevel set after a brush fill costs work proportional to the shed volume and not to the surviving component nor to the lattice. At a fixed brush radius, visited voxels stay flat as the lattice grows through 33³, 49³ and 65³.
Replaced — the mechanism. Not a union-find. A flat label array: every sample carries its
component id directly, so re-rooting a shed piece is a write per member and no surviving sample can
route through it (✗26). connected becomes O(1) and &self rather than &mut self. Union by size
over a dense Vec indexed by label with an explicit free list — not a HashMap, whose iteration
order is a determinism hazard and determinism is load-bearing (M-36).
Added — the adversarial clause, because the flat curve would otherwise measure the fixture.
Lockstep's stop condition bounds work by the second-largest piece, so M-320's "1 at the median" is
a property of the edit distribution, not of the structure. Fill one voxel at the midpoint of a
tunnel joining two equal caverns and both frontiers are huge: the search walks until one exhausts, which
is O(half the component), and visited grows with n at a fixed brush size. That fires P-25's
first falsifier for a reason that has nothing to do with the stop condition being wrong.
That edit is not exotic — sealing a passage between two spaces is the sealed-volume mechanic, which is the thing this layer exists to support. So the harness carries a deliberate bisect-a-tunnel fixture beside the measured distribution, and the prediction is stated separately for each: flat on the distribution, growing on the bisect. A structure that is flat on both would mean the bisect fixture is not adversarial and needs rebuilding.
Consequently "the levelled HDT scheme is unnecessary here" is conditioned, not asserted. It is unnecessary for the measured edit distribution. The bisect case is where it would earn its keep, and the answer this crate reaches for instead is a budgeted repair rather than a bounded one — see below.
Deferring the repair fails safe in both directions, which is not obvious. Before a fill repair
completes the two pieces still share a label, so connected says yes and the caller reads "not sealed
yet". Before a dig repair completes the labels are still distinct, so the caller reads "not connected
yet" and the breakthrough event fires late. Water leaking for three frames is recoverable; water not
leaking out of a room the engine wrongly believes is sealed is a broken game rule. The conservative
answer is the cheap answer in both directions, so repair takes the spend: FnMut() -> bool predicate
shape mesh_within_budget already uses (M-78) rather than being synchronous — because amortised is the
wrong statistic for the frame a breakthrough lands on (M-124: 20.62 ms unbudgeted against a 2.10 ms
budgeted peak).
Falsified by: visited voxels growing as n³ on the measured distribution at a fixed brush size.
Growth on the bisect fixture is predicted, not falsifying. And, as in P-25 and more seriously, by any
disagreement between the maintained components and a full rebuild — component count or any connected
answer.
Records: samples_per_axis, fixture, fills, dirty_samples, seeds, visited, splits,
shed_components, vanished_components, rebuild_visited.
V-45 — R-027's design does not merely change extract_into's contract; it converts a shipped determinism check's failure condition into its intent (R-027)
V. Verified in this repo's own source, crates/isomesh/src/validate/determinism.rs:268–300.
M-318 measured R-027's ceiling and found the encoding was not the obstacle: of three shapes, stable order does not help, index-is-edge-id costs 230× memory, and only a persistent edge→slot map — state carried across extractions — delivers the 45×. The ticket weighed that as an API cost, with X-005's 294 call sites as the headline. That accounting missed the binding constraint.
check_determinism runs the extractor three times, and the third is the one that matters:
let mut reused = MeshBuffer::<R>::new();
extract(&mut reused);
reused.reset();
extract(&mut reused);
under a doc comment that states the intent in as many words — "one reused buffer to catch output that depends on the buffer's prior state… every algorithm in this crate is meant to be driven by resetting one buffer across thousands of chunks, and nothing else checks that it survives being driven that way."
A persistent edge→slot map makes that dependence intentional. The third run's whole purpose is to fail when output depends on prior state; R-027's only working shape is output that depends on prior state by design. So R-027 does not cost an API migration on top of a working design — it invalidates the check that would otherwise police it, and T-004 is a committed gate rather than a preference.
This is a stop rather than a preference, and it splits the ticket: an S to locate where M-318's 45×
actually goes, before any L touches extract_into's contract. That measurement may dissolve the L, since
M-318 already says the encoding is not the cost.
Would be shown wrong by: a formulation where the persistent map is derivable from the inputs — a pure function of the grid and the field rather than of call history — which would keep the third run meaningful. Nothing in M-318's three shapes is that, but the ticket has not been asked the question in those terms.
P-27 — registered for R-029, before the harness was written
What M-172 is and is not. M-172 measured BrushStack::gradient returning exactly [0.0, 0.0, 0.0]
on a wall slab's mid-plane and the row reads as "the gradient is exactly zero on the medial axis". The
dossier's correction (§4.1, from the Attali/Boissonnat/Edelsbrunner survey, READ): on the medial axis
generally ‖∇ρ‖ = cos(θ/2) where θ is the separation angle of the two nearest boundary points — an
exact zero needs them antipodal, θ = π, which is a slab's mid-plane and nothing else a player digs. And
even the slab case should die under a sub-voxel translation, because the zero is a cancellation the
sampling lattice happens to sit on, not a property the field carries with it.
H. Offsetting the slab's mid-plane by half a voxel takes the count of lattice samples whose default
Sdf::gradientreturns exactly[0, 0, 0]from one full lattice plane (65² = 4,225 at 65³) to zero, while the count of sub-voxel probes with voxel-step central-difference‖∇ρ‖ < 0.1changes by < 5%.
Two populations, because on one of them the second clause is vacuous. Under voxel-step central
differencing a slab's gradient magnitude at distance d from the mid-plane is exactly d/h for
|d| < h, so the sub-threshold set is the band |d| < 0.1h — thickness 0.2h, thinner than the
lattice pitch. Counted on the voxel lattice itself, clause 2 collapses from one full plane to zero
under any misalignment and would be false for the instrument's reason rather than the field's. The
registered instrument is therefore split: clause 1 on the voxel lattice with the default gradient
(M-172's actual instrument, DIFF_STEP-scaled), clause 2 on a fixed regular probe lattice of pitch
h/200 spanning |y| ≤ 2h, gradient by normals::central_difference at step h — the voxel regime a
game actually has. Derived, not tuned: a width-0.2h window sliding over a pitch-h/200 lattice holds
40 ± 1 probes, so the worst count change any rigid offset can produce is 1/40 = 2.5% — half the
registered bound, and the margin between the two numbers is exactly the room left for the discrete band
to misbehave.
Falsified by exact zeros surviving the offset — the discrete gradient doing something the
continuous identity does not describe, a question R-030 would inherit before anything else runs. Clause
2 separately falsified by the band count moving more than 5%, which the 2.5% instrument bound says can
only happen if the discrete band is not the rigid 0.2h ramp the arithmetic assumes.
The fixture is exact on purpose. h = 2⁻⁴ over [-2, 2], offset 2⁻⁵, slab half-thickness 0.5
— every lattice coordinate and both plane positions representable, so an exact zero is a property of
the field and not of a rounding accident, and y = 0 lands on the lattice by construction. A generic
y₀ would manufacture clause 1's confirmation out of floating point.
Inversion, in the harness before the verdict is read: a third probe pass at voxel pitch must show the ≈100% collapse — the > 5% branch demonstrated reachable, and the vacuity trap the registration routes around documented as a row rather than a footnote. And a full-voxel offset must bring the exact zeros back: the cancellation is the lattice's, and re-aligning the lattice must re-create it.
Corrected before the first run, same day — the full-voxel inversion above is arithmetically wrong,
and the correction sharpens the claim. Checked against the actual IEEE operations before the harness
was written: a full-voxel offset does not cleanly restore the zeros, and cannot. The cancellation
needs fl(y₀ + h_cd) − y₀ == h_cd exactly on both probe sides, which holds unconditionally only at
y₀ = 0.0, where 0 + x is exact. At y₀ = h = 2⁻⁴ the probe additions round at ulp(2⁻⁴) = 2⁻⁵⁶
and the − t subtractions rebucket at ulp(0.5) = 2⁻⁵³, so whether a plane point keeps its exact zero
depends on its DIFF_STEP·scale — computed point-by-point with the crate's own literal
(6.055_454_452_393_343e-6) over the fixture's scale classes: 3,136 of 4,225. The full-voxel arm
is therefore no longer an inversion but a third pre-stated prediction — exactly 3,136 — and the
sharper reading it carries: M-172's exact zero is not even a lattice-alignment artifact, it is a
coordinate-origin artifact. Clause 1's two branches are instead demonstrated by the aligned arm
(4,225) against the half-voxel arm (0), and the probe-pitch collapse pass stands as registered.
Records arm, offset_voxels, exact_zeros, band_count, probe_pitch_voxels.
💥 ✗27 — "an exactly-zero SDF gradient detects the medial axis"
Believed because: M-172. game_destruction fired charges at a wall slab's mid-plane and
BrushStack::gradient returned exactly [0.0, 0.0, 0.0] on consecutive shots — real, reproduced here
(4,225 of 4,225 aligned lattice points), and read as a detector: the gradient is exactly zero on the
medial axis, so the medial axis is free. The dossier's survey reading (Attali, Boissonnat &
Edelsbrunner, 10.1007/b106657_6, READ) already bounded the belief: on the axis ‖∇ρ‖ = cos(θ/2),
zero only at θ = π — the two nearest boundary points antipodal, which is a slab's mid-plane and
nothing a player digs. P-27 tested whether even the slab case survives the lattice moving.
Tested by: cargo bench --bench experiment_p27 (P-27, R-029), docs/experiments/p-27.csv.
Result: it does not survive. Half a voxel of mid-plane offset: 4,225 → 0 exact zeros. A full
voxel — the lattice perfectly re-aligned with the plane — restores only 3,136, exactly as the
pre-run IEEE enumeration predicted: the cancellation needs fl(y₀ + h_cd) − y₀ == h_cd on both probe
sides, which holds unconditionally only at y₀ = 0.0. The exact zero is a coordinate-origin
artifact riding on a lattice-alignment artifact. Meanwhile the field's medial band ‖∇ρ‖ < 0.1
moved 0.00% under the same offset.
Consequence: the detector is retired; the score survives. ‖∇ρ‖ magnitude reads medial
stability continuously — small ‖∇ρ‖ with large ρ is medial and stable — and that is the quantity
the identity r = ρ·√(1 − ‖∇ρ‖²) consumes, which R-030 now checks against a brute-force oracle.
M-172 amended in place; quote this row, not its headline.
Would be shown wrong by: exact [0,0,0] returns from the default gradient at points off the
coordinate-origin cancellation set — zeros that belong to the field after all.
🔬 M-324 / P-27 — HELD on both clauses, and the exact zero is a coordinate-origin artifact (R-029)
🎉🎊🔥✨🏆 DISCOVERY 🏆✨🔥🎊🎉
🥇 The exact-zero medial detector dies at half a voxel of offset, the
‖∇ρ‖ < 0.1medial band does not move at all, and the zero was never even a lattice-alignment artifact — a full-voxel re-alignment restores only 3,136 of 4,225, the exact integer the pre-run IEEE derivation named.🧪 Tested by:
cargo bench --bench experiment_p27(P-27),docs/experiments/p-27.csv🎯 Result: exact zeros 4,225 → 0 at half a voxel; band 43,560 → 43,560 (0.00% against a registered 5% and a derived 2.5% bound); full-voxel restore partial at exactly 3,136 📐 Why it earns the banner: 🪤 twice before the first measurement — the single-lattice reading of clause 2 is vacuously false for the instrument's reason (the band is0.2hthick, thinner than the lattice pitch), and the registration's own full-voxel inversion was arithmetically wrong, corrected pre-run to a derivation the run then hit to the integer. And the held prediction re-opens a line this project had closed around a boolean: what survives M-172's amendment is‖∇ρ‖as a continuous stability score — the reading the identityr = ρ√(1−‖∇ρ‖²)needs, and R-030 now gates. 💣 Would be shown wrong by: exact[0,0,0]returns off the coordinate-origin cancellation set, or the band moving under sub-voxel translation on a fixture this slab does not represent.
M. cargo bench --bench experiment_p27, docs/experiments/p-27.csv.
| arm | offset (voxels) | exact zeros | band count | probe pitch (voxels) |
|---|---|---|---|---|
| aligned | 0 | 4,225 | 43,560 | 0.005 |
| offset_half | 0.5 | 0 | 43,560 | 0.005 |
| offset_full | 1 | 3,136 | 43,560 | 0.005 |
| naive_aligned | 0 | 4,225 | 1,089 | 1 |
| naive_half | 0.5 | 0 | 0 | 1 |
Clause 1 held exactly as registered. One full lattice plane of exact [0, 0, 0]s — the
reachability arm, so the counter demonstrably fires — goes to zero under a half-voxel offset of the
plane. The zero belongs to the sampling arithmetic, not to the field.
Clause 2 held at its predicted 0.00%. The half-voxel offset is 100 probe pitches, so both arms share a probe phase and the band count is not merely inside the 5% registered and 2.5% derived bounds — it is identical: 40 per column on all 1,089 columns, both arms, per the registration's own 40 ± 1 arithmetic. The field's medial neighbourhood does not care where the lattice sits; only the boolean does.
The corrected third prediction hit its integer. 3,136 of 4,225 zeros return at a full-voxel
offset — perfect lattice re-alignment — because fl(y₀ + h_cd) − y₀ == h_cd holds unconditionally
only at y₀ = 0.0; which columns survive depends on how DIFF_STEP·scale rounds against
ulp(2⁻⁴) and ulp(0.5), and the pre-run enumeration of exactly that arithmetic named the count.
M-172's zeros were measured at z = 0 — the one plane in the world where the cancellation is
unconditional.
The naive rows document the trap the registration routed around. At voxel probe pitch the band holds one probe per column and collapses 1,089 → 0 under the same offset that moved the real band by nothing — the > 5% branch of clause 2 demonstrated reachable, and the single-lattice instrument shown to measure lattice phase rather than the field.
Consequence: ✗27 retires the boolean reading and M-172 is amended in place. The medial line
re-opens on ‖∇ρ‖ as a continuous stability score, and R-030's identity oracle is the next gate:
Calibre, the throat metric and handholds now rest on it.
Would be shown wrong by: a fixture producing exact [0,0,0] default-gradient returns at points
off the coordinate-origin cancellation set; or a field whose ‖∇ρ‖ < 0.1 population shifts by more
than the derived bound under a sub-voxel translation — which would mean the band is a lattice
artifact too, and the continuous score inherits the boolean's disease.
📖 V-46 — R-030's specified oracle cannot tell the identity from a wrong one; the inversion rule fails before the harness exists (R-030)
V. Derived pre-build from the ticket's own specification, arithmetic checked numerically; the
survey's printed two-point case (r = ρ·sin(θ/2), ‖∇ρ‖ = cos(θ/2)) is the one population the
instrument does handle, and lattice samples land on it with probability zero. P-28 is deliberately
not registered — registering a harness this analysis says cannot go red would be pre-registration
theatre.
The ticket's shape: compare r_formula = ρ·√(1 − ‖∇ρ‖²) (voxel-step central differences)
against a brute-force minimal-enclosing-ball oracle over boundary samples within ρ + tol, on a 64³
grid with ≥ 3 overlapping brushes; ≥ 99% agreement within 1 voxel, median residual O(h); falsified
by an h-independent residual. The trouble is that r(x) in the continuum is zero almost
everywhere and O(ρ) on a measure-zero medial set — a spike — and the two estimators mollify that
spike at different scales, so the comparison has three regimes and no discriminating one:
- Generic samples (~95–99% of the population). True
r = 0; both the correct form and a deliberately wrong one (r = ρ·(1 − ‖∇ρ‖)) output ≈ 0 — the correct formρ√(2δ)withδ = O(h²)gradient error, the wrong formρδ. The oracle's own floor — cap radius√(2ρ·tol) ≈ 0.43voxels at the derivedtol = 3h_c²/8ρ— dominates both residuals. Every registered clause passes for both forms here; the median-halves-with-h clause passes for both too, because the oracle floor is itself O(h). What the clauses measure is the oracle. - Medial shells, thickness ~h (the only place
ris large). The CD formula is a mollifier of width h: half a voxel off a capsule's axis it still reads≈ 0.87ρ(11 voxels); the tight-tol oracle has already collapsed to its 0.4-voxel cap floor at offsets beyondtol/2 ≈ 0.004h. They disagree at O(ρ), h-independently in shape — for the correct form. The wrong form reads smaller on the shell and therefore sits closer to the oracle: inverting the formula improves the score where the score is largest. An inversion check cannot go red; it goes green. - Exact medial hits. On the sheet the CD formula reproduces the survey's own two-point relation — that is the identity working — but on-sheet lattice hits are measure-zero, and R-029/M-324 is the measured demonstration of what lattice-exact coincidences are worth.
The population arithmetic seals it. The shells are exactly the samples the ≥ 99% clause has room
to lose: a capsule's codim-2 axis shell is 1.5% of interior samples at 33³, 0.38% at 65³, 0.10% at
129³ — the clause flips between resolutions for geometry's reasons, nothing about the identity —
and the ticket's own ≥-3-brush union fixture has codim-1 medial sheets whose ~h shells are ~4–7%
of the interior at 65³, so the headline clause is predicted to fail on the specified fixture for
the mollifier's reason, not the gradient's. A pass and a fail are both pre-computable from shell
geometry; neither would say anything about √(1 − ‖∇ρ‖²).
What is not in question: the continuum identity (Attali/Boissonnat/Edelsbrunner Eq. 1 plus the
enclosing-ball radius; Lieutier's ‖∇ρ‖² = 1 − r²/ρ²) — a theorem, not a hypothesis. And the
mollified reading M-324 established: ‖∇ρ‖ as a continuous stability score is stable under
sub-voxel translation. What died is the proposed empirical test, which compares a width-h
mollifier against a width-h_c²-tolerance spike-estimator and calls the difference evidence.
Calibre, the throat metric and handholds do not die from this; their gate moves to whichever
instrument replaces it — the candidate with teeth is a matched-analytic oracle: fixtures (wedge,
capsule) where the CD-mollified truth is itself computable in closed form, with the MEB oracle
demoted to a recorded column. Options and the decision are on the ticket's BLOCKED line.
Would be shown wrong by: building the specified harness anyway and watching the wrong-form inversion go measurably red on any registered clause — if it does, this analysis is wrong, the instrument discriminates after all, and R-030 proceeds as written. (The wrong form's global median is predicted ~6× the right form's — 0.2 against 0.03 voxels — but both sit far beneath every registered threshold, which is rule 9's complaint stated as a number.)
P-28 — registered for R-030, before the harness was written; the matched-analytic instrument V-46 asked for
The shape change, in one line. V-46 killed the MEB-oracle comparison because it compared two
different mollifiers of a spike; this registration compares the measured r_f = ρ·√(1 − ‖∇ρ‖²)
(voxel-step central differences through the crate's real code path) against derived truths —
exact closed forms where the field is piecewise linear, an analytic zero where the true inscribed
radius vanishes — so the residual isolates the discrete-gradient behaviour and a wrong closed form
has somewhere to go red.
H. C1 (form). On air-slab, air-wedge and triangular-prism fixtures in generic position, the measured
r_fmatches the derived voxel-step mollified truthr̃within1e-9of the gap on 100% of medial-band samples — the two-point (slab θ = π, wedge θ = π − 2γ) and three-point (prism axis,|Π| = 3) cases both exercised. C2 (curvature). On a capsule at generic off-axis band samples — true inscribed radius zero — the formula's own noise floorr_f = ρ·√(2δ),δ = O(h²/s²), has world-unit median that halves per resolution doubling: 33³→129³ end-to-end ratio ≤ 0.35. C3 (clearance). For slab gapsW ∈ {3h, 6h, 10h}at 8 controlled sub-voxel phases, the band-maxr_fsits in the derived envelope [√3/2 · (W − h/2), W] on 24 of 24 rows.
The derivations, committed before the run.
- Slab (normal
n̂, half-gapW, signed offsetsfrom the mid-plane): per-axis voxel-step CD ofρ = W − |s|is exactlyg_i = −sign(s)·n̂_iwhere|s| ≥ h·|n̂_i|and−(s/h)·sign(n̂_i)where|s| < h·|n̂_i|;r̃ = (W − |s|)·√(max(0, 1 − ‖g‖²)). Axis-aligned case:r̃(e) = (W−|e|)·√(1 − (e/h)²)— the profile whose maximum over a phase-φlattice is(W − φh)·√(1 − φ²), bounded below overφ ∈ [0, ½]by√3/2·(W − h/2): C3's envelope. - Wedge and prism:
ρ = minof two (three) linear distances; each probe evaluates the min of shifted linears, sor̃is the same construction casewise. On the prism axis the three feet sit at 120° and the enclosing-ball radius equalsρ— the|Π| = 3case the original ticket demanded, now with the analyticΠinstead of a brute-force cloud (the "MEB oracle" reduced to its exact value, recorded asclearance_true_voxels). - Capsule floor: at radius
sfrom the axis, worst probe orientation gives‖CD‖² ≈ 1 − O(h²/s²), sor_f ≈ ρ·h/s · c_orwithc_or ∈ [0, ~1]— first order inhat fixed world geometry, which is the honest version of the dossier's "median residual halves": it is the formula's own curvature noise, and whether it shrinks with resolution is exactly whether the score is usable at a fixed world scale. Predicted 65³ band median 0.05–1.5 voxels; orientation anisotropy recorded.
Falsified by C2's end-to-end ratio ≥ 0.7 — an h-independent noise floor, the one outcome that kills Calibre, the throat metric and handholds together, exactly the teeth the ticket's falsifier always meant. C1 failing is an implementation/transcription finding, not a verdict on the identity. C3 failing breaks the clearance-envelope derivation and the λ-test's accuracy claim with it. A ratio in (0.35, 0.7) is a loud UNDECIDED, reported as falsification-shaped rather than absorbed.
The inversion this instrument was rebuilt to have: the wrong form ρ·(1 − ‖∇ρ‖) must fail C1 on
≥ 30% of mid-band samples by more than 0.1·W — the two forms agree at u ∈ {0, 1} and differ by up
to 0.41·ρ at u ≈ 0.7, which the wedge's mid-range band hits by construction. If the wrong form
does not go red here, V-46 applies to this design too and the ticket stops again.
Recorded, unregistered: the min-composition characterisation the original fixture conflated —
three overlapping spheres, ρ_field = |min(f₁,f₂,f₃)| against the analytic true distance to the
union boundary (swallowed-cap geometry computed exactly): gap fraction and magnitude, predicted
h-independent. It is a statement about brush-composed fields, not about the identity, which is why
it is out of the registration.
Records fixture, samples_per_axis, band_samples, within_tol_pct,
band_median_residual_world, clearance_true_voxels, clearance_est_voxels, clamped.
🔬 M-325 / P-28 — the discrete medial score converges O(h) and the mechanics live; the clause that died was C1's own tolerance derivation (R-030)
🎉🎊🔥✨🏆 DISCOVERY 🏆✨🔥🎊🎉
🥇 The identity's discrete score has a curvature-noise floor that halves per resolution doubling — end-to-end ratio 0.146 against a registered 0.35 bound and a 0.7 kill-line — so the gate opens and Calibre, the throat metric and handholds live on a measured convergence rather than an assumption. And the one clause that died, C1, was killed by the very amplification C2 measures as signal: √(1−u²) turns 1e-16 representation dust into 1e-9 residuals at the band edge.
🧪 Tested by:
cargo bench --bench experiment_p28(P-28),docs/experiments/p-28.csv🎯 Result: C2 medians 7.81e-2 / 2.27e-2 / 1.14e-2 world across 33³/65³/129³ (ratio 0.146); C3 24/24 rows inside the derived envelope, phase profile matching(W−φh)·√(1−φ²)to four digits; C1 1/9 rows at 100% — falsified as registered; the wrong-form inversion red on 99.9% of the mid-band. 📐 Why it earns the banner: 💥 a pre-registered clause was falsified instructively — the float-dust tolerance was derived where the function is flat and applied where it is vertical, and that earned a new Part 5 rule — and 🔓 the dossier's #2-ranked open question moved: the identity survives discretisation with an O(h) floor, measured against derived truths that a wrong closed form demonstrably fails. 💣 Would be shown wrong by: a finer-resolution run where the C2 ratio stops falling, or any fixture on which the wrong form passes the mid-band inversion.
M. cargo bench --bench experiment_p28, docs/experiments/p-28.csv.
| clause | registered | measured | verdict |
|---|---|---|---|
| C2 — curvature floor halves per doubling | 33³→129³ world-median ratio ≤ 0.35, kill at ≥ 0.7 | 7.81e-2 → 2.27e-2 → 1.14e-2, ratio 0.146 | HELD |
| C3 — clearance envelope | band-max r_f ∈ [√3/2·(W−h/2), W], 24/24 |
24/24, and per-phase max equals the derived (W−φh)√(1−φ²) to 4 digits |
HELD |
| C1 — form at float dust | |r_f − r̃| ≤ 1e-9·G on 100% of band, 9 rows | 1/9 rows; failing medians 1.5–3.3e-9, i.e. 12 orders below the gap and ~4× above the tolerance | FALSIFIED |
| inversion | wrong form fails ≥ 30% of mid-band by > 0.1·G | 99.9% (12.9% over the whole band — the u→1 edges collapse both forms, which is why the registration said mid-band) | red demonstrated |
C2 is the row the mechanics live on. On the capsule's exact-cylinder band every sample has a
unique closest point and the true inscribed radius is zero, so r_f there is pure instrument: the
O(h²/s²) central-difference error √-amplified to first order. It came out O(h) and cleanly so —
successive ratios 0.29 and 0.50 — with the voxel-unit ceiling resolution-invariant at ≈ 1.6 voxels
(the ρ·h/s prediction seen from the other side: in voxels, ρ·c/s does not depend on h). The
registered falsifier — an h-independent floor, the one outcome that killed Calibre, the throat
metric and handholds together — did not fire. What a build inherits: at fixed world geometry the
score's noise floor is ~1.6 voxels at the band's inner edge and halves with every resolution
doubling; a λ-test needs λ comfortably above that floor at the coarsest resolution it will run at.
C1 falsified its own tolerance, not the transcription. The failing rows' medians sit at
1.5–3.3e-9 — twelve orders below the gap — and every corroborating read says the form is wired
right: the 33³ slab matched at 2.8e-17 (true dust, 100% of 2,178 samples), C3's phase profile
reproduced the derived closed form to four digits, and the wrong form missed by five orders more.
What the registration got wrong is now a Part 5 rule: d r/d(radicand) = ρ/(2√(1−u²)) is unbounded
at the band's u → 1 edge, so a uniform dust tolerance derived in the interior must lose the edge —
the clamped column (up to 39% of a band) is the same fact, measured: ‖CD‖ crosses 1 by dust and
the radicand goes negative. A tolerance of dust · ρ/(2√(1−u²)), per sample, is what C1 should have
registered.
The first run aborted itself, and that is part of the record. The inversion gate fired at 12.9%
because the check populated the whole band instead of the registered mid-band; no clause was printed
and no CSV written before the abort, so the operationalisation (derived-truth u ∈ [0.2, 0.95]) was
fixed blind to outcomes. The whole-band number stays printed beside the mid-band one because the gap
between them — 12.9% against 99.9% — is V-46's collapse mechanism, seen once more from inside the
working instrument.
Recorded beside the registration: the min-composition characterisation (three-sphere union against analytic true distance) was descoped from this run's fixtures during the redesign — it is a statement about brush-composed fields, not about the identity — and remains open for the Calibre build ticket to demand.
Consequence: R-030 closes with the gate open: the identity is buildable-on, pending only O-19 (the λ-filter direction, the last definitional discrepancy). ✗27/M-324's continuous-score reading now has its convergence constant.
Would be shown wrong by: a 257³ run where the capsule floor's median stops halving; a fixture where the mid-band inversion passes the wrong form; or a C1 rerun with the per-sample amplified tolerance still losing rows — which would mean the residual is not representation dust after all.
P-29 — registered for R-031, before the harness was written; the kinetics come from the source, not from tuning
The sourcing that had to happen first, and did. The dossier recorded Dreybrodt & Gabrovšek
(10.5194/hess-23-1995-2019) as downloaded, conversion failed — a rule-5 stop waiting to happen,
since "linear dissolution kinetics" was the dossier's entire specification. The conversion has since
succeeded on the corpus (20 pages, 2026-08-17), and the paper is now READ. Everything the simulator
needs is in it, verbatim: the 2-D net of 1-D fractures (length l = 200 cm, width b = 100 cm,
aperture a₀ = 0.02 cm); constant heads 15 m → 0 with periodic transverse boundaries (their
cylinder topology, which makes evolution independent of border distance); cubic-law resistance
R = (12η/ρg)·∫dx/(a³b); linear kinetics F(c) = k·(1 − c/c_eq) with the composite constant
k = k₁·(1 + k₁a/6Dc_eq)⁻¹, k₁ = 4×10⁻¹¹ mol cm⁻² s⁻¹, c_eq = 10⁻⁶ mol cm⁻³,
D = 10⁻⁵ cm² s⁻¹; the closed-form transport F(x) = F(0)·exp(−x/λ), λ = Q·c_eq/(P·k); widening
da/dt = 2γF; the seeding protocol (Δa = 10⁻⁹·a₀ on the first ten downstream fractures); the
lognormal heterogeneous net (a in [0.015, 0.025] cm about a 0.02 peak, σ = 0.2); and the
interaction ranges (seeds 10 nodes apart fight, 50 apart ignore each other). One OCR ambiguity is
carried rather than resolved silently: the composite k renders once cleanly as 6Dc_eq and once
garbled as 3-D·c_eq; 6D is adopted from the clean occurrence, and the alternative would shift
late-stage rates ≤ 2× without touching any registered claim's mechanism. γ is the standard
mol-to-retreat conversion via calcite's molar volume, 100.09 g mol⁻¹ / 2.71 g cm⁻³ = 36.93 cm³
mol⁻¹ — derived from handbook constants, not fitted. The recharge-limited contrast is sourced too:
Perne, Covington & Gabrovšek (10.5194/hess-18-4617-2014, READ in relevant part) run exactly the
two post-breakthrough scenarios and state that with recharge capped at Q_max "further expansion
of the network is suppressed as the head along the growing existing pathways decreases in time."
H. With the paper's constants on a 64×64 lattice (~8k edges, 8 segments per fracture): (C1) under constant heads, the post-breakthrough aperture distribution is bimodal by the central-gap statistic — max consecutive gap in sorted
ln a, 1% tails dropped, threshold 0.2 (the registered initial log-sd) — on both the 3-seed homogeneous net and the lognormal heterogeneous net, while the fixed-flux recharge-limited arm stays unimodal at matched cumulative dissolved volume; (C2) past breakthrough, > 90% of dissolution flux (mol/s per edge) sits in < 10% of edges.
The statistic is derived, not tuned. For N ≈ 8k draws from any unimodal bulk comparable to the
initial lognormal, the maximum central spacing is O(σ·ln N/N) ≈ 2×10⁻⁴ — three orders under the
0.2 threshold — while the published mechanism freezes losers near a₀ and runs the winner to
~50–100·a₀, a gap of ln 50 ≈ 3.9. (Ashman's D was rejected on its own null: a forced 2-means
split of one Gaussian scores D ≈ 2.65 and passes.) Detector red/green run before any verdict: the
t = 0 lognormal apertures must read unimodal, a synthetic half-shifted (+4σ) sample must read
bimodal, and the recharge arm is the physics inversion — both-arms-bimodal indicts the statistic,
both-unimodal the kinetics.
Flow is solved exactly, so bimodality cannot be solver noise. Cubic-law contrast reaches
(a_max/a_min)³ ~ 10⁶ exactly when the dynamics get interesting, which is where a fixed-iteration
Krylov solve quietly turns the pressure field into noise. The harness therefore does no iteration at
all: one banded Cholesky factorisation per tick (y-major indexing, periodic wrap Δ = 63, bandwidth
65; Dirichlet elimination keeps it SPD), ~9 MFLOP/tick. The time step is adaptive-deterministic — a
pure function of state, dt = 1%·min_s(a_s / ȧ_s) clamped to [10⁻³, 1] yr — with a per-tick
max(da/a) ≤ 1.01% assert; ~10³ ticks per arm by the log-growth arithmetic. The recharge arm's
per-input flux is the constant-head arm's own computed t = 0 inflow, frozen — self-consistent rather
than transcribed.
Falsified by no bimodal split on either constant-head arm, or C2's concentration failing — the mechanic's positive-feedback premise dies with the kinetics. Instrument-falsified if the recharge arm goes bimodal while the detector also flags the t = 0 sample.
Corrected before the first run, same day — two defects found by arithmetic, not by data.
First, the tick count. The "~10³ ticks by the log-growth arithmetic" above assumed the entrance
segment binds the 1% step cap; it does not — the front does. A freshly-reached segment always
sits at a ≈ a₀ with F ≈ k, so ȧ/a ≈ 4.6 yr⁻¹ holds somewhere for the whole run and a 1% cap
means dt ≈ 2.2×10⁻³ yr throughout: ~10⁶ ticks to a 1,890-year breakthrough. The corrected step
policy: the aperture ODE is non-stiff and self-limiting (k(a) falls with a, saturation bounds
c, growth is monotone), so the cap is re-derived at 10% per tick (~10⁵ ticks), and the
discretisation claim is measured rather than argued: a control arm reruns the heterogeneous case
at a 5% cap and every registered verdict — both bimodal flags and C2's share within 2 points — must
be unchanged, or the run fails loudly. Second, the matched-volume target. Matching the recharge
arm to the head arm's final dissolved volume is unreachable by construction — the post-breakthrough
surge dissolves at a rate a capped-recharge arm can never reach, which is the suppression itself,
not a fair epoch. The registered target becomes the head arm's cumulative dissolved volume at its
breakthrough: the same rock removed as the competitive arm had removed when its winner broke
through. Both corrections precede any simulation output.
Records arm, ticks, years, breakthrough_years, max_gap_ln, bimodal,
flux_top10_pct, gini_flow, max_da_over_a_pct, tick_ms_median.
💥 M-326 / P-29 — FALSIFIED on both clauses, while the recorded columns show the mechanism both registered instruments missed (R-031)
🎉🎊🔥✨🏆 DISCOVERY 🏆✨🔥🎊🎉
🥇 The pre-registered bimodality detector trimmed away the wormhole it was built to find — a 1% tail cut on 8,128 edges eats an entire 63-edge winning path — and the pre-registered 90% dissolution share is capped by the paper's own surface kinetics at a measured 78%, even as water flux concentrated to a Gini of 0.976. Both clauses died; the competition, the winner, and the recharge suppression are all visible in the recorded columns.
🧪 Tested by:
cargo bench --bench experiment_p29(P-29),docs/experiments/p-29.csv🎯 Result: C1 gaps 0.060 / 0.022 / 0.052 (hom / het / recharge) — all under the 0.2 threshold, with the "unimodal" control outscoring the bimodal-expected arm; C2 dissolution share 16.1% / 78.1% against a registered > 90%. Recorded: flow Gini 0.976 (het) vs 0.560 (recharge-limited); the recharge arm dissolved the same at-breakthrough rock volume with no breakthrough at all; het broke through before hom (23 vs 181 yr — the paper's ordering). 📐 Why it earns the banner: 💥 two pre-registered clauses falsified instructively — one by an instrument defect that was derivable before the run (the winner mode's minimum size is the lattice's own input→output path length; a new Part 5 rule records it), one by a physical correction to the dossier's number (surface kinetics rate-limits the winner while water flux runs away). The detector's own red/green passed; what failed was never checked against the mode size. 💣 Would be shown wrong by: the trim-free, mode-guarded statistic (P-30) still reading no gap on the constant-head arms — which would make the falsification the kinetics' after all.
M. cargo bench --bench experiment_p29, docs/experiments/p-29.csv.
| arm | ticks | years | breakthrough | max gap (trimmed) | flux top-10% | Gini(flow) |
|---|---|---|---|---|---|---|
| hom_seeded3 | 896 | 216.8 | 180.6 | 0.060 | 16.1% | 0.742 |
| heterogeneous | 250 | 27.5 | 22.9 | 0.022 | 78.1% | 0.976 |
| het_dt_control (5% cap) | 473 | 26.3 | 21.9 | 0.024 | 80.0% | 0.976 |
| recharge_limited | 175 | 35.4 | none | 0.052 | 100.0% | 0.560 |
C1 falsified by the instrument, and the data says so from inside. The registered statistic dropped 1% tails — 81 of 8,128 edges — while a winning wormhole path is at most one input→output chain, ~63 edges: the upper mode is smaller than the trim, so the detector returned the bulk's spacing on every arm and the ordering came out nonsensical (recharge 0.052 > het 0.022). Meanwhile the untrimmed columns carry the split: het's flow Gini 0.976 against recharge's 0.560, and the dt-control arm reproduced both readings at half the step, so discretisation is not the story.
C2 falsified by the physics, and that is the more interesting half. Water flux concentrates as
the paper says — but dissolution flux cannot follow it all the way, because the winner's edges are
rate-limited at k·P·l by surface kinetics no matter how much undersaturated water passes, while
small-flow edges each dissolve their entire inflow (Q·c_eq). Measured share at 1.2·T_B: 78%,
not the dossier's > 90%. The dossier's number was its own R-tier extrapolation; the corrected figure
is now measured, and the "re-mesh cost decreases monotonically post-breakthrough" story it fed needs
the 78% version.
The suppression is real and quantified. With recharge capped at the head arm's own t = 0 inflow, the same cumulative rock volume that carried the competitive arm to breakthrough (5.54×10⁴ mol) produced no breakthrough, a flow Gini of 0.560, and dissolution parked at the input column — Perne, Covington & Gabrovšek's "further expansion of the network is suppressed", as a number.
Recorded scale caveat: breakthrough times are ~8–25× shorter than the paper's (a 63-fracture domain at ~3× the per-fracture gradient); the paper comparison was registered as an ordering, not a magnitude, and the ordering held.
Consequence: the kinetics are not convicted — the registered detector was. P-30 re-registers C1 only, with the trim replaced by a mode-size guard derived from the lattice (a gap counts only with ≥ 8 edges on each side; the smallest possible winner mode is 63). C2 is answered and closed at 78%.
Would be shown wrong by: P-30's guarded statistic still finding no gap on the constant-head arms; or a finer-domain rerun showing the 78% share was an artifact of the 1.2·T_B evaluation epoch rather than of the kinetics cap.
P-30 — registered for R-031, before the corrected instrument ran; P-29's prediction with the trim replaced by a mode guard
The M-289 shape, deliberately. P-29's bimodality clause was falsified by its own detector's trim (M-326); this registration re-asks the same question with the defect removed and nothing else changed — the same deterministic runs, seeds and constants, re-read. The correction is derivable without the data: a winning wormhole path is at least one input→output chain, 63 edges on this lattice, so the guard requires ≥ 8 edges on each side of a candidate gap (0.1% — eight-fold below the smallest possible winner mode, eight-fold above single-edge outliers) and drops the percentile trim entirely.
H. With the guarded statistic — max gap in sorted
ln aover all 8,128 edges, qualifying only with ≥ 8 edges on both sides, threshold 0.2 — the constant-head arms (3-seed homogeneous, lognormal heterogeneous) read bimodal post-breakthrough and the recharge-limited arm reads unimodal at the same at-breakthrough dissolved volume. Recorded beside it: the water-flux top-10% share, next to the dissolution share M-326 closed at 78%.
Falsified by no qualifying gap on either constant-head arm — which, with the guard in place, would mean the aperture histogram genuinely is not gapped-bimodal: the dossier's tier-R "bimodal" reading dies, and the competition claim stands on the concentration columns M-326 already measured (flow Gini 0.976 vs 0.560; suppression at matched rock volume). The positive-feedback premise itself is convicted only if those columns also regress, which M-326 shows they do not. The detector's red/green (synthetic +4σ half-shift, t = 0 lognormal) runs again before any verdict.
Records the P-29 columns plus guarded_gap_ln, guarded_bimodal, flux_water_top10_pct.
💥 M-327 / P-30 — FALSIFIED again, by the distribution this time: heterogeneous wormholing has no gapped aperture histogram, and the same run proves the detector could have seen one (R-031)
🎉🎊🔥✨🏆 DISCOVERY 🏆✨🔥🎊🎉
🥇 With the mode guard in place the homogeneous arm's split is found at 0.222 — the instrument demonstrably sees a real gap — and the heterogeneous arm still reads 0.037: its aperture histogram is a broad continuum, not two modes. The dossier's tier-R "goes bimodal" reading is dead on the fixture the mechanic would actually run on, while the competition itself is overwhelming in the water column: 99.8% of flow in the top decile of edges, against 35.7% recharge-limited.
🧪 Tested by:
cargo bench --bench experiment_p30(P-30),docs/experiments/p-30.csv— the same deterministic runs as M-326, re-read. 🎯 Result: guarded gaps 0.222 / 0.037 / 0.063 (hom / het / recharge); water-flux top-10% share 53.9% / 99.8% / 35.7%; dissolution share stands at M-326's 78%. 📐 Why it earns the banner: 💥 a pre-registered prediction falsified for the world's reason after M-326 falsified it for the instrument's — the pair is exactly what pre-registration exists to separate. The literature claims wormhole competition; "bimodal aperture distribution" was the dossier's gloss on it, and the gloss is what died. 💣 Would be shown wrong by: a longer post-breakthrough run in which the heterogeneous histogram opens a qualifying gap after all — the evaluation epoch is 1.2·T_B, registered.
M. cargo bench --bench experiment_p30, docs/experiments/p-30.csv.
| arm | trimmed gap (M-326) | guarded gap | water top-10% | dissolution top-10% | Gini(flow) |
|---|---|---|---|---|---|
| hom_seeded3 | 0.060 | 0.222 — bimodal | 53.9% | 16.1% | 0.742 |
| heterogeneous | 0.022 | 0.037 — no gap | 99.8% | 78.1% | 0.976 |
| het_dt_control (5% cap) | 0.024 | 0.038 | 99.8% | 80.0% | 0.976 |
| recharge_limited | 0.052 | 0.063 — unimodal ✓ | 35.7% | 100.0% | 0.560 |
The discrimination is inside the run. The homogeneous arm's bulk is a point mass at a₀ and its
widened mode clears the guard: 0.222 found, bimodal called — so a real split does not hide from this
instrument. On the lognormal net the winner's apertures connect to the bulk through the
partially-widened front and laterals: a continuum, no qualifying gap at any split with 8 edges a
side. That is a property of heterogeneous wormholing, not of the reader — and the heterogeneous net
is the one the dossier itself says nature resembles ("wormholes start to grow immediately, which is
more likely expected in nature").
What R-031 actually established, across M-326 and M-327: the paper's mechanism reproduces from its own constants — competition, a winner, breakthrough ordering (het before hom), and recharge-limited suppression at matched rock volume — and its game-facing observable is flow concentration (water top-10% share, Gini), not a histogram shape. The dissolution share is capped by surface kinetics at 78% even as water hits 99.8%, which is the number the "re-mesh cost falls post-breakthrough" story must use. The build ticket, when written, should emit brushes and budget re-meshing off the concentration columns.
Would be shown wrong by: any of the three registered fixtures replayed with a different seed family reversing a verdict (the runs are deterministic; the seed is registered); or a post-breakthrough epoch at which the heterogeneous histogram genuinely separates.
P-31 — registered for R-032, before the harness was written
What the certificate needs, and why the dossier expects it missing. The λ-medial axis's homotopy
guarantee needs λ < wfs, the weak feature size — the smallest distance from a critical point of
the air's distance function to the boundary. Destruction carves near-tangential intersections, and
near-tangential geometry puts critical points close to the boundary; the dossier predicts the
certificate essentially never holds at brush scale, and this registration is that prediction with
its instrument pinned. M-325 opened the gate on the stability side; this decides what the build
may claim — a homotopy guarantee, or Hausdorff stability (Chazal–Lieutier; Lieutier & Wintraecken
10.1145/3564246.3585113) alone.
H. On > 80% of 20 seeded dug scenes — a solid block carved by 12 random overlapping capsule brushes through the crate's own
BrushStackcomposition — the measuredwfsis < 2 voxels. The control scene (one 20-voxel cavity in generic position) reportswfs ≥ 10 voxels.
The instrument, derived where it can be. Critical-point candidates are interior air samples
whose voxel-step central-difference ‖∇ρ‖ < 0.5 — the dossier's own filter constant (θ > 120°,
since on a two-sheet medial ‖∇ρ‖ = cos(θ/2)), stated in §2.4 and reused rather than re-invented —
non-maximum-suppressed over 26-neighbourhoods (a sample survives only when no neighbour reads a
strictly smaller magnitude). wfs = min ρ over survivors, in voxels. The scan is restricted to
|xᵢ| ≤ 1.5, inside the block, so the exterior shell (gradient ≡ 1, no critical points, boundary
partially outside the sampled domain) cannot contribute.
Reachability and inversion in one control: the single-cavity scene's centre is a genuine
critical point at ρ ≈ 20 voxels. An instrument that cannot report the certificate available
there is not to be trusted reporting it absent on the dug scenes; its 10-voxel floor is asserted
before any verdict is read, as is a non-empty critical set and a sane carved fraction (2–60% air) on
every dug scene.
Falsified by wfs ≥ 2 voxels on half or more of the dug scenes — the certificate comfortably
available, the stronger guarantee live, the Hausdorff fallback unnecessary. Either way the answer
decides what §1.1's build may claim, and neither outcome halts the list.
Records scene, air_samples, critical_points, wfs_voxels, epsilon, samples_per_axis.
🔬 M-328 / P-31 — HELD at 20 of 20: the homotopy certificate is never available in a dug scene, and the instrument proved it could have said otherwise (R-032)
M. cargo bench --bench experiment_p31, docs/experiments/p-31.csv.
Across 20 seeded scenes carved by 12 overlapping BrushStack capsules each: every scene's wfs is
under 2 voxels — and not marginally. The measured values sit at 0.00–0.15 voxels on 19 scenes
and 0.66 on the twentieth: the critical points of a dug scene's distance function live essentially
on the boundary, which is the near-tangential-intersection mechanism the dossier predicted stated
as a number. A homotopy certificate λ < wfs would need λ under a tenth of a voxel — no gameplay λ
(a shoulder width is many voxels) can ever satisfy it. The control cavity reported the certificate
available at 19.5 voxels from exactly one critical point, so the twenty absent-verdicts are
readings of the scenes, not of a blind instrument.
Consequence, recorded so nobody re-derives the strong claim: the λ-medial direction drops the
homotopy guarantee permanently and rests on Hausdorff stability — Chazal–Lieutier, with Lieutier
& Wintraecken's d_H ≲ d_H^{1/2} / d_GH ≲ d_H^{1/4} bounds (10.1145/3564246.3585113) — which is
weaker, parameter-free beyond λ itself, and still far better than a tuned persistence constant. With
M-325 (the score converges O(h)) and ✗27/M-324 (the score, not the boolean), the Calibre line's
epistemic footing is now fully measured; only O-19's definition direction remains.
Would be shown wrong by: a dug-scene generator whose carves are deliberately non-tangential (disjoint fat chambers with fat connectors) reporting comfortable wfs — which would mean the result is a property of overlapping brush edits specifically, and level designers who avoid overlaps could buy the certificate back.
P-32 — registered for R-033, before the harness was written; the kill-shot carries its own unit conversion
The factor of two that decides the verdict, registered up front. The ~0.6% just-noticeable
difference is a pitch threshold — it lives on frequency — and f ∝ √λ, so
audible ⟺ ½·|Δλ|/λ ≥ 0.6%: the λ₁ threshold is 1.2%. Applying 0.6% to λ directly would make
the null twice as hard to hold, silently. (The JND constant itself is the ticket's, tier-F; the
conversion is arithmetic.)
H. On a carved, mildly asymmetric, base-anchored pillar (~32³ occupancy): (C1) all 8 seeded strictly-interior one-voxel digs move λ₁ by < 1.2%; (C2) at least 1 of 4 digs adjacent to the fixture's two-cell-thick web exceeds 1.2% — the ticket's "only edits near a thin feature are audible", both sides of it; (C3) carving a 20%-volume cavity moves λ₁ by > 15% — the null's reachability, so "inaudible" is a reading of the edit and not of a numb instrument.
The instrument, and what makes fixed counts safe. Trilinear hexahedral FEM assembled directly on
the occupancy grid — the discretisation the sound literature itself uses, no tetrahedralisation —
with one reference 24×24 element stiffness from 2×2×2 Gauss quadrature of BᵀDB (E = 1,
ν = 0.3, ρ = 1; units cancel in Δλ/λ), lumped diagonal mass, base layer fixed. λ₁ by
matrix-free inverse power iteration (48 outer) over Jacobi-preconditioned CG (256 inner,
warm-started). The safety is not the counts but the certificate: with M diagonal,
ε = ‖Kx − λ_R·Mx‖_{M⁻¹} / ‖x‖_M is a one-pass a-posteriori bound and there is an eigenvalue
within ε of λ_R; every reported value must carry ε ≤ 5·10⁻⁴·λ_R — 24× under the decision
threshold — or the run fails loudly. Two deterministic starts must agree within 2ε. The certificate
is itself shown able to go red on a deliberately under-converged (2-outer) run before any verdict is
read. Element validation: the free single element's spectrum must hold exactly six rigid modes
(Jacobi eigensolver over the 24×24), symmetry to 1e-10, and translation/rotation null vectors.
Descoped, deliberately: the k ∈ {8..128} mode-count timing sweep the dossier sketched. The registered hypothesis is λ₁-only; block deflation is several hundred lines that matter only if the kill-shot survives, and premise-falsifiers-first is this backlog's own ordering rule.
Falsified by any interior dig at ≥ 1.2% (modal audio earns its ticket, pre-bounded at ≈40 modes
in 5 ms by Picard's O(m^2.8)); C2 failing the other way closes the direction entirely; and
instrument-falsified by the certificate, the two-start disagreement, the numb control, or a
single-element spectrum with other than six rigid modes.
Records edit, cells, dof, lambda1_base, lambda1_edited, delta_pct, audible,
certificate_rel.
💥 M-329 / P-32 — the modal kill-shot fired: no one-voxel edit is audible anywhere, including against the thin web, and the direction closes for a day's cost (R-033)
🎉🎊🔥✨🏆 DISCOVERY 🏆✨🔥🎊🎉
🥇 One voxel cannot move a carved body's fundamental audibly — the worst interior dig shifted λ₁ by 0.11% against a 1.2% audibility threshold, and the digs against the two-cell-thick web did even less (≤ 0.032%, forty-fold under audible). The ticket's own second clause — "edits near thin features are audible" — is what died, and with it the whole per-edit modal direction, at the price the dossier set: a day, not a sprint.
🧪 Tested by:
cargo bench --bench experiment_p32(P-32),docs/experiments/p-32.csv🎯 Result: C1 HELD (8/8 interior digs, worst 0.1126%); C2 FALSIFIED the closing way (best near-web dig 0.0321%); C3 control: a 20%-volume cavity moved λ₁ 63.9%, certificates at 5.5×10⁻⁸ relative — four orders under their bound — and both starts agreed on every solve. 📐 Why it earns the banner: 💥 a pre-registered clause falsified in the direction that kills a candidate mechanic outright, before anything was built on it — the exact trade the premise-first ordering exists to buy. And the numbers carry the mechanism: a one-voxel dig moves λ₁ by roughly its share of modal strain energy, ~1/N — so the result is not marginal and no fixture tuning rescues it. 💣 Would be shown wrong by: a fixture whose fundamental is a thin-feature mode (a body that is mostly web), or edits at a near-failure hinge where the mode concentrates — either would make single-voxel audibility real for that body class.
M. cargo bench --bench experiment_p32, docs/experiments/p-32.csv.
| edit set | Δλ₁/λ₁ range | verdict at 1.2% |
|---|---|---|
| 8 strictly-interior digs | 0.0020% – 0.1126% | inaudible, 8/8 (C1 HELD) |
| 4 digs adjacent to the 2-cell web | 0.0065% – 0.0321% | inaudible, 4/4 (C2 FALSIFIED) |
| 20%-volume cavity (886 cells, 4 orphan fragments fell away, printed) | 63.9% | the null's reachability (C3 HELD) |
The mechanism, visible in the spread. A single cell is ~0.025% of this 3,982-cell body, and the
interior deltas bracket exactly that: first-order eigenvalue perturbation says Δλ/λ ≈ the removed
cell's share of the mode's strain energy. The web digs move λ₁ less than interior digs because the
fundamental is the pillar's sway and the web is a passenger in it — "near a thin feature" was never
the right variable; modal strain density is. Audibility therefore needs either ~50+ cells
removed at once (the cavity's regime, on this body) or an edit where the mode concentrates —
a near-failure hinge — which is a different mechanic (pre-fracture creaking) with a different
trigger, not per-edit modal audio.
The margin survives the constant's tier. The 0.6% pitch JND is the ticket's tier-F constant; the conversion to 1.2% on λ is arithmetic. The measured worst case sits 11× under the threshold and the web case 37× under — a JND wrong by an order of magnitude would not flip the verdict.
Instrument record: element validated before trust (symmetry, translation/rotation nulls, exactly 6 rigid modes from the free-element Jacobi spectrum); certificate shown red on a 2-outer run (2.3×10⁻¹ vs the 5×10⁻⁴ bound) before any verdict; every reported eigenvalue certified at ≤ 5.6×10⁻⁸ relative; the control cavity's 4 orphaned fragment cells pruned as fallen debris, on the record.
Consequence: the modal direction closes. Picard's ≈40-modes-in-5-ms budget is moot for per-edit audio; no build ticket is earned. What survives as a lead worth a different premise experiment someday: λ₁ tracking as a structural signal (the cavity's 63.9% says large-scale carving is very audible in principle), and mode-concentration at near-failure hinges as a creak trigger.
Would be shown wrong by: the two fixture classes the banner names; or a certificate bug — the inversion demonstrated red, so that path is covered.
P-33 — registered for R-034a, before the harness was written; the only external ground truth in the batch
What this one is for. Every other Phase 18 experiment checks a prediction against this repo's own
constructions; R-034a checks a solver against numbers the world already knows. Whiting, Ochsendorf &
Durand (10.1145/1618452.1618458, READ in full — including its appendix's equilibrium indexing)
validated their rigid-block program on two closed-form results, and a reimplementation either hits
them or is wrong: Milankovitch 1907 — minimum thickness over centerline radius of a
semicircular arch, 0.1075 (their solver: 0.10746, at a 100-block tessellation) — and
Ochsendorf 2002 — critical ground tilt 15.84° at t/r = 0.20, which they matched exactly.
H. The pure-Rust program — per-vertex interface forces at the two ends of each radial cut, equilibrium
A_eq·f = −w(3 rows per block in 2-D: forces and torque), friction cone|f_t| ≤ 0.7·f_n, compression-only — reports the 100-block threshold at 0.1075 ± 0.0010 and the tilt at 15.84° ± 0.05°.
Two decisions with reasons committed in advance.
- Weights at exact annular-sector centroids. Sector area is
Δθ·R·tand the centroid radius is the closed-form(2sin β/3β)·(R_o³−R_i³)/(R_o²−R_i²)— because a centerline-lumped weight reproduces Heyman's 0.106, not Milankovitch's 0.1075, and the third decimal is the whole point of using this as a gate (the memo's highest-ranked trap for this ticket). - The solver is alternating projection, and it replaced FISTA before the first run. As first
registered, the solver was FISTA on
‖A_eq·f + w‖²over the cones, 20,000 iterations — and the convergence arithmetic kills that instrument before it runs: FISTA's residual tail is O(1/k), so the registered budget lands near3×10⁻³·W, two orders above the 10⁻⁵ feasibility band, and the band-abort would fire on every feasible probe. Corrected before any run: plain alternating projection between the equilibrium affine set{f : A_eq·f = −w}— exact per iteration via one prefactored dense Cholesky ofA·Aᵀ(300×300) — and the per-vertex friction cones, whose projection is closed-form. Feasible probes converge to the intersection; infeasible probes stall at the minimal-distance pair, and the decision reads the cone-side iterate's equilibrium residual per unit weight: feasible < 10⁻⁵, infeasible > 10⁻⁴, band asserted never hit; both bisections stop at a width that keeps every probe a classification margin away from the threshold (4×10⁻⁴ in t/r, 0.02° in tilt — both well inside the registered tolerances). The thresholds are scale-invariant (gravity-doubling must move nothing, asserted) and are policed by the golden values: a mis-set threshold cannot land on 0.1075 from both sides. Whiting's ownΣ(f_n⁻)²reading is reported beside it at spot values.
Recorded, not registered: the threshold at N ∈ {25, 50, 100, 200} — the paper's own warning that coarser blocks over-estimate stability (a hidden gameplay parameter), so the coarse thresholds should sit below the fine ones; the direction is the claim, the magnitude is data.
Falsified by missing either golden value. Instrument-aborts, before any verdict: a gravity-scale variance, or any bisection step in the undecided band. R-034b (split at registration, per the ticket's own note) carries the warm-start bimodality clause and the game-facing economics.
Records test, blocks, value, target, abs_error, within_tolerance,
residual_feasible, residual_infeasible.
🔬 M-330 / P-33 — HELD on both golden values: the feasibility solver is now held to external truth, and the coarsening warning would not reproduce on an arch (R-034a)
M. cargo bench --bench experiment_p33, docs/experiments/p-33.csv.
| test | value | target | error | tolerance |
|---|---|---|---|---|
| Milankovitch minimum thickness, 100 blocks | 0.10734 | 0.1075 | 0.00016 | ± 0.0010 (Whiting: 0.10746) |
| Ochsendorf critical tilt at t/r = 0.20 | 15.850° | 15.84° | 0.0096° | ± 0.05° |
The instrument behaved exactly as corrected. Feasible probes land in the intersection — cone-side equilibrium residuals of 10⁻¹⁶ of total weight — while infeasible probes stall three orders above the 10⁻⁴ line, so the undecided band (asserted never hit) was never even approached; gravity-doubling moved no verdict; both bracket ends classified as registered before either bisection was trusted. The pre-run FISTA→alternating-projection correction is what made those readings possible at 20,000 fixed iterations.
The recorded coarsening sweep is a small falsification of an expectation that was never registered here, and worth keeping. The paper warns that coarser blocks over-estimate stability, and the dossier's own sketch predicted a ≥ 5% unconservative shift under 2× coarsening. Measured on the arch: thr(25) = 0.10703, thr(50) = thr(100) = thr(200) = 0.10734 — a 0.3% shift at 25 blocks and flat from 50 up, at a 4×10⁻⁴ bisection width. The brief's own caveat applies verbatim: a plain arch is too simple to discriminate the block-size effect; measuring it needs a compound structure (vaults, buttresses — where Whiting's own hinging-mechanism warning lives). R-034b's fixture should be built to discriminate it.
Consequence: the solver is trusted — nothing structural was buildable on it until these two numbers hit, and they hit. R-034b (warm-start bimodality, the cheap-incremental question) is unblocked and next in the phase order.
Would be shown wrong by: a tessellation sweep showing the 0.10734 drifting with N beyond the bisection width (the paper's own value moved in the fifth digit, ours in the fourth); or the tilt value failing to track μ once sliding governs (μ = 0.7 keeps hinging in charge here, tan 15.85° = 0.28 ≪ 0.7).
P-34 — registered for R-034b, before the harness was written; the cheap-incremental question, counted
What the original R-034 registered and the split deferred. Warm-started re-solve is bimodal — under 15% of cold cost for edits that do not sever a load path, under 2× speedup for those that do — or the cheap-incremental story dies and the admissibility gate is background-budget-only. M-330's solver is now trusted; this measures its economics.
H. On a running-bond masonry wall (8 courses, ~96 blocks, bed and head joints, μ = 0.7): (C1) over 10 non-severing edits — single-block weight nudges, small gravity tilts — the median warm/cold ratio of iterations to the feasibility decision is ≤ 0.15; (C2) over 10 severing edits — an interior block removed, forces rerouted around the hole — the median ratio is ≥ 0.5; and the two class medians are separated by > 3×, which is the bimodality claim stated as a number.
Fixture chosen for redundancy, on M-330's evidence. A severing edit can only leave a standing structure if an alternate load path exists; the arch has none, and M-330 measured the arch too simple to discriminate block-structural effects at all. A running-bond wall reroutes around a hole by corbel action through its bond — the classic redundant masonry element.
Counted, not timed (✗24). Cost is the alternating-projection iteration count until the cone-side residual per unit weight first crosses the 10⁻⁵ feasibility line — cold from zero, warm from the pre-edit solution carried across by interface identity (a removal drops its own interfaces; every other variable maps 1:1). Wall-clock is printed beside the counts and gates nothing.
Falsified by a unimodal ratio distribution — class medians within 3× — which kills the
cheap-incremental story. Instrument notes, registered: an edit that classifies infeasible at the
20,000-iteration cap is recorded collapsed and excluded with its count printed (a corpus that
mostly collapses is a fixture failure and aborts); every surviving edit must reach the decision
line within the cap.
Records edit, class, iters_cold, iters_warm, ratio, feasible.
💥 M-331 / P-34 — FALSIFIED as registered, by an instrument floor the registration promised was fine, and by a corpus that mixed two edit species (R-034b)
M. cargo bench --bench experiment_p34, docs/experiments/p-34.csv.
C1 read a non-severing median ratio of 0.400 against the registered ≤ 0.15; C2 held (severing median 0.800 ≥ 0.5); the bimodality clause read 2.0× separation against the registered
3× — FALSIFIED. And the registration's own sentence — "counts carry that granularity — recorded, and far finer than the 3× separation under test" — is where the defect lives, in three parts:
- The probe floor sat above the registered bound. Cold solves took 40–80 iterations on this wall (the base stood in 50), and the decision was probed every 10 — so the minimum measurable ratio was 10/50 = 0.2. All five weight-nudge edits pinned exactly there: an instant warm solve could not have scored under 0.2, and C1's 0.15 was unreachable by construction. The granularity promise was written against an estimated cold count of hundreds, never checked against the fixture — the same failure shape as P-29's tick arithmetic, one experiment later.
- The fixture is too easy for the question. A 92-block wall decides in 50 iterations from zero; there is no dynamic range for incrementality to show in. The dossier's warm-start question lives at ~1,000 blocks and 30–200 ms solves.
- Tilts are not local edits. A 0.3–0.7° gravity rotation moves every interface force; the measured 0.4–0.6 ratios are honest for what tilts are — a global re-load — and mixing them into the "non-severing" class buried the local-edit signal.
The signal underneath, recorded not registered: single-block weight nudges (floor-pinned ≤ 0.2) against block removals (0.5–1.0, median 0.8) separate by ≥ 4× — consistent with the bimodality the ticket wants, and undecidable at this instrument's floor. P-35 re-asks once, with the corrections derivable in advance: probe every iteration, a wall sized for three-digit cold counts, and tilt as its own recorded class.
Would be shown wrong by: P-35 finding the weight-nudge class still above 0.15 with the floor removed — which would mean the 0.400 was never the instrument's and the cheap-incremental story dies on merit.
P-35 — registered for R-034b, before the corrected instrument ran; P-34 with its floor removed and its corpus unmixed
The M-289 shape, third use today. M-331 falsified P-34's clauses through an instrument floor (probe granularity 10 over 50-iteration cold solves puts the minimum measurable ratio at 0.2, above the 0.15 bound) and a mixed corpus (tilts are global re-loads, not local edits). This re-asks the ticket's own prediction once, with every correction derivable in advance: the decision probed every iteration (floor = 1/cold); the wall grown to 20 courses × 24 blocks (~470 blocks) so cold counts get three digits of dynamic range; tilts out of the registered corpus and recorded as their own class.
H. Over 10 single-block weight nudges the median warm/cold iteration ratio is ≤ 0.15; over 10 interior removals it is ≥ 0.5; the class medians separate by > 3×. (M-331's floor-pinned nudges and 0.8 removal median already point here at 4×, undecidably.)
Falsified by the weight-nudge median still above 0.15 with the floor at 1/cold — then the 0.400 was never the instrument's, and the cheap-incremental story dies on merit, demoting the admissibility gate to background-budget-only exactly as the original R-034 registered. Or medians within 3× — unimodal, same consequence. Collapsed removals excluded on the record as in P-34, aborting past three.
Records edit, class, iters_cold, iters_warm, ratio, feasible.
🔬 M-332 / P-35 — HELD on all three clauses: warm-starting the admissibility solve is bimodal by edit class, and the tilts confirm their own exile (R-034b)
M. cargo bench --bench experiment_p35, docs/experiments/p-35.csv.
| class | ratios (warm/cold iterations) | median | registered |
|---|---|---|---|
| local (10 single-block weight nudges) | 0.036 – 0.179 | 0.143 | ≤ 0.15 — HELD |
| severing (10 interior removals, all stood) | 0.536 – 0.971 | 0.679 | ≥ 0.5 — HELD |
| separation | — | 4.8× | > 3× — HELD |
| tilt (recorded, exiled by M-331) | 0.607 – 0.774 | 0.72 | severing-grade, as diagnosed |
The floor is gone and the answer is the ticket's. With the decision probed every iteration, the minimum measurable ratio fell to 1/28 and one nudge decided in a single warm iteration; the local-edit class landed at a 7× median advantage, structural edits at ~1.5×, and the class medians separate 4.8×. Warm-started re-solve of the M-330-validated program is bimodal by edit class — the cheap-incremental story the original R-034 registered survives, with two caveats on the row: C1's median clears its bar by a fifth of one iteration quantum (0.143 vs 0.15 at a 0.036 quantum), and at these sizes even the cold solve is trivial — the 470-block wall stood in 28 iterations from zero, so the economics that matter at the dossier's 1,000-block, 30–200 ms scale are extrapolated from counts, not yet from big-structure walls.
The tilt class confirms M-331 from inside the data: every tilt ratio sits in the severing band. "Does this edit re-load the whole structure" is the variable; adjacency was never it — the same lesson M-329 taught about modal strain density, in statics costume.
Consequence: the admissibility gate may plan on warm starts for local edits and budget cold re-solves for structural ones; the block decomposition remains a pure function of the edit log per the paper's warning, and the big-structure timing scale stays open for the build ticket.
Would be shown wrong by: a wall or compound structure whose cold count reaches the hundreds showing the local-edit advantage collapsing (the extrapolation failing exactly where it matters); or any corpus where removals reroute nothing (a wall with no bond) reading bimodal anyway — which would mean the classes measure the solver, not the structure.
🔬 M-333 — the heat-operator substrate verifies against a dense reference, and its own numbers pre-shrink two of R-035b's expectations (R-035a)
M. cargo bench --bench r035a_substrate, docs/measurements/r035a-substrate.csv. Comparative,
deliberately without a P- id — correctness against a reference is not a hypothesis (the M-322
precedent).
On a 447-vertex Surface Nets mesh, the up-looking sparse LDLᵀ under the BFS-bisection
nested-dissection ordering matches a dense LDLᵀ of the permuted heat operator entrywise at
3.1×10⁻¹⁶ and their solves agree at 1.4×10⁻¹⁴. On the 64³ chunk — 12,615 vertices (the
dossier extrapolated ~15k), 24,366 triangles, h̄ = 0.0577, t = h̄² — the factor holds
‖LDLᵀ − A‖_F/‖A‖_F = 2.0×10⁻¹⁶ against the derived 1.4×10⁻¹⁰ bound with nnz(L) = 1,144,427,
and a partial refactor over an ancestor closure with unchanged values reproduces the factor
bit-for-bit across 11,228 closure rows — the update path demonstrated to be a no-op exactly when
nothing changed, which is the cheapest strong correctness check this machinery admits.
Two numbers that pre-shrink R-035b, recorded before it runs. The full refactorisation costs 87.7 ms — already under the ticket's "> 100 ms" absolute, which is why R-035b registered the ratio as its load-bearing clause. And 131 scattered seeds closed over 89% of all rows: the elimination-tree paths are long even under nested dissection, so everything rests on whether a clustered brush halo closes small — which is precisely the question the experiment exists to answer rather than assume.
Would be shown wrong by: any input on which the no-op partial refactor is not bit-identical, or a mesh whose heat operator fails the SPD pivot assert — both abort loudly rather than report.
P-36 — registered for R-035b, before the harness was written; the routing decision, on a verified substrate
What this decides. The dossier's Law 2 disqualifies any prefactored surface operator for live
carving unless its factorisation can be updated rather than rebuilt; if the update is not clearly
cheaper, everything surface-intrinsic routes to the Closest Point Method (Dziuk & Elliott,
10.4171/ifb/182, READ: the matrices "depend only on the evaluation of the gradient of the level
set function" — a brush touching k voxels changes exactly k stencils). M-333 verified the
substrate and pre-shrank two expectations: the full refactor already costs 87.7 ms (under the
ticket's > 100 ms absolute — the ratio is the registered clause), and scattered seeds close 89%
of the elimination tree; whether a clustered brush halo closes small is exactly what this
measures.
H. A radius-4-voxel surface perturbation changes ≤ 400 vertex slots (M-318's 346 of 15,706, keyed by cell identity; the 1-ring operator-row halo counted beside it, expected 3–6×), and a partial refactorization over the elimination-tree ancestor closure of the changed columns re-establishes a valid factorisation ≥ 20× cheaper than a full refactorisation by wall time, with the flop ratio ≥ 10 alongside — a large time ratio over a small flop ratio is an implementation artifact, not a result.
Validity asserted, never assumed: the updated factor must hold the same Frobenius bound a fresh one does; its solve must agree with the refactored solve within 10⁻⁸ relative (κ-derived with five orders of margin); and a deliberately skipped closure column must push the residual past its bound — the inversion seen red before any verdict. The fixture is a value update on a stable pattern: the slot set changing at all aborts the run, and says so. Timing interleaved both orders (ABAB/BABA), 11 repetitions, medians, flops counted beside wall (✗24, M-197 both honored).
Falsified by the update under 10× by wall or under the flop floor — the prefactored family is dead for live carving and the CPM takes the intrinsic lane; that routing decision is the ticket's whole point, and it gets recorded whichever way it lands. The slot count exceeding 400 re-scopes M-318's extrapolation without deciding the routing by itself.
Records rep, order, update_ms, refactor_ms, update_flops, refactor_flops,
changed_slots, changed_rows, closure_rows.
💥 M-334 / P-36 — FALSIFIED at 1.7× against a registered 20×: the separators eat the update, the prefactored family is dead for live carving, and the intrinsic lane routes to the Closest Point Method (R-035b)
🎉🎊🔥✨🏆 DISCOVERY 🏆✨🔥🎊🎉
🥇 An 86-vertex brush halo — four times under the registered slot budget — drags an elimination-tree ancestor closure of 5,853 rows, 46.4% of the matrix, through exactly the nested-dissection separator columns where the factorization's work lives: the "update" costs as many flops as the full refactorization and saves only 1.7× of wall. The failure is structural, not implementational — the halo was tiny and the validity was perfect — and it makes the routing decision the ticket existed to make: everything surface-intrinsic goes to the Closest Point Method.
🧪 Tested by:
cargo bench --bench experiment_p36(P-36),docs/experiments/p-36.csv🎯 Result: update 46.9 ms vs refactor 81.8 ms (medians, interleaved both orders) — wall 1.7× against the registered ≥ 20× and the ≥ 10× kill-line; update flop count ≥ the full refactor's; slots 86 ≤ 400 (that clause HELD); validity: residual 2.0×10⁻¹⁶, solves bitwise identical, skipped-column inversion red at 5.2×10⁻⁶. 📐 Why it earns the banner: 💥 a pre-registered prediction falsified with a clean structural mechanism — M-333's scattered-seed flag (89% closure) confirmed in clustered form, which is the form that mattered — and the consequence is a routing decision, made on measurement rather than on the dossier's hope. Two 🪤 rode along: field-level value edits always change the slot set near the zero set (M-318's "appears, vanishes, or moves" is the common case, recorded from two aborted fixtures), and a per-fixture-derived parameter leaked global change into a local-edit experiment (the new Part 5 rule). 💣 Would be shown wrong by: a supernodal or subtree-cached update (the Herholz line the dossier lists as unobtained acquisitions) beating the closure barrier on this same fixture.
M. cargo bench --bench experiment_p36, docs/experiments/p-36.csv.
| quantity | value | registered |
|---|---|---|
| changed slots (cell-keyed) | 86 | ≤ 400 — HELD (M-318 extrapolated 346) |
| changed operator rows (1-ring) | 122 (1.4×) | recorded (memo guessed 3–6×; a contiguous ball's ring is mostly internal) |
| ancestor closure | 5,853 / 12,615 rows (46.4%) | the unknown M-333 flagged, now measured |
| update vs refactor, wall | 46.9 ms vs 81.8 ms — 1.7× | ≥ 20× (H), < 10× kills — FALSIFIED |
| flop comparison | update ≥ refactor | the ≥ 10× floor, unreachable |
| validity | 2.0×10⁻¹⁶ residual; solves bitwise equal; inversion red | all asserted before timing |
The mechanism, and why no tuning rescues it. The halo is not the problem — 86 slots is better than M-318 promised. The problem is where the closure goes: every clustered edit's elimination-tree paths climb into the top separators, the separators on a surface mesh are O(√n) wide, and their columns are where the factorisation's arithmetic is concentrated. Recomputing 46% of the rows is recomputing most of the work. (The recorded update-flop counter additionally over-counts scan-past entries in partial mode; the wall ratio is the honest figure, and at 1.7× the over-count changes nothing — both readings sit an order under the kill-line.)
The routing, per the dossier's own three escapes: chunk-scoped refactorisation survives as a
background-budget option (81.8 ms per 64³ chunk, off the frame path); CHOLMOD-style updating is
dead here on structure, not implementation; and live surface-intrinsic work routes to the
Closest Point Method (Dziuk & Elliott, 10.4171/ifb/182, READ: the matrices depend only on the
level-set gradient — a brush touching k voxels changes exactly k stencils, no global factor to
repair). The Herholz-line update papers remain unobtained; if acquired and their subtree machinery
beats the closure barrier, this row is the fixture to re-run.
Two fixture lessons, kept as data: field-level value edits at 0.3 and 0.08 voxel amplitudes
both changed the slot set — near the zero set there are always samples under any amplitude, so a
value-only factor update can never serve a whole real brush edit anyway; and the heat time t
must be pinned across compared meshes (the new Part 5 rule), which the first validity run found at
a cost of one morning's confusion and no data contamination.
Would be shown wrong by: the banner's supernodal escape; or a chunk size at which the closure fraction drops enough to clear 10× (smaller chunks shrink the separators — but also the refactor they're racing).
P-37 — registered for R-036, before the harness was written; and the ticket's premise correction is the registration's first line
The premise, checked against the code (workflow step 1). The ticket says the tracker "already
maintains the two accumulators a Sabine estimate needs (component volume, boundary surface area)".
Half true: Air::component_size maintains volume; no surface-area accumulator exists anywhere in
the crate — verified by read (connectivity.rs holds size, free, live, pending and
scratch; nothing counts faces). The contradiction is the finding, and the measurement requires this
batch's one public-API addition, plan-approved: area: Vec<u32> maintained beside size, exposed
as component_area(label).
H. With per-label air–solid face counts delta-maintained through
build,dig's blob growth,fill's retirement, merge transfer and split hand-off — domain-boundary faces counted as solid (the sealed-box convention; a component touching the chunk edge isAirWorld's problem, deliberately out of scope) — (C1) a Sabine RT60 for the breach-frame component (0.161·V/(α·S), two accumulator reads and a divide) costs < 0.1 ms, structurally; (C2) a Planeverb-style 2-D FDTD re-bake of a 64×64 slice (Rosen, Godin & Raghuvanshi,10.1111/cgf.14099, public C++ reference; leapfrog pressure–velocity, 1,000 steps ≈ half a second of audio at the CFL step — the length a decay measurement needs; damped edges, cost is the claim and acoustic fidelity is not) completes in < 30 ms single-threaded. Falsified by either figure exceeding its bound by 3× — the ticket's own falsifier.
The invariant, and its red demonstration. After any synchronous op sequence, a full O(6n)
recount must equal the maintained per-label counts, and a label-free global face total must equal
their sum — asserted in the crate's own tests over build/dig/fill/split/merge sequences on the
noise_cavity distribution fixture and the P-26 bisect fixture, with a deliberate one-count
corruption shown to turn the checker red. Budget-truncated ops leave area conservatively stale
exactly as labels already are — scoped and documented, not solved (the drained state is the
contract, as it is for label).
Recorded, not registered: dig/fill costs with the accumulator in place (the O(dirty·6) claim, read against M-321's baselines), and the split rate against M-319's one-in-six — a divergence there would be news; the clauses holding is not, and this row expects no banner.
Records quantity, value, unit, bound, held.
🔬 M-335 / P-37 — HELD on both clauses with orders to spare, and the premise correction is the part that mattered (R-036)
M. cargo bench --bench experiment_p37, docs/experiments/p-37.csv.
| quantity | value | bound | margin |
|---|---|---|---|
| RT60 read on the breach frame | 0.0015 µs | 100 µs | ~66,000× — two counter reads and a divide, structural as registered |
| 64×64 FDTD re-bake, 1,000 steps | 3.07 ms | 30 ms | ~10× |
| RT60 of the merged chamber | 0.70 s | recorded | a plausible cave-chamber reverb at 0.25 m voxels, α = 0.15 |
| split rate over 200 fills | 0.050/fill | recorded | fixture-dependent — see below |
| fill / dig medians with the accumulator | 0.004 / 0.0003 ms | recorded | the O(dirty·6) claim, held in practice |
The part that earned the ticket was never the timing. The dossier called this "the one Tier 1
row with no premise left to falsify" — and its premise was still half wrong: no surface-area
accumulator existed. The work was Air's one public-API addition (component_area,
delta-maintained at every site label is, sealed-box boundary convention, drained-state contract),
policed by a recount oracle that runs after every op in the crate's tests, survives a seeded 60-op
merge/split/vanish sequence, and was shown to go red on a deliberate one-count corruption. Once the
counters exist, the Sabine read is nanoseconds by construction — which is what "structurally so"
in the registration meant.
The split-rate note, kept honest: 0.050/fill here against M-319's ~0.167 is two fixtures, not a divergence of the tracker — M-319 measured a noise-cavity distribution, this run fills two big open chambers. The registered would-be-news condition was a divergence on comparable geometry; this is not that, and no banner is claimed.
What a build inherits: the reverb domain is the connected air component; its Sabine estimate is
free on the frame of any breach; the invalidation trigger (splits/merges) is already counted by
Repair/Fill; and the 2-D re-bake fits comfortably inside two frames. AirWorld roll-up (seam
faces) remains the stitching layer's problem, deliberately.
Would be shown wrong by: the recount oracle diverging on any op sequence (it has its own red demonstration); or a real-geometry fixture where the accumulator's O(dirty·6) maintenance shows up against M-321's baselines — the recorded medians say it does not.
Phase 19 — six registrations from the 2026-08-23 dossier, all before their harnesses
Source: docs/research/2026-08-23-discovery-dossier.md — eight parallel corpus sweeps over lenses the
two previous rounds never used. All six are registered here in the commit before the commit that
measures any of them, per Phase 15's protocol. Tier at registration is F; each becomes M or ✗
with its result.
One instrument finding is worth banking before any of them run, because it changes how the next
sweep should be run: abstract_search returned zero relevant hits on every graphics or geometry
query across all eight agents, while distill_search returned rank-1 hits on the same subjects. The
graphics corpus carries no abstract text, so the abstract index degrades to title-or-nothing and the
known 37.3% null-title rate becomes effectively total for this region. openalex_search was down for
the entire session — 30-second SSE timeouts on roughly 25 calls — so the third-channel novelty check was
done with paper_get, paper_search and paper_citations instead, and each candidate records which.
And paper_download is not a presence oracle: it reported "No open-access PDF found" for Museth's
VDB, which catalog_read then showed is present, converted and embedded with 45 chunks.
P-38 — registered for R-037: A-024's remedy reached one of the two engines
The contradiction, found by reading both engines side by side. dual.rs carries
row_stride(size) = size[0] | 1 and the doc comment recording what it bought — "Surface Nets measured
3.37× the cost of 127³ or 129³ there … 256³ pays 1.39×" (A-024, M-287). MarchingCubes has no such
thing: it indexes its private values buffer through shape.linearize (marching_cubes/mod.rs:687),
so at 128 samples per axis the row stride is 512 bytes and the plane stride exactly 65,536 — both
aliasing periods, unmitigated. Its edge_vertices cache is worse: 3 · sample_count u32, a plane
stride of 3 × 65,536, and it is the buffer with the scattered access pattern.
H. (C1) On
sphere, Marching Cubes at 128³ costs more than 1.5× the mean of its 127³ and 129³ neighbours per sample. (C2) Giving both private buffers thesize[0] | 1stride takes that ratio under 1.1 and is worth at least 1.25× at 128³. (C3) All 216 golden hashes are bit-identical afterwards — structurally, since the change permutes where floats are stored and not which floats are computed, nor the order cells are visited, nor the order vertices are created. Falsified by the 128³ ratio coming in under 1.5× before the change, which would mean Marching Cubes' access pattern does not alias and A-024's remedy is specific to the dual path. A moved golden hash falsifies C3 outright and makes this a behaviour change rather than a layout change.
It runs first for a reason. P-40 measures a traversal-stage ratio at 128³. If Marching Cubes is sitting in a 3× aliasing hole at exactly that size, a 128³ comparison measures the hole — the ✗14 lesson in new clothes: a null measured under a dominant confound is a statement about the confound.
Records extractor, samples_per_axis, ns_per_sample_before, ns_per_sample_after,
neighbour_ratio_before, neighbour_ratio_after, golden_unchanged.
P-39 — registered for R-038: a brush that cannot win can be deleted, bit-exactly
The workload. BrushStack::sample is a linear fold over every brush, and MarchingCubes::extract
prefills the whole sample grid before any cell work, so a 33³ chunk evaluates the entire edit history
35,937 times. In a destructible world the tape only grows, and nothing in the crate attacks it.
The mechanism. Bound each brush's shape over the chunk AABB — with declared Lipschitz constant l
the bound over a box of circumradius r about c is f(c) ± l·r, so it is one sample per brush per
chunk — and delete every brush that provably cannot affect the result inside. Keeter measures the
reduction at "two orders of magnitude"; Barbier et al. generalise it to the Lipschitz property and
name this use case as future work: "could also lead to significant improvement for SDF discretization
or polygonization." This is not the tabled Sharp & Jacobson row — that rejects cells with no
surface; this shortens the expression the surviving cells evaluate.
The lemma is ours, derived from this repo's source. No paper in that literature discusses IEEE
bit-identity of pruning, because none of them has a 216-hash gate — they prune to preserve a rendered
image, which tolerates ULP drift. apply(Add) = min and apply(Subtract) = max select an operand
rather than computing a new value, and negation is exact, so dropping a provably-losing hard brush moves
the result by zero ULP. smooth_min is exactly dominant at h == 0 and not bit-exactly prunable
in the losing direction: at h == 1 it returns b + (a − b), which is not bit-identical to a.
H. On a 64-brush stack of
Add/Subtractspheres and capsules scattered over a 4×4×4 chunk world: (C1) the median surviving-brush fraction per chunk is under 0.5; (C2) meshing against the pruned tape is at least 1.25× meshing against the full one; (C3) every chunk's mesh is byte-identical between the two. Falsified by a survivor fraction at or near 1.0 — nothing to prune, whatever the papers report — or, far more interestingly, any byte difference on a hard-op-only stack, which would refute the selection lemma the mechanism rests on.
Sources. Barbier et al., Lipschitz Pruning, 10.1111/cgf.70057 — not in corpus, DOI verified.
Keeter, 10.1145/3386569.3392429 — not in corpus, double-checked by catalog_read and
distill_exists. Tilove, A null-object detection algorithm for CSG, CACM 1984,
10.1145/358105.358195 — in corpus and indexed, and it is the same argument as set theory forty
years early. It ranked third on its query with title: null, which is the 37.3% hazard firing live.
Records brushes, chunks, survivor_fraction_median, survivor_fraction_max,
ns_per_sample_full, ns_per_sample_pruned, speedup, mesh_identical.
P-40 — registered for R-039: the active-cell test is one bit, so 64 cells decide at once
DualMesher::place_vertices gathers eight corners and counts insides for every cell and skips ~97%
of them. Pack value < 0 into a u64 along x and fuse the four rows bounding a cell row:
any = OR(w | w>>1), all = AND(w & w>>1), active = any & !all — about twenty word operations for
sixty-four cells. Walk the set bits with while w != 0 { let b = w.trailing_zeros(); w &= w - 1; },
which is safe stable core, no_std, and lowers to tzcnt/popcnt and rbit+clz with no
target-feature gate and no unsafe. Mechanism source: Museth, VDB, 10.1145/2487228.2487235 — in
corpus, whose whole topology layer is per-node bitmasks under word-level boolean ops.
H. (C1) On a surface-free 128³ field, where the active path never runs, the traversal stage is at least 2× faster. (C2) On
sphereat 128³ the whole extractor is at least 1.25× faster. (C3) The mesh is byte-identical: the bit is the same comparison and the set-bit walk visits cells in the same lexicographic order, so vertex creation order is unchanged. Falsified by the stage ratio under 2× — the scalar gather was not the cost — or the whole-extractor ratio under 1.25×, which puts the mechanism under the Amdahl floor M-296's field-evaluation dominance sets.
One trap, registered rather than discovered. The IEEE sign bit is not the inside bit: -0.0 has
it set while -0.0 < 0.0 is false, and box_exact is exactly zero across its whole boundary, so signed
zeros are reachable in this crate's own fixtures. The comparison stays.
Records field, samples_per_axis, active_fraction, stage_ns_scalar, stage_ns_bitmap,
stage_ratio, extract_ns_scalar, extract_ns_bitmap, extract_ratio, mesh_identical.
P-41 — registered for R-040: is the sign lattice well-composed, and is that where the duals fail?
A digital set is well-composed exactly when its boundary is a 2-manifold, which Latecki characterises by the absence of two critical configurations — a diagonal pair sharing only an edge, and a diagonal pair sharing only a vertex. In a well-composed set 6-, 18- and 26-connectivity coincide, so "is this cave sealed" stops depending on which connectivity was picked. The move would be to repair the sign pattern upstream, before the case table is indexed, rather than to repair the mesh.
H. (C1) Over the eight reference fields at 65³, the count of cells whose 2×2×2 sign neighbourhood hosts a critical configuration is non-zero on at least
noise_cavity. (C2) At least 90% of the non-manifold edge and vertex incidentsMeshReportalready reports forDualContouringandSurfaceNetsoccur in cells the census flagged. Falsified by a zero census on all eight fields — the lattice is already well-composed and the non-manifold output comes from somewhere else, the QEF vertex escaping its cell being the obvious other suspect — or co-location below 90%, meaning a repair would be treating the wrong object.
This registers the detector only, and that is deliberate. The repair moves the surface by up to a cell and breaks every golden hash, so it is worth designing only if C2 holds. Overlap, named: this is not the banked union-find safety gate, which gates a vertex reposition after extraction on the mesh.
Sources. Latecki, Eckhardt & Rosenfeld, 10.1006/cviu.1995.1006; Latecki, 10.1006/gmip.1997.0422;
Boutry, Géraud & Najman, 10.1007/s10851-017-0769-6 — all DOI-verified, none in corpus. Two
near-miss DOIs caught during verification and recorded so nobody re-derives them:
10.1006/cviu.1995.1013 is Brechbühler's SPHARM paper, and 10.1016/j.dam.2015.01.006 is about Turán
numbers.
Records field, samples_per_axis, cells, critical_2d_cells, critical_3d_cells, extractor,
non_manifold_edges, non_manifold_vertices, incidents_in_critical_cells, colocation_fraction.
P-42 — registered for R-041: curvature as a measure, with a bound the crate computes itself
MeshReport carries mean_ratio and euler_characteristic and nothing that measures curvature or
bounds its own error. Angle defect is textbook and is not the claim. Two things are: normal-cycle
measures are additive — N(A ∪ B) = N(A) + N(B) − N(A ∩ B), so a chunk's measure is the sum over its
cells with the shared boundary subtracted once, and per-chunk numbers compose into per-world numbers with
no global pass — and Sun & Morvan's Theorem 6 (10.5802/acirm.50) gives an error bar C·K·ε
with K = Σ cr(t)² + Σ_{t∩∂B≠∅} cr(t) and ε = max cr(t), every quantity computable from the mesh
alone. (Attribution corrected 2026-08-23 by external audit §B.1: 10.1145/777792.777839, Cohen-Steiner
& Morvan SoCG 2003, has exactly one numbered theorem — Theorem 1 — plus Proposition 3 and Lemmas 2 and
4–9. The numbered Theorem 6 is Sun & Morvan's, which this registration already cited as the in-corpus
companion carrying the transcribable formulas. The substance is untouched; the theorem number belongs to
the other paper of the two.)
validate::accuracy measures distance and validate::isotopy certifies topology; neither states a bound
it derived rather than sampled.
H. (C1) On
sphereat 33³/65³/129³, the residual|Σ α_v − 4π|falls inside the computed bound at all three. (C2) That residual falls at least linearly ashhalves. (C3) Ontorusthe defect sum is zero to within the same bound — which an accumulator that lost the sign would fail loudly. Recorded beside them, not registered: the mean-curvature total, and theχrecovered from the defect sum against theχMeshReportcomputes independently. Falsified by the residual exceeding its own bound at any resolution, or failing to fall ashhalves.
The falsifier is aimed at the interesting failure. Theorem 6 needs the polyhedron closely inscribed
with the projection a bijection, and marching-cubes vertices lie on the trilinear interpolant's zero
set, not the field's. If the residual escapes its bound, that hypothesis has failed — and the remedy is
to state the bound against the interpolant, which is the move isotopy.rs already makes.
Sources. Cohen-Steiner & Morvan, SoCG 2003, 10.1145/777792.777839 — DOI-verified, not in
corpus; Sun & Morvan, 10.5802/acirm.50 — in corpus, and it carries the formulas, the additivity
law and Theorem 6's constants, so rule 5 is satisfiable without the primary.
Records field, samples_per_axis, gaussian_total, gaussian_expected, residual, bound,
within_bound, mean_curvature_total, chi_from_defect, chi_from_report.
P-43 — registered for R-042: one evaluation at the cell centre as an under-sampling witness
The crate cannot tell a caller that a chunk's resolution is inadequate for the field it carries, so an
edit that carves a feature thinner than a voxel produces wrong geometry with no diagnostic.
validate::field_bound samples the gradient and is explicit that a sampled maximum is only a lower bound
on a supremum: it can disprove a declared bound and cannot certify sampling adequacy. Evaluate the field
once at each cell centre, compare against the trilinear interpolant of the eight corners, normalise by
cell size. The witness is one-sided in the safe direction — it can prove a chunk inadequate and can never
prove it adequate, which is field_bound.rs's own discipline pointed the other way.
H. (C1) Across
noise_cavityandgyroidat 17³/33³/65³/129³, the per-grid maximum normalised centre residual correlates with the symmetric Hausdorffvalidate::accuracyalready reports at Pearson r ≥ 0.7. (C2) The extra evaluations are under 15% of the corner evaluations — the structural ⅛ plus slack. Falsified byrbelow 0.7. The failure mode is named in advance rather than rationalised afterwards: a feature passing cleanly through the cell centre without perturbing it gives a residual near zero while the reconstruction is badly wrong, andthin_plateis constructed to be exactly that, so it is measured beside the two registered fields as the adversary.
Sources. Petersen & Middleton, 10.1016/s0019-9958(62)90633-2, DOI-verified, for the
sampling-theoretic root; Chazal, Cohen-Steiner & Lieutier, 10.1007/s00454-009-9144-8 — in corpus and
indexed — for the version that tolerates non-smooth shapes, which is what csg_difference and
box_exact need.
Records field, samples_per_axis, centre_residual_max, centre_residual_mean,
symmetric_hausdorff, pearson_r, extra_eval_fraction.
💥 ✗28 / M-336 — FALSIFIED at 0.98 against a registered 1.5×: the 128³ penalty is a property of the access pattern, not of the stride, and Marching Cubes does not have one (P-38, R-037)
⚠ CORRECTED at ✗35 / M-348 — the table below is not the run in
p-38.csv. The verdict is untouched: every reading in either run sits between 0.93 and 1.01 against a registered 1.5×. The numbers are what moved.
M. cargo bench --bench experiment_p38, docs/experiments/p-38.csv. Sphere, f64, one thread,
median of five timed runs after an untimed warm-up, each reported per sample of its own grid.
| extractor | n | [n,n,n] |
neighbour mean of [n±1]³ |
ratio | [n\|1,n,n] |
[n,n,n\|1] control |
|---|---|---|---|---|---|---|
| marching_cubes | 128 | 8.643 | 8.850 | 0.977 | 8.899 | 8.916 |
| marching_cubes | 256 | 8.570 | 8.603 | 0.996 | 8.574 | 8.590 |
| surface_nets (control, already fixed) | 128 | 11.493 | 11.879 | 0.968 | 11.311 | 11.726 |
| surface_nets (control, already fixed) | 256 | 12.047 | 12.842 | 0.938 | 12.007 | 12.001 |
Clause one is dead on arrival, and it takes clause two with it. The registered threshold was
> 1.5× at 128³ and the measurement is 0.977 — 128³ is marginally faster than the mean of its
neighbours. On the surface-free field, where A-024's 3.37× was originally found and where nothing but
scaffolding is being timed, Marching Cubes reads 8.116 against a neighbour mean of 8.046, a
ratio of 1.009. There is no penalty to remove, so no stride change was made: adding a pad that buys a
measured nothing would be a layout nobody can justify from a number.
✗28 — "the 65,536-byte plane stride is the defect, so any buffer with it pays". That is the belief
this row kills, and it was mine: the inference from dual.rs's doc comment to "MarchingCubes has the
same latent defect" is exactly the shape of reasoning A-024's own note warns about, and it was made
from the buffer's dimensions without looking at how it is walked. The two engines touch values
completely differently. Marching Cubes reads eight corners of the current cell and then steps x, so
consecutive cells share four corners and the whole traversal streams: two rows and two planes are live,
the prefetcher sees a linear pattern, and the set-aliasing period is never exercised because the working
set never spans enough distinct lines mapping to one set. The dual mesher's emit_quads walks every
grid edge on all three axes — M-284's 82%-of-cycles stage — loading both endpoints of edges that are a
row and a plane apart, which is precisely the pattern that turns a 64 KiB plane stride into a conflict
miss on every access.
The pad_z control is what makes this a measurement rather than an absence. [128,128,129] adds
the same 0.8% of work as [129,128,128] and touches neither stride, and it comes in at 1.0075 of the
neighbour mean against the padded row's 1.0054. Both are noise. In A-024's run that control kept the
entire 3.35× penalty, which is what identified the stride as the cause there. Here there is no
penalty for it to keep.
So A-024's remedy is correctly scoped, and now that is measured rather than assumed. size[0] | 1
belongs to DualMesher because the defect belongs to DualMesher's access pattern. A future extractor
inherits the pad only if it inherits the walk.
Two things recorded beside the registered clauses. Clause three held vacuously and is still worth
having: the harness recomputes every marching_cubes row of the committed fixture through
validate::mesh_hash and reports 24 of 24 matching, which is the golden gate running inside the
bench rather than beside it. And surface_nets at 256³ reads 0.938 of its neighbour mean — its
odd-sized neighbours 255³ and 257³ are slower than the padded 256³, by about 6%. That is the fix
working from the other side and is not claimed as more than an observation; nothing here isolates it.
Provenance note. Every CSV produced in this phase carries (WORKING TREE DIRTY) in its header. The
tree holds untracked research documents from an earlier session that are not this phase's to commit; the
measuring commit is named in the same header and the harness is committed before the run.
Would be shown wrong by: a machine whose L1 associativity or line count makes the streaming pattern
alias after all — the claim here is about an access pattern on this machine, and scripts/machine.sh
stamps which. Re-running the same bench elsewhere is the check, and it costs thirty seconds.
🔬 M-337 — HELD on all three clauses: the active-cell test is one bit, the stage is 5.5× and not one triangle moved (P-40, R-039)
⚠ CORRECTED at ✗35 / M-348 — C2's verdict does not survive its own artefact, and the table below is not the run in
p-40.csv. Read the correction before citing any number here. C1 and C3 stand; C2 does not.
M. cargo bench --bench experiment_p40, docs/experiments/p-40.csv, f64, one thread, median of
five timed runs after a warm-up. The extractor arm reads its "before" from
docs/measurements/p40-baseline.csv, blessed at the parent commit 64bef8a on exactly the grids that
were timed.
| clause | registered | measured | verdict |
|---|---|---|---|
| C1 traversal stage, surface-free 128³ | ≥ 2× | 5.49× (2.220 → 0.405 ns/cell) | HELD, by 2.7× the bar |
C2 whole extractor, sphere 128³ |
≥ 1.25× | 1.336× Surface Nets · 1.179× Dual Contouring | HELD for Surface Nets, missed for Dual Contouring |
| C3 mesh byte-identical | no change | 12 of 12 grids hash-identical to the blessed baseline | HELD |
The whole table, because the shape of it is the finding.
| field | n | active cells | stage scalar → bitmap | ratio | Surface Nets | Dual Contouring |
|---|---|---|---|---|---|---|
sphere_surface_free |
64 | 0 of 250,047 | 2.261 → 0.413 | 5.47× | 8.852 → 6.410 (1.381×) | 8.757 → 6.207 (1.411×) |
sphere_surface_free |
128 | 0 of 2,048,383 | 2.220 → 0.405 | 5.49× | 9.940 → 7.576 (1.312×) | 10.083 → 7.401 (1.362×) |
sphere_surface_free |
256 | 0 of 16,581,375 | 2.216 → 0.415 | 5.34× | 10.254 → 8.066 (1.271×) | 10.241 → 8.130 (1.260×) |
sphere |
64 | 4,730 (1.89%) | 2.295 → 0.433 | 5.31× | 9.917 → 7.227 (1.372×) | 24.348 → 21.698 (1.122×) |
sphere |
128 | 19,010 (0.93%) | 2.263 → 0.412 | 5.49× | 10.634 → 7.960 (1.336×) | 17.189 → 14.576 (1.179×) |
sphere |
256 | 76,778 (0.46%) | 2.239 → 0.420 | 5.33× | 10.908 → 8.747 (1.247×) | 14.034 → 11.855 (1.184×) |
Where clause two misses, and why it is a qualification rather than a surprise. The registration
said "the whole extractor" in the singular and the mechanism serves two. Dual Contouring pays a QEF
solve per active cell — 24.3 ns/sample at 64³ against Surface Nets' 9.9 — and no amount of skipping
inactive cells touches that. The mechanism removes a per-inactive-cell cost, so its leverage is
exactly inactive work / total work, and Dual Contouring's denominator is larger. That is visible in
the table as the two extractors converging as the active fraction falls: at 256³ they are 1.247× and
1.184×, and on the surface-free field, where the QEF never runs at all, Dual Contouring is the faster
of the two to improve at 1.411×. The clause is recorded as held for Surface Nets and missed for
Dual Contouring rather than averaged into a number that describes neither.
Clause three is checked where it matters, not where it is convenient. The golden suite meshes eight
fields at 17³/25³/33³, and it passes unchanged — but none of those are the grids this measured. So the
baseline carries a mesh_hash per row alongside its time, and all twelve post-change hashes equal their
pre-change value, including both extractors at 256³ where a word-boundary error would first show. That
boundary is the one real hazard in the mechanism: bit 63 of a word must take its +x corner from bit 0
of the next word, and getting it wrong punches a hole every 64 cells — invisible at 33³, which has
one word per row, and fatal at 256³, which has four.
The stage ratio is flat in n, at 5.3–5.5× across a 265× range of cell counts. That is the
signature of a mechanism that changed the work per cell rather than the memory behaviour: 2.22 ns/cell
is about eight loads and eight compares at this IPC, and 0.41 ns/cell is about twenty word operations
amortised over sixty-four cells plus the one comparison per sample the bitmap build still pays. Nothing
in it depends on the working set, which is why it does not drift with resolution.
The trap that was registered rather than discovered. The bit is is_inside(v), i.e. v < 0, and
not the IEEE sign bit. -0.0 has the sign bit set while -0.0 < 0.0 is false, and box_exact is
exactly zero across its entire boundary — so a sign-bit shortcut would have been faster still and would
have changed the mesh on a reference field. It is named in the registration, in the field's doc comment
and here, because it is the kind of shortcut a later reader will reach for.
What a consumer gets: Surface Nets is 1.25–1.38× faster on every grid measured, with byte-identical output, and the win is largest exactly where a voxel game spends its time — chunks that are mostly solid or mostly air, where the active fraction is near zero.
Would be shown wrong by: a field whose active fraction is high enough that the bitmap build's own
n³ comparisons stop paying for themselves. The crossover is where active fraction approaches the point
at which eight-corner gathers would have run anyway; gyroid at low resolution is the fixture that would
probe it, and it is not measured here.
🔬 M-338 — HELD, and the relation is a bijection rather than a correlation: the critical-configuration census does not predict the duals' non-manifold vertices, it counts them (P-41, R-040)
M. cargo bench --bench experiment_p41, docs/experiments/p-41.csv. Eight reference fields at 65
samples per axis, f64, DualContouring and SurfaceNets, 16 rows.
| field | 2D-critical | 3D-critical | non-manifold edges | non-manifold vertices | co-location |
|---|---|---|---|---|---|
noise_cavity |
567 | 35 | 322 | 602 | 1.000000 |
gyroid |
132 | 9 | 69 | 141 | 1.000000 |
fbm_terrain |
58 | 0 | 29 | 58 | 1.000000 |
sphere, torus, box_exact, csg_difference, thin_plate |
0 | 0 | 0 | 0 | — |
C1 held — the census is 602 on noise_cavity, and non-zero on three of the eight fields rather than
the one the clause named. C2 held at 1.000000 against a 0.90 bar: 2,442 of 2,442 incidents pooled
over both extractors, and 1.000000 again under the stricter both-endpoints rule for edges, so the
union-versus-both reading of "which cell owns an edge" was not load-bearing.
The bar was not cleared by arithmetic, and the null control is what says so. The share of
vertex-hosting cells that are critical — the chance baseline a random incident would hit — is
0.66% on gyroid, 0.69% on fbm_terrain and 2.1% on noise_cavity. Against that, 100%.
The unregistered half is stronger than the registered one. On every affected field,
critical cells == non-manifold vertices == critical cells hosting one
141 == 141 == 141 (gyroid)
58 == 58 == 58 (fbm_terrain)
602 == 602 == 602 (noise_cavity)
One critical cell, one non-manifold vertex, no exceptions and no extras. The clause asked whether the census predicts where the defects are. What it does is count them. And the implication runs both ways: the five fields with a zero census produce zero non-manifold output from both extractors, so this is not a one-sided detector that happens to fire near trouble — it is an exact characterisation of the dual extractors' non-manifold vertex set at this resolution.
The rival suspect the falsifier named is measured and cleared. "The QEF vertex escaping its cell"
was the other candidate cause. DualContouring's Clamp::ToCell insets by (1 − ε) and not one
vertex escapes on any field. (SurfaceNets is different and it is worth recording: its centroid rule
places 5,400 of 5,768 vertices exactly on a cell boundary on box_exact — with smoothing_passes at
its default zero nothing clamps the average of twelve edge crossings, so on a field that is exactly zero
across its boundary the centroid lands on the cell's upper face and floor() names the neighbour. It
changed no attribution here — nm_vertices_on_cell_boundary is 0 on all 16 rows — but it is a real
behavioural difference between the two placement rules and it is written down rather than left to be
rediscovered.)
The table was computed, not transcribed (rule 5). Enumerating all 256 sign bytes from the definitions gives 120 2D-critical, 8 3D-critical, disjoint — the 8 being four main diagonals × two complements — and a second classifier written from a different formulation (2×2 face parity rather than corner-index XOR) reproduces all three numbers. The 2D-critical class covers 47% of sign bytes and 0.02–0.23% of real cells, which is why the census is cheap to state and rare to trigger.
The instrument checked itself. The harness recomputes the non-manifold edge and vertex sets from
positions/indices independently, and the crate already exposes the locations through
validate::validate_features — so the row carries a list-versus-list agreement, element for element,
not merely a count-versus-count one. counts_agree and locations_agree are true on all 16 rows.
Rows with no incidents record n/a, not 1.0. An empty numerator over an empty denominator would
let the five clean fields outvote the three dirty ones in any later average — manufacturing agreement
out of silence is the failure the whole pre-registration mechanism exists to prevent.
What this buys, and what it does not. The crate can now state a number it could not: how far its input sign lattice is from well-composed, per chunk, from the sign bytes alone and before any extraction. Because the relation is a bijection, that number is also the exact count of non-manifold vertices the dual path will produce. What it does not buy is the repair: flipping a sign moves the surface by up to a cell and breaks every golden hash, and the registration deliberately withheld it pending exactly this result. The repair now has a target it can be measured against — a well-composed lattice must drive all three numbers to zero together.
Would be shown wrong by: a field where the census and the incident count come apart. The bijection is measured at one resolution on eight fields; it is a strong regularity, not a theorem, and the honest next move is a resolution sweep rather than a claim of necessity.
💥 ✗29 / M-339 — FALSIFIED on both clauses, and the mechanism survives both: the max is the wrong order statistic, and the cost clause was wrong arithmetic (P-43, R-042)
M. cargo bench --bench experiment_p43, docs/experiments/p-43.csv. Marching Cubes, f64,
noise_cavity and gyroid (registered) plus thin_plate (the registered adversary), at 17³/33³/65³/129³.
| clause | registered | measured | verdict |
|---|---|---|---|
| C1 Pearson r, max residual vs symmetric Hausdorff | ≥ 0.7 per registered field | noise_cavity +0.881, gyroid −0.847, pooled +0.249 |
FALSIFIED |
| C2 extra evaluations | < 0.15 of corner evaluations | 0.834 → 0.977 across 17³ → 129³ | FALSIFIED |
C2 was wrong when it was written, and that is the more embarrassing half. The registration says
"under 15% of the corner evaluations — the structural ⅛ plus slack". One eighth is the ratio under
per-cell accounting, one centre against a cell's eight corners. This crate does not evaluate corners
per cell: MarchingCubes::extract prefills one shared n³ grid and every corner is evaluated once
and shared by the up-to-eight cells that touch it. Against the denominator a caller actually pays, the
ratio is (n−1)³/n³, which rises toward 1, not toward ⅛. The harness records both readings —
extra_eval_fraction and extra_eval_fraction_unshared, the latter exactly 0.125 on every row — so
the row can be read either way, and neither reading rescues the clause as stated. The true cost of the
witness is about one extra field evaluation per cell, i.e. roughly a doubling of the sampling work, and
any future version of this idea has to be priced at that.
C1 failed for a mechanism the data names precisely. The maximum normalised residual does not fall with resolution at all:
| field | decay exponent, centre_residual_max |
decay exponent, symmetric_hausdorff |
|---|---|---|
noise_cavity |
+0.146 | +0.516 |
gyroid |
−0.029 | +0.936 |
thin_plate |
−0.015 | +0.937 |
A C¹ crease makes |f(centre) − mean(corners)| an O(h) quantity rather than O(h²), so dividing by
h — which the registration's "normalised by cell size" requires — leaves a constant that does not
shrink. Every field in the sweep has a crease: gyroid is Intersection{Gyroid, Sphere}, a max, so a
CSG seam; thin_plate is an exact box; noise_cavity has an unbounded gradient. One crease cell out
of 2.1 million pins the maximum at every resolution, and an order statistic that one cell can pin is
not a witness of a whole grid's adequacy.
The registered adversary did not fail in the registered way, and that is a second correction. The
falsifier predicted thin_plate would give "a residual near zero while the reconstruction is badly
wrong". The reconstruction is indeed badly wrong — ThinPlate::canonical is 0.4 cells thick at its
reference and sub-voxel at all four resolutions here, with hausdorff_forward_max pinned at exactly
8.333e-3 on all four rows and the whole symmetric figure carried by the reverse direction. But the
residual is not near zero: 0.265 → 0.282, the same order as gyroid's. The witness fires on the
adversary at every resolution. The plate uses the exact box distance, which is creased at its edges and
ridged at its midplane, so the "feature that passes through the cell centre without perturbing it"
does not exist for this field. thin_plate fails C1 for the same reason gyroid does — a max pinned by
creases — and not for the reason the falsifier named.
What survives, stated as the post-hoc observation it is. Swap the order statistic and the picture inverts:
| field | r, mean residual vs Hausdorff | decay exponent, mean | decay exponent, Hausdorff |
|---|---|---|---|
noise_cavity |
+0.984 | +0.521 | +0.516 |
gyroid |
+0.983 | +0.900 | +0.936 |
thin_plate |
+0.9998 | +0.988 | +0.937 |
Every field above the 0.7 floor, pooled +0.763, and the decay exponents agree with the Hausdorff's to
within 0.05 on all three. This is not evidence for a hypothesis — it is the hypothesis a falsified
experiment suggested, read off the same data that falsified it, which is precisely the thing
experiment.rs refuses to let a registration be amended into. So it is recorded here as tier M
observation and re-registered as P-44 against the four fields this run never used, where it can fail.
And the one field that passed C1 passed by accident. noise_cavity's +0.881 on the max comes from
a sequence that moves over only a 34% band and is non-monotone — it rises from 65³ to 129³ — with a
decay exponent of +0.146. Four points over a nearly flat, non-monotone sequence is a coin flip that
landed heads. Its symmetric Hausdorff is non-monotone too, rising from 6.241e-1 at 17³ to 6.471e-1 at
33³ before falling: the only field in the sweep where one refinement made accuracy worse, and worth its
own look.
One thing the failure does not touch. The witness's one-sidedness is independent of the correlation: cells whose residual exceeds ten times the grid median run 2.93–19.4% on every registered row and are never zero. Flagging cells still works; what failed is summarising a grid by their maximum.
Would be shown wrong by: P-44, which is the honest re-test and is registered before it runs.
💥 ✗30 / M-340 — FALSIFIED: with B the whole closed surface, the registered residual is discrete Gauss–Bonnet in an approximation check's costume, and what it measures is one f64 epsilon per vertex (P-42, R-041)
M. cargo bench --bench experiment_p42, docs/experiments/p-42.csv. Marching Cubes, f64,
sphere and torus at 33³/65³/129³.
| clause | registered | measured | verdict |
|---|---|---|---|
| C1 residual inside the bound | at all three resolutions | residual 2.81e-13 → 4.95e-12, bound 2.87 → 2.10 |
HELD, vacuously — the bound exceeds the residual by 4.2 × 10¹¹ to 1.0 × 10¹³ |
| C2 residual falls at least linearly | ratio ≤ ~0.5 per halving | 4.01× then 4.39× (sphere), 4.32× then 4.46× (torus) | FALSIFIED |
| C3 torus defect sum zero within bound | yes | −2.32e-13 → −4.46e-12 |
HELD, and the sign check fires |
The registered Gaussian clause cannot fail, and the reason is a theorem. For any closed manifold
triangle mesh 3F = 2E, so Σ_v (2π − α_v) = 2π(V − E + F) identically. Taking B to be the whole
surface makes the residual a topology check, not an approximation check — residual_topological is
exactly 0 on all six rows, chi_from_defect, chi_from_report and the combinatorial V − F/2 all
agree, and what is left over is pure accumulation error: residual / vertices is 2.42e-16, 2.37e-16,
2.57e-16 on the sphere and 2.06e-16, 2.38e-16, 2.56e-16 on the torus — one f64 machine epsilon
per vertex, at ε = 2.22e-16. The vertex count grows ×4.11 then ×4.04, so the residual grows ×4. C2
is falsified by the floating-point accumulator, which is exactly what a clause with no geometric content
left in it must measure.
That is the registration's error and it belongs on the record. Cohen-Steiner & Morvan's Theorem 6 is
stated for B the relative interior of a union of triangles — a patch, with a boundary term. The
registration wrote |Σ defects − 4π|, which is B = everything and ∂B = ∅, and the harness duly
records bound_k_boundary_term = 0 on every row. The additivity that makes the measure interesting to a
chunked mesher was never exercised. Re-registered as P-45, where ∂B is not empty.
Theorem 6's bound does not converge on a marching-cubes mesh, and the mechanism is named. K is flat
at 16–19 across the sweep, as Σ cr² ≈ O(area) should be. But ε = max circumradius is 1.75e-1,
9.96e-2, 1.13e-1 against h = 0.125, 0.0625, 0.03125 — ε/h = 1.40, 1.59, 3.61, not O(h)
and not even monotone, while mean_circumradius halves cleanly (8.14e-2 → 4.06e-2 → 2.06e-2). It is
the maximum that misbehaves, and the cause is measurable: Theorem 11's uniform-fatness hypothesis is
violated by this mesh family, with min_triangle_fatness falling monotonically 4.16e-2 → 1.21e-2 on
the sphere and 8.74e-3 → 2.62e-4 on the torus. Marching Cubes' needles get relatively worse with
resolution, so a bound written in terms of the worst circumradius cannot shrink.
And the slivers responsible are not the ones the crate calls degenerate. degenerate_triangles is 0
on five rows and 16 on the 129³ torus, yet excluding them changes the bound in the seventh digit
(2.093583 either way). ε ≈ 4h is set by ordinary needles whose area clears the 1e-6·h² floor. A
fatness problem, not a degeneracy problem — and it is the second time this repo has found that
"degenerate triangles are a recorded metric, not a gate" was the right call for the wrong reason.
The constant was not invented. Sun & Morvan say only that C_S "depends on the geometry of S" — no
value, no formula, nothing a mesh carries. The harness reports bound = K·ε with
bound_constant_c = "unstated_in_source" in the artefact, and recovers falsifiable content anyway:
c_required = residual / (K·ε) is the smallest constant that would make C1 true, and the theorem asserts
one constant across the sequence, so an unbounded c_required would falsify its form. Measured
9.77e-14 → 6.68e-13 → 2.36e-12 — growing by four per step, which is C2's rounding growth, and still
eleven orders below 1. The theorem's form is not threatened; the bound is simply enormous.
The half that earns its keep was not registered. ½ Σ l(e) β(e) is a genuine second-order estimator
of ∫_S H da:
| field | 33³ | 65³ | 129³ | ratio |
|---|---|---|---|---|
sphere, relative error vs 4π |
1.801e-3 | 4.487e-4 | 1.120e-4 | 0.249, 0.250 — O(h²) |
torus, relative error vs 2π² |
2.676e-5 | 2.231e-5 | 6.154e-6 | — |
The factor of two was settled against the source rather than chosen: for [−1,1]³ the Steiner ε²
coefficient is 6π while Σ l β is 12π, so ∫H da = ½ Σ l β. Both forms are in the CSV, because the
registration named the unhalved one.
Two smaller things worth keeping. A marching-cubes sphere is not edge-convex — Σ l|β| exceeds
Σ l β by about 1.0 at every resolution, so roughly 0.5 of length-weighted concave turning survives at
129³; staircase artefacts that do not wash out. And Theorem 5(2)(a) as printed in the in-corpus source
gives the polyhedral Gaussian measure as Σ α_v, where Definition 1(1) has just defined α_v as the
sum of incident corner angles — a total near 2π|V|, not near ∫G da. The defect is what the theory
means and what was used; the discrepancy is documented in the bench rather than silently corrected.
Would be shown wrong by: P-45, which puts a boundary on B and is registered before it runs.
🔬 M-341 — HELD on all three clauses: a brush that provably cannot win is deleted for free, and the mesh does not move by one ULP (P-39, R-038)
M. cargo bench --bench experiment_p39, docs/experiments/p-39.csv. 4×4×4 chunks of 33³ samples
over [−8, 8]³, base Sphere{r = 6}, a tape of 64 brushes — 34 Add, 30 Subtract, spheres and
capsules — placed by one fixed-seed LCG. 64 rows, one per chunk.
| clause | registered | measured | verdict |
|---|---|---|---|
| C1 median survivor fraction | < 0.5 | 0.2969 (19 of 64 brushes) | HELD |
| C2 speedup, pruned vs full | ≥ 1.25× | 3.365× median, 2.473× world aggregate | HELD |
| C3 mesh byte-identical | every chunk | 64 of 64, by to_bits() comparison and by mesh_hash |
HELD |
The distribution is the result, not the median. Speedup runs from 0.992× to 22.47×, and it is monotone in what it should be monotone in: the three chunks where nothing prunes are the three straddling the world centre, where every brush is inside the chunk's circumradius, and the chunks that prune to a single surviving brush are corners. 56 of 64 chunks clear 1.25×, and the 8 that do not are exactly the 8 with the highest survivor fractions. The worst row, 0.992×, is a chunk where all 64 brushes survive — the pruned tape is the full tape and the 0.8% is timing noise, which is the right failure mode for a mechanism that can only ever remove work.
C3's instrument is proven sensitive rather than assumed to be. A comparator that cannot see a
difference reports agreement, which is a failure this repo has had before. So the same pruning geometry
was run against a SmoothAdd stack, pruned in the losing direction — precisely the h == 1 region
where smooth_min returns b + (a − b) — and 48 of 64 chunks come back different. The 16 that
match are the chunks where only Subtracts were pruned. The comparator and the hash both detect 1-ULP
shifts; the 64/64 on the hard-op stack is a real result.
That is also the registered asymmetry, demonstrated rather than argued. The registration carved
SmoothAdd out of the losing-direction prune before the run, on the algebra alone. Had it not, this
experiment would have produced a 48-chunk mesh difference and it would have read as a determinism
regression rather than as the expected behaviour of a non-selecting operator.
The bound is free, and by three orders of magnitude. Deciding the whole 64-brush tape for a chunk
costs 540–1450 ns — 65 field samples, one per brush plus the base. bound_cost_fraction runs
4.4e-5 to 1.3e-3 of the meshing it enables. Even on the chunk that prunes hardest, from 64 brushes to
1, the bound costs 0.13%.
One negative worth having before anyone builds on this. dominant_adds is 0 on all 64 chunks:
not one Add ever provably wins the whole chain over a chunk. A dominant Add would make the base
field and the entire tape prefix dead, which is a much larger prize than pruning losers — but
BrushStack has no way to express "start from this brush" without replacing the base, and on this
fixture the opportunity does not exist anyway: the base sphere's own enclosure is ±3.46 wide over a
chunk, so no brush of radius ~1 can clear it. The prefix cut is a different mechanism with a different
precondition, and it is not free.
A consistency check fell out of the fixture and is worth recording as method. Nineteen chunks share a triangle count of 3,227; seventeen share 173; seven are empty. That is not a bug — the world, the chunk lattice and the base sphere are all symmetric under the octahedral group, so chunks in the same symmetry class have identical base-only meshes, and those are exactly the chunks where every surviving brush contributed no geometry. A chunk meshing the wrong region could not land on its symmetry partner's triangle count, so the coincidence is free evidence that the grid origins are right.
What a consumer gets. The mechanism's leverage is 1 − survivor fraction, and survivor fraction
falls as the edit history grows and spreads — which is the direction a destructible world runs in. At 64
brushes a chunk meshes 3.4× faster with byte-identical output, and the cost of deciding is a rounding
error against the saving. Sources: Barbier et al. 10.1111/cgf.70057, whose own future work names
polygonization; Keeter 10.1145/3386569.3392429; and Tilove's 10.1145/358105.358195, in corpus, which
is the same argument as set theory forty years earlier.
Would be shown wrong by: an edit pattern that is not spatially scattered — one enormous brush covering the world drives the survivor fraction to 1 and the mechanism to nothing. The three all-survive chunks here are that case in miniature, and they cost 0.8%.
💥 ✗31 / M-342 — the correlation reproduced out of sample and the line dies anyway: the exponent gap is the normalisation, and a mean's convergence order cannot track a supremum's (P-44, R-042a)
M. cargo bench --bench experiment_p44, docs/experiments/p-44.csv. The four reference fields P-43
never touched — sphere, torus, box_exact, csg_difference — at 17³/33³/65³/129³, Marching Cubes,
f64.
| clause | registered | measured | verdict |
|---|---|---|---|
| C1 Pearson r, mean residual vs Hausdorff | ≥ 0.9 per field | 0.980 sphere, 0.982 torus, 0.99994 box_exact, 0.997 csg_difference | HELD, out of sample, on all four |
| C2 decay-exponent gap | ≤ 0.15 per field | 1.008 sphere, 0.888 torus, 0.019 box_exact, 0.127 csg_difference | FALSIFIED |
| C3 witness cost | < 0.5× an extraction | best row 0.563, worst 1.262 | FALSIFIED |
C2 fails on exactly the two smooth fields and passes on exactly the two creased ones, which is
verbatim what P-44's own falsified_by predicted: the agreement P-43 saw was a property of its three
fields' shared crease structure, not of the witness. And the mechanism is closed-form rather than
statistical. The gap is the /h normalisation, exactly one order. The witness's exponent is
field-independent — +0.968 to +0.999 on all four — because a mean is set by the smooth bulk of
the domain. The Hausdorff's is field-dependent — 2.007 and 1.871 on the smooth pair, 1.000 and
0.841 on the creased pair — because a supremum is set by the worst local feature. A quantity whose
order does not vary with the field cannot track one whose order does, and no fixed power of h repairs
that: un-normalised it mirrors the failure instead of curing it.
C1 held and it does not rescue anything, which is the methodological point. An r of 0.98 between
two quantities that both shrink monotonically over four points is close to uninformative — the same
harness reports r = 0.976–0.979 against a mean-type metric it was not pointed at. A correlation that
high against almost anything is a statement about monotonicity, not about prediction. C2 is the clause
with discriminating power, and it is the one that failed.
And P-43's max statistic is dead on any SDF, not merely on creased ones. decay_exponent_max is
≈ 0 on all four fields including the smooth pair, and on sphere the maximum is bit-identical at
every resolution: 2.558110331e-1, at 17³, 33³, 65³ and 129³ alike. That is not a coincidence and not
a floor — it is the medial-axis cell, where the analytic value
|√3/2 − (3 + 3√2 + √3)/8| = 0.2558110330515817 is independent of h and of the radius, verified to
seven digits against the measurement. A witness whose maximum is an h-independent constant on the
simplest field in the suite is not a witness of resolution adequacy.
So the direction is closed, on the second null, rather than re-registered a third time. Finding one says no exponent choice can work; finding two says the max was never viable. What survives from the whole line is the one-sided cell flag recorded at ✗29 — cells above ten times the grid median, 3.8–19.4% and never zero — which does not depend on any correlation and was never the thing that failed.
Load caveat, on the artefact. loadavg was 12.96 during these runs (sibling benches on the same
machine), so the absolute witness_ns and extract_ns columns are contaminated by up to ~40%. The
ratio is not: both timings are taken back to back, so a uniform slowdown cancels, and C3's verdict held
across three separate runs and under both cost readings — standalone (minimum ever observed 0.509 over
48 row-measurements) and incremental with the corner grid already resident (worst 0.950, and only the
four sphere rows under 0.5). No interpretive choice rescues it.
P-46 — registered for R-040a, before the repair exists: the bijection gave it a target
M-338 measured that critical cells, non-manifold vertices and critical-cells-hosting-one are the same number on every affected field. R-040 deliberately withheld the repair pending exactly that result, and now it has a falsifiable form: drive the census to zero and the defect count must follow.
The repair is of the sign lattice, not the mesh, and by minimal value perturbation rather than an
arbitrary sign flip. For each critical cell, move the corner of smallest |value| across zero by the
smallest representable step. It was registered as "Boutry, Géraud & Najman's self-dual repair
(10.1007/s10851-017-0769-6)" applied to the grey-level function rather than to the binary set, and
choosing the cheapest corner is what bounds the geometric cost — an arbitrary flip can move the
surface by a whole cell.
⚠ CITATION CORRECTED 2026-08-23 by external audit §B.1, and it is material rather than tidy.
10.1007/s10851-017-0769-6is A Tutorial on Well-Composedness — a survey. The self-dual repair is10.1007/978-3-319-18720-4_47, How to Make nD Functions Digitally Well-Composed in a Self-dual Way (ISMM 2015, same three authors). Same family, different paper, and the method cited is not the method that was implemented. So M-344's "the repair is provably stuck" is a statement about this rule — move the cheapest corner, sweep — and not about Boutry's. The 36-of-4,096 exhaustive result stands as written for the rule it tests; whether the published method escapes those 36 is open, and reading it is the precondition for R-040b rather than an optional tidy.H. On
noise_cavity,gyroidandfbm_terrainat 65³, forDualContouringandSurfaceNets: (C1) exactly 0 non-manifold edges and 0 non-manifold vertices after the repair, where before they were 322/602, 69/141 and 29/58. (C2) a fixpoint in at most two sweeps — a perturbation can create a critical configuration in a neighbour, and an unbounded cascade rules the mechanism out of a frame budget outright; the residual is recorded either way. (C3) the symmetric Hausdorff against the unrepaired field rises by less than 10% on each field. Falsified by any surviving non-manifold output — which would make well-composedness necessary but not sufficient, the more interesting result, sinceManifoldDualContouringalready buys the same guarantee with extra vertices — or a residual census after two sweeps, or Hausdorff up 10% or more, which would mean the manifoldness was bought with geometry the caller never agreed to sell.
This changes the mesh, so it is a capability claim only and needs its own golden set. It can never clear the speed bar and must not be presented as if it could.
Records field, samples_per_axis, extractor, critical_before, critical_after, sweeps,
non_manifold_edges_before, non_manifold_edges_after, non_manifold_vertices_before,
non_manifold_vertices_after, hausdorff_before, hausdorff_after, hausdorff_ratio.
P-47 — registered for R-043, before the harness: the gradient hole a composed field falls into
The premise, checked against the code. All eight reference fields override Sdf::gradient
analytically and fields/mod.rs says the central-difference default "is never used by a reference
field". True, and it stops being true the moment anything is composed: BrushStack does not override
gradient, and neither does Capsule — verified by read. So a sculpting tool's every vertex normal
takes the six-sample central difference at O(h²), and each of those six samples evaluates the whole
tape. M-341 measured a 64-brush tape at 309–553 ns/sample unpruned; six of those per normal is the
hidden cost, and the crate has never stated the error it buys.
A forward-mode dual number (value, [dx, dy, dz]) carried through the fold fixes both halves in one
traversal. min and max propagate the selected branch's derivative — the same selection that makes
P-39's pruning bit-exact — smooth_min propagates the analytic derivative of its polynomial, and the tie
at a CSG seam is broken by lowest index so the result stays a pure function of its inputs.
H. (C1) On a 64-brush
BrushStack, the mean angular error of the central-difference normal against the exact dual-number normal exceeds 0.1° and the maximum exceeds 5°. (C2) Normals for a meshed chunk compute at least 2× faster through the tape than through six central-difference samples. (C3) The control: on a bareSpherethe dual-number normal reproducesp/|p|to within 1e-12. Falsified by a mean error at or under 0.1°, which would mean the hole is theoretical — a real possibility, sinceDIFF_STEPscales with|p|and these shapes are smooth away from their seams — or a speedup under 2×. C3 failing means the dual arithmetic is wrong and nothing else in the row can be believed.
This is a fourth NormalStrategy measured against the third, never a replacement. Switching the
default would move mesh.normals and break all 216 golden hashes, and normals.rs's own docs already
require that a fourth variant arrive "with a measurement attached". This is that measurement.
Records fixture, brushes, vertices, mean_angular_error_deg, max_angular_error_deg,
central_ns_per_normal, dual_ns_per_normal, speedup, sphere_control_max_error.
💥 ✗32 / M-343 — the two measures split: the Gaussian one is chunk-local and does not sum, the mean one sums and is not chunk-local (P-45, R-041a)
M. cargo bench --bench experiment_p45, docs/experiments/p-45.csv. sphere and torus at 65³,
partitioned into a 4×4×4 grid of spatial chunks by triangle centroid.
| clause | registered | measured | verdict |
|---|---|---|---|
| C1 Gaussian chunk sum = global | gap < 1e-9 | 339.29 (sphere), 647.17 (torus) | FALSIFIED by eleven orders |
| C2 mean chunk sum = global | gap < 1e-9 | 2.98e-13, 1.71e-13 | HELD, ~3500× inside tolerance |
| C3 isolated chunk reproduces its value | bit for bit | Gaussian 0 of 56/64/56 mismatched; mean 56/56 and 64/64 mismatched | SPLIT — and the split is the result |
C1's gap is exactly quantised, which is what turns a bug into a mechanism. gaussian_gap_over_pi
reads 108.000000000 and 206.000000000 — integers — and gaussian_gap_matches_excess is true on
every row, where excess_chunk_incidence = Σ_v max(k(v) − 2, 0) is 108 and 206 for the same meshes. So
the chunk sum is π(2χ + excess) exactly. The cause: a vertex shared by k chunks is a boundary
vertex of all k, and is charged kπ where 2π is owed. On the sphere it localises in closed form —
the 4×4×4 grid has 27 interior grid lines, each crossing a convex closed surface twice, giving 54
four-chunk vertices and 54 × 2 = 108. On the torus, 142 three-chunk plus 32 four-chunk vertices give
142 + 64 = 206.
That is not a transcription slip, it is the construction missing a term. Sun & Morvan's additivity is
N(A ∪ B) = N(A) + N(B) − N(A ∩ B), and the harness implemented the first two terms. A partition of
faces is not a partition of space: the chunks share their boundary curves, and the shared part has to
be subtracted once. The registration said "additive with a boundary term" and specified the boundary
term; it did not specify the intersection term, and the measurement found the omission by producing an
integer.
C2 held to 3500× inside tolerance, and the half-weight seam rule is why. An edge on a chunk boundary belongs to two chunks and is weighted one half in each, which is the intersection term for a one-dimensional overlap — so the mean measure got the correction the Gaussian one did not, because edges are shared by exactly two chunks and vertices are shared by up to eight.
C3 is the clause that decides whether any of this is usable, and it answers in two directions. The Gaussian measure computed from a chunk's own triangles alone — boundary detected from that set, nothing read from a neighbour — reproduces its in-context value on every chunk of every field, verified by a routine that never builds a patch at all. The mean measure fails in every chunk, by 12.3% and 12.0%, and what it needed from outside itself is exactly the opposite triangle's normal on each seam edge: 2,040 seam edges on the sphere (14.3% of its edges), 3,264 on the torus (25.9%). One triangle of halo per seam edge — a one-ring.
So the two measures have opposite defects. The Gaussian measure is chunk-local and needs an inclusion–exclusion correction to compose; the mean measure composes and needs a halo to compute. Either is fixable and neither is fixed here, because fixing a registered construction after seeing its number is the move this machinery exists to prevent.
box_exact is not exact, and the reason is the extractor. ½ Σ l β reads 18.324 against 6π =
18.850, 2.79% low — sixty times worse than the same estimator on the smooth fields (4.49e-4 and 2.23e-5
at 65³). The edge-class decomposition settles it: right_angle_edges = 0 — not one mesh edge carries
|β| = π/2. The 16,548 flat edges contribute exactly zero and all 36.649 of the turning comes from 744
other_edges, which is 12 × 62: two intermediate-dihedral edges per cell along each of the twelve cube
edges. Marching Cubes bevels the right angle, and l·β is a product, so splitting one turn across
two longer diagonal edges does not preserve it. A finding about the extractor, not the estimator. And
box_exact passes C3 spuriously — all 2,232 of its seam β are exactly zero — which makes it the
control proving the mean measure's failure is about seam dihedrals alone.
Scope note on the artefact: the 4×4×4 grid spans the mesh's bounding box, not the field's domain,
so on sphere the surface occupies 56 of 64 boxes; chunks and chunk_boxes are both recorded.
💥 ✗33 / M-344 — the repair is free and total where the critical set is sparse, and catastrophic where it is dense (P-46, R-040a)
M. cargo bench --bench experiment_p46, docs/experiments/p-46.csv. Minimal value perturbation —
move the corner of smallest |value| across zero — at 65³, both duals.
| field | critical before → after | sweeps | non-manifold vertices after | Hausdorff ratio | corners moved |
|---|---|---|---|---|---|
fbm_terrain |
58 → 0 | 1 | 0 | 1.000000 | 28 (0.010%) |
gyroid |
141 → 0 | 5 | 0 | 1.000000 | 143 (0.052%) |
noise_cavity |
602 → 118 | 64 (cap) | 118 | 4.45× (DC), 1.69× (SN) | 5,190 (1.89%) |
C1 FALSIFIED, on noise_cavity alone. C2 FALSIFIED — the two-sweep bound is missed on two of
three fields (5 sweeps on gyroid; critical_after_two_sweeps is 8 there and 103 on noise_cavity).
C3 FALSIFIED on noise_cavity at 4.45×, and held perfectly elsewhere: the repair on gyroid and
fbm_terrain costs exactly nothing — hausdorff_ratio = 1.000000 to six decimals, because moving a
corner whose value is already the smallest in its cell moves the interpolated crossing by less than the
measurement's own resolution.
So the honest statement is a conditional, and the condition is density. Where critical cells are isolated the repair is total, converges in one to five sweeps, touches 0.01–0.05% of samples and costs no accuracy. Where they are dense it does not converge at all: 64 sweeps, 6,307 cells stuck, 5,190 corners moved, 1.9% of the sample grid perturbed, and the mesh 13% larger (57,764 → 65,272 triangles) while being 4.45× further from the field it was supposed to describe. A manifold mesh of the wrong surface is not a bargain, which is exactly what C3 was registered to catch, and it caught it.
The stall is structural, and it is settled exhaustively rather than argued. Walking all 4,096
face-adjacent sign patterns: 820 have cell A critical and cell B clean; in 64 of those, some corner
choice fixes A and breaks B; and in 36 of them, no corner leaves both clean. Witness:
A = 0x5a, B = 0x05. The survey lets the rule pick any of the eight corners freely, so this is not
an artefact of refusing to move a corner twice — on those 36 the rule is genuinely stuck. The dynamics
agree: noise_cavity's flips-per-sweep reaches exactly 0 at sweep 41 and stays there for the last 24
sweeps while the count sits flat at 118. Not slow. Stopped. This is the same finite-space move that
settled the four-triangles-on-one-edge question at A-015, and it is why the residual can be reported as a
property of the rule rather than of the budget.
The predictor is cluster size, and it is monotone across the three fields. Maximum 26-connected
critical component before repair: fbm_terrain 4 → clears in one sweep; gyroid 10 → clears in
five; noise_cavity 27 → never. And the survivors are more clustered than the population they came
from: mean 26-connected component size goes 3.09 → 4.54 (6-connected 2.41 → 3.37) and 195 components
collapse to 26. An isolated critical cell has eight corners of its own to spend; a clump of 27 competes
for shared ones.
Even the successful case is non-monotone, which is the missing convergence property visible where
the rule still wins: gyroid runs 141 → 11 → 8 → 18 → 8 → 0 — it rises at sweep three.
noise_cavity peaks at 336 on sweep eight, higher than after sweep one. Any future version of this
rule needs a potential function, and this one has none.
M-338's bijection survives the repair, and that is the strongest corroboration it could get.
residual_nm_vertices_in_critical = 118 = critical_after = non_manifold_vertices_after, for both
extractors, after 64 sweeps of scribbling on the sign lattice. The set identity — 118 distinct cells,
one vertex each — holds exactly for DualContouring. For SurfaceNets the 118 vertices land in 103
distinct cells, which is not a new phenomenon but M-338's unclamped-centroid mapping artefact firing
again: 15 of its vertices sit exactly on a cell boundary on this field, so floor() names a neighbour.
DualContouring is the clean witness, as it was there.
Clause three failed on exactly the field clause one failed on, and held at 1.000000 on both fields
where the repair completed. No field bought manifoldness with geometry — the one field that lost
geometry did not get manifoldness either.
What this rules out and what it leaves. Sign-lattice repair is not a general answer to dual
non-manifoldness, so ManifoldDualContouring keeps its job. It is a free and complete answer where the
critical set is sparse, which is two of the three affected fields and — on the evidence of the five with
a zero census — most fields a game meshes. Anyone building on it must gate on maximum cluster size, not
on count, and must measure Hausdorff, because the failure mode is silent geometry loss rather than an
error.
💥 ✗34 / M-345 — the gradient hole is real, measurable, and three orders too small to matter; the speedup is real and holds (P-47, R-043)
M. cargo bench --bench experiment_p47, docs/experiments/p-47.csv. Forward-mode dual numbers
carried through BrushStack's fold, against the six-sample central difference Sdf::gradient falls back
to on any composed field.
| clause | registered | measured | verdict |
|---|---|---|---|
| C1 mean angular error > 0.1°, max > 5° | on a 64-brush stack | mean 7.6e-5°, max 4.365° | FALSIFIED |
| C2 normals ≥ 2× faster | one traversal against six | 2.84× at 64 brushes | HELD |
| C3 sphere control within 1e-12 | p/\|p\| |
2.83e-16 | HELD |
| brushes | 1 | 8 | 16 | 32 | 64 | 64 smooth |
|---|---|---|---|---|---|---|
| mean angular error, ° | 6.4e-10 | 1.8e-8 | 1.9e-8 | 8.3e-5 | 7.6e-5 | 7.7e-5 |
| max angular error, ° | 6.3e-9 | 8.1e-4 | 8.1e-4 | 4.365 | 4.365 | 4.365 |
| ns per normal, central → dual | 39.4 → 17.0 | 296 → 105 | 544 → 190 | 1000 → 353 | 1883 → 663 | 2729 → 1096 |
| speedup | 2.31× | 2.82× | 2.86× | 2.83× | 2.84× | 2.49× |
C1 is falsified in the mean by three to seven orders of magnitude, and its own falsified_by named the
reason in advance: DIFF_STEP scales with |p| and these shapes are smooth away from their seams, so
the central difference is very nearly exact almost everywhere. central_matches_mesh_normals is true
throughout — the crate's shipped normals are the central-difference ones and they are not visibly
wrong.
What the max column says is worth more than the verdict. The error is not uniformly negligible: it is negligible on 99.99% of vertices and reaches 4.365° on a few, and the jump appears between 16 and 32 brushes — which is when the stack becomes dense enough that a vertex's six-point stencil straddles a CSG seam. That is the one place a central difference cannot work: it averages across a gradient discontinuity and returns a direction the surface does not have. 4.365° missed the registered 5° bar, and missing it is the right outcome for a threshold picked without data, but the mechanism is real and the harness names the worst vertex and its seam gap.
C2 held flat at 2.8× from 8 brushes up, which is the shape a one-traversal-against-six mechanism
should have: the ratio is 6 minus the dual's arithmetic overhead, and it stops improving once the tape
dominates. And it inverts where there is nothing to amortise — on a bare Sphere and a bare
Capsule the dual is 0.86× and 0.88×, i.e. slower, because carrying three derivative
components through one cheap primitive costs more than evaluating it six times. That is the honest
boundary of the mechanism and it is in the table rather than in a caveat.
So the fourth NormalStrategy is not justified by accuracy and might be by cost. It computes an
exact gradient 2.8× faster than the approximate one on composed fields, and the accuracy it buys is worth
nothing on this evidence except at seams. normals.rs asks that a fourth variant arrive with a
measurement attached; this is the measurement, and what it says is "not for the reason you would
expect."
P-48 — registered for R-044, before the inclusion function exists: the gap isotopy.rs names in its own header
validate/isotopy.rs states its own limit, verbatim: "The general form needs interval arithmetic over
an arbitrary F, which this crate has no way to do — an Sdf hands back point values. A sampled hull of
the gradient would be a lower bound on its variation, so the predicate could pass where the truth fails,
which is the one direction a certificate must never err in." It therefore certifies the trilinear
interpolant and says plainly that it does not certify the analytic field against it.
A compositional inclusion function over the crate's own field types closes that with no dependency and no
interval library: (lo, hi) pairs and six operations, widened by one ULP per operation because core has
no directed rounding — which keeps the enclosure sound in the only direction that matters.
H. (C1) Soundness, and it is fatal. Over the eight reference fields at 33³, every cell the certificate calls surface-free is surface-free under 4,096-point dense sampling: zero unsound certifications, no tolerance. (C2) Non-vacuity. On the fields built from exact distance primitives —
sphere,box_exact,torus,csg_difference— the certificate proves at least 90% of the cells dense sampling shows to be surface-free. (C3) Reach. The certified fraction is reported for all eight and is strictly positive on at least six. Falsified by any unsound certification at all — a certificate that can be wrong is not a certificate, and the failure would be in exactly the directionisotopy.rsforbids — or under 90% on the exact fields, or reach confined to the eikonal cases, which would leavegyroid,noise_cavityandfbm_terrain, the three that actually go wrong, outside it.
Not the tabled Sharp & Jacobson row. That one is coarse-cell rejection, an accelerator. This is a topology certificate and is scored on soundness; it must never be presented as a speedup.
Records field, samples_per_axis, cells, cells_surface_free_sampled, cells_certified_empty,
certified_fraction, unsound_certifications, undecided_fraction, certified_vs_trilinear.
P-49 — registered for R-045, before the harness: connectivity is a boolean and a game asks for a number
R-022a's Air answers is this sealed. A game asks can the player get through, and that is a
bottleneck value rather than a boolean: for a pair of chunk faces, the maximum over air paths of the
minimum distance-to-solid along the path. A monotone union-find over air voxels in descending
(field value, grid index) computes it — a total order, so no PRNG, no atomics and no HashMap, the
same discipline the weld already uses. The output is a 6×6 symmetric aperture matrix plus a
reachability mask, which is the composable boundary summary: neighbouring chunks combine theirs with no
global solve.
H. (C1) Against exact ground truth. On a
BoxExactslab with aCapsuleof radiusrsubtracted alongx, forrof 2, 4 and 8 cells, the reported−x/+xaperture equalsrto within one cell size and every other face pair reports unreachable. (C2) On a real field. The capped gyroid at 65³ reports all six faces mutually reachable — it is bicontinuous, so a disconnected pair is a proven bug in the instrument rather than a property of the field — with positive aperture on all 15 pairs. (C3) Cost. The whole 6×6 costs under 2× a Marching Cubes extraction of the same grid. Falsified by an aperture off by more than one cell where the answer is known exactly; any falsely reachable pair, which is the unsound direction and fatal for something a game would gate movement on; a gyroid pair reported unreachable; or cost at or above 2×.
Overlap, named: the connectivity half is banked as union-find over the air sublevel set. The aperture value and the composable 6×6 are the delta, and the ticket stands or falls on those.
Records fixture, samples_per_axis, channel_radius_cells, aperture_reported_cells,
aperture_error_cells, reachable_pairs, expected_reachable_pairs, false_reachable_pairs,
aperture_ns, extract_ns, cost_ratio.
🔬 M-346 — HELD on all three clauses, with exactly zero error where the answer is known: the crate can state a clearance, not just a connection (P-49, R-045)
M. cargo bench --bench experiment_p49, docs/experiments/p-49.csv. Monotone union-find over air
voxels in descending (field value, grid index), 65 samples per axis, f64.
| fixture | channel radius | aperture reported | error | reachable pairs | false | cost ratio |
|---|---|---|---|---|---|---|
slab, r = 2 cells |
2 | 2.000000 | 0.000000 | 1 of 1 | 0 | 0.444 |
slab, r = 4 cells |
4 | 4.000000 | 0.000000 | 1 of 1 | 0 | 0.555 |
slab, r = 8 cells |
8 | 8.000000 | 0.000000 | 1 of 1 | 0 | 0.588 |
| capped gyroid | — | 17.83 min / 28.00 max | — | 15 of 15 | 0 | 1.108 |
| uncapped gyroid (extra) | — | 6.39 min / 6.84 max | — | 15 of 15 | 0 | 0.829 |
C1 held, and not marginally. The registration allowed one cell of slack and the error is exactly
zero at all three radii. The fixture is why: subtraction is max(box, −capsule), so inside the channel
the box term is deeply negative and the value is −capsule, exactly r − ρ at radius ρ from the
axis; 65 samples over [−2, 2] puts a sample at 0.0 on every axis, so the axis line is sampled and the
value r is actually attained. The instrument had nowhere to hide and it did not need anywhere. All
fourteen other face pairs report unreachable on every slab, and false_reachable_pairs and
missed_reachable_pairs are both 0 on every row — no error in either direction, so there is nothing
to say about which way it runs.
C2 held, and the harness proved the fixture wrong before the run rather than after. The clause's
reasoning invokes the gyroid's bicontinuous channel network, but capped_gyroid is
max(gyroid, sphere(6)) over [−7, 7]³, so everything outside radius 6 is air — including all six
domain faces — and the pairs connect through the shell around the cap before a channel is consulted.
That is confirmed to six figures: the twelve adjacent-face pairs all report exactly 27.9971 cells,
and (7√3 − 6)/h = 27.997054 — the shared corner sample (7,7,7), which lies on +x, +y and +z at
once, at clearance |p| − 6. The three opposite-face pairs read 17.83 because they have no shared
sample and must route around. On the capped fixture the aperture matrix has two values and is measuring
the shell. So an uncapped gyroid row was added on the identical grid, where no shell exists: 15 of 15
again, with the fifteen values spread over 6.39–6.84 rather than collapsing to two. The registered
clause stands as written; the extra row is what makes it mean something.
C3 held with room. Worst cost_ratio is 1.108 against a 2× bar, and that is the expensive
reading — "the whole 6×6" taken to include sampling the grid, like for like against Marching Cubes,
which also samples. With the early exit disabled, the number to budget for, the worst is 1.486, still
under. Given samples a mesher already has, the marginal cost is 0.023× to 0.391×.
The early exit is where the speed is, and it is sound rather than heuristic. Each aperture is fixed at the first — and therefore highest — value that connected its pair, so no later sample can revise one, and the walk can stop when all fifteen are decided. On the gyroid it fires after 12,101 of 231,421 air samples: 5%. A caller wanting the matrix for only some pairs keeps most of that.
Three instrument checks, because a clearance a game gates movement on has to be checked at the input
too. The air census agrees with closed form exactly on all three slabs — 585, 2,925 and 12,545
samples, which is 65 planes times the lattice points with j² + k² < r² (9, 45, 193); an aperture of
exactly r read off the wrong air set would still be wrong. Determinism is verified, not inferred
from the absence of a PRNG: two solves from identical values agree on all fifteen apertures and on the
air and visited counts, on all five rows. And the ratios are stable across two runs at different machine
load (gyroid_capped 1.097 then 1.108) because both arms are timed interleaved in one process —
loadavg was 6.5 at the start, a sibling bench.
What this buys. Air answers is this sealed; this answers can a body of radius r get through,
per pair of chunk faces, as a 6×6 symmetric matrix plus a reachability mask — and that matrix is the
composable boundary summary, so neighbouring chunks combine theirs with no global solve. The
connectivity half was already banked; the value and the composability are the delta, and they are what
the clauses were written on.
Would be shown wrong by: a fixture where the bottleneck path is not monotone in the field value — the union-find assumes the first connection is the widest, which is true for a sublevel-set filtration and would stop being true if the traversal order were anything but a total order on the value.
🔬 M-347 — HELD on all three clauses, and the by-product is sharper than the claim: there are 24 cells on the unit sphere where the surface passes through and all eight corners agree (P-48, R-044)
M. cargo bench --bench experiment_p48, docs/experiments/p-48.csv. Eight reference fields at 33³,
f64, a compositional inclusion function with one-ULP outward widening per rounding operation. Two runs
byte-identical.
| field | certified of all cells | certified of sampled-free | unsound | mean enclosure width / h |
|---|---|---|---|---|
sphere |
0.9639 | 1.000000 | 0 | 1.547 |
torus |
0.9656 | 1.000000 | 0 | 1.449 |
box_exact |
0.9058 | 1.000000 | 0 | 1.180 |
csg_difference |
0.9078 | 0.998255 | 0 | 1.200 |
thin_plate |
0.9802 | — | 0 | 1.260 |
gyroid |
0.8201 | — | 0 | 1.866 |
fbm_terrain |
0.7368 | — | 0 | 8.439 |
noise_cavity |
0.7420 | — | 0 | 8.000 |
C1 held clean: zero unsound certifications over 262,144 cells and 1.07 billion dense field
evaluations (8 fields × 32,768 cells × 4,096 points), first_unsound_cell = none on every row. The
caveat belongs on the record: dense sampling is one-sided. It can falsify soundness and cannot prove
it. This is strong evidence, not a proof.
C2 held on both readings and the two differ, which is worth knowing. The registered wording is "at
least 90% of the cells dense sampling shows to be surface-free" — 1.000, 1.000, 1.000 and 0.998 on the
four exact-distance fields. Read instead against all cells it is 0.9639, 0.9656, 0.9058 and 0.9078: the
same verdict, but box_exact clears by 0.58 points and csg_difference by 0.78, which is thin.
C3 held at 8 of 8 against a bar of 6, and the three fields the falsifier singled out as likely to
fall outside reach are all well clear: gyroid 0.82, fbm_terrain 0.74, noise_cavity 0.74.
The by-product is the result. Decomposing the undecided cells into "the interpolant hides a surface here" (corners agree, dense sampling finds the analytic surface anyway) versus "my enclosure is merely too loose":
| field | hidden | loose | undecided |
|---|---|---|---|
sphere |
24 | 0 | 24 |
torus |
0 | 0 | 0 |
box_exact |
1,736 | 0 | 1,736 |
thin_plate |
136 | 0 | 136 |
csg_difference |
1,582 | 52 | 1,634 |
gyroid |
97 | 558 | 655 |
fbm_terrain |
94 | 6,571 | 6,665 |
noise_cavity |
394 | 1,885 | 2,279 |
On the four exact-distance fields the loose term is exactly zero. The inclusion function decides
every cell 4,096-point sampling can decide, and every cell it refuses is one where the analytic surface
genuinely passes through while all eight corners agree in sign. 4,063 such cells across the eight,
1.55% of the grid — and they are cells validate::isotopy counts as trivially certified by its first
clause and never even admits to active_cells.
Twenty-four of them are on the unit sphere at 33³. Not a noise field, not an adversarial fixture —
the simplest field in the suite, and 1,736 on box_exact. That is the gap isotopy.rs's header
describes in prose, measured for the first time: "what this does not certify is the analytic field
against its trilinear interpolant."
Do not read certified_vs_trilinear against certified_fraction — different denominators, different
questions. IsotopyReport::certified_fraction() is a share of active cells; the apples-to-apples
partner is trilinear_inactive_fraction, the share of all cells whose corners agree, which is exactly
isotopy.rs's first clause. Certified is always a subset of inactive, and trust_gap_fraction is the
difference: the cells the interpolant passes over in silence and this certificate refuses.
Tightness says the enclosures are near-optimal where it matters. For a unit-Lipschitz field the true
range over a cell is at most √3·h = 1.732h; the exact-distance enclosures sit at 1.18–1.55, within
about 11% of the best any inclusion function could do. fbm_terrain at 8.44h is the loose one and the
reason is structural: four octaves enclosed independently, so no cancellation between them is tracked.
Nothing came out undecidable, including the two fields expected to. perlin is Σ_c w_c(t)·(g_c·d_c)
with w_c ≥ 0 summing to 1; the quintic fade has derivative 30t²(t−1)² ≥ 0 for every real t, so it is
monotone and its endpoints give its range exactly, and every GRAD12 entry has two ±1 components and
one zero so g·d is sign flips and two adds. Evaluating that sum term by term rather than through
the one-line convex-combination bound is what makes it sharp — the bound admits a far corner's g·d ≈ −2
whose actual weight is under a thousandth. Derived from the crate's own construction, not from a
Lipschitz constant, which would have been a guess: NoiseVolume declares Unbounded and no constant is
derived anywhere.
Gyroid got a real monotonic-branch analysis rather than an endpoint approximation: on an interval
narrower than 2π the endpoints give the range unless a critical point is inside, containment decided by
a guard that errs toward including the extremum so it can only widen; endpoints widened three times
because libm's sin/cos are not correctly rounded and an interior point can exceed an endpoint by up
to two ULPs on a monotone branch.
One liability, stated rather than discovered later. hash3, GRAD12 and OCTAVE_OFFSET are private
to fields/noise.rs, so the noise enclosure transcribes them and a change to any would silently
invalidate it. It is guarded, not trusted: a reimplemented perlin/fbm is compared bit-for-bit against
NoiseVolume::sample and FbmTerrain::sample at 137,842 points, max |Δ| = 0, before any certificate
is issued, and noise_transcription_verified is on every row. The guard catches drift today and nothing
prevents it tomorrow; crate-side visibility is the clean fix and this ticket did not authorise it.
Framing, deliberately: this is strictly more work than sampling — a proof obligation discharged per cell — and the only thing it buys is that a cell it calls surface-free has no surface in it rather than no surface where anyone looked. It is not a speedup and must never be presented as one.
Would be shown wrong by: a single unsound certification, which dense sampling can only ever find by luck; the honest strengthening is a second, independent enclosure to cross-check against, not more samples.
💥 ✗35 / M-348 — two Phase 19 entries quote runs that are not in the CSVs they cite, and one of them was a verdict: the bitmap's C2 fails (P-38, P-40, R-037, R-039)
Found by external audit (docs/research/2026-08-23-findings-audit-and-phase-20-registrations.md,
§A.2), which checked entries against the artefacts they name rather than against their own prose. Both
hits are mine and both are the same mistake.
The mechanism, which the audit could not see and I can. Both entries were written from a run I
watched, and then the bench was re-run inside the commit command — cargo bench … && git add … &&
git commit — so the committed CSV is run N+1 while the entry quotes run N. The rule earns itself:
never fold a re-run into the commit that publishes its numbers.
✗28 / M-336 — the numbers moved, the verdict did not.
| row | entry | committed p-38.csv |
|---|---|---|
| MC 128³ ratio | 0.977 | 0.9986 |
| MC 256³ ratio | 0.996 | 1.0056 |
| SN 128³ ratio | 0.968 | 0.9867 |
| SN 256³ ratio | 0.938 | 0.9320 |
pad_z ratio, MC 128³ |
1.0075 | 1.0038 |
| scaffold, MC 128³ | 8.116 / ratio 1.009 | 8.1792 / 1.0138 |
Every reading in either run sits between 0.93 and 1.01 against a registered 1.5×. ✗28 stands: Marching Cubes does not alias at 128³, and the access pattern is why.
M-337 — the verdict does not survive, and it is worse than the audit could measure. The audit read
the committed CSV at 1.1925× for Surface Nets at 128³ against a registered ≥ 1.25×. Re-run three
times on a quiet machine (loadavg 0.67, where the committed run was taken with four sibling
benches on the box):
| run | SN 128³ extract ratio | stage ratio |
|---|---|---|
| entry as written | 1.336 | 5.49 |
| committed CSV at audit time | 1.1925 | 5.15 |
| fresh run 1 | 1.022 | 4.91 |
| fresh run 2 | 1.184 | 5.54 |
| fresh run 3 | 1.177 | 5.09 |
C2 is FALSIFIED. Not one quiet-machine run clears 1.25×, and the recorded 1.336 was the outlier.
The structural fault is worse than the clerical one. P-40's before column is a committed
fixture — blessed at the parent commit and never re-timed — while after is timed live. The two
arms were therefore never measured under the same conditions, and all the ratio's variance sits in one
of them. The stage ratio, where both arms are timed back to back in one process, is stable at
4.91–5.54 across every run and every version of this entry. That is the difference between a
comparison and a stopwatch reading.
✗24 already earned this rule and Phase 19 did not apply it: "A wall-clock ratio is not a gate. Gate the count the ratio samples." P-38's whole table, P-40's C2 and P-47's C2 are all wall-clock ratios registered as pass/fail thresholds, on a machine whose governor M-280 caught swinging 1.8×.
What survives, and it is most of the mechanism. C1 holds on every run — the packed predicate is ~5× the scalar one, and that ratio is stable because both arms are in-process. C3 holds outright and deterministically: 12 of 12 mesh hashes identical, which no amount of machine noise can perturb. The bitmap prepass removes work and provably does not change the output. What it does not have is a defensible whole-extractor speedup on this evidence.
The fix is registered as P-50 — the audit's P-54, renumbered — and it is the right shape: the
quantity the prepass actually changes is how many eight-corner gathers run, which is cells under
the scalar path and active_cells under the bitmap path. Two integers, already in the CSV, identical on
every machine. Gated as an equality, a gather on an inactive cell means the mask is wrong, and wrong
the other way is a hole — so it is a correctness gate wearing a performance gate's clothes.
Two smaller corrections from the same audit, recorded here rather than by editing their entries.
✗29 says the inadequate-cell fraction runs "3.8–19.4% on every registered row"; measured from
p-43.csv the low end is 2.93% (gyroid at 17³). The claim it supports — never zero — is
unaffected. And the audit's §A.3 and §A.4 are stale rather than wrong: it reports P-45/P-46/P-47 as
having no ledger entries and doc_facts.sh red, both of which were true at its snapshot 61c6201 and
fixed thirty minutes later at 5d0d758 and ceda7c6. The audit opens by confessing the same failure
mode against itself, which is the reason to trust the rest of it.
And a process item the audit is right about. doc_facts.sh gates counts; nothing gates numbers
quoted inside a FINDINGS.md entry against the CSV that entry names. That check is mechanical for the
subset that matters — an entry naming docs/experiments/p-NN.csv and printing a markdown table — and it
would have failed on Phase 19 twice. Opened as F-009.
P-50 — registered for R-039a, before the harness: the count the ratio was sampling
M-348 falsified P-40's C2 on its own artefact and then on three quiet-machine re-runs. ✗24 had already earned the rule — "a wall-clock ratio is not a gate; gate the count the ratio samples" — and the count was in the CSV the whole time. The bitmap prepass does not make an eight-corner gather faster. It removes gathers, and how many run is an integer that does not depend on a governor, a load average or a machine.
H. (C1) As an equality, not a ratio and not a tolerance: the scalar predicate performs exactly
cellsgathers and the bitmap predicate exactlyactive_cells, on every field at every resolution. (C2) The prepass's own cost is exactlysample_countcomparisons pluscells_x.div_ceil(64) · cells_y · cells_zfused word groups — cells, not samples, which is the defect E-307 found and M-348 fixed, worth about 30% of the stage at every64k+1grid this crate benchmarks. So the prepass isO(n³/64)word groups against theO(n³)gathers it replaces, and the two counts locate the crossover with no clock in the room. (C3) The two predicates name the same ordered active list, element for element — which is what makes the mesh identical rather than merely equal in count. Falsified by C1 failing as an exact equality: a gather on an inactive cell means the mask admits what it must not, and a mask wrong the other way drops a cell and punches a hole, so this is a correctness gate wearing a performance gate's clothes and a mismatch of one is a failure. C3 failing would mean the set-bit walk does not reproduce lexicographic order, which changes every vertex index downstream of the first disagreement.
Timing is recorded beside all three and gates nothing. That is the whole point of the re-registration.
Records field, samples_per_axis, cells, active_cells, gathers_scalar, gathers_bitmap,
gathers_equal_cells, gathers_equal_active, bitmap_comparisons, bitmap_word_groups,
word_groups_predicted, same_ordered_list, ns_per_cell_scalar, ns_per_cell_bitmap.
🔬 M-349 — HELD as three exact equalities on 15 of 15 rows: the bitmap's claim was always a count, and a count does not have a governor (P-50, R-039a)
M. cargo bench --bench experiment_p50, docs/experiments/p-50.csv. Three fields × five grids
chosen to straddle a word boundary — 33, 64, 65, 128, 129 — f64.
| clause | registered | measured |
|---|---|---|
C1a gathers_scalar == cells |
equality | true on 15 of 15 |
C1b gathers_bitmap == active_cells |
equality | true on 15 of 15 |
C2 word_groups == cells_x.div_ceil(64)·cells_y·cells_z |
equality | true on 15 of 15 |
| C3 same ordered active list | element for element | true on 15 of 15 |
This is what P-40's C2 should have been. The mechanism removes gathers, and how many it removes is an integer:
| field | 128³ | gathers scalar → bitmap | removed |
|---|---|---|---|
sphere |
2,048,383 cells | 2,048,383 → 19,010 | 99.07% |
fbm_terrain |
2,048,383 cells | 2,048,383 → 33,817 | 98.35% |
gyroid |
2,048,383 cells | 2,048,383 → 85,077 | 95.85% |
Those numbers are identical on every machine, under every governor, at every load. The wall clock is in
the CSV beside them — 2.39 → 0.42 ns/cell on sphere, 2.58 → 0.47 on gyroid — and gates nothing,
which is the entire point of the re-registration.
C2 is where E-307's defect would have shown up, and it is why 65 and 129 are in the fixture. The
prediction is over cells, cells_x.div_ceil(64), and the code M-348 fixed iterated over samples,
size_x.div_ceil(64). At 65 samples those are 1 and 2; at 129, 2 and 3. Had the fix not landed, C2
would read 8,192 against a predicted 4,096 on the sphere 65³ row and the equality would have failed by
exactly a factor the grid explains. It reads 4,096 = 4,096. A count clause catches a wasted word; the
ratio clause it replaces measured that same waste as noise and could not name it.
C3 is the one that matters for correctness and it is the cheapest to state. The two predicates agree on the active list as an ordered sequence, not merely as a set or a count — which is what makes vertex creation order, and therefore every index and every golden hash, unchanged. A set-equal but order-different result would pass a count gate and corrupt every downstream index from the first disagreement.
What the phase learns from this, beyond the mechanism. ✗24 said gate the count the ratio samples and Phase 19 registered three wall-clock thresholds anyway (P-38's table, P-40's C2, P-47's C2). Two of the three failed on re-measurement and the third (P-47's 2.8×) is the one nobody has re-run on a quiet machine. The countable form is not a weaker claim — it is a stronger one: an equality on 15 rows admits no tolerance, no median-of-five, and no argument about load, and it turns a performance assertion into a correctness gate. A gather on an inactive cell means the mask admits what it must not; a mask wrong the other way drops a cell and punches a hole.
Would be shown wrong by: a grid where cells_x is a multiple of 64 and the sample row is not, or
any future change to the walk order — both of which C2 and C3 would catch as an integer mismatch rather
than as a slow afternoon.
Phase 20 — six registrations from the audit, four citations corrected before any harness
Source: docs/research/2026-08-23-findings-audit-and-phase-20-registrations.md, an external audit of
this ledger against its own committed artefacts, and
docs/research/2026-08-23-phase-20-source-corrections.md, which records what four parallel reads of the
primary literature found. All six are registered in crates/isomesh/src/experiment.rs before their
harnesses exist. Experiments are bench-local; crates/isomesh/src/** is read-only apart from the
registrations themselves.
This heading is not renamed, and what a reader needs is one sentence rather than a rewrite (D-018).
P-55…P-60 and ✗39…✗43 were registered and run after the six this heading names and landed in
this same section, so the file has no ## Phase 21 and a reader looking for one cannot find it. The
research docs — and BACKLOG.md's own Phase 21 — call that later material Phase 21; it is
everything from ### P-55 down to ✗43. The heading stays as written because it records what the
phase was called at the time, which is the same reason this file re-tiers rather than rewrites.
Three of the six rested on a claim the source does not make, and that was found by reading the source rather than by running anything. The corrections are recorded here because a registration built on a figure that does not exist is the failure ✗21 already catalogues — a property lifted from a summary, not from the thing itself — and this is the cheapest possible moment to catch it.
P-51 — registered for R-046, before the harness: both halves of the tangent-sphere constraint
Sellán, Batty & Stein 10.1145/3610548.3618196 state it in one sentence: the surface "must be tangent
to every sphere at least once while strictly containing every sphere with negative value and excluding
every positive value one". Piercing is counted as vertices whose |d(p)| − ‖v − p‖ exceeds 0.05 cells;
untouched is counted as samples no vertex comes within 0.05 cells of tangency to. C2 is a ratio,
DC ≥ 20× MC, because M-27 already measured ~150 per 1,000 and an absolute bar of 20 could not fail.
Records field, extractor, samples_per_axis, vertices, samples, pierced, pierced_per_1k,
worst_piercing_cells, dc_over_mc_ratio, untouched, untouched_per_1k, worst_untouched_cells,
samples_probed_per_vertex, control_box_exact_zero, threshold_cells.
P-52 — registered for R-047, before the harness: tangency as a placement rule, on our own baseline
⚠ CITATION CORRECTED BEFORE THE RUN. The audit cited arXiv:2604.00157 for "edge Chamfer 0.0262
against MC 0.417 and DC 0.350 — 13× on sharp features". A full read of the tangency literature in corpus
finds no edge-Chamfer metric, no sharp-feature metric and no 13× figure anywhere; the actual paper
measures Hausdorff, Chamfer and its own energy, and treats sharp features purely qualitatively. The
clause is therefore rebuilt on this crate's own measurements — M-315's placement ceiling and M-66's
35.796° corner error that does not soften with h. Only Eq. (8) is borrowed. C4 predicts the trade
M-315 implies: vertex term improves, centroid term worsens.
Records field, samples_per_axis, rule, iterations, symmetric_hausdorff,
hausdorff_ratio_vs_qef, vertex_term, vertex_term_ratio_vs_qef, centroid_term,
centroid_term_ratio_vs_qef, self_intersections_per_1k, vertices, triangles, non_manifold_edges,
counts_identical_to_qef, ns_per_sample.
P-53 — registered for R-048, before the harness: the third corner label on CT data
⚠ SCOPE CORRECTED BEFORE THE RUN. Custódio, Pesco & Silva 10.1186/s13173-019-0086-6 report no
count of degenerate triangles removed on any dataset — only radii-ratio histograms, Betti numbers and
blocked-cube percentages — so C2's 10× is this crate's own bar, not a reproduction. Their triangulator is
also a per-cube convex hull, explicitly "without the need of a look up table", with cross-cell face
dedup; that half is not reproduced. The label assignment itself is a pure pre-pass over the
eight-corner classification, which is exactly what a bench can do.
Records volume, isovalue, label_rule, cells, surface_cell_corners, equal_corners,
degenerate_triangles, degenerate_from_equal_corners, degenerate_attributable_fraction,
degenerate_ratio, triangles, euler_characteristic, non_manifold_edges, boundary_edges,
mesh_hash, half_offset_identical.
P-54 — registered for R-049, before the harness: affine arithmetic where correlation lives
⚠ DERIVATION CORRECTED BEFORE THE RUN. Fryazinov, Pasko & Comninos 10.1016/j.cag.2010.07.003
contains no correlation argument and no quantified tightening figure — its evidence is end-to-end
wall-clock tables — and gives no min/max or abs rule at all. Both gaps are load-bearing: the 1.5× is
derived here from M-267's measured supremum, and the absence of a min/max rule is precisely why C2
predicts under 5% on the two fields built from min/max. A non-uniform prediction is the whole
point; a uniform one would not distinguish the mechanism from a better constant.
Records field, samples_per_axis, bound, cells, rejected_cells, rejected_fraction,
rejected_ratio_vs_lipschitz, has_min_max, mesh_identical, mesh_hash, bound_evals,
bound_ns_per_cell.
P-55 — registered for R-050, before the harness: a monotone-edge certificate, labelled as a 3D port
⚠ STATUS CORRECTED BEFORE THE RUN. arXiv:2608.12142 resolves exactly as cited — Finken, Li, Wang,
Guo & Levine, IEEE VIS 2026 short paper — and its Theorem 1 is proved, not merely observed. But the
proof is 2D, its pigeonhole step is "since a triangle has only three edges", and the paper's own
Discussion names the restriction to 2D as a limitation. The theorem also does not apply to the trilinear
interpolant, under which interior critical points genuinely exist — that is the origin of the
ambiguous-face problem. So a held C1 is evidence about this crate's meshes and never a proof
transported to 3D. The tolerance is isomesh's invention: the paper gives a bare sign-disagreement
predicate with no epsilon and no flat-region guard.
Records field, extractor, samples_per_axis, edges, non_monotone_edges,
non_monotone_per_1k, k_samples, tolerance, non_monotone_at_1e14, non_monotone_at_1e10,
worst_reversal, falls_with_resolution.
P-56 — registered for R-051, before the harness: the seam bound P-47 left behind
P-47's accuracy clause died by three orders of magnitude and its artefact says why: the bulk mean is
1.9e-8° and one vertex in 57,470 carries 4.365°, with worst_stencil_straddles_seam true from 32
brushes upward. The surviving claim is mechanical — at a min/max seam the field is C⁰, a central
difference averages two gradients, and the error is at most half the angle between them, M-283's
(180° − θ)/2 in a second setting. It does not shrink with h, because DIFF_STEP scales with
|p|. Tightness is recorded per fixture so a bound that holds only by being loose everywhere is visible
as the vacuous pass it would be.
Records dihedral_deg, samples_per_axis, seam_cells, vertices, straddling_vertices,
straddling_max_error_deg, predicted_bound_deg, worst_over_bound_ratio, within_bound,
non_straddling_mean_error_deg, scaling_exponent.
🔬 M-350 — HELD, and the bound turned out to be provable: a central difference across a CSG seam is wrong by at most half the crease angle, and it essentially attains that (P-56, R-051)
M. cargo bench --bench experiment_p56, docs/experiments/p-56.csv, 28 rows, f64, dual_contouring.
Seven dihedrals from 30° to 175° × four resolutions. Two spheres composed by the crate's Difference.
| clause | registered | measured |
|---|---|---|
C1 straddling error ≤ (180° − θ)/2 |
every vertex, every fixture | HELD — 0 breaches on the 24 rows with a straddling population |
C2 straddling count scales O(n) |
fitted exponent < 1.5 | FALSIFIED — worst 2.0922 |
| C3 non-straddling mean error | < 1e-6° | HELD — worst 6.754e-10°, 1,480× inside |
C1 is not a threshold that happened to hold; the bound is attained. Median tightness
worst_error / bound is 0.9748, 9 of 24 rows exceed 0.99, 16 exceed 0.90, and the registration's
own vacuity trap — median under 0.1 — is missed by a factor of 9.7. At 129³ the worst measured error
tracks the prediction across the whole sweep: 2.498 against 2.5 at 175°, 7.422 against 7.5, 14.423
against 15, 29.982 against 30, 44.823 against 45.
And the mechanism is a proof, not a fit. With u = n₁, v = −n₂ the two branch gradients and
w = u − v, the central difference across the seam returns g = u − Λw for a diagonal Λ whose
entries are all ≤ ½ while branch A is active. Then |Λw| ≤ |w|/2 = sin(α/2), and the largest angle
between u and u − z over |z| ≤ R is asin(R) — which is exactly (180° − θ)/2. Equality occurs at
s(p) = 0 with every λᵢ = ½, where g = (u + v)/2. That is why the ratios sit at 0.99 and not at some
arbitrary value below 1: the worst case is reached wherever a vertex lands on the seam, and a dual
vertex on a crease is what a QEF produces by construction.
P-47's lone outlier is explained exactly. One vertex in 57,470 at 4.365° back-solves to a seam
near 171°, and (180 − 171)/2 = 4.5. It was a near-tight straddle, not a fluke — which is what turns
a dead accuracy clause into a mechanism.
C2 failed, and the interesting part is that my instrument was wrong rather than the claim. The
sentence "the count scales like seam length, not area" is true: straddling_vertices / seam_cells is at
most 1.015 on 28 of 28 rows, and the straddling share of all vertices halves on every doubling —
1.995e-2 → 9.92e-3 → 5.01e-3 → 2.52e-3 at θ=120°, ratios 2.01/1.98/1.99, an O(n) population on an
O(n²) surface. What fails is the fitted exponent, because a fit over a range containing the
saturation crossover measures where the grid sits relative to √(2rh)/sin θ, not the seam's
dimensionality. The extra column seam_offset_stencils shows it directly: 0.74 → 0.08 at θ=120°
(saturated at every resolution, exponent 1.0253) but 75 → 3.3 at θ=30° (never saturated, so the fit
reads the climb). A scale-free equality was available and I registered a curve fit instead — the same
family of error as ✗24, one level up: not a clock this time, but a statistic whose value depends on the
sampling window.
One correction to my own registration. It says the stencil step is DIFF_STEP · |p|. sdf.rs uses
DIFF_STEP · max(|pₓ|, |p_y|, |p_z|, 1) — max-norm, floored at 1. No effect here (every seam point lies on
the unit sphere, so both give DIFF_STEP), but the sentence misstates the crate. The conclusion drawn
from it survives and is confirmed: seam_offset_stencils falls with the grid while the stencil does not,
so worst_over_bound_ratio rises toward 1 with resolution rather than falling.
Would be shown wrong by: a seam whose two branches are not both 1-Lipschitz at the crossing, where
Λ's entries could exceed ½; or an extractor that never places a vertex on the crease, which is why
surface_nets is excluded by construction — its centroid rule puts the vertex where no crease is, and it
would report zero straddles at every resolution and look like a pass.
💥 ✗36 / M-351 — FALSIFIED on all three clauses, and the zero was unreachable by geometry rather than by sampling: a mesh edge is a chord, so the monotone predicate ports to the wrong complex (P-55, R-050)
M. cargo bench --bench experiment_p55, docs/experiments/p-55.csv, 32 rows — eight fields ×
17³/33³/65³/129³ — marching_cubes, f64. Three independent runs; every gated integer, ratio and
boolean bit-identical.
| clause | registered | measured |
|---|---|---|
C1 zero non-monotone edges on sphere, torus, box_exact at 65³ |
0 | 917.6 / 893.7 / 42.3 per 1k |
C2 gyroid, fbm_terrain non-zero and falling with resolution |
falling | rising ×4 per refinement |
C3 noise_cavity highest of the eight |
highest | 5th of 8; sphere is highest at every resolution |
C1's zero is not attainable at any k, any w, or any tolerance, and there is a closed form. A mesh
edge joins two vertices that both lie on the extracted zero set, so it is a chord. For a strictly
convex surface the chord's interior is strictly inside the solid, so f runs 0 → negative → 0 and the
directional derivative must change sign. On a sphere of radius r with central angle θ:
g(0) = (a·b − r²)/r = r(cos θ − 1) < 0andg(1) = r(1 − cos θ) > 0, for every distinct pair of surface points.
The measurement agrees to the digit: sphere at 17³ scores 1000.000 per 1k — 804 of 804 edges — and
worst_reversal falls as h² (7.092e-2 / 1.997e-2 / 5.420e-3 / 1.408e-3, ratios 3.552 / 3.684 / 3.851
converging on 4), which is the chord sagitta rθ²/2 and nothing else.
k is not the cause, which kills the registration's own falsification reading. The registered
falsifier says a non-zero C1 "would mean the gate is measuring the sampling of the edge and k is the
problem". It is not: 97.5% of the sweep's 901,583 flags — all but 22,573 — were decided by g(0) and
g(1) alone, before any interior sample existed, and all_flags_from_endpoints is true on 17 of 32 rows
including sphere and box_exact at 65³.
The tolerance I invented is structurally inert, and scaled by the wrong quantity. The guard scales by
|f(a)| + |f(b)| — the residual at two vertices that are on the zero set. max_abs_tolerance is
exactly 0.0 on box_exact at all four resolutions and never exceeds 7.63e-13 anywhere, against a
minimum deciding reversal of 1.408e-3, nine orders of magnitude above. Counts are identical at 1e-14,
1e-12 and 1e-10 on 31 of 32 rows. Registering a tolerance is not the same as registering a useful
one, and the sensitivity columns are what made that visible.
The inversion is the most interesting row. The one field whose rate genuinely halves per refinement is
box_exact — 178.1 / 86.1 / 42.3 / 21.0 per 1k — the resolution-witness behaviour C2 predicted for
gyroid and fbm_terrain, on the field C1 predicted zero for. The mechanism is exact: box faces are
planar, the analytic gradient there is an axis-aligned unit vector, the chord's component along it is an
exact f64 zero (38,520 such samples at 65³), so no guard is needed. What remains is the corner
population — an edge straddling a convex box edge picks up one face normal at each end, with
worst_reversal_over_w exactly 1.000000 at all four resolutions — and box edges are O(n) against
O(n²) surface cells, hence the halving.
Where the non-vacuous port lives, named rather than measured. Finken et al.'s PL function lives on the
ambient complex, and monotonicity is a condition on that complex's edges — whose endpoints are not
on the zero set and for which |f(a)| + |f(b)| is a real scale. Porting it to the extracted surface mesh
is what makes both the predicate and its tolerance vacuous. Opened as R-052; this harness measured
what was registered, and naming the alternative is a finding, not a substitution.
One more correction to my own registration. It says the substitute for the paper's autodiff is "the
crate's central difference". It is not — all eight reference fields reach an analytic Sdf::gradient,
and fields/mod.rs says so in its opening lines: "The central-difference default is never used by a
reference field." All 3,437,646 gradient evaluations here are exact, so the noise story the registration
flagged as unanalysed never arises.
A free manifoldness confirmation fell out. Exact-bit edge deduplication gives
edge_instances == 2 × edges exactly on all 20 rows of the five closed fields, so every mesh edge is
shared by exactly two triangles and the vertex a shared grid edge produces is bit-identical from both
incident cells. The three deviations are the documented ones: fbm_terrain is open, gyroid carries +10
at every resolution, noise_cavity +132 to +200.
🔬 M-352 — HELD, FALSIFIED, HELD: every degenerate triangle comes from an exactly-equal corner, the repair moves no geometry at all, and it is safe on one CT volume and changes the topology of the other (P-53, R-048)
M. cargo bench --bench experiment_p53, docs/experiments/p-53.csv, 8 rows — fuel 64³ and
bonsai 256³ × isovalue 32 and 32.5 × binary and ternary labelling. Real uint8 CT data, f64
extraction. 8.8 s; nothing downscaled.
| clause | registered | measured |
|---|---|---|
| C1 ≥80% of degenerates attributable to equal corners | ≥ 0.80 | HELD — 1.000000 on both volumes |
| C2 ≥10× fewer degenerates, χ / nm-edges / boundary unchanged | both halves | HELD on fuel, FALSIFIED on bonsai |
| C3 byte-identical at a half-offset isovalue | identical | HELD on both |
C1 is not 80%, it is everything. degenerate_from_equal_corners equals degenerate_triangles
exactly — 164 of 164 on fuel, 58,097 of 58,097 on bonsai. Tagged, not correlated: every
triangle carries the base sample of the cell that emitted it, recovered by replaying the march, and
replay_matches_crate is true on all 8 rows — the replay's index buffer equals the crate's element for
element. The harness exits non-zero if that comparison fails, so the attribution is licensed rather than
assumed.
The premise was inverted and it did not matter, which is the sharpest thing here. The registration
says MC33 classifies an equal corner as inside and proposes a strict comparison. isomesh::cube::is_inside
is already strict — value < 0 — so an equal corner is outside here. The degenerates appear anyway,
and the real mechanism is downstream of the sign: on a cut edge with an exactly-zero endpoint the
interpolation parameter t = a/(a−b) is exactly 0 or exactly 1, so the crossing lands on the
sample, every cut edge meeting there does the same, and the vertex cache is keyed on the grid edge
rather than on the point — so nothing is shared. Proof that it is coincidence and not sliver area:
degenerate_repeated_index = 0 and degenerate_zero_area_only = 0 on every row, while
degenerate_coincident_position is 164 and 58,097. What the crate needs from Custódio is the third
label's consequence — one shared vertex at the corner — not its comparison.
max_snap_distance is exactly 0. The vertex is already at the corner, so the repair moves no
geometry whatsoever; it only merges indices. That makes the whole thing purely combinatorial, and it
is why the topology question below is a decision rather than an approximation.
C2 splits, and the split is the finding. Both volumes lose every degenerate triangle. Only one keeps its topology:
| degenerate | χ | non-manifold edges | boundary edges | pinch groups | |
|---|---|---|---|---|---|
fuel 64³ |
164 → 0 | 19 → 19 | 0 → 0 | 24 → 24 | 0 of 50 |
bonsai 256³ |
58,097 → 0 | 517 → 585 | 0 → 561 | 4,366 → 3,716 | 516 of 17,201 |
The deciding diagnostic separates the two cases exactly, and it is a graph property, not a threshold.
Run a disjoint-set over the baseline mesh's own triangles. Two vertices snapped to the same = corner
that already share a triangle are a fold being flattened — that triangle is one of the degenerates,
and no edge, boundary or component can move. Two that share no triangle lie on different sheets of
the surface that merely meet at that sample, and identifying them welds the sheets:
pinch_excess_components counts 520 previously separate pieces joined on bonsai, against 0 on
fuel.
So the repair is safe exactly when the equal-corner set is pinch-free, and that is a property of the
data, not of the algorithm. fuel is; bonsai is not, at 3.0% of its collapse groups. A crate that
shipped this unconditionally would silently weld 520 components of a CT scan and pass every gate except
euler_characteristic. The precondition is cheap to test — one union-find over the baseline
triangles — and that is the shippable result here, not the label. Opened as R-053.
C3 is the control and it did its job. At isovalue 32.5 an integer sample cannot equal the isosurface:
equal_corners = 0, snapped_vertices = 0, and the two arms hash identically on both volumes —
1307533111487838477 on fuel, 14069567395604099995 on bonsai. At isovalue 32 the same comparison is
false and is recorded as such, so the control distinguishes the two cases rather than passing everywhere.
Source honesty, restated because the registration already carried it: the paper reports no degenerate-triangle count on any dataset, so the 10× bar is this crate's own, and the convex-hull triangulator was out of scope and was not reproduced.
💥 ✗37 / M-353 — FALSIFIED on three of four clauses, and the algebra says why: Eq. (8) confined to a cell is a contraction toward the cell centre, not toward the surface (P-52, R-047)
M. cargo bench --bench experiment_p52, docs/experiments/p-52.csv, 12 rows — sphere, torus,
box_exact, thin_plate × Qef / Centroid / Tangency, 65³, f64. Two consecutive runs produce
byte-identical CSVs in every column.
| clause | registered | measured |
|---|---|---|
| C1 sharp fields ≥1.25× better Hausdorff | ≥ 1.25× | FALSIFIED — 64.8× and 87.2× WORSE |
| C2 smooth fields within ±10% | ±10% | FALSIFIED — 13.25× and 6.32× worse |
C3 counts identical to Qef |
identical | HELD — 0 of 12 rows differ |
| C4 vertex term improves, centroid term worsens | ≥3 of 4 fields | FALSIFIED — 0 of 4 |
The mechanism is derived, not guessed, and it is one line of algebra. Per cell,
t_i = p_i + λ_i(c − p_i) with λ_i = σ_i|s_i| / ‖c − p_i‖. With comparable λ the least-squares
minimiser of Σ‖v − t_i‖² is (1 − λ)·mean(pᵢ) + λ·c — and the mean of the eight corners of a cube is
the cell centre. So the rule does not pull the vertex toward the surface; it pulls it toward the middle
of its own cell.
Measured, in a column added for the purpose. offset_from_cell_centre_in_cells, tangency against
Qef: sphere 0.2691 vs 0.3923 (−31.4%), torus 0.2533 vs 0.3734 (−32.2%), box_exact 0.3832 vs
0.5132 (−25.3%), thin_plate 0.2673 vs 0.3348 (−20.1%). Tangency is the closest rule to the cell centre
on 4 of 4 fields — closer even than Centroid on three of them.
C4 is the informative failure, and it is the opposite of the one the registration anticipated. M-315 predicted a trade: pull vertices onto the surface and the vertex term improves while the centroid term worsens, because the QEF buys better-centred facets at the cost of worse-placed vertices. The centroid half held on 4 of 4 — it worsens by 6.0× to 96.6×. The vertex half failed on 4 of 4 — it worsens too, by 6.3× to 121.0×. A uniformly worse arm does not test a trade, so M-315's tangent-plane explanation is untouched by this result rather than confirmed or refuted by it. The registration named the informative outcome as "vertex improves and centroid does not worsen"; what happened was neither arm improving, which is a third case it did not enumerate.
C3 passing is what makes the rest attributable. Vertices 4760 / 4208 / 5768 / 2048 and triangles
9516 / 8416 / 11532 / 4092 are identical across all three rules on every field, with zero non-manifold
edges and zero self-intersections on all 12 rows — identical by construction, since all three rules
emit one whole-cell vertex per active cell through the same mesher, so the index buffer cannot move.
Without that, none of the ratios above would mean anything.
This confirms the source's own ablation rather than contradicting it, which is the honest reading.
The scout read of 10.1145/3610548.3618196 warned before the harness was written that globality is the
claimed mechanism and not an implementation detail: their c_i is a closest point on the whole
evolving mesh found by an AABB tree, their solve is global and sparse with a mass matrix, and their Fig.
17 measures clamping away far spheres as progressive detail loss. Confined to a cell, c_i degenerates
to the current vertex and the spheres degenerate to eight corners whose mean is the centre — so the
energy stops being about the surface at all. The paper is not wrong; the reduction is, and now there is a
number and an identity for it instead of an intuition.
Would be shown wrong by: a neighbourhood wider than one cell restoring the vertex term, which is the cheap next probe and is exactly the ablation axis Fig. 17 sweeps — but it costs the per-cell parallelism that makes this crate's extractors chunkable, so it is a different design, not a tuning.
🔬 M-354 — HELD on all three, and the prediction's shape is what held: affine arithmetic rejects 3.85× more cells on gyroid and exactly zero more where min/max destroys the correlation (P-54, R-049)
M. cargo bench --bench experiment_p54, docs/experiments/p-54.csv, 12 rows — six fields × two
bounds, 17³ (4,096 cells), f64. Revised affine form: five stored reals, fixed size, no heap.
| clause | registered | measured |
|---|---|---|
C1 gyroid rejects ≥1.5× more cells |
≥ 1.5× | HELD — 3.847384× |
C2 the min/max fields rise <5% |
< 5% | HELD — +0.000% and −0.515% |
| C3 mesh byte-identical | identical | HELD — 12 of 12 rows |
Soundness was verified before any verdict, because an unsound bound would make C1 meaningless and C3
fail. Two checks, 0 violations in both: a per-noise-symbol substitution sweep over sin, cos,
sqrt — 12,442,589 samples, minimum margin +5.66e-14 — and an end-to-end dense probe against the
crate's own Sdf::sample, 2,985,984 points per field, 17,915,904 total. The exact fields' margins sit
at 2.5e-13–4.8e-13, which is the declared per-operation slack 256·EPS·max(1,|v|) doing its job:
256 × 2.22e-16 × 3.46 ≈ 1.97e-13 against a measured 2.54e-13. Tightness, not fragility.
C1, and the row that makes the mechanism unmistakable.
| field | Lipschitz | affine | ratio | only-affine | only-Lipschitz |
|---|---|---|---|---|---|
gyroid |
688 / 4,096 | 2,647 | 3.847× | 1,959 | 0 |
gyroid_uncapped |
0 / 4,096 | 1,098 | ∞ | 1,098 | 0 |
box_exact |
3,312 | 3,312 | 1.000000 | 0 | 0 |
csg_difference |
3,300 | 3,283 | 0.994848 | 0 | 17 |
gyroid_uncapped is the cleanest result in the phase: Hart's test rejects nothing at all — 0 of 4,096
— and the affine form rejects 1,098. A triply periodic field has no useful global Lipschitz ball, and
correlation does not care.
C2 came in finer than the clause asked, and the extra precision is the confirmation. It is not that
the min/max fields merely fail to gain. On box_exact the two rejected sets are identical — 0 gained
and 0 lost, the same 3,312 cells, not merely the same count. On csg_difference the affine set is a
strict subset: 0 gained, 17 lost. Where the source paper gives no affine rule and the only sound
treatment collapses the form to an interval, correlation-aware arithmetic is not neutral — it is slightly
worse, because it pays the collapse and gets nothing back. That is a mechanism confirming itself, not
a threshold being cleared.
C3 has a negative control, so it is a gate rather than a tautology. mesh_identical true on 12 of 12
by two independent checks — zero baseline vertices inside any rejected cell, and equal mesh hashes — and
then every field is re-gated with Hart's constant divided by 4, M-244's incident made deliberate.
control_detected is true on all six: the sabotaged bound leaves 338 to 4,121 baseline vertices
inside rejected cells and changes the hash every time. An instrument that cannot report a hole is not
reporting their absence either.
Cost, recorded and gating nothing: 42.0 → 505.4 ns/cell on gyroid, 2.1 → 36.3 on sphere. The
affine bound is roughly 12× the arithmetic for 3.85× the cells rejected, so this is not a speedup and
is not registered as one — it is a capability: the ability to reject a cell of a field whose global
Lipschitz constant is worthless. Whether it pays depends on the cost of the work being skipped, which is
a different measurement.
Would be shown wrong by: a field built from min/max whose affine set is a strict superset — that
would mean the interval collapse is not what costs, and the non-uniformity has another cause.
💥 ✗38 / M-355 — C1 and C3 HELD, C2 falsified by a measured absence: nothing pierces the empty ball, and between 2.9% and 80.5% of spheres are never touched (P-51, R-046)
⚠ CORRECTED 2026-08-23 by its own demo, before this entry was a day old. Two numbers in the prose below are wrong and the artefact is right. (1) The floor is 3.13%, not 2.9% — the smallest
untouched_per_1kover the 15 committed rows is31.2863(sphere/dual_contouring); the ceiling804.7155 = 80.47%reproduces. (2)box_exact/ DC's worst miss is not exactly1/√2: inf64it is1/√2 + 1.767767e-9cells, and the residual is derivable rather than noise —Clamp::ToCellinsets the QEF vertex byCLAMP_EPSILON·h/2perpendicular to theh/√2displacement, and a perpendicular offset enters a distance at second order,o²/2b, which in cells isCLAMP_EPSILON²·√2/8 = 1.767767e-9independent ofh. Measured over predicted is1.0000001. The CSV is untouched and was always right:worst_untouched_cells = 0.707107matches to the digit, and six decimals cannot show the residual. By contrastthin_plate/MC's1.000000andbox_exact/MC's√2are bit-exact, delta exactly0.000000e0, because an MC vertex is an interpolation whose root lands on a lattice point. This is F-009's failure mode caught by an artefact rather than by review — the demo parsesp-51.csvby column name and printedDISAGREESrather than quoting the prose it was given.
M. cargo bench --bench experiment_p51, docs/experiments/p-51.csv, 15 rows — five fields × three
extractors, 65³, f64, 274,625 samples per row. Four consecutive runs identical in every gated quantity.
| clause | registered | measured |
|---|---|---|
C1 marching_cubes pierces < 1 per 1k |
< 1 | HELD — 0.0000, 0 of 22,790 vertices |
C2 dual_contouring ≥ 20× marching_cubes |
≥ 20× | FALSIFIED — 0/0, undefined |
| C3 untouched non-zero, MC > DC | both | HELD — 5 of 5 fields |
C2's falsification is the registered outcome that "closes four 2025–2026 papers for this crate in one
pass", and it is exactly what happened. Dual Contouring pierces 0 of 22,798 vertices on every field.
Exhaustively — no neighbourhood cutoff, max over all 274,625 samples — its worst violations are -0.0066
(box_exact), 0.0174 (sphere), 0.0394 (torus), -0.0013 (thin_plate), 0.0232
(csg_difference) cells, two of them negative, all under a 0.05 gate. The QEF's cell clamp is
apparently sufficient: the exclusion half of the tangent-sphere constraint is already respected by
construction, and the four papers built on recovering it have nothing to offer these extractors.
The control failed as registered, and the registration's inference is what is false. It says "an
instrument that finds violations there is measuring its own tolerance". On box_exact, Marching Cubes
reports exactly 0 and Dual Contouring 0 with a negative margin, while Surface Nets reports 368
of 5,768 at a worst of 0.422650 cells — 8.5× the gate. A tolerance artefact hits all three. This
separates them, and the magnitude is an exact closed form, checkable by hand:
SN vertex
(-0.958333)³, sample(-0.9375)³,|d| = hexactly, distance= h/√3, violation= h(1 − 1/√3) = 0.4226497 h.
It is derivable, not incidental: box_exact's faces lie exactly on sample planes, so the corner cell has
one inside corner at f = −h and seven at f = 0, every crossing edge roots at t = 1, and the mean of
the three crossings is that vertex. It is Surface Nets' documented corner rounding — fields/mod.rs
says "surface nets rounds these corners, dual contouring holds them" — and the identical magnitude and
witness recur on csg_difference. The control fails; the instrument is fine.
C3 is the half nobody had measured, and the worst cases are exact geometric constants.
| field | MC untouched /1k | DC untouched /1k | MC/DC |
|---|---|---|---|
thin_plate |
717.18 | 44.83 | 16.00× |
box_exact |
515.63 | 179.99 | 2.86× |
csg_difference |
572.68 | 265.79 | 2.15× |
torus |
48.09 | 32.76 | 1.47× |
sphere |
35.25 | 31.29 | 1.13× |
Between 2.9% and 80.5% of all samples never have their sphere touched by any vertex — and there is no cutoff to blame, the touching search is exhaustive on all 15 rows. The extremes are exact:
box_exact/ MC: √2 cells exactly. Sample(-1,-1,-1)is the box corner with|d| = 0, and Marching Cubes puts no vertex on a box edge or corner — both endpoints of every spanning grid edge there havef = 0, so there is no sign change. A zero-radius sphere lying on the surface is missed by√2cells. That also sizes the count: 48.8% of the grid sits outside the box in two or more axes.box_exact/ DC: 1/√2 exactly — DC's vertices live on the dual lattice, half a cell off the sample lattice, so a sample lying exactly on the surface can never be touched.thin_plate/ MC: 1.000000 exactly.
Two defects in shipped metadata fell out, and the second is real. The registration calls
csg_difference one of "the five fields declaring FieldBound::Exact". Only four do —
fields/mod.rs:965 declares Underestimate { q: 0.5 }, because max of two exact distances is not one.
And that declared q = 0.5 is optimistic by roughly 5×: at sample (1.0625)³, |f| = 0.108253 —
exactly h√3, the distance to the box corner (1,1,1) — but that corner is carved away by the
subtracted sphere, and the true distance is 0.96–1.06 as three independent extractors agree to within
7%. So |f|/d ≈ 0.11 against a declared 0.5. Conservative rejection trusts declared bounds, which
makes this worth its own ticket: opened as R-054.
P-57 — registered for R-055, before the harness: is a mesh bit-exactly equivariant under the octahedral group?
⚠ THE RELATION IS SCOPED BEFORE THE RUN, AND SCOPED DOWN.
docs/research/2026-08-23-discovery-dossier.md:267 already considered an octahedral metamorphic relation
and held it, because table.rs picks safe_apex by lowest edge index, which is not invariant under
axis relabelling: stated at triangle level the relation "manufactures 2,688 false positives". So the
registered comparison is sorted vertex-position multisets, and the triangle-level count is recorded as
C3 to quantify that warning rather than repeat it. All 48 elements are tested, not the 24 the existing
generator at dual_contouring/solve/tests.rs:130-165 filters to — a reflection is exact in f64 too, and
it is where the ordering question actually lives. M-177's exemption is the load-bearing prior: a lattice
rotation can negate a component, so a sum of positions is not bit-exactly equivariant by that route,
where the three-term dot product is. M-178's vacuous-fixture trap is why fixture_can_fail is a column
and not an assumption — box_exact and thin_plate are exactly representable at 17³ and 33³ and did
move at 25³.
Records field, extractor, family, samples_per_axis, vertices, elements_tested,
elements_vertex_exact, elements_triangle_exact, first_failing_element, first_failing_det,
worst_component_ulp, fixture_can_fail.
P-58 — registered for R-056, before the harness: Robins' lower-star census, with a tie-break this crate has to invent
⚠ THE REVIEW'S PROVENANCE CLAIM WAS FALSE, AND IT WAS CHECKED BEFORE THE HARNESS EXISTED. Robins,
Wood & Sheppard 10.1109/tpami.2011.95 is in the corpus, converted, embedded and cited in zero repo
files. The review that proposed this registration asserted the corpus markdown "terminates mid-§4
before Theorem 11" and that the paper's flagship guarantee is therefore not transcribable. It does
not. §4 is complete through Lemmas 7–10, Theorem 11 is stated in full with both of its arms, and so
are Theorem 3, Theorem 6, Propositions 4–5, Lemma 12 and the pseudocode of Algorithms 1, 2 and 3. Nothing
here needs reconstructing and rule 5 is not engaged. The clause C1 tests is the paper's own sentence:
"the results in Section 4 show that for 2D and 3D complexes the number and type of critical cells found
by ProcessLowerStars are independent of this ordering — a property of our algorithm that arises from the
homotopic growth of each lower star."
The real limit is the one the review buried. Eq. (8) perturbs ties with a global ramp
g'(i,j,k) = g(i,j,k) + η(i + Ij + IJk)/(3IJK), which depends on the whole image dimensions I, J, K —
chunk-dependent, hash-breaking, and liable to underflow — and the ordering-independence result is proved
with ties assumed away. This crate's fields tie exactly (box_exact is exactly zero across its
boundary), so the chunk-local exact tie-break (value, linear_index) under f64::total_cmp is
registered, not discovered, and C1 asks the question the paper never had to: does the independence
survive exact ties? Stage 2 (ExtractMorseComplex) is not local and is O(N²) worst case: out of
scope. C2 is stated as containment, not set equality, because a Morse census can be non-empty where
no MC ambiguity exists and equality would indict the instrument. The paper's own ≤ 27 is quoted
directly — "the maximum number of cells in the lower star of a voxel in a 3D lattice is 27" — which is
why max_lower_star_cells above 27 means the enumeration is wrong, not the paper.
Records field, samples_per_axis, voxels, critical_0, critical_1, critical_2, critical_3,
critical_total, max_lower_star_cells, census_matches_reverse_order, ambiguous_cells,
ambiguous_with_critical, ambiguous_containment_holds, critical_cells_outside_ambiguous,
ns_per_voxel.
P-59 — registered for R-057, before the harness: how many of P-39's 19 survivors are necessary?
M-341 measured the median survivor count at 19 of 64 (0.2969), 3.365× median speedup, 64/64
byte-identical. No measurement of the minimal correct survivor set exists anywhere in this repo — no
ablation, no per-brush necessity test — so the tightness of that bound is unknown rather than good.
Leave-one-out decides it, on P-39's fixture reproduced brush-for-brush so the numbers are comparable to
M-341's. C1 is a soundness control and is reported first: if removing all non-survivors moves any
chunk's hash, the bound is unsound and every other number in the CSV is void. C2 pays either way — a
median necessary / survivors above 0.75 closes the direction with a distribution rather than a hunch.
Records chunk, brushes, survivors, necessary, necessary_fraction, non_survivors_removed,
control_hash_unchanged, unnecessary_far_from_surface, unnecessary_far_fraction, mesh_hash,
remeshes, ns_per_remesh.
P-60 — registered for R-058, before the harness: a shifted-linear root, on one grid line
⚠ SCOPE FIXED BEFORE THE RUN. Blu, Thévenaz & Unser 10.1109/tip.2004.826093 is in the corpus,
converted, embedded, and named once in an inventory line
(docs/research/2026-08-18-corpus-audit-and-procurement.md:128) and never used. The transcribable numbers
are the optimal shift τ_opt = ½(1 − √3/3) ≈ 0.21, the practical τ = 1/5, a gain of "about 8 dB
asymptotically", and the range of validity "for ω < 3π/4". At τ = 1/5 the causal one-pole prefilter
c_n = −τ/(1−τ)·c_{n−1} + 1/(1−τ)·f_n becomes c_n = −2⁻²·c_{n−1} + (1 + 2⁻²)·f_n, which is
multiplication-free. It is also global with (1/4)^k decay per sample — slab-local, not
chunk-local — which is why C3 measures the guard band rather than assuming one, and why this experiment is
scoped to a single grid line and touches no extractor: the reconstruction change would re-derive the
whole A-002 apparatus. C2 is a pre-registered failure, not a hedge: the paper states a Gibbs
phenomenon on a step, a sharp CSG boundary is one, and finding the shifted method better on box_exact
would be the surprise. No golden hash can move — nothing here calls an extractor.
Records field, samples, tau, root_error_standard, root_error_shifted, error_ratio,
median_error_ratio, is_step_like, gibbs_overshoot, guard_band_k, guard_band_delta_cells,
guard_band_converged.
💥 ✗39 / M-356 — C1 and C2 FALSIFIED, C3 HELD: plain marching_cubes is bit-exactly equivariant under axis relabelling and not under reflection, because a/(a−b) and b/(b−a) are two different divisions of the same two values — and every other extractor loses some relabellings too (P-57, R-055)
M. cargo bench --bench experiment_p57, docs/experiments/p-57.csv, 112 rows — eight fields × seven
extractors × 33³ and 25³, f64, 5,488 extractions, 9m38s. All 48 signed coordinate permutations on
every row: 24 with det = +1, 24 with det = −1, asserted pairwise distinct with an exact inverse.
| clause | registered | measured |
|---|---|---|
| C1 all 48 exact on the four primal extractors | 48/48 on 64 rows | FALSIFIED — 60 of 64 rows below 48; minimum 1 of 48. Under the literal bit-pattern reading, 64 of 64 |
| C2 dual extractors exact on strictly fewer than 48 | < 48 on 48 rows | FALSIFIED as stated — 4 of 48 dual rows reach 48. HELD on all 42 dual rows whose fixture can fail |
| C3 triangle-level fails where vertex-level holds | non-zero | HELD — 799 element-instances across 103 of 112 rows; elements_triangle_exact never exceeds 6 anywhere |
The fixture had to be repaired before the experiment could be about the extractor at all, and that is
the first finding. The relation mesh(g·f) vs g·mesh(f) is a statement about an extractor only if the
sample grid is exactly closed under g. A grid origin + i·h mirrors bit-exactly only when h is a
binary fraction, which holds at 17/33/65 samples over [−L, L] and fails at the crate's own 25³:
2L/24 is not dyadic and pos[i] != -pos[n−1−i] on 16 of 25 coordinates per axis. Running there
would have falsified the hypothesis on the fixture. So 33³ is the crate's own domain at h = L/16, and
25³ uses h = 3L/32 with origin = −1.125L — dyadic, so the grid mirrors exactly, and not of the form
L/2^k, so crossings stay generically non-representable. grid_symmetric is asserted true on all 112
rows.
M-178's trap is escaped on seven fields of eight and box_exact defeats both fixtures.
order_sensitive_edges — cut edges where the crossing computed from the far endpoint differs by a bit —
is measured per fixture before any extractor runs:
| field | 33³ | 25³ | field | 33³ | 25³ | |
|---|---|---|---|---|---|---|
sphere |
72 | 24 | thin_plate |
450 | 242 | |
torus |
152 | 32 | gyroid |
532 | 320 | |
box_exact |
0 | 0 | fbm_terrain |
291 | 249 | |
csg_difference |
50 | 31 | noise_cavity |
643 | 360 |
box_exact has 1,350 cut edges and 0 order-sensitive ones at 33³: its zero set lies on planes any
dyadic grid hits exactly. All eight of the file's elements_vertex_exact = 48 rows are box_exact
rows, and every one of them has order_sensitive_edges = 0. There is not a single row in the file where
a fixture that can fail produced 48 of 48. Breaking box_exact needs a non-dyadic offset, which is
exactly what breaks grid symmetry — the two requirements are in direct conflict for that one field and
this harness did not resolve it.
C1's mechanism is closed, not inferred. On all 16 marching_cubes rows,
worst_differing_vertices == order_sensitive_edges exactly — 72/72, 24/24, 152/152, 32/32, 0/0, 0/0,
50/50, 31/31, 450/450, 242/242, 532/532, 320/320, 291/291, 249/249, 643/643, 360/360. A quantity computed
from the grid with no extractor in sight predicts, to the unit, how many vertices move. And the split is
by element type: pure_permutation_exact is 6 of 6 on every marching_cubes row while
pure_sign_flip_exact runs 1, 4 or 8 of 8.
So the registration's stated reason is true and does not imply its conclusion. C1 predicts primal
exactness "because a primal vertex is a/(a−b) on one grid edge — two values, no accumulation". The
premise holds. But EDGE_CORNERS always orients an edge along increasing grid index, so a sign flip
swaps which endpoint is lo: the extractor computes b/(b−a) where it computed a/(a−b), and anchors
the lerp at the other corner. Those are mathematically 1 − t and geometrically identical and not
bit-reciprocal. Absence of accumulation was never sufficient; the order of the two values is the whole
issue.
The two tetrahedral extractors fail by a second mechanism the registration did not anticipate.
marching_tetrahedra and subgrid_marching_tetrahedra never exceed 12 of 48 (range 6–12) and fail
even on box_exact, where order_sensitive_edges = 0 and the interpolation argument has nothing to bite
on. pure_permutation_exact is 6 of 6, pure_sign_flip_exact only 1–2, and worst_differing_vertices
reaches 22,146 of 22,247 vertices — a different vertex set, not a perturbed one. Their
six-tetrahedron decomposition of a cell is not octahedrally invariant: the diagonals cut different edges
after a relabelling. That is why worst_component_ulp is a "different mesh" flag on those rows rather
than a rounding measurement, and why worst_differing_vertices sits beside it.
The range first printed here was
(0–2,432)and it belongs to different rows (D-019).0–2,432is the span over the 32marching_cubesandmarching_cubes+deciderrows, and 2,432 occurs on exactly two of them —fbm_terrainat 25³ under each face rule. All 32 tetrahedral rows read ≈9.2e18 (9,213,546,001,304,149,272 to 9,242,512,335,271,100,416), which is the+x/−xpairing artefact this entry says was discarded, so the number quoted as evidence for the different-mesh reading was in fact the artefact. Counted over the file: 55 of 112 rows exceed 1e6 — all 32 tetrahedral, 10 of 16dual_contouring, 10 of 16manifold_dual_contouringand 3 of 16surface_nets(torus,csg_differenceandgyroidat 33³). So the sorted-merge multiset difference still pairs a leftover+xagainst a leftover−xwherever the vertex sets differ at all, which is not confined to the tetrahedral rows.worst_component_ulpmeans a displacement on the 57 rows at or below 1e6 and nothing on the other 55; the consumer note below is scoped to those 57.
C2 is falsified by being stated too strongly, and its own fixture caught it. "Strictly fewer than
48" is false for dual_contouring and manifold_dual_contouring on box_exact at both resolutions —
raw bit-pattern counts included, so the signed-zero normalisation is not responsible. M-177's ordering
argument needs a sum that actually loses bits; on box_exact the crossings are exactly representable and
the dual solve is exact too. Restricted to the 42 dual rows whose fixture can fail, the clause holds 42 of
42, and the identity of the surviving subgroup is the new number:
| extractor | exact elements | who survives |
|---|---|---|
surface_nets |
1 of 48, 7 rows | identity only |
surface_nets |
6 of 48, 6 rows | all six pure axis permutations (sphere 33/25, torus 25, csg_difference 33/25, thin_plate 33) |
surface_nets |
12 of 48, 1 row | six permutations × two sign patterns each |
dual_contouring / manifold_dual_contouring |
2 of 48, 22 rows | identity and the x↔y swap |
dual_contouring / manifold_dual_contouring |
4 of 48, 2 rows | four pure permutations |
dual_contouring / manifold_dual_contouring |
24 of 48, 4 rows (thin_plate) |
an order-24 subgroup |
A QEF loses even pure permutations, which M-177 predicts and no prior entry had counted:
pure_permutation_exact is 2, 4 or 6 on the DC rows against a flat 6 for marching_cubes. Axis
relabelling reorders the accumulation into AᵀA, and that is enough.
C3 quantifies the dossier's warning instead of repeating it.
docs/research/2026-08-23-discovery-dossier.md:267 held this relation because table.rs picks
safe_apex by lowest edge index and a triangle-level statement "manufactures 2,688 false positives".
Measured: 799 element-instances across 103 of 112 rows are vertex-exact and triangle-different,
and elements_triangle_exact never reaches 48 on any row — its maximum anywhere is 6. The nine rows
with zero triangle-only failures all have elements_vertex_exact = 1, i.e. no headroom, so they are a
degenerate denominator and not evidence that safe_apex is invariant.
One incidental result, in neither clause: the asymptotic decider adds its own axis dependence.
marching_cubes+decider drops to 1 of 48 on noise_cavity where plain marching_cubes gives 6 on
the same grid, and its pure_permutation_exact falls from 6 to 1. The face test does not merely inherit
MC's edge asymmetry; it contributes.
Signed zero is normalised, and the literal reading is kept beside it. Both fixtures are centred with
an odd sample count, so 0.0 is a grid coordinate and −(0.0) is −0.0: left raw, every sign-flipping
element fails on a disagreement about which encoding of zero was written rather than about any position,
which is the kind of false positive this experiment exists not to manufacture. −0.0 is folded to 0.0
in the comparison key, identically on both sides, and nothing else is touched — a one-ULP gap anywhere
else is still a failure. elements_vertex_exact_raw and elements_triangle_exact_raw carry the literal
bit-pattern reading; they differ on 10 and 6 of 112 rows respectively, all on box_exact or thin_plate,
and every clause verdict is identical under both.
A harness defect was found and its run discarded before any number was kept. The first draft computed
worst_component_ulp by walking the two sorted vertex lists positionally, so one inserted vertex shifted
every later entry against its neighbour and it reported 9.2e18 — the gap between +2 and −2 — for
meshes differing by one bit on 72 edges. Replaced by a sorted-merge multiset difference that cancels the
agreeing vertices first. The identity element is a control and is asserted vertex-exact and
triangle-exact on all 112 rows; a failure there would mean the extractor is not deterministic and would
void the row rather than falsify anything.
What a consumer should take from this. Bit-exact octahedral equivariance is available from this crate
for the six pure axis permutations on plain marching_cubes — 6 of 6 on all 16 of its rows — and
surface_nets gets all six on 7 of its 14 fixture-can-fail rows as well. It is not available from
marching_cubes+decider, which drops to pure_permutation_exact = 1 on noise_cavity at both
resolutions, nor reliably from the duals, which run 2 (11 rows), 4 (1) and 6 (4). Under any reflection,
expect vertex positions to move by up to worst_component_ulp on the 57 rows where that column is a
displacement rather than a set difference; under any element at all, expect the index buffer to differ.
The "and for nothing else" clause was false when it was written, and its own file said so (D-019). Six
surface_netsrows sit atelements_vertex_exact = 6withpure_permutation_exact = 6andfixture_can_fail = true—sphere33/25,torus25,csg_difference33/25,thin_plate33 — and a seventh,thin_plate25, reaches 12 of 48 with all six permutations inside it. They were omitted from the "who survives" table above, which accounted for 36 of the 42 fixture-can-fail dual rows, and the consumer sentence was written from the table rather than from the file. Surface Nets is therefore a second extractor with the full permutation subgroup, on half its rows.
The fix for the primal case is small and named, and it has a degenerate case the naming hides. Anchor
edge_position's lerp at a value-canonically ordered endpoint rather than at the lower grid index. That
needs a tie-break when the two endpoint values are equal, and equal endpoints are not rare: P-58's own
census measures box_exact at 65³ with 274,145 of 274,625 voxels tied, and six of the eight fields
above 230,000. A tie-break is a second rule with its own invariance obligation, which is a fix whose
correctness argument is longer than the defect's.
P-61's centred form has no such case, and that is why it is the fix rather than this. Storing the
crossing as d = ((a + b)/2)/(a − b) from the edge midpoint is antisymmetric under the simultaneous
endpoint-and-sign swap by IEEE guarantee — fl(a+b) = fl(b+a), halving is exact, fl(b−a) = −fl(a−b),
and fl(S/−D) = −fl(S/D) because round-to-nearest is odd — so equal endpoints need no arbitration at all;
they simply give d = ±1/2. Either way it is a src/ change and a golden-hash move, so it is a ticket
and not this experiment: R-059.
💥 ✗40 / M-357 — FALSIFIED on all three clauses, and two of the three failures are the clause's fault rather than the paper's: reversing a tie-break re-partitions the complex, and a critical-cell count is not a topological signature for a field with a degenerate critical set (P-58, R-056)
M. cargo bench --bench experiment_p58, docs/experiments/p-58.csv, 24 rows — eight fields ×
17³/33³/65³, f64. Algorithm 1 of Robins, Wood & Sheppard 10.1109/tpami.2011.95 transcribed from the
corpus text with its G-ordering, both priority queues and num_unpaired_faces as written, running on
integer ranks so every comparison is exact. Each census computed twice, forward and reverse
tie-break — 48 censuses in all.
| clause | registered | measured |
|---|---|---|
| C1 census identical under the reversed tie-break | all 24 rows | FALSIFIED — 5 rows differ; worst csg_difference 65³, 117 against 873 |
| C2 every ambiguous cell contains a critical cell | containment on all 24 | FALSIFIED — fails on all 9 substantive rows; fbm_terrain 65³ is 58 ambiguous cells and 0 containing one |
C3 sphere/torus under 2×, noise_cavity over 4× |
both | FALSIFIED on both halves — torus 17 → 41 → 73, i.e. 2.412× at the first step; and noise_cavity misses its own 4× at 3.758 and 2.289 |
Twelve controls, none of which fired — which is what makes three falsifications readable. Three are
worth naming. Proposition 4 in aggregate: 2·pairs + critical_total == (2n−1)³, on all 48 censuses.
Lemma 10, both arms: critical_3 equals the count of voxels whose reduced lower star is the whole
octahedron, on all 48. And an independent global check the transcription never uses: Theorem 3 with
Theorem 6 says the Morse complex computes H_*(K); K is the cubical complex of a box and therefore
contractible; so χ = c₀ − c₁ + c₂ − c₃ must be 1. It is 1 on all 48 censuses, forward and reverse.
Nothing in the code arranges that. max_lower_star_cells takes only the values 8, 18 and 27 — exactly
the corner, face and interior truncations a box admits — against the paper's own bound of 27, and 27
occurs on precisely the three fields with critical_3 > 0.
Two more results fall out as free confirmations. sphere gives critical_total = 1 at every
resolution: its sublevel sets are ball ∩ box, convex and contractible throughout the filtration, so
exactly one topology change, and the census reproduces that exactly. torus gives c₀ = c₁ at every
resolution — 8/8, 20/20, 36/36 — with c₂ = 1 always.
C1 differs, and the honest reading is that C1 does not test the sentence it cites. The registration's
committed provenance correction quotes §3.1: "the number and type of critical cells found by
ProcessLowerStars are independent of this ordering". In context "this ordering" is the G-ordering
within a lower star — the paragraph's subject is "Any ordering based primarily on the maximal g
value of the vertices of the cell and in which a cell is ranked after its faces will suffice." Reversing
the voxel-index tie-break does not change G's rule. It changes g′ itself, and therefore changes which
voxel owns a tied cell — the lower-star partition of K, not the traversal order inside a part. So the
measured sensitivity is to the choice of perturbation, which the paper never claims invariance under. It
is real and large and worth having, and it is not a counterexample to §4.
| field | n | forward (c₀,c₁,c₂,c₃) |
reversed | total |
|---|---|---|---|---|
csg_difference |
17³ | 5, 6, 3, 1 | 20, 33, 15, 1 | 15 → 69 |
csg_difference |
33³ | 11, 18, 9, 1 | 47, 108, 63, 1 | 39 → 219 |
csg_difference |
65³ | 35, 57, 24, 1 | 221, 435, 216, 1 | 117 → 873, 7.462× |
noise_cavity |
33³ | 294, 853, 738, 178 | 296, 855, 738, 178 | 2,063 → 2,067 |
noise_cavity |
65³ | 762, 2025, 1600, 336 | 763, 2026, 1600, 336 | 4,723 → 4,725 |
That 7.462× is the finding, and it is a warning about chunked meshing. csg_difference is
max(box, −sphere), so vast plateaus of its grid tie exactly; which voxel is declared the owner of a
tied cell decides whether a pair is available, and the answer cascades. tied_voxels sizes it —
box_exact at 65³ has 274,145 of 274,625 voxels tied. Any tie-break that depends on chunk-global
quantities, which the paper's Eq. (8) ramp g′ = g + η(i + Ij + IJk)/(3IJK) does by construction, will
therefore produce a different census per chunk decomposition on this crate's fields. The registered
chunk-local (value, linear_index) order is not a convenience; it is the only kind that can be stable.
fbm_terrain's C1 pass is vacuous and the CSV says so rather than making a reader infer it.
tied_voxels = 0 at all three resolutions — distinct_values == voxels — so the reversed ordering is
the forward ordering there, and census_matches_reverse_order = true is an identity, not evidence.
C2's containment fails in the direction the clause declared fatal, and there was never a theorem behind it. The Morse census is a property of the entire lower-level-cut filtration, over every threshold. Marching Cubes ambiguity is a property of one level set, the zero set. Nothing links them. The clause hedged one direction — "a Morse census can be non-empty where no MC ambiguity exists" — and the measured failure is the other: ambiguity where there is no criticality.
| field | n | ambiguous | containing a critical cell |
|---|---|---|---|
gyroid |
17³ / 33³ / 65³ | 52 / 27 / 132 | 34 / 15 / 18 |
fbm_terrain |
17³ / 33³ / 65³ | 16 / 30 / 58 | 0 / 0 / 0 |
noise_cavity |
17³ / 33³ / 65³ | 193 / 502 / 567 | 177 / 308 / 226 |
sphere, torus, box_exact, csg_difference and thin_plate produce zero ambiguous cells at all
three resolutions, so ambiguous_containment_holds is trivially true on 15 of 24 rows and the clause is
only substantive on the other nine — where it fails on all nine. And the excess is not an excess: on 18
of 24 rows critical_cells_outside_ambiguous / critical_total is exactly 1.0000.
"Essentially disjoint" was read off a ratio that is 1 by construction on most of those rows (D-019). Of the 18, 15 have
ambiguous_cells = 0— the five fields that produce none at any resolution — so the ratio is 1 because the denominator's competitor is empty, not because two populated sets fail to overlap. The claim only has content on the nine substantive rows, and there the fraction runs 0.483–0.992: the sets overlap substantially wherever ambiguity exists at all. What the file supports is "a critical-cell census does not predict Marching Cubes ambiguity", which is C2's verdict and is unaffected; "essentially disjoint" is a stronger statement its own rows do not carry.
C3 fails on torus, and the substantive result is a null about the metric. torus's topology is
resolution-stable exactly as the clause expected — c₂ = 1 and c₀ − c₁ = 0 at 17³, 33³ and 65³. What
grows is the count of critical cells along the torus SDF's circle of minima: c₀ runs 8 → 20 → 36 with
c₁ identically, roughly linear in n. So critical_total is not a topological signature for a field
with a degenerate (positive-dimensional) critical set; the 2× bound was measuring sampling density along a
circle. C3 fails under both readings of "across 17³/33³/65³" — consecutive ratios 2.412 and 1.780, and
end-to-end 4.294 — so it is not rescued by picking the kinder one. noise_cavity misses too, for the
mirror-image reason: its consecutive ratios are 3.758 and 2.289, neither above 4, while end-to-end it is
8.603.
One adjective in the registration is narrower than it reads. "allocation-free" describes the
tie-break, and only that. Ranking is a sort into a dense Vec<u32> per grid and allocates once;
ProcessLowerStar itself is allocation-free — fixed 64-slot arrays indexed by star code — and that is the
part which runs 274,625 times per ordering.
What survives for this crate. The transcription is correct — χ = 1 on 48 censuses says so
independently — and it is a working per-voxel, order-independent critical-cell census over an SDF grid,
which nothing here had. What it is not is a predictor of Marching Cubes ambiguity, and
critical_total is not a topology metric on fields with degenerate critical sets. Both directions are
closed by measurement rather than by opinion.
💥 ✗41 / M-358 — C1 and C2 HELD, C3 FALSIFIED: the 1,507 surviving brushes cut to 73 world-wide bit-exactly (9.45× on the 13 chunks where a brush matters, 20.6× counted over the whole world), and the over-keep has two causes where the registration named one (P-59, R-057)
M. cargo bench --bench experiment_p59, docs/experiments/p-59.csv, 64 rows — one per chunk,
1,571 re-meshes, 19.6 s, f64, marching_cubes. P-39's fixture reproduced brush-for-brush by copying
rather than importing: BRUSHES = 64, the same Interval, pad, enclose and prune_into under
Policy::Sound only. assert_comparable refuses to proceed unless the fixture reproduces M-341
exactly — 64 chunks, median 19 survivors, median fraction 0.2969 — and all three matched.
| clause | registered | measured |
|---|---|---|
| C1 removing all non-survivors changes no hash | 64/64 | HELD — 64 of 64, median 45 of 64 brushes removed |
C2 median necessary / survivors ≤ 0.75 |
≤ 0.75 | HELD — median 0.000000, max 0.250000 |
| C3 ≥ 90% of unnecessary survivors far from the surface | ≥ 0.90 | FALSIFIED — 1,218 / 1,434 = 0.849372 |
C1 is the soundness control and it is reported first because everything else depends on it. Removing
every non-survivor at once leaves mesh_hash bit-identical on all 64 chunks, which re-confirms M-341's C3
on an independent harness. The instrument's ability to report the other answer is not argued but
demonstrated from inside the same run: 73 leave-one-out removals did change the hash, decided by the
same hash_of and the same ==.
C2 held, and the honest caveat is that 0.75 could not have failed on this fixture. The median is
0.000000 and the single worst chunk in the file is 0.250000 — 16 necessary of 64 survivors — so even
the extreme sits exactly at "three quarters droppable". Overall 1,434 of 1,507 survivors (95.16%) are
individually droppable. The clause is satisfied by a factor nobody would have registered on purpose, and
a HELD verdict on it therefore carries much less information than its wording implies. 51 of 64 chunks
have necessary == 0; seven of those mesh to zero triangles and are a confound, and dividing them out
changes nothing material — 44 of the 57 non-empty chunks still have necessary == 0 and the non-empty
median is still 0.000000, which is why triangles, empty_chunks and the _nonempty aggregates are
columns rather than an argument.
The number that matters is not in any clause, and it is a factor of 20. Leave-one-out measures
individual droppability, which does not license the registration's framing sentence "the bound
over-keeps" — two brushes can each be redundant while the other is present and jointly decisive, which is
ordinary min/max behaviour. So the joint claim was measured rather than inferred:
necessary_only_hash_unchanged re-meshes each chunk from its necessary brushes alone, every
individually-unnecessary survivor removed at once, order preserved. It is bit-identical on 64 of 64
chunks. The tape cuts from 1,507 survivors to 73 brushes world-wide, bit-exactly. Without that
column an entry citing C2 could have upgraded "individually" to "jointly" unearned; with it, the upgrade
is a measurement.
Two statistics, and the first version of this entry chained them (D-019). It read "a 20.6×
further reduction on top of P-39's 64 → 19", which multiplies a world-wide total by a per-chunk
median — P-39's 64 → 19 is the median chunk, and 1,507 → 73 is the sum over all 64. There is no clean
median counterpart, because the median necessary is 0. The fixture is why: it starts from a base
sphere of radius 6, so 51 of 64 chunks have necessary = 0 and 44 of those mesh non-empty and
bit-identically from an empty brush list — their geometry is entirely the base field, and no brush pruner
can be credited for it.
| statistic | survivors | necessary | ratio |
|---|---|---|---|
| world-wide total, all 64 chunks | 1,507 | 73 | 20.64× |
| the 13 chunks where any brush matters at all | 690 | 73 | 9.45× |
| per-chunk median | 19 | 0 | undefined |
9.45× is the like-for-like figure — survivors and necessary counted over the same population — and
20.64× is the honest world-wide total, which is a different and also useful number because a world is
what a consumer meshes. Both are stated; neither is multiplied by anything.
C3 fails at 0.849372 because the over-keep has two causes and the registration named one. The named mechanism is real and dominant — 1,218 of 1,434 unnecessary survivors are more than a cell size clear of zero over the chunk — but the remaining 216 near-surface unnecessary survivors are concentrated exactly in the chunks with the most surface: 29 in the 7,439-triangle chunk, 24 in the 6,177, 17 in the 4,149, 15 in the 1,527. Those are brushes whose enclosure genuinely straddles the surface band. Being far from the surface is sufficient to be unnecessary; it is not necessary, and what the 216 are unnecessary for is unmeasured.
The first version of this paragraph named the second route as a result, and nothing in the file measures it (D-019). It read "dominated there by another brush in the min/max chain … the second route is domination rather than distance".
p-59.csvhas adominant_addscolumn and it reads 0 on all 64 rows, and its definition in the bench counts a different notion than the sentence invokes — so the mechanism was stated with the instrument for it returning zero, on every row, which isM-44's rule exactly. The 216 are real and their concentration in the highest-triangle chunks is real; the cause is nowO-20and not a finding.
Half of C3's predicate cannot fire on this fixture, structurally, and the CSV shows it rather than
hiding it. The registered predicate reads symmetrically — "an interval over the chunk whose distance
from zero exceeds one cell size", implemented as lo > cell_size || hi < −cell_size — and
unnecessary_far_by_hi is 0 on all 64 rows, 0 of 1,434. It cannot fire. The tape's draw range caps a
brush radius at 1.1, so f(centre) ≥ −1.1 and the arm is already dead at that bound — and E-315's demo
recomputed the measured maximum from the same seed, 0.706948 for the largest sphere and 0.538635 for
the largest capsule, which widens the gap from 3× to 5×: against an enclosure Lipschitz reach of ≈ 3.464,
hi < −0.125 would need f(centre) < −3.589. So "distance from zero" here only ever means "entirely
more than a cell above zero". 1.1 is a bound and not a measurement, and the two are separated here
because a reader would otherwise take it for one. (E-315 also records the near-miss that makes this worth
writing down: a capsule's field minimum is −radius, not −(radius + half_length) — the segment is a
zero-distance set, not a point — and the wrong version printed −1.1100, which would have looked like
agreement with the bound.)
What this licenses and what it does not. A tighter bound has 20× of headroom on this fixture and the direction is open, not closed — that is the opposite of what C2's wording suggests. What it does not license is a per-brush necessity test: deciding necessity here cost 1,571 re-meshes, and any cheap replacement has to be a conservative bound, which is what the 216 domination cases make hard.
💥 ✗42 / M-359 — C1 FALSIFIED and C3 HELD, and C2 passes for a reason that is not its own: the paper's 8 dB reconstruction gain maps to a root-position gain that is exactly |σ − 2τ| / σ and therefore a lottery over where the root falls (P-60, R-058)
M. cargo bench --bench experiment_p60, docs/experiments/p-60.csv, 32 rows — eight fields × four
guard-band widths, 65 samples along the domain-centre x axis, f64. No extractor is called and no
golden hash is reachable. The prefilter is Blu, Thévenaz & Unser's causal one-pole with their own
c₀ = f₀ initialisation, at τ = 1/5 where it is cₙ = −2⁻²·cₙ₋₁ + (1 + 2⁻²)·fₙ and multiplication-free;
the reconstruction's knots sit at (n + τ)T, so the segment carrying the crossing comes from the shifted
knot grid.
| clause | registered | measured |
|---|---|---|
| C1 shifted root error ≥ 30% lower on the four smooth fields | ratio ≤ 0.70 | FALSIFIED — median 1.486067 |
| C2 shifted worse or equal on the two step-like fields | ≤ 1 | NUMBER HELD at exactly 1.000000; MECHANISM FALSIFIED |
C3 truncating to k preceding samples moves the root < 1e-6 cells at k ≥ 10 |
true |
HELD — 8 of 8 fields, worst 7.152528e-7 |
Two controls decide whether any field number means anything, and both behave. The positive control
is a synthetic exactly-quadratic line whose closed-form root-error ratio is exactly 1/5 at its crossing:
measured 1.984127e-1, which pins the pole sign, the gain, the knot offset and the two-piece segment
choice all at once. The negative control feeds the identical code path the raw samples in place of c
— the shift applied without the prefilter that makes it interpolate, which is the most likely way to get
this wrong — and returns 39× worse than the standard rule, a root biased by 0.195 cells, i.e. τ. The
interpolation identity τ·cₙ₋₁ + (1 − τ)·cₙ == fₙ holds to 2.220446e-16 on all eight fields.
C1 fails, and the reason is a closed form rather than a null.
Two symbols, defined here because the first version of this entry used them without doing so (D-019).
τ is the knot shift, a fixed property of the method: the reconstruction's knots sit at (n + τ)T
rather than at nT, and this run uses τ = 1/5. σ is a property of the data: the fraction of the
standard cell at which the true root falls, σ ∈ [0, 1), measured per row as crossing_fraction. The
root's fraction inside the shifted segment is therefore u = σ − τ when σ ≥ τ, and u = σ + 1 − τ
when σ < τ, because the root then belongs to the previous shifted segment.
For a locally quadratic signal the reconstruction error at fraction u of a segment is
(g″/2)·[u(1 − u) − τ(1 − τ)], and the standard rule's is (g″/2)·σ(1 − σ). Substituting u = σ − τ:
u(1 − u) − τ(1 − τ) = (σ − τ)(1 − σ + τ) − τ(1 − τ) = (1 − σ)(σ − 2τ)
so the ratio of root errors is |(1 − σ)(σ − 2τ)| / (σ(1 − σ)) = |σ − 2τ| / σ, and on the other branch
u = σ + 1 − τ gives −σ(σ + 1 − 2τ) over the same denominator, i.e. (σ + 1 − 2τ)/(1 − σ). At τ = 1/5
those are |σ − 2/5| / σ for σ ≥ 1/5 and (σ + 3/5)/(1 − σ) for σ < 1/5.
The intermediate first printed here was
|σ(σ−1) + τ(1−τ)| / (σ(1−σ))and it does not reduce to|σ − 2τ|/σ. Atτ = 1/5, σ = 0.5the stated expression gives 0.36 against the correct 0.20. The error is a frame mix: the numerator's error term lives in the shifted-segment fractionuwhile the denominator lives in the standard-cell fractionσ, and the expression substitutesσinto both. The missing step is the one line above,u = σ − τ. The harness computes the right thing —predicted_error_ratiois0.372965ongyroidatσ = 0.637923and0.758948onfbm_terrainatσ = 0.090365, which is the two-branch form to six digits — so only the ledger's printed derivation was wrong, and anyone re-deriving from it got a different function. In a file whose value is that its algebra can be re-checked, that is the defect.
It equals exactly 1 when the root lands on a knot (σ = τ, which torus hits to the digit at
crossing_fraction = 0.200000), exactly 0 at σ = 2τ, never exceeds 1 in the quadratic regime on the
upper branch, and clears the 30% bar on 82% of uniformly distributed crossing positions — recomputed
here as 0.823529 exactly, the union of σ ∈ [4/17, 1] on the upper branch and σ ∈ [0, 1/17] on the
lower. The control confirms it to 0.8%. So the paper's asymptotic 8 dB reconstruction gain does transfer,
but as a strongly position-dependent root-position gain — and registering a median over four arbitrary
crossing positions was registering a lottery over σ.
And the closed form mispredicts both real rows, which the first version said about one of them. The
five fields with standard_is_exact are NaN or degenerate; the two measurements that mean anything are:
| field | σ |
predicted | measured | factor off |
|---|---|---|---|---|
gyroid |
0.637923 | 0.372965 | 1.972134 | 5.29× |
fbm_terrain |
0.090365 | 0.758948 | 0.204694 | 3.71× |
gyroid's excess is explained below — its crossing sits at an inflection point of sin, outside the
quadratic regime the form assumes. fbm_terrain's 3.71× has no such explanation and the entry was
silent about it, which matters because fbm_terrain is the row the entry cites as a success: it clears
the 30% bar by being better than predicted, on the branch σ < τ where the form is a different
expression. Two rows, two disagreements over 3×, in opposite directions. So the form is right about the
shape — position-dependence, the zero at 2τ, the 1 at τ — and is confirmed quantitatively only by
the synthetic control, at 1.984127e-1 against a predicted 1/5.
Half of C1's population is degenerate, and the registration could not have known it. The domain-centre axis is a symmetry axis of six of the eight fields, along which the field restricts to a piecewise-linear ramp through the first crossing:
| field | root_error_standard |
root_error_shifted |
ratio |
|---|---|---|---|
sphere |
7.105427e-15 | 7.105427e-15 | 1.000000 |
torus |
3.552714e-15 | 4.768370e-8 | 1.342177e7 |
gyroid |
5.103006e-4 | 1.006381e-3 | 1.972134 |
fbm_terrain |
4.600501e-2 | 9.416940e-3 | 2.046938e-1 |
sphere restricts to |x| − 1 and torus to ||x| − 1| − 0.3; chord_deviation_cells is exactly zero
on both, standard_is_exact is true, and their errors are the bisection floor. With g″ = 0 both
reconstructions are exact and there is nothing to compare — torus's 1.34e7 is entirely the causal
startup transient, its shifted error 4.768370e-8 being ¼·τ·(1/4)¹⁰ to the digit. So the clause rests on
two real measurements, and they split: fbm_terrain is 4.9× better and clears the bar with room, while
gyroid is 2× worse because its crossing sits at x = −π exactly, an inflection point of sin where
the local second derivative vanishes and the error is cubic-dominated, outside the quadratic closed form.
C2's number holds and its stated cause is absent, so per this project's own rule it is not a finding.
is_step_like measures false on both box_exact and csg_difference — on the centre axis both
restrict to |x| − 1, whose second difference is exactly 0 in the whole window, so the 10× test is a
comparison against nothing — and gibbs_overshoot is 2.909629e-12, six orders below the cell size and
plainly machine noise rather than an overshoot. The tie at exactly 1.000000 is two rules returning the
identical −1.0 because the root sits exactly on sample 16, with both errors at the same bisection floor
7.105427e-15. The one field is_step_like does flag is thin_plate, whose plate kink at
|x| = 0.9875 puts a 5.0e-2 second difference three samples from the crossing against a zero median.
The "step-like restriction" the registration imagined is what a line tangential to a box face would
see; a line through the centre sees a ramp. There is no Gibbs phenomenon on this fixture to find.
C3 held, and k = 10 is the real threshold rather than a loose one.
| field | k = 2 |
k = 5 |
k = 10 |
|---|---|---|---|
torus |
3.999995e-2 | 7.805355e-4 | 7.152528e-7 |
gyroid |
2.178023e-2 | 1.657553e-4 | 1.927142e-7 |
k = 5 fails the 1e-6 bar on both fields that carry a non-zero delta and k = 10 passes it. The
(τ/(1−τ))^k = (1/4)^k decay is clean: torus gives 1.951e-2 and 9.164e-4 for the two steps against
(1/4)³ = 1.5625e-2 and (1/4)⁵ = 9.766e-4. On the other six fields the delta is exactly zero at
every k, and that is a real zero with a named cause rather than an untested one — on an exactly linear
signal the startup transient cancels out of the left-piece root, because those crossings land at
s = 1 − τ = 0.8 exactly. guard_band_truncated distinguishes the two kinds of zero per row, and it also
records that k = 20 tests nothing: the largest crossing index on this line is 18, so all eight
k = 20 windows are the whole line.
What this closes and what it opens. For a mesher, the guard band is affordable — 10 samples of
slab overlap buys a root indistinguishable from the whole-line answer — so C3's arm of the direction is
open. The accuracy arm is closed as registered and replaced by something better than a null: the gain is
|σ − 2τ| / σ, exact, bounded by 1, zero at σ = 2τ and 1 at σ = τ. A mesher cannot choose σ, so the
expected benefit is the 82% figure and not the 8 dB one.
"Exact, bounded by 1" is a statement about the form and not about this file (D-019). The form is exact for an exactly quadratic signal and the synthetic control reproduces it to 0.8%; on the only two real non-degenerate rows it is off by 5.29× and 3.71×, and
gyroid's measured ratio is 1.972134, which is not bounded by 1. Scoped correctly:|σ − 2τ|/σ ≤ 1forσ ≥ τis a property of the expression, and the measured ratio is bounded by 1 only where the quadratic regime holds. A successor registration is still not needed — the closed form answers the question the clause was reaching for — but the residual is a real gap and belongs to the third derivative rather than to the method.
💥 ✗43 / M-360 — "one interior vertex per cell is enough": the interior rule fans every contour of a cell from the same apex, and two contours glue into a bowtie (T-005b, O-12)
Believed because: three places in the same module said one, and none of them asked what a cell with
two long contours does. trilinear.rs's INTERIOR was documented as "the code a triangle uses to name
the cell's one interior vertex"; Contours::fan's doc said "rings of more than three vertices fan
from it" — singular, over a loop that runs on every ring in the cell; MAX_INTERIOR_VERTICES
recorded "a fanned disk uses one, INTERIOR itself." And the geometry behind it is a real
construction: Grosso's disk rule adds an interior vertex — the body saddle — to a cell whose contour
crosses an ambiguous face twice, and one body saddle is what BodySaddles::interior_vertex returns.
Falsified by: property::extraction::the_interior_rule_meshes_convex_bodies on a fresh proptest
seed — precisely the event check_trilinear's own doc comment pre-declared ("if this ever fails it is a
finding and not a regression: it would mean a second mechanism exists"). Reduced out-of-tree to a single
half-space against the generator's own radius-1.5 bound: f(p) = max(|p| − 1.5, n·p − offset),
n = [0.23765582945243893, 0.9693452841978661, 0.06236526862470124],
offset = -0.6030279510789542, grid [6,6,6], origin [-2,-2,-2], h = 2·2.0/(6−1) = 0.8,
FaceAmbiguity::AsymptoticDecider + InteriorAmbiguity::Trilinear. That field is a convex genus-0
body, so there is no honest geometry here for a pinch to come from.
Result: at 6³, vertices 27, edges 72, faces 48, χ 3, components 2, non-manifold vertices 1,
non-manifold edges 0, boundary edges 0, inconsistently oriented 0, degenerate triangles 1 →
is_closed() false. The pinch vertex is at
[-0.7326381707309315, -1.1999999999999973, -0.08000000000000007], cell [1,1,2], with 1 of 3
coordinates on the sample lattice, and it carries 8 incident faces in 2 edge-connected groups: two
rings of length 4, each fanned to the same apex. Clean at every size the committed test covers: 6³ after
the fix, and refinements 9³, 13³, 17³, 25³ and 33³ all closed with non_manifold_vertices 0.
Two claims in the paragraph above were narrowed at D-019, and the conclusion survives both.
The coordinate count rules out edge vertices and not face vertices. The original argument read "an edge vertex has 2 of 3, so this is the cell-local interior vertex". A vertex interior to a cell face also has exactly 1 of 3 coordinates on the lattice, and this one is on a face plane: with
origin = −2andh = 0.8the sample planes are at−2, −1.2, −0.4, 0.4, 1.2, 2.0, andy = −1.1999999999999973is−2 + 1·0.8. So the stated argument does not establish what it concludes. The conclusion is still right and the evidence for it is the other sentence: the vertex carries eight incident faces in two edge-connected groups of four, which isContours::fanfanning two rings of the same cell from one apex — a face vertex would be shared between two cells andedge_verticesis keyed on(lower sample, axis)with no slot to name one. The mechanism, the fix and the counts all read off the face grouping, not off the coordinate count."7³–18³ all closed" asserts nine sizes nothing covers. The committed test asserts exact counts at 6³ and then loops
[9, 13, 17, 25, 33]; 7, 8, 10, 11, 12, 14, 15, 16 and 18 are covered by no test, no bench and no CSV. The sentence above is restated to the set that is actually gated.
This is the first example for O-12's vertex-link clause, and it has M-301's signature exactly. Every
edge counter reads clean because two cones glued at a point still give every edge exactly two faces
— nothing about the edge census is wrong, so non_manifold_edges, boundary_edges and
inconsistently_oriented_edges are all zero. Only the vertex-link walk sees it, and χ sees the
consequence rather than the cause: two closed sheets sharing one vertex give 2 + 2 − 1 = 3, an odd χ
for a closed orientable surface. O-12 named this gap in as many words — "the two-cell sweep is
exhaustive and the vertex-link case is not covered by it at all" — and a two-cell sweep could never have
found it, because the defect is entirely inside one cell.
Prevalence — and this is where the entry over-claimed (D-019). The original text reported a
deterministic sweep of 1,152 single-plane caps (16 θ × 8 cos φ × 9 offsets over the generator's own
-0.8..=0.8) at each of 6³–12³ giving "2 of 8,064 not closed, both at 6³" before the fix and "0 of
8,064" after. That sweep exists in no bench, no test and no CSV in this repository: grep -rn
'8064\|8,064\|1152\|1,152' over crates/ and bevy_isomesh/ returns nothing. It was run and not
committed, which is CLAUDE.md's hard rule 4 and the ✗35 failure mode, in the one entry whose whole
claim was to be "a rate and not an anecdote".
So the claim is restated to what is committed, and the rate is withdrawn rather than repaired. What
the_cell_that_fanned_two_contours_from_one_apex_is_now_manifold covers is one field at six grid sizes
— exact counts at 6³ (V 28, E 72, F 48, χ 4, components 2, every non-manifold and boundary counter zero,
is_closed() true) and is_closed() at 9³, 13³, 17³, 25³ and 33³ — plus the committed proptest seed
563fd2ba…, which replays the generator's own path, and
the_fan_covers_each_ring_once_and_repeats_no_index over all 16,384 (case, mask) pairs. The
in-cell combinatorial statement is therefore exhaustive and the prevalence over fields is unmeasured.
Re-adding the sweep is a registration, not a repair — it is a rate, so it needs a pre-registered
falsifier and a CSV like any other number — and it is cheap: the same 1,152 caps, one bench,
docs/experiments/p-nn.csv. Not registered here, because inventing a P- id inside a correction is how
two copies of a hypothesis start.
Consequence: Contours::fan names ring r's apex INTERIOR + r instead of one cell-wide
INTERIOR, and emit_trilinear fills one slot per fanned ring — the body saddle when exactly one
ring is fanned, so no currently-passing measurement moves, and each ring's own centroid when two or
more are. One saddle cannot serve two rings: it lies inside at most one of them, so fanning the other to
it is wrong geometrically as well as topologically. The centroid is A-015's construction for exactly this
problem on the table path. After the fix the same 6³ cell reads vertices 28, edges 72, faces 48, χ 4,
components 2, non-manifold vertices 0, degenerate triangles 0, is_closed() true — one vertex added
and no edges, because the spokes were already distinct (apex, ring vertex) pairs. Two components at
h = 0.8 is honest under-resolution, which SurfaceGate::Closed permits; a shared apex is not. The index budget does not move: a cell holds at most MAX_CONTOURS = 4
rings and a fourth ring only exists when all four are triangles, so three apexes is the disk path's
ceiling under the six the tunnel already reserves.
Two smaller things fell out, both now stated in code rather than left to be rediscovered. An apex used
to be created whenever interior_vertex() was Some, even when no ring was long enough to fan it — an
unreferenced vertex in the output. And the one degenerate triangle at 6³ went to zero, because the apex
moved from the saddle to a ring centroid; recorded, not gated, per this repo's rule that slivers are the
algorithm.
Pinned three ways, and all three fail on the mutation. Reverting fan to the single shared apex
fails the_cell_that_fanned_two_contours_from_one_apex_is_now_manifold (left: 27, right: 28),
the_interior_rule_meshes_convex_bodies on its committed seed
563fd2ba… (on case 0, before any fresh case), and
the_fan_covers_each_ring_once_and_repeats_no_index, which now asserts each fanned ring's apex is named
exactly as many times as that ring is long over all 16,384 (case, mask) pairs — the in-cell version of
the same statement, and the cheap one.
Would be shown wrong by: that field at 6³ coming back with non_manifold_vertices != 0, or any of the
16,384 (case, mask) pairs naming a fanned ring's apex a number of times other than that ring's length, or
any cell where a per-ring apex is worse than the shared one. It would be extended by a non-manifold vertex whose two face groups sit in different
cells — that is a third mechanism, and O-12 stays open for it: one mechanism found is not a proof that no
other exists.
💥 ✗44 / M-361 — "IsomeshPlugin is engine-agnostic and platform-agnostic": its frame budget calls std::time::Instant::now(), which compiles on wasm and then panics (D-012)
Believed because: nothing said otherwise, anywhere, and the crate's own documentation reads as a
platform-neutral promise. bevy_isomesh's README presents IsomeshPlugin as the way to use isomesh
from Bevy; the plugin's own doc comment describes streaming, budgets and chunk lifetimes without a word
about targets; and Instant is in std, which wasm32-unknown-unknown has. The type resolves, the
call type-checks, and cargo check --target wasm32-unknown-unknown was green on the whole crate before
this was found. There is no compile error to notice.
Falsified by: putting game_showcase on a web page. plugin.rs:51 was
use std::time::{Duration, Instant}; and :395 was let started = Instant::now(); inside
apply_finished_meshes — the system that spends the per-frame mesh budget, which is to say the one system
every streaming consumer runs on the first frame a chunk lands. On wasm32-unknown-unknown
std::time::Instant::now() panics with "time not implemented on this platform", so the plugin took down
quickstart, game_showcase, game_terrain_stream, game_walk and game_capsule_walk — the crate's
entire browser story — at the moment it started working rather than at the moment it started.
Result: bevy_platform = "0.19" in [dependencies], with features = ["web"] under
[target.'cfg(target_arch = "wasm32")'.dependencies], and use bevy_platform::time::Instant; in place of
std's. Duration stayed on std, because it carries no clock. Verified in the resolved graph rather
than by inspection, which matters here because the failure mode is a feature silently not reaching the
library: cargo tree --target wasm32-unknown-unknown -e normal -i web-time prints
web-time v1.1.0 <- bevy_platform v0.19.0 <- bevy_isomesh, so Instant is web_time::Instant in the
normal (non-dev) wasm graph; the same command without --target prints "nothing to print", so
native carries no web-time and no behaviour changed there. bevy_platform unified onto the single copy
Bevy already pulled in transitively — grep -c 'name = "bevy_platform"' bevy_isomesh/Cargo.lock is 1,
so there is no second clock in the graph.
The generalisable part is the shape of the hole, not the call. A platform claim that no test states is
not a claim, it is an assumption, and cargo check --target wasm32-unknown-unknown cannot see this class
of defect at all — std on that target is present and partly unimplemented, so the panics are runtime.
Three of the five affected examples were already in this repository and none of them ran anywhere that
would have noticed. The demos on the site are now what notices.
Would be shown wrong by: a browser run of any IsomeshPlugin demo panicking in
apply_finished_meshes again, or web-time leaving the wasm normal graph, or bevy_platform appearing
twice in the lockfile.
🧊 M-362 — wasm-opt -Oz shrinks both site modules on disk and makes both bigger gzipped, so it is rejected on all ten (D-012)
Registered as a rejected optimisation with numbers, which is worth more than an untried one: isomesh_web
is the module behind isomesh.ladvien.com's front-page demo, and the wire is what a front page pays.
isomesh_web |
bytes | vs. raw |
|---|---|---|
cargo build --release --target wasm32-unknown-unknown |
133,115 | — |
the same, wasm-opt -Oz |
112,642 | −15.4% |
raw, gzip -6 |
49,837 | — |
-Oz, gzip -6 |
50,493 | +1.3% |
marching_cubes_tunnel_bg.wasm (a Bevy module, post-wasm-bindgen) |
bytes | vs. raw |
|---|---|---|
--profile wasm-release, wasm-bindgen --remove-name-section --remove-producers-section |
37,409,471 | — |
the same, wasm-opt -Oz |
29,094,422 | −22.2% |
raw, gzip -6 |
8,729,859 | — |
-Oz, gzip -6 |
9,314,752 | +6.7% |
wasm-opt 132, binaryen version_132, one run each, on the 5900X. The optimiser's own passes are not the
question — it does remove a sixth of the small module and a fifth of the large one — it is that gzip was
already finding that redundancy, and -Oz's output compresses worse than the input it shrank. For
isomesh_web the [profile.release] block does the work instead:
opt-level = "z", fat LTO, one codegen unit, panic = "abort" (every export returns a sentinel, so there
is nothing to unwind and the landing pads are dead weight) and strip = true.
Two flags are needed to run it at all, recorded because the failure is 60 screens of validator output
that names neither cause: rustc emits bulk-memory, multivalue, mutable-globals,
nontrapping-fptoint, reference-types and sign-ext by default on wasm32-unknown-unknown — check
with rustc --print cfg --target wasm32-unknown-unknown | grep target_feature — and binaryen 132 accepts
none of them unless each is passed as --enable-…. Without them wasm-opt exits 1 on
memory.copy operations require bulk memory operations.
The direction is the same on both and the magnitude is worse on the big one, which is the part that
decided it. The rule was set before either measurement — adopt only at a ≥15% gzipped saving — and
-Oz is not merely short of that bar, it is on the wrong side of zero on a 133 KB module and 6.7% on the
wrong side on a 37 MB one. The Bevy pass also costs 23 s wall per module, so nine of them would add
about three and a half minutes to every site job to ship 585 KB more over the wire. binaryen is
therefore in neither build_web.sh nor CI, and the site has exactly one build path per module.
Would be shown wrong by: a binaryen release whose -Oz output gzips smaller than the input's, or a
host that serves these modules uncompressed — on which the disk figure would be the wire figure and the
decision would invert.
📖 V-47 — a wgpu storage buffer bound read_write and read_only in one bind group is a validation error, not a free alias (GPU-014)
GPU-014's kernel gained a fifth binding, a read-only base the caller fills, and one bind-group layout has
to be filled on every path — including the four GpuField ids that never read it. The plan's primary
scheme was to bind the dispatch's own output buffer there, on the reasoning that a binding the shader
never reads costs nothing. It is not free, and this is where that is written down before someone tries it
again.
Believed because: the shader provably never reads base when select.id names a GpuField, so the
aliasing looked like a naming detail rather than a state conflict.
Tested by: reading wgpu 29.0.4's own source rather than the docs —
wgpu-types-29.0.4/src/buffer.rs:146 and wgpu-core-29.0.4/src/track/mod.rs:331, plus
track/mod.rs:500 and track/buffer.rs:25.
Result: BufferUses::EXCLUSIVE contains STORAGE_READ_WRITE, and
invalid_resource_state(state) is state.any_exclusive() && !state.bits().is_power_of_two(). A buffer
bound read_write at one binding and read_only at another merges to
STORAGE_READ_WRITE | STORAGE_READ_ONLY — two bits, one of them exclusive — so
UsageScope::merge_bind_group returns ResourceUsageCompatibilityError, whose webgpu_error_type is
Validation. The check is in wgpu-core, so it is backend-independent: a native Vulkan run does not
get away with what WebGPU would reject.
Consequence: FieldSampler holds a 4-byte unused_base created once in new, bound at 4 by every
path that does not read it. The layout stays single — one kernel, one pipeline, two public entry points
over one private run — which was the point the aliasing was meant to serve. Verified by the thirteen
field_sampler tests: ten reach sample_stack and so dispatch with unused_base bound at 4, and the
three new fold_into ones bind a real base there.
Would be shown wrong by: a wgpu release moving STORAGE_READ_WRITE out of EXCLUSIVE, or narrowing
the usage scope from the bind group to the individual binding — at which point the alias becomes legal and
the four bytes can go.
💥 ✗45 / M-363 — "five samples in a cross under the foot beat one": at a fixed depth the cross reaches into terrain above the foot, and the body hangs 12.5 cm in the air (D-013)
The claim, and it was in a plan that had been approved. game_dig's resolve_body probed one point
for ground, foot − Y·(BODY_RADIUS + GROUND_PROBE), and that is genuinely wrong: a body wedged with its
centre over a void and part of its foot on rock reads air, grounded goes false, and
move_camera's world.grounded && Space refuses the jump — the hole the player dug is a trap. The fix
specified was five samples at that same depth, offset laterally by 0.7 · BODY_RADIUS.
Falsified by the first run of the settle test. The body came to rest at 1.8249992 against a true
1.70 on flat ground at the origin, and the existing
a_dropped_body_lands_on_the_terrain_and_stands_still failed with it. The excess is not noise and not a
tuning problem — it is the terrain rise over the lateral offset, arithmetic:
| quantity | value |
|---|---|
Ground height gradient at the origin, ∂h/∂x = 0.35·0.9 + 0.15·2.1 |
0.630 |
lateral offset, 0.7 · 0.25 |
0.175 |
height(0.175, 0) = 0.35·sin(0.1575) + 0.15·sin(0.3675) |
0.1088 |
probe depth below the foot centre, R + GROUND_PROBE |
0.310 |
foot centre at eye 1.825 |
0.375 |
straight-down sample, 0.375 − 0.310 |
0.065 — air |
| lateral sample at the same depth, against a surface at 0.1088 | 0.065 − 0.1088 = −0.044 — solid |
measured hover, 1.8249992 − 1.70 |
0.125 |
The falling body was at y = 1.825 on frame 29 of a 4.0-unit drop (4.0 − 0.0025·n(n+1)), the cross
found ground it was not touching, gravity_step zeroed the velocity, and it stayed there. The lateral
samples were asking a different question from the centre one — "is there solid somewhere below me"
rather than "is there solid under my foot" — and on any slope those differ by the slope.
What replaced it, and why that shape. The lateral samples sit on the foot sphere's own lower
boundary: at offset r the sample is sqrt(R² − r²) below the centre and only then drops by
GROUND_PROBE, so the tolerance is purely vertical, which is what GROUND_PROBE's doc comment always
said it was. Scanned over 108 pit fixtures (subtract-sphere radius 0.25 … 1.2 × three depths × six
horizontal offsets): 34 where the single point reads airborne and the chord cross reads grounded, so
the trap is real and the fix reaches it. Hover on bare terrain over five columns: 0.0000130, 0.000939,
0.00455, 0.0326, 0.0419 — every one inside GROUND_PROBE = 0.06, which is the bound the design
admits rather than a number chosen to pass.
An intermediate that was also wrong, recorded because it is the tempting one. Sampling the sphere
radially — foot + (R + GROUND_PROBE)·dir for five unit directions at 45° — keeps the samples on a
sphere but on a sphere of radius R + GROUND_PROBE, so the diagonal reaches 0.219 sideways while
descending 0.219, and against a 0.59 local slope it still finds uphill material: measured 0.078 of
hover at r = 0.35, offset = 0.1. Only the chord form, which puts GROUND_PROBE in −Y alone, has no
lateral reach to trade.
Would be shown wrong by: a fixture where the chord cross reports grounded with the foot sphere more
than GROUND_PROBE above every solid point beneath it, which is what
the_body_is_a_capsule_that_never_hangs_above_the_terrain asserts on five columns.
💥 ✗46 / M-364 — "headless Chrome on this host exposes no navigator.gpu": it exposes the object and no adapter, which is the one failure the old gate could not see (D-013)
The claim was this repository's own, in .omp/skills/isomesh-site-deploy/SKILL.md: "headless Chrome
here exposes no navigator.gpu — --enable-unsafe-webgpu with SwiftShader through ANGLE does not
change that", and in D-012's archive note, which reports every demo reading the same 250 ms/frame on a
software rasteriser. Both were true of the Chrome that was measured. Neither is true of the Chromium on
this host now.
Playwright Chromium 1228, --headless=new --no-sandbox, driven over CDP against the live site:
| probe | value |
|---|---|
location.protocol |
https: |
window.isSecureContext |
true |
typeof navigator.gpu |
object |
await navigator.gpu.requestAdapter() |
null |
#loading after load |
removed |
| canvas pixels | all black |
The two halves of that table are the finding. navigator.gpu present and requestAdapter() null is
a real browser state — a blocklisted driver, a VM, a headless run — and web/play.html's gate tested only
the object. So the gate passed, overlay.remove() ran, await init() resolved because bevy_winit calls
event_loop.spawn_app on wasm and that returns immediately, Bevy then failed asynchronously inside the
event loop where nothing was watching, and the page was a black canvas with no text on it. The deployed
site was in exactly this state when it was checked, which is how the mechanism was found rather than
reasoned about: the gate's own honest message never appeared because the gate never fired.
requestAdapter() in the gate turns it into
"This browser has WebGPU but no usable GPU adapter, so there is nothing to render with." — verified by
serving the patched web/dist locally and reading #loading back, on the same browser that produced the
black canvas.
Consequence for the deploy skill: "seeing the gate's text is a real result" now has two texts and they discriminate. Would be shown wrong by: a Chromium build here that returns an adapter, at which point the live canvas becomes drivable from this machine and the section saying it is not becomes stale.
🧊 M-365 — one wgpu::Instance per test deadlocks game_dig's suite at default parallelism, and a shared device halves its runtime (D-013)
wgpu_pair() built a fresh wgpu::Instance, requested an adapter and requested a full-limits device on
every call, and harness() calls it once per test. At sixteen tests that was five instances and it
passed. At twenty-three it hangs.
--test-threads |
outcome |
|---|---|
| 8 | pass, 1.50 s |
| 12 | hang — the same five harness tests never report |
| 16 | pass, 1.54 s |
| 24 (default here) | hang — same five |
Clean at 8 and 16 and hung at 12 and 24 is a race, not a threshold, and the first observation of it
cost 1800 s of wall clock against a timeout. The five that hang are exactly the ones that open a device
after other devices are already open; the six device-opening tests run alone in one filtered invocation
pass in 1.35 s, so no single test and no single count is the trigger.
wgpu::Device and wgpu::Queue are #[derive(Debug, Clone)] Arc handles (wgpu 29.0.4,
src/api/device.rs:19, src/api/queue.rs:13), so one instance behind a LazyLock, cloned per test, is
both correct and what an application does — an engine does not open a device per system. 23/23 pass, and
the suite went 1.5 s → 0.6 s across five consecutive default-parallelism runs.
Registered as a fixture defect, not a wgpu defect: nothing here shows wgpu is wrong to serialise, only that a test harness which opens N drivers has N chances to lose.
🧊 M-366 — a GitHub Pages project page is redirected by the user site's custom domain, and an archived repo cannot be fixed through the API (D-013)
https://ladvien.github.io/isomesh/ 301'd to https://ladvien.com/isomesh/ → 404, and it kept doing
it after isomesh's own custom domain was cleared (cname: null confirmed by
gh api repos/Ladvien/isomesh/pages). The redirect is not the deployed repository's:
| observation | value |
|---|---|
repos/Ladvien/ladvien.github.io/pages cname |
ladvien.com |
that entry's https_certificate |
absent |
dig +short ladvien.com |
52.84.217.{59,81,93,120} — CloudFront, not GitHub's 185.199.x |
curl -sSI https://ladvien.com/ |
server: AmazonS3, x-cache: Hit from cloudfront |
repos/Ladvien/ladvien.github.io archived |
true, pushed_at 2022-06-06, a fork |
gh api -X PUT …/pages on it |
409 Repository is archived. |
So an account-level custom domain rewrites every project page on the account, and this one pointed at
a host GitHub provably does not serve. Clearing it needs three calls — PATCH archived=false, PUT
{"cname": null}, PATCH archived=true — after which https://ladvien.github.io/isomesh/play.html
returns 200 with num_redirects=0 and https_enforced: true, and ladvien.com is unchanged because
CloudFront serves it.
Why it was load-bearing rather than cosmetic: WebGPU is secure-context-only, so the http:// page the
redirect chain ended on had navigator.gpu undefined and all nine demos refused to start in every
browser, desktop Chrome included. The diagnostic order that would have saved the time: when a project
page redirects somewhere unexpected, read the user site's cname before anything in the repository
being deployed.
💥 ✗47 / M-367 — "GPU_JOBS_MAX bounds the queue": the cap was checked after the push, so it bounded nothing at all (D-014)
drain_dirty's backpressure was the second clause of mesh_within_budget's budget
predicate, in_flight.get() < GPU_JOBS_MAX. The predicate is consulted after meshing a chunk, and
deliberately — the crate's own docs say a budget too small for one chunk must still make progress, so
the livelock cannot happen. The consequence for a counting clause is that a frame which begins at
the cap dispatches one more before the predicate can refuse; and because that repeats on every frame in
which no readback retires, the queue grows by one per frame with no bound:
| observation | value |
|---|---|
| declared cap | 16 |
| first failure | 17 jobs in flight at frame 39 |
after asserting cap + 1 |
18 at frame 47 |
| jobs outstanding at frame 900 of a 256-chunk switch | 78 chunks, pending pinned at 16 |
| cost per overshoot | two 295 KB geometry buffers plus a staging copy |
Only reachable when readbacks lag a whole frame, which on an idle device they do not — so it survived every previous run and surfaced when six tests began sharing one device (M-365).
Two fixes that look right and are not, both tried and measured. Refusing to enter the drain while
the list is full stalls the switch outright — measured as a hang at the test's 900-frame guard;
Readback::ready polls the device itself so retirement does not need a new submission, but the frame
that dispatches nothing also defers every chunk, and the throughput that was carrying the drain was the
overshoot. Asserting cap + 1 is not a bound: it is the first term of an unbounded series, which the
18 proved one run later.
What holds: the closure checks in_flight before gpu_dispatch and, when there is no room, puts
the chunk back in the dirty set — deferred rather than dropped, and not quietly meshed on the CPU
either, because key 8 means the device meshed it and a silent fallback would make the HUD's own claim
false. world.backlog becomes the set's length rather than report.remaining, since a chunk the queue
had no room for is backlog too.
Would be shown wrong by: pending exceeding 16 on any frame, which
key_eight_meshes_the_sandbox_on_the_gpu now asserts through the shared drain helper on every frame
of every drain in the suite.
🧊 M-368 — the backpressure was measured against a stale queue: drain_dirty ran before gpu_collect (D-014)
in_flight starts at pending.jobs.len(), and in the chained Update order drain_dirty came
before gpu_collect — so it counted every job the device had already finished but nothing had
retired yet. The cap was therefore compared against last frame's high-water mark, and no slot ever
looked free: with the cap fixed and the order left alone, a 256-chunk switch dropped to one chunk per
twelve frames with pending pinned at 16 for 900 frames.
Swapping them — retire, then dispatch into the freed slots — restores the switch to under a second for the whole suite and costs nothing: a job dispatched this frame is collected next frame at the earliest either way, so the latency is unchanged. A queue length read before the thing that shortens it is not the queue length.
💥 ✗48 / M-369 — "the field already stops the descent, and the floor slab is scenery": dig out the bottom and the player leaves the world (D-014)
D-013 shipped the five boundary slabs as geometry with a position clamp on x and z only, on the
stated reasoning that "no y clamp — the field already stops descent, and the floor wall is
scenery". Reported by the user and reproduced: dig out the bottom and the body sinks through the
floor.
The mechanism is not where the reasoning looked. aim refuses to place a brush centred outside
sandbox, but a brush centred on the floor plane still reaches its own radius below it — up to
2.00 at the top of the wheel's range against a box floor at y = -5.4. So a shaft dug to the bottom
removes the field underneath the box, the chunks and their meshes stop at -5.4, and the body falls out
of the visible world until it meets whatever Ground still has, embedded in rock nobody can see or dig.
And a y clamp could not have fixed it, which is the more useful half: clamping a coordinate stops
the fall without ever reporting ground, so the body hangs at the limit with grounded false, the jump
refused, and gravity_step accelerating into a surface it is not allowed to touch. The boundary has to
be in the field the resolver samples, so that depenetration, the ground probe and the jump all see it
— which also deleted the x/z clamp as a second path doing the same job worse.
Walls is five half-spaces from the same sandbox() call walls() draws from, unioned with the brush
stack for collision only — the mesher must not see them, because they are already on screen as five
cuboids. Half-spaces rather than the 0.5-thick slabs on purpose: the body only ever touches an inner
face, and a half-space has no far side for one fast frame to tunnel through.
Would be shown wrong by: a body that ends below lo.y + 1.70 after a shaft is dug through the
floor, or a boundary face whose zero is not the drawn slab's inner face — asserted on all five by
the_collision_boundary_is_solid_exactly_where_the_slabs_are, with the wiring gated separately by
walking_into_the_wall_stops_at_the_sandbox (removing the boundary from move_camera walks the body to
x = 42.1).
Phase 23 — twelve registrations from the 2026-08-26 audit, each before its harness
Source: docs/research/2026-08-26-audit-and-phase-23-registrations.md, a skeptical audit of the four
Phase 21 experiments and the ✗43 entry followed by twelve new pre-registrations, P-61…P-72, drawn
from mathematics, formal logic and systems results the 2026-08-23 sweeps did not reach. All twelve are
registered in crates/isomesh/src/experiment.rs before their harnesses exist, each in its own commit,
and the git order is what makes the predictions falsifiable rather than narrated. Experiments are
bench-local; crates/isomesh/src/** is read-only apart from the registrations themselves, except where
an experiment is a source change and says so at registration (P-61, P-68's feature, P-69).
The audit's central finding is a method rule and it changes how these are written. Four Phase-21
clauses could not have discriminated anything — P-58's C1 and C2, P-59's C2, P-60's C2 — and every
one was catchable before its harness existed. So each registration below names the rows on which each
clause can fire, that set is shown non-empty from the CSV itself, and a clause whose population is
empty is re-fixtured or dropped before the harness rather than softened after.
Four of the twelve are expected to return nulls, registered as such on purpose: P-64's C2,
P-72's C1 on the smooth fields, P-61's C4, and P-67's C1 if the condensation is worse than Knoll's
band suggests. A phase where every clause holds is a phase whose clauses were too easy.
🧊 M-370 — an existence check passes on a commit that left the branch: git cat-file -e is a property of the checkout, merge-base --is-ancestor is a property of the artefact (D-017)
M. scripts/csv_provenance.sh over all 50 files in docs/experiments/, three clauses per file.
The 2026-08-26 audit's A-1 reports that p-57.csv, p-58.csv and p-60.csv name 0d81ae6, which a
rebase rewrote away, and prescribes a gate built on git cat-file -e <sha>^{commit}. That command
succeeds on all three. The object is on disk, held by a reflog, referenced by no branch, and one
git gc from unreadable — so the prescribed check is green in this clone and red in a fresh one of the
same repository. A gate whose verdict depends on which copy of the repo it runs in is not a gate.
git merge-base --is-ancestor <sha> HEAD asks the question the header exists to answer, and answers it
identically everywhere.
Counting the directory rather than the phase found two more, and the audit's three is five:
| clause | violations | which |
|---|---|---|
| SHA not in HEAD's history | 5 | p-41, p-42 (cceb112); p-57, p-58, p-60 (0d81ae6) |
WORKING TREE DIRTY |
34 of 50 | eight of Phase 19's, all six of Phase 20's, all four of Phase 21's, and 16 older |
no # commit header at all |
1 | p-26.csv, written before common::experiment stamped anything |
p-59.csv's f55416c is an ancestor, so the audit's "three of the four" is right about Phase 21
and understates the tree by two rows in Phase 20. A-2's "four of four dirty" understates it by thirty.
The pins are asserted exactly, not as a subset, and that is the load-bearing choice. Each of the
three lists above is a literal in the script, and the observed violation set must equal it: a new
violation fails, and a file re-run clean fails too until its name is removed. An allow-list checked
with ⊆ decays into a list of files that no longer violate anything, and nothing ever notices — M-4's
rule (pin a known defect as an assertion, never as an exclusion) in a second place. The headers are not
rewritten; those runs really were dirty and the stamp is the honest part of this whole mechanism.
The instrument can report the other answer, demonstrated four ways rather than argued. A scratch
CSV stamped with a non-resolving 40-hex SHA fails naming the file; the same file marked dirty fails; the
same file with no header fails; and clearing p-59.csv's dirty flag fails the stale-pin clause,
naming p-59.csv. All four then revert to green. unknown passes, because ask()'s own documentation
says it is what an absent git writes and it claims nothing.
Would be shown wrong by: a CSV committed with a header naming a commit outside HEAD's history
that this gate reports green, or a pinned name that stops violating its clause without the gate saying
so.
📖 V-48 — wgpu 29 puts every subgroup operation in the native half of the split Features struct, so the browser backend cannot have them even though Chrome ships them (D-018)
Read from the pinned source on disk, not from a doc page. wgpu-types-29.0.4/src/features.rs
declares SUBGROUP (1 << 38), SUBGROUP_VERTEX (1 << 39) and SUBGROUP_BARRIER (1 << 40) inside
FeaturesWGPU, which has 65 entries. FeaturesWebGPU has 18, enumerated in full —
DEPTH_CLIP_CONTROL, DEPTH32FLOAT_STENCIL8, the six TEXTURE_COMPRESSION_*, TIMESTAMP_QUERY,
INDIRECT_FIRST_INSTANCE, SHADER_F16, RG11B10UFLOAT_RENDERABLE, BGRA8UNORM_STORAGE,
FLOAT32_FILTERABLE, FLOAT32_BLENDABLE, DUAL_SOURCE_BLENDING, CLIP_DISTANCES, IMMEDIATES,
PRIMITIVE_INDEX — and no subgroup entry. So subgroups reach native Metal, Vulkan and DX12 and do
not reach wgpu's browser backend at all, independently of what any browser implements.
Consequence, and it is why P-70 has a C3 rather than a note: any subgroup path needs a fallback and
the nine wasm demos are on it. P-70's C3 exists because of this row, and it is the clause that makes
the fallback exercised rather than merely present.
Two constraints that will bite, both read from source rather than from an issue tracker.
The 1-D workgroup blocker is a single if and here is where it lives.
naga-29.0.4/src/valid/interface.rs:281-287 rejects @builtin(subgroup_id) and
@builtin(subgroup_invocation_id) whenever ep.workgroup_size[1..].iter().any(|&s| s > 1), returning
VaryingError::InvalidMultiDimensionalSubgroupBuiltIn — "Workgroup size is multi dimensional,
@builtin(subgroup_id) and @builtin(subgroup_invocation_id) are not supported." This is a validation
error at shader-module creation, not a runtime fallback, so a bitmap pass dispatching with y or z > 1
does not compile and must be flattened to 1-D first. That flattening carries its own hash risk and is
P-70's stated pre-condition.
The subgroup size moved out of Limits. subgroup_min_size and subgroup_max_size are fields of
AdapterInfo at wgpu-types-29.0.4/src/adapter.rs:164 and :177, so in 29 they come from
adapter.get_info() and not from device.limits(). Code written against a pre-28 example reads them
from the wrong object.
Would be shown wrong by: a FeaturesWebGPU in the pinned wgpu-types carrying a subgroup bit, or a
naga version that validates a multi-dimensional workgroup with subgroup_invocation_id — either of which
makes P-70's C3 cheaper than registered rather than wrong.
📖 V-49 — a correction to V-23 / GPU-007: WGSL mesh shaders on Metal are unimplemented!() in naga 29, full WGSL support landed in wgpu v30.0.0, and the decision is to wait (D-018)
V-23 is right about the pinned version and about to stop being right, and the sharpest evidence is
one line of naga rather than a changelog sentence. naga-29.0.4/src/back/msl/writer.rs:6937:
crate::ShaderStage::Task | crate::ShaderStage::Mesh => unimplemented!(),
Not an error return — a panic. Meanwhile wgpu-hal-29.0.4/src/metal/device.rs does build mesh
pipelines (:1418-1466, mesh_stage, descriptor.meshBuffers()) and accepts ShaderInput::Msl and
ShaderInput::MetalLib as ShaderModuleSource::Passthrough (:1152-1190). So the picture at 29 is
exact: Metal mesh pipelines work, and only with hand-written MSL.
Both changelog quotes verified verbatim against gfx-rs/wgpu trunk. v28.0.0's Mesh Shaders major
change: "They are now fully supported on Vulkan, and supported on Metal and DX12 with passthrough
shaders." v30.0.0 → Metal: "Added full support for mesh shaders, including in WGSL shaders. By
@inner-daemons in [#8739]." The same release completes DX12: "Added support for mesh shaders in naga's
HLSL writer, completing DX12 support for mesh shaders. By @inner-daemons in [#8752]."
v30.0.0 is dated 2026-07-01 and v30.0.1 2026-08-21, so this is a shipped release and not a plan.
Trunk's own spec document is stale against trunk's own changelog. docs/api-specs/mesh_shading.md
still lists the naga backends as 🛠️ SPIR-V, 🛠️ HLSL, ❌ MSL with ❌ = Planned — two releases
after the HLSL writer was completed and one after MSL landed. Both files are in the same repository at
the same commit. V-23's original source was this document, which is why the characterisation
outlived the code.
The decision, recorded as a decision because an omission reads as an oversight. The mesh-shader draw
is worth 6.7% at 129³ (M-149). Paying for that at wgpu 29 means hand-written MSL, a forked shader
pipeline and a second source of truth for the shader that produces geometry — which is CLAUDE.md rule 5
and the one-path rule at once. 6.7% does not buy that. When Bevy moves to wgpu 30 the same 6.7% arrives
for a feature flag and a WGSL entry point. So: wait. O-5 — the Metal capability probe — is still
unrun and is now cheap to interpret, because this row says what answer a correct wgpu 29 must give.
Would be shown wrong by: Bevy pinning wgpu 30 while this row still says "wait", or a naga 29 patch
release that emits MSL for a mesh entry point.
📖 V-50 — CGAL shipped an Isosurfacing package in 6.1 whose own manual pictures cracks at octree level transitions, so M-128/M-132/M-133/M-106 are not catching up to a literature (D-018)
Read from the v6.1 tag, not from the announcement. Isosurfacing_3 ships marching_cubes(),
TMC (Grosso 2016, 10.1111/cgf.12975) and dual_contouring(), authored by Julian Stahl and Maël
Rouxel-Labbé, under SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial. The papers
are fair game and the code is not.
The seam result is the finding, and CGAL states it plainly with a figure of it.
Isosurfacing_3/doc/Isosurfacing_3/Isosurfacing_3.txt:343-346, verbatim: "Note that in this
configuration, all methods lose guarantees, and cracks can easily appear in the surface for
Marching Cubes if the octree is not adapted to the surface being extracted." And the figure caption at
:355-358: "the octree … has been applied arbitrary refinement in one eighth of the domain and the
resulting mesh exhibits cracks (boundaries) at the regions where octree levels are discontinuous."
One correction to the audit that sourced this row. It quotes the octree example's comment —
examples/Isosurfacing_3/contouring_octree.cpp:76-78, "the surface can enter and leave a cell without
involving the cell's vertex. In practice, that means a hole if at nearby adjacent cells the voxels did get
refined" — and reads it as a property of the octree domain. It is not: that comment describes the
example's own Refine_around_isovalue split predicate, and its mechanism is under-detection (a cell
whose eight corners agree in sign while the surface clips it), which is a different failure from a crack
at a level transition. The manual sentence above is the one that says the seam thing, and it says it
about all three methods. The conclusion is unchanged and now rests on the right sentence.
So a mature C++ library, shipped 2025-10, has no adaptive seam handling. Combined with the audit's
sweep finding no peer-reviewed 2023–2026 work on chunk seams, LOD stitching or crack-free transitions for
the DC/MC family — the line still terminating at Schaefer/Ju/Warren 2007 and Lengyel's Transvoxel —
M-128, M-132, M-133 and M-106 are not this crate catching up. (The negative half is the
audit's sweep, carried here with its provenance rather than re-run: ✗9's rule is that "nobody has done
X" needs evidence like any other claim, and the evidence here is one sweep, not two.)
The architecture is worth copying and it factors further than the audit says. The domain splits into
a partition (IsosurfacingPartition_3; Cartesian_grid_3, Octree_partition), a value field
(IsosurfacingValueField_3; Value_function_3, Interpolated_discrete_values_3) and a gradient
field (IsosurfacingGradientField_3; Finite_difference_gradient_3, Gradient_function_3) — the
gradient a separately supplied capability rather than a finite-difference assumption baked into the
extractor, which is sharper than Sdf + a NormalStrategy. And there are two more concepts the audit
did not name: IsosurfacingEdgeIntersectionOracle_3 and IsosurfacingInterpolationScheme_3, i.e. the
root-finder and the reconstruction filter are pulled out too. That is five axes, free to adopt.
Their guarantee table, verified, matches this crate's own is_closed()/is_manifold() split.
MC: 2-manifold no, watertight no, topologically correct no. TMC: yes / yes / yes.
DC: no / no / no, sharp features "yes (not guaranteed)". Watertightness carries the footnote
"assuming the isosurface does not exit the specified bounding box of the input 3D domain" — the same
caveat, in the same place, as A-002's.
And two claims to not inherit, because the package makes them with no numbers anywhere: "it generates fewer faces and higher quality faces than Marching Cubes, in general" (DC section) and "Marching Cubes is substantially faster" than Delaunay refinement "but often tends to generate more triangle facets for an equivalent desired sizing field". Both are unbenchmarked in the manual. The second is also the opposite direction from the audit's paraphrase of it.
Would be shown wrong by: a CGAL release adding a transition-cell or crack-free octree path, or a 2023–2026 peer-reviewed DC/MC seam result the sweep missed — the second being the more likely and the reason this row names its sweep rather than asserting exhaustiveness.
📖 M-371 — MCPro is in the corpus as a 383-character landing page that read "converted, embedded": catalog_read is not a presence oracle either, and P-65 is blocked (D-020)
M. Six acquisitions attempted through home-still (9,518 documents, 290,612 chunks, CUDA distill,
both scribe instances idle). catalog_read on each candidate stem first, per ✗4; paper_download only
on the misses.
| paper | DOI | in corpus? | blocks |
|---|---|---|---|
| Finken et al., monotonicity constraints | 10.48550/arXiv.2608.12142 |
yes, genuinely — 3.65 MB PDF, 37,165 chars of markdown by olmocr, 12 chunks, 2026-08-23 |
P-66 unblocked |
| Stahl & Grosso, MCPro, GRAPP 2025 | 10.5220/0013309800003912 |
entry yes, paper no — see below | P-65 BLOCKED |
| Knoll et al., IA vs RAA, CGF 28(1) | 10.1111/j.1467-8659.2008.01189.x |
no; "No open-access PDF found" | P-67 BLOCKED |
| Smith, Levien & Owens, SPAA '25 | 10.1145/3694906.3743326 |
no; "No open-access PDF found" | nothing — P-70's prior is transcribed |
| Chernikov & Xu, IMR 2013 | 10.1007/978-3-319-02335-9_28 |
no; "No open-access PDF found" | nothing — P-63 prior art |
| Ahrens, Demmel & Nguyen, TOMS 46(3) | 10.1145/3389360 |
no; "No open-access PDF found" | nothing |
All four misses resolve as metadata through paper_search — the DOIs are real, the titles match, and
Chernikov & Xu's title is "A Computer-Assisted Proof of Correctness of a Marching Cubes Algorithm" — so
what failed is the open-access PDF, not the identifier. paper_download takes a DOI and nothing else, so
there is no in-policy route to an author copy.
The MCPro entry is the finding, and it is ✗4's rule one step further out. The standing rule is that
distill_search is not a presence oracle. catalog_read was the prescribed substitute, and on this stem
it reported markdown_path set, conversion.server = "html-parser", total_pages: 1, and
embedding.chunks_indexed: 1 — every field a present, converted, indexed paper has. The document behind
it is a 279,882-byte SciTePress landing page, and its markdown is 383 characters:
MCPro: A Procedural Method for Topologically Correct Isosurface Extraction Based on Marching Cubes
Topics:Fundamental Methods and Algorithms; Geometric Computing; Modeling and Algorithms
InProceedings of the 20th International Joint Conference on Computer Vision, … ,331-338,2025, Porto, Portugal
A title, a topic list and a page range. Not one sentence of the method. pdf_path ends in .html,
which is the tell and is not a field anybody reads. So the check that was supposed to be sound reported
sound, for thirteen days, on the acquisition that gates the largest item in Phase 23.
Two mechanical discriminators, either of which would have caught it, and they are cheap. The markdown
is 383 characters against Finken's 37,165 — two orders of magnitude, on documents of comparable page
count — and chunks_indexed is 1 against 12. A paper that converts to one chunk is a paper that did
not convert. pdf_path not ending in .pdf is a third, and it is exact rather than statistical.
Re-running paper_download returns the same landing page — 279,882 bytes again, and a different
sha256 (74b1a3d9… against the catalogued 49730d45…), because the page carries per-request state. It
also reset the entry's conversion and embedding blocks, so the entry now honestly reads
downloaded, not converted, which is the true state of the paper text and is left that way deliberately.
The 383-char markdown object and its single Qdrant chunk are still on disk from the 2026-08-13 ingest;
distill_exists still reports indexed: true for the stem. That is a corpus-hygiene item on big, not a
change this repository should make.
Consequence. P-65 is registered and not run: R-063 carries a > BLOCKED: line naming the
acquisition. The paper describes a face classification into hyperbola / singular cross / single line /
degenerate plane, a quadrant division around the asymptote centre, a per-cell halfedge assembly and an
inner hexagon — all of that is from the abstract, and CLAUDE.md rule 5 forbids inventing the parts
an abstract omits. P-67 is registered and not run for the same reason: its C3 exists to reproduce
Knoll's measured 1.5–2× / 3–4× band and his superquadric inversion, and reproducing a band from a
transcription of a summary is what ✗21 catalogues.
Would be shown wrong by: a catalog_read whose markdown_path points at real paper text while
chunks_indexed is 1, which would make the discriminator above a false positive; or either paper becoming
open-access, which unblocks its experiment with no other change.
P-61 — registered for R-059, before the harness: is the crossing bit-exactly antisymmetric if it is anchored at the edge midpoint rather than at the lower corner?
The hook is ✗39. M-356 found a mesh bit-exactly equivariant under axis relabelling and not under
reflection, and attributed it to a/(a−b) and b/(b−a) being two different divisions of the same two
values. That attribution is right and incomplete, and completing it produces a fix.
The subtraction is not the culprit. IEEE round-to-nearest is sign-symmetric, so fl(b−a) = −fl(a−b)
exactly and the two denominators are exact negations. The asymmetry enters in two other places: the
division rounding — fl(a/d) and −fl(b/d) are independent roundings that do not sum to 1 — and the
anchor. cube::edge_crossing returns a parameter measured from the lower corner, and the placements
put the vertex at lower + t. A reflection swaps which corner is "lower", so the correct reflected
parameter is 1 − t, and 1 − t is not representable as b/(b−a).
The construction. Store the crossing as a signed offset from the edge midpoint:
d = ((a + b) / 2) / (a − b) # in [−1/2, +1/2]
position = edge_midpoint + h · d
Exactly antisymmetric under the simultaneous endpoint-and-sign swap, and the proof is four IEEE 754
guarantees rather than four observations: fl(a+b) = fl(b+a) because addition is commutative; halving is
exact because 2 is a power of two; fl(b−a) = −fl(a−b) because round-to-nearest is odd; and
fl(S/−D) = −fl(S/D) for the same reason. The [0,1] parameter frame cannot host this, because
reflection acts there as 0 ↔ 1 — an affine map — and floating point respects sign flips exactly and
affine maps only approximately.
This is a src/ change and it is registered as one. cube::edge_crossing becomes
cube::edge_offset, and all five placements move to the centred frame: marching_cubes/mod.rs's
edge_position (which computes a/(a−b) inline rather than through cube), trilinear.rs's
local_crossing, surface_nets.rs, hermite.rs and transvoxel/cell.rs. The audit's own list named
three; there are five.
Each clause's population, counted from the committed artefact before this harness was written — which is the audit's central finding turned into a step:
| clause | fires on | currently |
|---|---|---|
| C1 | 98 of 112 p-57.csv rows have fixture_can_fail = true — 56 primal, 42 dual |
0 of 98 reach 48 |
| C2 | 16 of 16 fixtures (8 fields × 33³/65³); box_exact alone has 1,350 cut edges at 33³ |
every fixture has cut edges |
| C3 | 16 of 16 fixtures, marching_cubes |
baseline computed in the same run |
| C4 | 3 spacings × 2 arms; h = 0.1 is where the off-repo measurement moves 75.0% → 0% |
— |
box_exact's 14 rows are excluded by fixture_can_fail because its zero set lies on dyadic planes: all
eight of p-57.csv's 48 of 48 rows are its rows, and every one has order_sensitive_edges = 0. A
clause that counted them would be measuring the fixture.
C1 is registered knowing two mechanisms it cannot reach, and a falsification on them is the expected
outcome rather than a surprise. The two tetrahedral extractors fail because a six-tetrahedron
decomposition of a cell is not octahedrally invariant — the diagonals cut different edges after a
relabelling — which M-356 measured at 6–12 of 48 even on box_exact, where order_sensitive_edges is
0 and the interpolation argument has nothing to bite on. And a QEF accumulates into AᵀA in an order that
axis relabelling permutes, which is M-177. The clause is registered as the doc states it, because
softening a clause to what is likely is how a registration stops being a prediction.
C2 is a cost clause, not a benefit clause. The vertex positions genuinely move, T-007's 216 golden
hashes are rebaselined in the same commit as the source change, and a hash that survives falsifies it.
C3 is scoped to marching_cubes, and the doc's clause leaves that unstated. A placement change cannot
touch the sign classification, so the topology and the index buffer are bit-identical and the two arms are
the same mesh with substituted positions — an exact comparison rather than two runs. A dual vertex is a
QEF solve over the crossings and its lower-corner counterpart is not recoverable by substitution, so it is
not claimed.
C4 is registered as measurement with a stated risk of a null, and the null is the expectation: M-32's
named mechanism is world_of_sample, not the crossing.
The instrument is held against the old one where they overlap. The harness asserts cut_edges,
order_sensitive_edges, grid_symmetric and fixture_can_fail against docs/experiments/p-57.csv row
for row before it reports anything, so a drift in the re-implemented octahedral group or in either fixture
is a failure rather than a new number. The appendix's off-repo pre-measurement is re-run inside the
harness in Real for both scalars rather than quoted.
Records block, field, extractor, samples_per_axis, scalar, cell_size,
elements_vertex_exact, elements_vertex_exact_p57, elements_triangle_exact,
pure_permutation_exact, pure_sign_flip_exact, fixture_can_fail, cut_edges, edges_moved,
worst_move_ulp, hausdorff_lower_corner, hausdorff_centred, hausdorff_ratio,
self_intersections_per_1k_lower_corner, self_intersections_per_1k_centred,
self_intersections_ratio, seam_vertices, seam_mismatches_lower_corner, seam_mismatches_centred,
pairs, mismatches_lower_corner, mismatches_centred, out_of_cell_centred, c1_population,
c1_rows_at_48, c1_holds, c2_fixtures_with_moved_edges, c2_holds, c3_worst_hausdorff_ratio,
c3_worst_self_intersection_ratio, c3_holds, c4_seam_mismatch_delta, p57_fixture_columns_match.
💥 ✗49 / M-372 — C1 and C2 FALSIFIED, C3 and C4 HELD: plain Marching Cubes is now bit-exactly equivariant under all 48 octahedral elements, and the two clauses that failed did so for reasons that were named at registration (P-61, R-059)
M. cargo bench --bench experiment_p61, docs/experiments/p-61.csv, 155 rows, 9m33s, f64
(the pre-measurement block also in f32). Five blocks: 8 pre-measurement rows, 112 equivariance rows —
eight fields × seven extractors × 33³ and 25³, 5,488 extractions — 16 edge rows, 16 geometry rows and
3 seam rows. First CSV in this repository whose provenance line reads # commit 1cf4265 with no
(WORKING TREE DIRTY) beside it.
RE-RUN 2026-08-27 for C5 of the audit, and the re-run is its own control. The registered column
c1_rows_at_48counted all 112 equivariance rows while the registeredc1_populationbeside it counts the 98 that can fail — a numerator and a denominator over different sets, with the clause's own 28 parked in an extra column calledc1_can_fail_rows_at_48seven places further along. The obvious name was the wrong number, which is precisely how a reader gets misled by a correct file. Fixed by makingc1_rows_at_48the count overc1_population; the all-rows count keeps its own name,rows_at_48_all_rows, and no registration is amended — both names were already this experiment's. The re-run changed those two columns andwall_mson 81 of 155 rows, and nothing else at all: all 155 rows, everyelements_vertex_exact, everyworst_move_ulp, every Hausdorff and self-intersection ratio, all 8 pre-measurement counts, byte-identical. That isM-279's rule as a control on a refactor — the instrument agrees with itself everywhere it was not changed — and it is why none of the numbers in this entry moved.
| clause | registered | measured |
|---|---|---|
C1 elements_vertex_exact = 48 on every fixture_can_fail row |
98 of 98 | FALSIFIED — 28 of 98. And marching_cubes is 48 of 48 on all 16 of its rows, from 6 |
| C2 no reference field's golden hash is unchanged | 216 of 216 move | FALSIFIED — 135 of 216 moved, 81 unchanged, with three named causes; 14 of 16 fixtures have moved edges |
| C3 Hausdorff and self-intersections within 1% | both | HELD — 0.000000 on both, and the clause could not have failed |
| C4 the seam sweep, registered as measurement | a null | NULL, and provably non-vacuous — 205 = 205 |
The pre-measurement is the proof of the mechanism and it is exact, in both scalars. The appendix's
off-repo script, re-run in Real:
| frame | h |
pairs | lower-corner mismatches | centred | outside the cell |
|---|---|---|---|---|---|
cell-local, f64 |
1 | 2,000,000 | 1,035,808 (51.8%) | 0 | 0 |
cell-local, f32 |
1 | 2,000,000 | 1,184,666 (59.2%) | 0 | 0 |
world, f64 |
0.125 | 300,000 | 26,051 (8.68%) | 0 | 0 |
world, f32 |
0.125 | 300,000 | 28,618 (9.54%) | 0 | 0 |
world, f64 |
0.1 | 300,000 | 28,521 (9.51%) | 0 | 0 |
world, f32 |
0.1 | 300,000 | 30,998 (10.33%) | 0 | 0 |
world, f64 |
3/32 | 300,000 | 27,678 (9.23%) | 0 | 0 |
world, f32 |
3/32 | 300,000 | 30,065 (10.02%) | 0 | 0 |
Zero on 5,800,000 straddling pairs across both scalars, and the lower-corner form mismatching a million of them is the control: the instrument can report the other answer, and does, in the same loop.
The headline count was wrong by 59% for two commits, and the table it contradicted was three lines above it. It read "9.2 million straddling pairs"; the
pairscolumn of the eightpremeasurerows inp-61.csvsums to 5,800,000 —2 × 2,000,000 + 6 × 300,000. Two of those eight rows were also missing from the table above, which is how a sum nobody could perform stayed unchallenged: the printed rows came to 5,200,000 and the prose said 9.2 M, so neither number was the file's. Corrected against the CSV, table and headline now agree with each other and withdocs/experiments/p-61.csv.One of the doc's pre-measured figures does not reproduce, and the disagreement is the doc's script rather than this harness. The appendix reports
h = 0.1at 75.0% for the lower-corner form against 8.52% ath = 0.125; measured here it is 9.51% against 8.68% — no step at all. The cause is one term: the appendix computes the mirrored position as(-U) + h*t2, multiplying by the literalh, while an extractor interpolates between two computed corner positions and therefore multiplies byhi - lo, which at non-dyadichis noth. This harness does the latter because that is whatplacedoes. The exactness argument does not depend on either figure — it is four IEEE guarantees — and the centred form is 0 under both spellings.
C1's headline is inside its own falsification, and it is the result this experiment was for.
| extractor | p-57.csv |
now | at 48 of 48 |
|---|---|---|---|
marching_cubes |
6, 24, 48 | 48 only | 16 of 16 |
marching_cubes+decider |
1, 6, 24, 48 | 1 or 48 | 14 of 16 |
marching_tetrahedra |
6, 12 | 12 only | 0 |
subgrid_marching_tetrahedra |
6, 12 | 6, 12 | 0 |
surface_nets |
1, 6, 12 | 1, 6, 12 | 0 |
dual_contouring / manifold_dual_contouring |
2, 4, 24, 48 | 2, 4, 24, 48 | 3 each |
marching_cubes reaches all 48 elements on every field, gyroid, fbm_terrain and noise_cavity
included, with worst_component_ulp 0 on all 16 rows — not a small residue, no residue. ✗39's
consumer note said equivariance was available "for the six pure axis permutations"; it is now available
for the whole octahedral group, which is what turns the group into a 48-relation metamorphic oracle per
fixture rather than an interesting negative result.
marching_cubes+decider follows it everywhere except noise_cavity at both resolutions, where it stays
at 1 of 48. That is ✗39's incidental result — the asymptotic decider contributes its own axis
dependence rather than inheriting MC's — and this change cannot touch it, correctly: the decider compares
face values, not crossings. dual_contouring and manifold_dual_contouring gain thin_plate at 33³
(24 → 48) and are otherwise unmoved.
Both C1 failure modes were named in the registration, which is the point of naming them.
marching_tetrahedra improves from {6, 12} to a flat 12 of 48 and stops: a six-tetrahedron
decomposition of a cell is not octahedrally invariant, so its diagonals cut different edges after a
relabelling, and no placement rule reaches that. The duals accumulate crossings into AᵀA (or a centroid
sum) in an order that axis relabelling permutes, which is M-177. So C1 as registered was falsifiable and
was falsified; the clause's reach was over-stated and its mechanism analysis was not.
And one extractor is unmoved for a reason nobody had written down.
subgrid_marching_tetrahedra is identical to p-57.csv on all 16 rows, because it does not use the
linear crossing at all — subgrid::roots::all_roots bisects the real field, so its vertex positions are
independent of this change in both directions. That was found by C2, not by reading: all 24 of its golden
hashes came back unchanged.
C2 is falsified, 135 of 216 hashes moved, and the 81 survivors have three causes rather than one.
| cause | rows | why it is correct behaviour |
|---|---|---|
greedy_quads |
24 | a blocky mesher: cells are classified solid or empty and the vertices sit on the lattice. There is no interpolation to re-anchor |
subgrid_marching_tetrahedra |
24 | positions come from a root finder on the real field, not from a linear crossing |
| exactly-representable crossings | 33 | 27 are box_exact, whose zero set lies on dyadic planes — the same reason ✗39 found its only 48 of 48 rows there. The rest are csg_difference at 17³ and surface_nets rows where the centroid sum coincides |
Zero of 216 vertex or triangle counts changed, which is the design confirming itself: a placement
change cannot touch the sign classification, so the topology is bit-identical and only coordinates move.
Per fixture, 2,285 of 28,124 cut edges moved — 8.12% of them — at worst_move_ulp 0 to 268, and
the two fixtures with edges_moved = 0 are box_exact at both resolutions. thin_plate is the outlier at
44.1% of its cut edges moving.
This ratio read 7.3% for two commits and both of its counts were right.
2,285 / 28,124is 8.1247%. 7.24% is the 33³ subset alone (1,405 / 19,415); the 25³ subset is 10.10% (880 / 8,709); the mean of the per-rowedges_moved_fractioncolumn is 10.91%. Three defensible statistics over the same file and the entry quoted a fourth that is none of them — which is✗41's rule (two populations, two numbers, and say which population each one is over) failing on a single pooled ratio rather than on a chained one. The pooled figure is the one the sentence claims, so the pooled figure is what it now states.
C3 held and could not have failed, and that is stated rather than banked. Symmetric Hausdorff and
self-intersections-per-1,000 are identical to twelve significant digits on all 16 fixtures — every
hausdorff_ratio is 1.000000000. The clause's threshold is 1e-2 relative; a vertex moving by one
ULP at these magnitudes is ~1e-16 world units against a Hausdorff distance of ~5e-3. That is eleven
orders of magnitude of headroom, so a HELD verdict here carries much less information than its wording
implies — the same caveat ✗41's C2 earned, now earned by a clause registered in this phase. The
informative number is worst_move_ulp, which is per-fixture, non-zero, and bounded at 268.
C4's null is real, and the first version of the fixture could not have found that out. The registered
expectation was that the crossing form does not participate in a chunk seam, because M-32 names
world_of_sample. Measured at a chunk base of 16, over all three axes:
h |
cut edges | arms disagree about a coordinate | mismatches, lower-corner | mismatches, centred |
|---|---|---|---|---|
| 0.125 | 183 | 0 | 0 | 0 |
| 0.1 | 252 | 246 | 205 | 205 |
| 3/32 | 429 | 0 | 0 | 0 |
At the two dyadic spacings the two arithmetics agree bit-for-bit and there is nothing to measure; at
h = 0.1 they disagree about 246 of 252 endpoint coordinates and the crossing mismatch count is
identical under both placements. So the seam is world_of_sample's, exactly as M-32 says, and the
centred form neither helps nor hurts it. seam_worst_ulp is 4.37e18 under both arms, which is a
coordinate straddling zero rather than a large displacement — and it is the same number under both,
which is the clause's whole content.
The first fixture found 0 cut edges and printed a clean zero (M-44, seventh instance). It put two chunks side by side along
xand compared the shared plane'sy-edges — where both chunks have the sameybase, so both reconstructo + h·yidentically and there is nothing to disagree about. Theseam_coordinate_mismatchescolumn is now the control and the run asserts on it: a seam census whose two arms never disagree about a coordinate is not measuring the seam.
The audit's list of three placements is six, and C2 is what found the sixth. The doc named
cube.rs:186, surface_nets.rs:119 and trilinear.rs:1024. Also placing from the crossing:
marching_cubes/mod.rs's edge_position (which computed a/(a−b) inline, not through cube),
hermite.rs, transvoxel/cell.rs, the property suite's test double — and marching_tetrahedra.rs,
which had its own copy of the expression and was found only because all 24 of its golden hashes survived
the first blessing. The GPU shader had it by hand too (marching_cubes.wgsl), and leaving that would have
broken M-142's CPU/GPU agreement; the_gpu_mesher_agrees_with_the_cpu_one is green and game_dig is
26/26.
refine_crossing moved frames with it, and the reason is the same three lines. Its bisection bracket
is now [−1/2, +1/2] rather than [0, 1]: symmetric about zero, endpoints exact negations, so under the
simultaneous endpoint-and-sign swap a_inside flips, low and high swap roles, and the refined
offset negates exactly too. A [0, 1] bracket would have reintroduced the affine 0 ↔ 1 map the whole
change exists to remove, on the one path that iterates.
The instrument is P-57's, and that is checked rather than asserted. cut_edges,
order_sensitive_edges, grid_symmetric and fixture_can_fail are compared against
docs/experiments/p-57.csv row for row before any new number is reported — four columns that are
properties of the grid and the field values alone, so a placement change cannot move them.
p57_fixture_columns_match is true on all 155 rows. The identity element is asserted vertex-exact and
triangle-exact on every one of the 112 equivariance rows.
What a consumer should take from this, replacing ✗39's note. Bit-exact octahedral equivariance is
available from this crate for all 48 elements on marching_cubes and on marching_cubes+decider
except where an interior ambiguity is reached; for dual_contouring/manifold_dual_contouring on
thin_plate at 33³; and for the six pure axis permutations elsewhere as before. The index buffer still
differs under every non-identity element — elements_triangle_exact on the MC rows is 1 or 2 of 48,
because table.rs picks safe_apex by lowest edge index, which is ✗39's C3 unchanged and unaffected.
Would be shown wrong by: an f32 or f64 straddling pair where edge_offset(b, a) != -edge_offset(a, b)
— which the_offset_is_exactly_antisymmetric_under_the_endpoint_swap sweeps 4,096 of, with a searched
control that at least one pair separates the two forms; a marching_cubes row below 48 of 48 on a
symmetric grid; or a golden hash moving on greedy_quads, which would mean a blocky mesher had acquired
an interpolation.
P-63 — registered for R-061, before the harness: is O-12 finite at 2¹⁸, and does one sweep settle it for Marching Cubes?
O-12 is the oldest open question in the ledger — "is Marching Cubes unconditionally manifold
now?" — and its own text says what would settle it: "an exhaustive search over configurations spanning
more than two cells … or a proof that a cell-local cycle triangulation plus shared face segments cannot
produce a non-manifold vertex." ✗43 found the first counterexample and it was inside one cell. The
question stands because "a vertex whose two face groups sit in different cells would be" a third
mechanism.
The search space is much smaller than it looks, and that is the whole idea. In this crate every
Marching Cubes vertex sits on a grid edge — EDGE_CORNERS is lower-corner-first and the interior
vertex is cell-local after ✗43's per-ring apex. Every face incident to an edge vertex therefore comes
from one of the four cells sharing that grid edge, and those four cells span a 3 × 3 × 2 block of grid
corners: 18 corners, 2¹⁸ = 262,144 sign patterns. Not a sample. The whole space, in seconds.
This is a proof by exhaustion of the vertex-link case for Marching Cubes, and it is the case Chernikov
& Xu's Coq work does not cover: their 2013 IMR proof (10.1007/978-3-319-02335-9_28, "A Computer-Assisted
Proof of Correctness of a Marching Cubes Algorithm", title confirmed at D-020 and the PDF paywalled)
enumerates all 2⁸ single-cube sign configurations "disregarding any perceived symmetry" and proves
cohesion and water-tightness, then composes to a grid via face-local consistency — which is exactly the
argument that does not reach a vertex link.
Each clause's population, derived before the harness:
| clause | fires on | derivation |
|---|---|---|
| C1 | 131,072 patterns per interior rule, 262,144 link walks | the shared edge is the block's central z-edge, cut exactly when its two endpoint corners differ in sign — half of 2¹⁸ |
| C2 | patterns where some cell fans ≥2 rings, reported as fan_patterns |
a zero voids C2 rather than passing it |
| C3 | 128 of 256 cell sign bytes are critical — 120 by a checkerboard 2 × 2 face, 8 by a main-diagonal inside pair or its complement | so a critical cell is reachable on the great majority of patterns and the clause cannot be vacuous |
Which vertices are soundly testable, because the block has a boundary. The shared-edge vertex is the
only edge vertex in the block whose link is complete — every other one has cells missing outside the
block, so a defect there could be an artefact of the truncation, and those are reported as
link_defective_truncated rather than counted against C1. A cell's interior vertex is complete too,
because all of its faces come from that one cell, so it is counted.
C2 is the fixture-can-fail control and it reproduces the defect known to exist, bench-locally and
without editing src/: merging all of one cell's interior apexes into a single vertex is the pre-fix
topology — the same triangles with one shared apex — which is precisely what ✗43's per-ring apex fix
undid. A vertex identification, which is the operation the fix reversed.
C3 is a necessary-condition sweep and the entry must not exceed that. A dual vertex lives at a cell centre and its link involves the cell's 26 neighbours — 4³ = 64 corners, out of reach of an 18-corner block. The full dual sweep at 2²⁷ over a 3 × 3 × 3 block (134,217,728 patterns, an estimated 4–45 minutes single-threaded) is a nightly gate and a separate ticket, deliberately not registered here.
One id note, because the research doc will mislead a reader. The doc's C1 text names ✗49 for this
clause's falsification, written before Phase 23 ran. ✗49 is P-61's falsification (M-372); ids are
assigned when used and never reused, so a C1 failure here takes the next free number.
No golden hash can move — this experiment builds its own 3 × 3 × 2 sign lattice and never touches a
reference field or a src/ path.
Records arm, extractor, interior_rule, patterns, patterns_shared_edge_cut,
shared_edge_vertices, link_defective_shared_edge, link_defective_interior,
link_defective_truncated, worst_link_components, first_defective_pattern, fan_patterns,
critical_cells, critical_patterns, defective_equals_critical, c1_holds, c2_holds, c3_holds,
wall_ms.
💥 ✗50 / M-373 — "MAX_PATCH_TRIANGLES = 24 bounds the trilinear patch": it was a sampled maximum plus two, fan_tunnel's own buffer was already the derived 40, and the smaller one was the one that indexed (D-021, found by R-061's harness)
Believed because: it was measured, and the measurement was pinned by a committed test. The constant's
own doc comment said so: "Twenty-two, reached by a tunnel; a fanned disk tops out at twelve. Measured
exhaustively for the disk path and over 400,000 random cells for the tunnel."
the_worst_case_tunnel_triangle_count_is_pinned asserts worst_tris == 22 over those 400,000 cells and
has passed since it was written. 24 is that 22 with two added for margin.
Falsified by: P-63's harness, on its second run, before P-63 measured anything. An exhaustive sweep
over all 2¹⁸ sign patterns of a 3 × 3 × 2 block with magnitudes in general position reached
marching_cubes/mod.rs:514 — triangles[count] = t into [[u8; 3]; MAX_PATCH_TRIANGLES] — with
count == 24. Index out of bounds, in release, on an ordinary trilinear cell. Not an Error, not a
hole: a panic.
The mechanism is two bounds for one quantity, and the derived one was on the inside. fan_tunnel
buffers its own output in [[u8; 3]; 40], and its body states where 40 comes from — "twelve ring edges at
three triangles each plus a four-triangle closure". So the function could never overflow itself. The
caller's array in mod.rs was sized by MAX_PATCH_TRIANGLES = 24, the sampled figure, and the caller
is what receives every triangle fan_tunnel emits. The two numbers describe the same count and disagreed
by 16.
The reproducer, pinned as a fixture. Pattern 0x06b4a, cell 0, sign byte 0x96 — inside corners
1, 2, 4, 7, which is Marching Cubes case 13, the classic ambiguous one and exactly the case the tunnel
path exists for. Its eight corner values are committed verbatim in
the_case_13_cell_that_overflowed_the_patch_array_is_pinned, unrounded, because the count depends on where
the body saddles fall. It emits 26 triangles.
Two over. The margin was the entire safety argument and it was two triangles wide.
The fix is the derivation, written down once. MAX_PATCH_TRIANGLES is now 40 and carries the
derivation instead of the measurement: fan_tunnel emits at most 3 triangles per ring edge (its
ring_distance == 2 branch is the widest), a cell's contours run along its 12 cut cell edges so the ring
lengths sum to at most 12 however the rings are split, and a single twelve-vertex ring is a disk rather
than an annulus and takes a further 4-triangle closure. 12 × 3 + 4 = 40. fan_tunnel's buffer now
uses the same constant, so there is one bound rather than two that can disagree — which is the actual
repair, because raising 24 to 40 while leaving a second literal in place would rebuild the same defect one
release later.
No golden hash moves and none should. The constant sizes a stack array; it does not change a single
emitted triangle. 710 lib tests green, 216 hashes unchanged,
the_worst_case_tunnel_triangle_count_is_pinned still reads 22 over its 400,000 random cells — which is
the point: that test was never wrong, it was answering a different question. It pins what a sample
reaches. Nothing pinned what the construction can reach.
This is B-006/B-007's rule in a third place — "derive a measurement's bounds from the thing being measured; a hand-written bound is wrong twice before anyone notices" — and the aggravating detail is that the derivation already existed, eleven lines away, in the function the caller calls.
Would be shown wrong by: a trilinear cell whose patch exceeds 40 triangles, which would mean the ring lengths can sum past 12 and the derivation is wrong rather than the constant; or the pinned fixture emitting a number other than 26, which is a change in the emission logic and a finding in its own right.
🔬 M-374 — C1 and C2 HELD: O-12's vertex-link case is settled for Marching Cubes by exhaustion at 2¹⁸, on four independent magnitude draws, with the pre-fix defect reproduced 5,302 times in the same walk; C3 is falsified by its own block, which cannot host a dual link defect (P-63, R-061)
M. cargo bench --bench experiment_p63, docs/experiments/p-63.csv, 11 rows, 21.5 s total, f64.
Eleven arms over the same 3 × 3 × 2 block: 18 corners, 2¹⁸ = 262,144 sign patterns per arm, four cells
sharing the block's central z-edge — asserted to contain it rather than assumed — meshed, welded, and the
incident-face link of every vertex walked for connected components.
| clause | registered | measured |
|---|---|---|
| C1 zero non-manifold vertices over all 262,144 patterns, interior rule off and on | 0 | HELD — 0 on every arm, on four independent magnitude seeds, with 282,084–283,694 interior apexes each |
| C2 the pre-fix single-apex fan produces a non-zero count | > 0 | HELD — 5,863 patterns fanned, 5,302 link defects, worst_link_components 2 |
| C3 the dual family produces a non-zero count equal to the critical census | > 0 and equal | FALSIFIED, and vacuously — 0 defects against 524,288 critical cells, because a dual vertex in this block carries at most 2 faces |
C1 is the result, and it is a proof by exhaustion rather than a sample. Over the whole 18-corner sign
space, on both interior-ambiguity settings and at four independent magnitude draws, not one pattern
produces a shared-edge vertex whose link has more than one component, and not one produces a defective
interior apex either. worst_link_components is 1 on every non-control arm — not "no defects found",
but "no vertex anywhere in 1,048,576 meshings had a split link".
O-12 asked for "an exhaustive search over configurations spanning more than two cells … or a proof that
a cell-local cycle triangulation plus shared face segments cannot produce a non-manifold vertex." This is
the first: the third mechanism O-12 names — a vertex whose two face groups sit in different cells —
does not exist for Marching Cubes. Every face incident to an edge vertex comes from one of the four cells
sharing that edge, those four cells are 18 corners, and 18 corners is 262,144 patterns.
What the sweep is and is not exhaustive over, stated because it is the whole force of the claim. Exhaustive over signs. The magnitude space is continuous and the ring structure a cell produces depends on where its body saddles fall, so magnitudes are sampled — one draw per pattern, from four seeds, reported per seed and never pooled:
| seed | interior apexes | shared-edge defects | interior-apex defects |
|---|---|---|---|
0x00002026 |
282,084 | 0 | 0 |
0x0005EED1 |
283,694 | 0 | 0 |
0x00C0FFEE |
282,670 | 0 | 0 |
0xDEADBEEF |
283,339 | 0 | 0 |
Four draws agreeing is four draws, not a proof over magnitudes. What bounds the residue is that the ring
structure is a function of (case, joined_mask, inner-hexagon presence) — a finite set —
and the_fan_covers_each_ring_once_and_repeats_no_index already sweeps all 16,384 (case, mask) pairs
combinatorially. The two together are much stronger than either; neither alone is the full statement.
C2 is the control that makes C1's zero mean anything, and it fires hard. ✗43's defect was
Contours::fan naming one shared INTERIOR apex for every ring of a cell. Merging all of one cell's
interior apexes back into a single vertex is that topology — same triangles, one shared apex — because a
vertex identification is exactly the operation the per-ring-apex fix reversed. Run over the same sweep:
5,863 of 262,144 patterns have a cell that fans two or more rings, and 5,302 of them produce a
link-defective vertex, at worst_link_components = 2. Two components is M-301's signature and ✗43's
measured shape, to the number.
So the walk can return non-zero, on the one defect known to have existed, 5,302 times, in the same code
path that returns zero for the shipped extractor. M-44's rule is satisfied by demonstration rather than
by argument.
The ±1 arm is a finding about the interior rule, and it is why this harness has two fixtures. With
every corner at ±1 the trilinear's saddles are symmetric too, has_inner_hexagon's strict 0 < x < 1
test rejects, and the interior-ambiguity rule never fires at all: interior_vertices is 0 on both
unit arms against 282,084 on the generic one. So "with the interior rule on" at ±1 is the same arm as
"off" wearing a different name, ✗43's pre-fix fan has no apex to merge, and C2 cannot fire. The first
version of this harness used ±1 and its M-44 control refused to report — correctly.
A second reason
±1is a bad fixture, and it is a classification artefact rather than a null. At±1every crossing lands on a half-integer, so a cycle centroid can land exactly on the sample lattice and the three-way vertex classification — by how many coordinates are integral — mis-files it. That is✗43's own correction (a face vertex has one integral coordinate, an edge vertex two) biting the instrument. C1's verdict is therefore taken from the generic arms, where magnitudes are in general position and the classification is unambiguous; the unit arms are corroboration with this caveat attached.max_incident_facesdiffering between them — 10 and 14 at±1against 13 and 20 generic — is the same degeneracy visible from another angle.
C3 is falsified and the falsification is my own registration's fault, which is the audit's central
finding landing in this phase. The clause asked for a non-zero dual link-defect count equal to the
critical-configuration census. Measured: 0 on surface_nets, dual_contouring and
manifold_dual_contouring, against 524,288 critical cells across 229,492 patterns that carry at least
one. The reason is structural and the scope note said it in advance — a dual vertex lives at a cell centre
and its link involves the cell's 26 neighbours, 4³ = 64 corners — but the registration then derived C3's
population from the critical census rather than from the population of dual vertices with a complete
link, which in this block is empty. The measurement that says so is max_incident_faces: 2 on all
three dual arms. Two faces sharing a vertex cannot be split into two edge-disconnected components while
also being the whole link, so the configuration is unreachable here by construction.
So C3 is vacuous as registered, not merely false, and softening it is not available: experiment.rs
forbids amending a registration after its run. The honest statement is that the 18-corner block settles the
primal case and cannot address the dual family at all, and a valid version of C3 needs the 3 × 3 × 3
block — 2²⁷ = 134,217,728 patterns, the nightly ticket the registration already declined to register. That
is the P-43 → P-44 precedent: record the vacuity, and let a new id carry a fixture that can fail.
Two incidental measurements worth keeping. The table path's cycle centroids are cell-interior
vertices too — interior_vertices is 29,557 with the interior rule off, where the trilinear rule
contributes nothing — so the apex-merge control exercises A-015's construction as well as ✗43's, and
neither produces a split link. And link_defective_truncated is 0 on every arm: even the vertices whose
links are cut off by the block boundary never split, which is not a claim this experiment makes but is a
number a future 3 × 3 × 3 sweep will want to compare against.
Would be shown wrong by: a sign pattern, at any magnitude draw, whose shared-edge or interior vertex
link has two components — which is the third mechanism O-12 asks about and takes the next free ✗ id; or
a magnitude seed on which the interior rule stops firing, which would make that arm's zero vacuous and is
asserted against per seed rather than assumed.
P-69 — registered for R-067, before the harness: does restructuring the sample loop autovectorise, and do all 216 golden hashes survive it?
core::simd is nightly and staying nightly, so the lever is autovectorisation — and the measured prior
says autovectorisation is enough. Wilcox's AArch64/NEON study on 100k f32 samples: scalar 77.67 µs,
hand-written intrinsics 25.78 µs, autovectorised safe Rust 25.54 µs. Safe code matched intrinsics.
The patterns that decide it are shape rather than machinery — struct-of-fields rather than index
arithmetic, pre-slicing once outside the loop so LLVM can prove the bound, and chunks_exact/zip
iterators. dual.rs's sample() pushes into a Vec inside a triple loop, so the bound is re-proved per
element and the store is not a provable contiguous write.
The float caveat cuts the right way, which is why this is registrable at all. The blanket claim that autovectorisation fails on floats is about reductions: LLVM will not reassociate float adds without fast-math, and stable Rust does not expose it. Elementwise float map and zip vectorise fine. This crate's field evaluation is elementwise over independent samples, and its accumulations — active-cell popcounts, vertex counts — are integer. Both halves land on the good side.
Two corrections to the clause's own terms, both established from source before this harness was written — which is the audit's central finding used as a step rather than quoted:
| the doc says | measured from source | |
|---|---|---|
| the fields | C1 names sphere and gyroid |
libm 0.2.16's sqrtf carries a select_implementation on target_feature = "sse2" (and aarch64+neon), so sphere's sqrt(x²+y²+z²) − r can vectorise. sinf and cosf carry no arch selection at all — pure software with argument-reduction branches — so gyroid, which is six of them per sample, cannot, at any loop shape, while libm is the transcendental path |
| the machine | M-20's 4.75 ns/sample falls below 2.4, on the M5 |
the M5 is reachable and contended: Spotlight, WindowServer, Messages and loginwindow at ~76% of a core combined, load 1.65–1.87, 13 days up. That is exactly the contention M-005 is blocked on, and M-005 exists because a memory-bound single-threaded timing taken beside a persistent competitor is not a figure |
So C1 is registered as the doc states it — sphere and gyroid — with gyroid's failure predicted
here and its cause named, rather than softened to sphere alone. And the threshold is re-derived from
this repository's own committed baseline on this host:
docs/measurements/resolution_sweep-ryzen9-5900x.csv fits a marginal 13.1892 ns/sample over 9 rows
from 16³ to 256³ for marching_cubes/f32/sphere, so 2× is below 6.5946 ns/sample.
Two method rules bind the measurement and both are in the registration. M-281 — a millisecond is a
property of the binary — so the ratio is measured within one binary and one run, both loop shapes
compiled into the harness. M-280 — a nanosecond is not a unit on a governed CPU — so every row carries
cycles_per_sample and ghz.
C2 is the gate and it is the exact opposite of P-61's C2. All 216 golden hashes unchanged. IEEE
elementwise operations are exact per lane, so a hash movement means LLVM reassociated something and the
change is rejected rather than rebaselined: here a movement is a defect, not a cost. Its population is
216 rows, and the instrument is proven able to report the bad news rather than assumed to be — P-61
moved 135 of these same 216 four commits ago.
C3 survives the machine change unaltered. The doc's reason is that NEON is 2-wide at f64 against
4-wide at f32; on this host's AVX2 it is 4-wide against 8-wide. Same factor of two, same clause.
Verification requirement, stated at registration. cargo-show-asm output for the monomorphised f32
instance goes in the ticket. The crate is generic over Real; LLVM vectorises the monomorphised instance or
it does not, and a Criterion delta alone cannot distinguish a vectorised loop from a lucky one. The whole
experiment is void if the dump shows no vector instruction in the f32 sphere instance while C1 reports
a speedup, because then the speedup is the loop's bookkeeping rather than its arithmetic.
Records arm, field, scalar, samples_per_axis, samples, loop_shape, ns_per_sample,
cycles_per_sample, ghz, speedup_vs_push, marginal_ns_per_sample,
baseline_marginal_ns_per_sample, bit_identical_to_push, golden_hashes_unchanged,
vectorisable_body, c1_speedup_f32, c1_holds, c2_holds, c3_f64_over_f32_gain, c3_holds,
machine, wall_ms.
💥 ✗51 / M-375 — C1 FALSIFIED, C2 HELD, C3 VACUOUS: the prescribed loop shape is a 3–7% regression, %ymm is zero in every monomorphisation, and C1's 2× was arithmetically unreachable from a term that is 11.6% of the cost it was stated in (P-69, R-067)
M. cargo bench --bench experiment_p69, docs/experiments/p-69.csv, 58 rows — 48 loop rows (three
fields × two scalars × four resolutions × two loop shapes), 6 fitted marginals, 4 extraction rows — plus
scripts/p69_asm.sh over the bench's own codegen unit. Both loop shapes compiled into one binary per
M-281; cycles_per_sample and ghz on every row per M-280, with the run asserting the kernel did not
multiplex a counter.
| clause | registered | measured |
|---|---|---|
C1 ≥ 2× on the marginal f32 cost |
≥ 2.0 | FALSIFIED — 0.9305 sphere, 0.9735 gyroid, 0.9425 box_exact. A regression on all three |
| C2 all 216 golden hashes unchanged | 0 moved | HELD — 0 of 168 checked in the harness, and golden_hashes_are_unchanged green on all 216 |
C3 the f64 gain is at most half the f32 gain |
≤ 0.5 | VACUOUS — its denominator is the f32 gain and C1 left none |
The mechanism is read from the machine code, not inferred from a stopwatch — which is what the
registration required and the reason it required it. total %ymm across all eleven monomorphisations
of both loops is 0:
| field | shape | scalar | lines | %ymm |
packed | scalar ops |
|---|---|---|---|---|---|---|
sphere |
push | f32 | 204 | 0 | 4 | 25 |
sphere |
row | f32 | 314 | 0 | 6 | 27 |
box_exact |
push | f32 | 201 | 0 | 10 | 25 |
box_exact |
row | f32 | 277 | 0 | 9 | 27 |
gyroid |
push | f64 | 209 | 0 | 4 | 28 |
gyroid |
row | f64 | 299 | 0 | 4 | 27 |
Not one 256-bit register, at either shape, on any field. The packed column is not evidence of the
opposite: xorps and andps are the ordinary way to manipulate a sign bit on a single scalar, which is
why the script's discriminator is %ymm and not the packed count. So the loop shape the
autovectorisation literature prescribes — buffer sized once, one slice per row, bound hoisted,
iter_mut().enumerate() — did not cause LLVM to widen anything here, and the small regression is the
resize's zeroing pass being paid for a bound check that was already free.
And the field prediction held exactly, which is the one part of this that went to plan. It was
registered from libm 0.2.16's source before the harness existed: sqrtf carries a
select_implementation on target_feature = "sse2", sinf and cosf carry none. Measured per-sample
cost, f32: sphere 1.23 ns, box_exact 2.68 ns, gyroid 17.79 ns. A 14.5× spread from
the field body alone, and the vectorisable_body column is an input to the experiment rather than an
outcome of it.
The number that should have killed C1 at registration, and it was available. C1 is stated in the
marginal extraction cost — M-20's 4.75 ns/sample falling below 2.4. Measured here, the sample loop is
1.23 ns/sample against an extraction marginal of 10.68 ns/sample: the loop is 11.6% of the
quantity the clause is denominated in. Halving it gives
1 / (1 − 0.116/2) = 1.061×
1.06×, not 2×. So C1 was arithmetically unreachable however well the loop vectorised, and Amdahl —
not LLVM — is what refuted it. I registered the field population and the machine correctly and did
not compute the share, which is the audit's own central finding missed a second time in the phase that
exists to apply it. The share was measurable in advance from stage_breakdown.csv and one timing.
Part 5 earns a row from this and it is not the one the phase already added: a clause stated as a ratio of a total must name the share of that total it can move. Naming the rows a clause can fire on is not sufficient when the clause is a fraction — the population was non-empty and the clause was still impossible.
C2 held and its instrument is proven, not assumed. 0 of 168 rows moved in the harness and all 216 in
golden_hashes_are_unchanged. The hoisting is bit-identical by construction — a loop invariant moved out
is the same rounding — and the gate's ability to report the other answer is on record four commits back:
P-61 moved 135 of these same 216. So this zero is a zero from a gate that has been seen to fire.
C3 is vacuous rather than false, and the harness says so in as many letters. "The f64 gain is at
most half the f32 gain" divides by f32_gain − 1; with the f32 gain at 0.93 there is no denominator.
Reporting NaN ≤ 0.5 as FALSIFIED would be a claim the run cannot support, so c3_holds is a three-state
column and reads vacuous. This is a clause made unfirable by another clause's failure, which is not
knowable at registration and is a different shape from an empty population.
The decision, and it is a decision rather than a result (E×6). The loop shape is reverted — it
costs 3–7% and buys nothing measurable. The sharing is kept: there were three copies of this loop,
marching_cubes/mod.rs:240, dual.rs:356 and marching_tetrahedra.rs:157, differing only in whether
rows carry padding, and three copies of a loop is a one-path defect whatever the loop's shape. sdf::sample_grid
is now the single definition with the original arithmetic, so the 216 hashes are unchanged either way.
Finding the three copies is the durable half of this experiment and it was not in any clause.
One number deliberately not claimed. The extraction marginal measures 10.68 ns/sample against the
committed resolution_sweep-ryzen9-5900x.csv fit of 13.1892. That is a different binary, a different
run and a narrower size range (33³–129³ against 16³–256³), and M-281 says a millisecond is a property of
the binary. It is reported as a column and is not a 1.24× improvement.
Would be shown wrong by: a %ymm appearing in a monomorphised sample loop on this target, which would
mean the widening is available and something else blocked it; a gyroid speedup at or above 2×, which
would be a finding about libm rather than about this loop; or a golden hash moving, which under C2 is a
veto and not a measurement.
P-71 — registered for R-069, before the harness: is the 83% a blocking round-trip, and can both targets avoid it?
M-167 is the largest single number this project owns about its own GPU path: synchronisation was
83% of an extraction. M-159 localised it — the last four bytes cost 0.033 ms to move and 0.375 ms
to wait for, because poll(Wait) with no submission index drains every dispatch queued before it — and
M-160 showed what removing it buys: CPU time flat at ~0.17 ms from 33³ to 129³.
What wgpu 29 gives splits the two targets, and that split is why this is one experiment rather than
two. PollType::Poll is "check the device for a single time without blocking"; PollType::Wait is
"block until the given submission has completed execution". And verbatim from the docs: "On WebGPU,
this has no effect. Callbacks are invoked from the window event loop." So native Bevy has a real CPU
stall to design away and the web build has no blocking primitive at all — meaning any code shaped
around Wait is native-only scaffolding, and the restructuring must not become a #[cfg] fork, for the
same one-path reason the libm justification already gives. TIMESTAMP_QUERY is in FeaturesWebGPU
(V-48) and behaves identically on both targets, which is why C1 can be stated for both.
Two of the three mechanisms already exist in the tree, so this is partly a measurement of shipped code
rather than a build. extract_buffers waits once, for the four bytes of the triangle count.
extract_indirect waits not at all — it sizes the geometry from a budget and turns the total into
indirect draw arguments on the device. C2 is therefore the difference between two shipped entry points,
measured in one binary and one run.
Each clause's population, and C1's was probed on this host before this was written:
| clause | fires on | established |
|---|---|---|
| C1 | the adapter must advertise the feature | NVIDIA RTX 3090 / Vulkan, and TIMESTAMP_QUERY, TIMESTAMP_QUERY_INSIDE_PASSES and TIMESTAMP_QUERY_INSIDE_ENCODERS are all three true. The instrument exists on the machine the numbers will come from |
| C2 | every resolution both entry points accept | both already ship; the comparison is within one binary and one run (M-281) |
| C3 | exactly the rows M-124's sweep has, re-run with the ring |
the only genuinely new capability here |
C1's instrument is not currently reachable, and enabling it is a registered src/ change.
isomesh_gpu::headless::Gpu requests Features::empty(), and ExtractTimings' own doc says in as many
words that timestamp attribution "need[s] a device feature this crate does not request". The change is
shaped as a capability check that refuses loudly on an adapter without the feature — GPU-007's
pattern — rather than a fallback that quietly reports CPU-side numbers under a GPU-side column name.
C2's denominator is stated rather than assumed. "The measured synchronisation" is the wait component
C1 attributes, not the whole extraction. If C1 finds map-wait is not the largest component then C2's
own denominator is smaller than M-167 suggests, and the entry must say so rather than quoting 83% into a
percentage of something else. That is ✗41's chained-ratio defect anticipated instead of repeated.
A design question that is the owner's, not the harness's, and is registered as a question. C3 costs one to two frames of latency on collision. For a voxel game that is invisible; for a CAD tool it is a decision. The registration records the question and the entry must surface it rather than pick.
Void conditions, asserted rather than reported. The experiment is void if the timestamp period reads zero or if a resolved query set comes back monotonically non-increasing, because then the attribution is a column that was named and not measured.
Records arm, entry_point, samples_per_axis, cells, triangles, wall_ms, submit_ms,
execute_ms, map_wait_ms, copy_ms, largest_component, synchronisation_ms,
synchronisation_share, synchronisation_removed_share, timestamp_feature, timestamp_period_ns,
amortised_ms_per_frame, budget_chunks, within_one_chunk, ring_frames_delay, c1_holds, c2_holds,
c3_holds, adapter.
💥 ✗52 / M-376 — C1 and C2 FALSIFIED, C3 FALSIFIED at 5 of 24 cells: the 83% reproduces at 87.0% and M-160's flat 0.17 ms reproduces at 0.15 ms, but the biggest piece is the geometry copy and not the count wait — so extract_indirect removes 32%, not 60%; and the budgeted pass overshoots by 1.07–1.16 chunks at the two smallest budgets, which is a pass's first chunk and not the queue (P-71, R-069)
M. cargo bench --bench experiment_p71, docs/experiments/p-71.csv, 32 rows, f32, NVIDIA
GeForce RTX 3090 / Vulkan. Three arms: attribution (GPU-side spans from TIMESTAMP_QUERY against CPU
wall time, four resolutions), removal (extract_buffers against extract_indirect, one binary,
M-281), budget (DeferredGeometry under DirtySet::mesh_within_budget on M-124's own fixture, 24
cells). Median of 7 per attribution measurement. Timestamp period 1.0000 ns, two spans per extraction,
both asserted strictly positive.
Every number below is read from the committed
docs/experiments/p-71.csv, at2fc75b4, which is an ancestor of HEAD. The entry did not read that way for two commits and this is the correction. C1 and C2 were first measured atd3b79e7and this entry quoted that run —copy0.7075,map-wait0.3177,synchronisation_removed_share0.3098, a 0.31–0.45 band — while its own M. line named a file that had since been rewritten by the C3 amendment's run and contains none of them. Worse, the note that declared the two-run split claimed the amendment "reproduced them to within 0.5%", and its own two cited numbers refute it:copy0.6663 against 0.7075 is −5.83% andsynchronisation_removed_share0.3239 against 0.3098 is +4.55%. Both runs are the same rig, the same binary and the same fixture, so the spread is run-to-run variation on a governed CPU and a shared GPU (M-280,M-281) — which is the honest description and is an order of magnitude wider than the claim. Thed3b79e7figures are not reproduced here: an entry that quotes numbers no committed file contains is✗35's defect, and the fix is to quote the file, not to explain the gap. The verdicts are unchanged — both clauses are falsified on either run, and by margins far larger than 6%.
| clause | registered | measured |
|---|---|---|
| C1 the largest component is map-wait, not execute | map-wait | FALSIFIED — it is copy. 0.6663 ms against map-wait's 0.3191 and execute's 0.3175 at 129³ |
| C2 indirect draw args remove ≥ 60% of the synchronisation | ≥ 0.60 | FALSIFIED — 0.3239 at 129³, and 0.2967–0.3297 across the range |
| C3 the queue holds the amortised cost within one chunk across a 320× range | M-124's rows |
FALSIFIED — 19 of 24 cells hold; the 5 outside are 25 µs and 50 µs, overshooting by 1.07–1.16 chunks against a bar of 1.000 |
Two prior findings reproduce on the way, which is what makes the falsifications readable.
| prior | says | measured here |
|---|---|---|
M-167 |
synchronisation was 83% of an extraction | 87.0% — 0.9854 ms of a 1.1331 ms extraction at 129³ |
M-160 |
removing the wait leaves CPU time flat at ~0.17 ms from 33³ to 129³ | 0.1359 / 0.1619 / 0.1517 / 0.1477 ms across 33³–129³ — flat at ~0.15 ms over a 64× cell range |
So the phenomenon is exactly where M-167 and M-160 left it. What is wrong is the decomposition the
registration guessed.
The attribution, and it is the point of the experiment:
| n | indirect | buffers | extract | execute (GPU) | submit | map-wait | copy | largest |
|---|---|---|---|---|---|---|---|---|
| 33 | 0.1359 | 0.1949 | 0.3149 | 0.0450 | 0.0910 | 0.0590 | 0.1200 | copy |
| 65 | 0.1619 | 0.2640 | 0.4966 | 0.0924 | 0.0696 | 0.1020 | 0.2327 | copy |
| 97 | 0.1517 | 0.3334 | 0.7643 | 0.1563 | 0.0000 | 0.1818 | 0.4309 | copy |
| 129 | 0.1477 | 0.4669 | 1.1331 | 0.3175 | 0.0000 | 0.3191 | 0.6663 | copy |
copy is 59% of the whole extraction at 129³ and 68% of its synchronisation. The count read-back —
the four bytes M-159 measured at 0.375 ms of stall — is real and is 0.3191 ms, the second largest
piece. execute is 0.3175 ms and never leads at any resolution, so M-167's "the arithmetic never moved
and was never the point" survives and needs no re-tiering: C1's falsifier was execute leading, and
execute does not lead.
submitreads 0.0000 at 129³ and that is two clocks, not a measurement of nothing. It is computed asindirect_ms − execute_ms, andexecuteis a GPU-side span whileindirectis CPU wall time for a path that submits and does not wait. The GPU keeps working after the CPU returns, so the span can exceed the wall time and the difference is clamped at zero rather than reported negative. What the row does say is that CPU recording is at most ~0.09 ms and falls as the grid grows — which isM-160's flatness from the other side.
C2 is falsified for a reason that changes what the direction is worth, and it is not a smaller version
of the registered claim. extract_indirect removes the count wait entirely — that is 0.3191 ms of
0.9854, i.e. 32%. It cannot remove the geometry copy, because it removes it by not delivering the
geometry to the CPU at all: the totals stay in device memory and become indirect draw arguments. So:
- For a consumer that only draws,
extract_indirectremoves 100% of the synchronisation it needs to remove, andM-149's 6.7% is the whole remaining prize. The clause's 60% is the wrong bar for it. - For a consumer that needs the bytes — collider generation,
M-116's convex decomposition — the copy is unavoidable, and 60% was never available from indirect draw arguments. What is available is amortising it, which is C3's ring.
The deferred read-back works, and this is the half of the experiment that ships a capability. The
original arm measured it as a bench-local depth-2 ring over read_bytes_many_deferred, swept over
resolution — PollType::Poll as the readiness check, one call site for both targets and no #[cfg], which
is why the shape is legal under the one-path rule at all. Those rows are superseded and historical; they
are in this CSV's git history at d3b79e7 and not in the file now, because StagingRing was deleted when
DeferredGeometry shipped and two queues in one tree is the one-path defect:
| n | frames | depth | consumed | amortised ms/frame | not-ready | drain frames |
|---|---|---|---|---|---|---|
| 33 | 120 | 2 | 120 | 0.3116 | 0 | 85 |
| 65 | 120 | 2 | 120 | 0.4325 | 0 | 127 |
| 97 | 120 | 2 | 120 | 0.6059 | 0 | 31 |
| 129 | 120 | 2 | 120 | 0.9158 | 0 | 0 |
120 of 120 consumed and zero not-ready at every resolution: at depth 2 the read-back is always ready when its slot comes round, so the mechanism converts a 0.6663 ms blocking copy into a per-frame cost with no stall. That is a real result about a real mechanism.
But it was not C3, and the entry said so rather than claiming it. C3 is registered against "exactly
the rows M-124 has", and M-124 is a budget sweep — 288 chunks under
DirtySet::mesh_within_budget, budget from 25 µs to 8 ms, 2,360 frames each — while that arm swept
resolution over one field. Calling it HELD or FALSIFIED would have been a claim about a different
experiment, so c3_holds read not_measured on all twelve rows, the same shape as P-63's C3: a
registered population the harness did not deliver.
AMENDED 2026-08-27 (R-071, 2fc75b4). C3 is measured, and it is FALSIFIED by 14% at two of eight
budgets. Two things had to land first, and only one was in the bench: DeferredGeometry is now a public
type in isomesh-gpu, because the clause is about the queue under a scheduler and a queue that exists
only as bench scaffolding cannot be put under one. The fixture is M-124's, read from
bevy_isomesh/examples/game_budget.rs:58-74 rather than chosen — 16 cells a chunk, 0.25 units a cell,
12 × 2 × 12 = 288 chunks, its eight budgets, its 2,360 frames, and its Blobs field, because the field
decides the per-chunk triangle count and therefore the size of the read-back the queue carries.
ring_frames_delay is swept at 1, 2 and 4 frames, so 24 cells.
| budget | delay 1 | delay 2 | delay 4 | chunks a pass | overshoot, chunks |
|---|---|---|---|---|---|
| 25 µs | 0.3355 | 0.3515 | 0.3542 | 1.00 | 1.093 / 1.150 / 1.159 |
| 50 µs | 0.3309 | 0.3545 | 0.3562 | 1.00 | 0.989 / 1.072 / 1.078 |
| 200 µs | 0.3324 | 0.3491 | 0.3517 | 1.00 | 0.466 / 0.525 / 0.534 |
| 500 µs | 0.6319 | 0.6562 | 0.6558 | 1.99–2.02 | 0.464 / 0.550 / 0.548 |
| 1 ms | 1.1663 | 1.1825 | 1.1848 | 3.84 | 0.585 / 0.642 / 0.651 |
| 2 ms | 2.1909 | 2.1732 | 2.1953 | 6.95–7.12 | 0.672 / 0.610 / 0.687 |
| 4 ms | 4.2815 | 4.2550 | 4.2809 | 13.8–14.1 | 0.991 / 0.898 / 0.989 |
| 8 ms | 8.1820 | 8.1924 | 8.1972 | 27.0 | 0.641 / 0.677 / 0.694 |
Mean milliseconds per budgeted pass. Every budget from 200 µs up holds at every delay; the five bolded cells are the falsification, and the whole band is 0.464 to 1.159 chunks against a bar of 1.000.
The overshoot is attributed, and the obvious suspect was wrong. mesh_within_budget computes a
squared distance per chunk and sorts all 288, every call, before meshing anything — the natural explanation
for a one-chunk pass costing more than one chunk. Measured with a no-op mesh closure over the same set:
0.0073 ms, 2.6% of the bar. It is not the overshoot. What is: a pass that meshes one chunk spends
0.3462 ms on it, a pass that meshes more than ten spends 0.3049 ms each — a 1.14× premium on a
pass's first chunk. That is M-159's mechanism at pass granularity. extract_buffers waits with
poll(Wait) and no submission index, which drains every dispatch queued before it, so the first chunk of a
pass pays for the previous pass's outstanding deferred copies and every later chunk does not. A budget below
one chunk's cost is all first chunk; a 27-chunk pass amortises it 27 ways.
So the registered falsifier's stated meaning did not happen, and that is the finding. C3's falsifier
is "the amortised cost drifting outside one chunk of the budget, which means the ring traded a stall for
a queue". A queue trading a stall would show as no_room_frames > 0, or as the cost drifting away from
the budget as the delay deepens. no_room_frames is 0 in all 24 cells, and the overshoot band has no
trend in the delay at all — 0.464–1.093 at delay 1, 0.525–1.150 at delay 2, 0.534–1.159 at delay 4. The
queue is not what missed the bar; the scheduler's own first-chunk wait is. Exactly C1's shape in this same
entry, where the falsifier was execute leading and execute led nowhere.
Read the ratio, not the count. The bar is 1.000 and it is where mesh_within_budget's own doc puts
the never-livelock price — "overshooting by at most one chunk is the price" — so cells sit on the boundary
and the count is unstable: three runs of this fixture put 4, 9 and 5 cells outside while the band stayed
0.46–1.16. overshoot_chunks is a column in the CSV for that reason, and it is what this entry quotes.
The owner's question is now a number. The registration says the queue costs "one to two frames of collision latency" and declined to pick. Measured, per collected read-back: mean 1.41 frames, worst 2, identical at delays of 1, 2 and 4. The sentence was right, and it is no longer an assumption.
Three fixture defects in the new arm, each found by a control rather than by review.
ring_frames_delayis a frames column, not a slots column. At a flat capacity of 2 the queue held one un-ready slot at every drain — a read-back submitted last in a pass is microseconds old when the next frame looks at it — so the pass meshed exactly one chunk at every budget from 25 µs to 8 ms andc3_holdswould have been a measurement ofbudget / chunk_msagainst the number 2. Slots are now derived from the delay and the budget, and the control that refuses the old shape isno_room_frames == 0.- The tolerance has to be measured under the sweep's own conditions. A calibration that drained between chunks read 0.2754 ms against a sweep spending 0.32 ms on the same chunk — a 16% underestimate on C3's own bar. It now submits all 288 back to back, with no intervening collection.
- Tail-drain collections are excluded from the latency statistics. A poll after the last frame is not a frame, and folding them in reported a worst-case collision latency of 29–34 frames the running scheduler never paid. The real number is 2.
Three fixture defects in the original arm, all caught by this harness's own controls rather than by review.
extract_indirectmeasured 7.3 ms flat at every resolution on the first run — slower than the wait it removes. It sizes its geometry buffers from the budget and creates them per call, so a 4,000,000-triangle budget allocates 288 MB per extraction and the arm was timingcreate_buffer. The budget is now twice the measured count, which is what a game sizing from the previous frame would use.- The ring consumed 1 read-back in 120 frames and reported 0.0004 ms — the cost of an empty loop
wearing the ring's name.
Readback::readypolls withPollType::Poll, a single non-blocking check, and with nothing else submitting the queue never advanced.ticknow takes the frame's own GPU work as a closure, and the control isconsumed > FRAMES/2rather than> 0. StageTimestampswas notSync—CellandRefCellcompile insideisomesh-gpuand breakbevy_isomesh, which holds aMarchingCubesGpuas a BevyResource. Three examples failed to type-check.bevy: check --all-targetsis what caught it, which isM-293's step earning its keep on the exact class it was added for.
The design question the registration deferred is answered above — mean 1.41 frames, worst 2 — and the
drain tail that the original arm made the case for choosing a depth against is superseded by it. That tail
was 0 to 127 frames depending on resolution and not monotone in the grid (127 at 65³, 0 at 129³), which
was unexplained; the amendment's accounting shows what half of it was, because a poll after the last frame
was being counted as a frame of latency. Whether any of the residue is real is now a question about
Readback's completion time and not about the queue's depth.
Would be shown wrong by: execute leading at any resolution, which would re-tier M-167; a
consumer-visible path where indirect draw arguments remove the geometry copy as well as the count wait; a
no_room_frames above zero, which would mean the queue rather than the clock bound a pass and the C3 cells
measure the wrong thing; or a budget at or above 200 µs overshooting past one chunk, which is where the
first-chunk premium stops being able to explain the miss.
P-72 — registered for R-070, before the harness exists
The cubic knob is the chunk, and the source is what settled that. GVDB's ⟨3,3,3,B⟩ leaf-brick sweep is
a 256× spread from one parameter at fixed resolution — 616,444 bricks in 461 ms against 2,036 in
1.8 ms. P-40 picked 64 cells per word and never asked. But build_inside_bits packs those 64 along
x only, a flat per-row word array with no block layer, so there is no cubic granularity inside the
bitmap to sweep: u8/u16/u32/u64 would sweep a packing width in one dimension, not GVDB's knob.
The unit GVDB's knob actually maps to is the one that is rebuilt on an edit — mark_edit marks chunks,
DirtySet holds chunks, mesh_dirty re-meshes chunks — and C1 is denominated in edit-plus-remesh
time, which only the chunk path has. Registering the wrong structure would have made the experiment
unfalsifiable in the x35 way: a sweep of something whose spread no clause was about.
The tradeoff is arithmetic, computed before the harness, which is why an optimum should exist. Total
world cells held fixed at 128³, so a chunk of c cells re-samples its shared corner planes:
((c+1)/c)³ of the field evaluations — 1.4238× at c = 8, 1.1953 at 16, 1.0968 at 32, 1.0473 at
c = 64 — against a finer dirty set re-meshing fewer cells per edit. Small chunks pay in duplicated
samples and save in wasted remesh. C1's 2× has to come out of those two curves crossing.
| clause | prediction | falsified by |
|---|---|---|
| C1 | a pronounced optimum: best and worst edit-plus-remesh differ by ≥ 2× | a flat curve — a genuine null meaning 64 was already a plateau, and the expected outcome on smooth fields |
| C2 | the optimum is field-dependent, differing between gyroid (surface everywhere) and fbm_terrain (surface on a sheet) |
one granularity winning on both, making it a constant rather than a parameter |
| C3 | the spread is below 4×, far under GVDB's 256× | above 4×, which is the more valuable outcome and says chunk size is not the damping factor it looks like |
No golden hash moves and that is asserted, not hoped: this varies only how a fixed cell count is partitioned. A partition that changed the mesh would be a seam defect.
🔬 M-377 — C1 HELD at 51×, C2 and C3 FALSIFIED: the optimum is interior at 4³ on both fields, and the spread is 12.7× larger than the registered ceiling — so chunk size is not the damping factor GVDB's 2048³ regime made it look like (P-72, R-070)
M. cargo bench --bench experiment_p72, docs/experiments/p-72.csv, 12 rows, f64, Zen 3.
Chunk granularity swept 2³–64³ at a fixed 128³ world cell count, on an eleven-edit dig trace, on
gyroid (surface everywhere) and fbm_terrain (surface on a sheet). Median of three traces per arm; the
initial full build runs once and is not timed.
RE-RUN 2026-08-27 for C4 of the audit, and every timing below is the new file's. The
spreadcolumn carriedgyroid's value on thefbm_terrainrows — a global maximum under a name that reads per-field, sitting besidebest_chunk_cellsandworst_chunk_cellswhich were always looked up per field. Sofbm_terrain's own 47.2× was derivable from the file and not recorded in it, and this entry quoted a 47.19× that appeared in no column.spreadis now per field andspread_max_over_fieldscarries the quantity C1 and C3 are denominated in. Fixing a column means re-running, and re-running means re-quoting (✗35,✗52): the timings here are the 2026-08-27 re-run's at5f1f4b3, not the2b470c8run's. Every integer reproduced exactly —dirty_chunks_total1,501 / 396 / 108 / 51 / 35 / 31 and 1,456 / 376 / 102 / 57 / 43 / 29,remeshed_cells_total,sample_duplication, all three vertex columns and bothdistinct_surface_points— which isM-279's rule satisfied: the new run agrees with the old one on everything that is not a clock. Every timing moved by under 1.5%, and the two spreads by 0.7%.
| clause | registered | measured |
|---|---|---|
| C1 pronounced optimum, best-to-worst ≥ 2× | ≥ 2× | HELD — 50.69× on gyroid, 47.21× on fbm_terrain, and the optimum is interior |
| C2 the optimum is field-dependent | differs between the two fields | FALSIFIED — 4³ wins on both |
| C3 the spread is below 4× | < 4× | FALSIFIED — 50.69×, which is 12.7× the ceiling |
The curve, and the reason it needed extending below the registered range:
| chunk | chunks | grid dup | dirty remeshes | mark ms | remesh ms | total ms | ms/edit | raw verts |
|---|---|---|---|---|---|---|---|---|
gyroid |
||||||||
| 2³ | 262,144 | 3.3750× | 1,501 | 5.01 | 4.61 | 9.63 | 0.875 | 117,490 |
| 4³ | 32,768 | 1.9531× | 396 | 4.02 | 4.59 | 8.61 | 0.783 | 81,548 |
| 8³ | 4,096 | 1.4238× | 108 | 3.80 | 5.76 | 9.56 | 0.869 | 66,066 |
| 16³ | 512 | 1.1995× | 51 | 3.72 | 15.30 | 19.02 | 1.729 | 58,884 |
| 32³ | 64 | 1.0967× | 35 | 3.68 | 64.10 | 67.78 | 6.162 | 55,596 |
| 64³ | 8 | 1.0476× | 31 | 3.67 | 432.73 | 436.40 | 39.673 | 53,788 |
fbm_terrain |
||||||||
| 2³ | 262,144 | 3.3750× | 1,456 | 14.85 | 16.18 | 31.03 | 2.821 | 76,344 |
| 4³ | 32,768 | 1.9531× | 376 | 13.85 | 15.84 | 29.69 | 2.699 | 53,023 |
| 8³ | 4,096 | 1.4238× | 102 | 13.64 | 21.02 | 34.66 | 3.151 | 42,894 |
| 16³ | 512 | 1.1995× | 57 | 13.54 | 60.94 | 74.48 | 6.771 | 38,292 |
| 32³ | 64 | 1.0967× | 43 | 13.54 | 287.97 | 301.50 | 27.409 | 36,264 |
| 64³ | 8 | 1.0476× | 29 | 13.52 | 1388.13 | 1401.65 | 127.423 | 35,012 |
The registered 8³–64³ range gives a monotone curve whose minimum sits at the boundary, and a boundary
minimum is not C1's "pronounced optimum". That distinction is the reason 2 and 4 were added: the
sample-duplication penalty ((c+1)/c)³ is 3.3750 at c = 2 against 1.4238 at c = 8, so if the two
curves cross anywhere they cross below 8. They do. 4³ beats 2³ by 10.6% on gyroid and 4.3% on
fbm_terrain, and beats 8³ by 10.0% and 14.3%. Had the sweep stopped where it was registered, the entry
would have reported the smallest tested granularity as the answer and been wrong about the shape.
Where the 51× comes from, and it is one number: mark_ms is flat — 3.67 to 5.01 on gyroid, 13.52
to 14.85 on fbm_terrain, because mark_edit scans the same world region whatever the partition.
Everything is remesh_ms, and remesh is dirty_chunks × chunk_cells³: at 64³ the trace re-meshes
31 × 262,144 = 8,126,464 cells, at 4³ it re-meshes 396 × 64 = 25,344. That is 321× fewer cells
for the same eleven edits, and it lands as 432.73 ms against 4.59.
C2's falsification is the interesting one. The registration expected gyroid's everywhere-surface and
fbm_terrain's sheet to want different granularities, and they do not — 4³ wins on both. What differs is
the level, not the optimum: fbm_terrain's trace costs 3.4× gyroid's at the optimum (29.69 against
8.61 ms), almost all of it in mark_ms (13.85 against 4.02), which is FbmTerrain's per-sample cost and
not a granularity property at all. So over 2³–64³ the granularity optimum is a constant of this
extractor, and the field decides only how much the whole trace costs.
C3 is falsified by 12.7× and the registration named that as the more valuable outcome. The prediction was that the chunk-size regime damps GVDB's 256× to under 4×, on the grounds that a chunk is far smaller than a 2048³ SPH volume. It does not damp it: 51× from one knob, on a 128³ world, in an extractor with no tree at all. The mechanism transfers more strongly than the magnitude argument suggested because the cost here is re-meshing a whole brick to service a local edit, which does not care how big the volume is — only how big the brick is.
A granularity cost the registration did not name, recorded because the identity control found it:
raw_verts / distinct_surface_points on gyroid, against 53,110 distinct surface points that every
one of the six partitions agrees on exactly: 2.2122× at 2³, 1.5355 at 4³, 1.2439 at 8³, 1.1087 at 16³,
1.0468 at 32³, 1.0128× at 64³. Chunk-wise extraction emits coincident vertices on every shared chunk
face (A-015, M-220), so the 4³ optimum carries 51.6% more vertex data than 64³ for the same
surface — 81,548 against 53,788. weld closes them, and this is the number a consumer paying for GPU
upload should weigh against the 51× edit win. It is also the identity control's own corroboration: six
partitions, six different raw counts, one distinct-point count.
Four fixture defects, all caught by this harness's own controls rather than by review.
- The identity control compared raw per-chunk vertex lists and fired instantly — 73,032 at 8³ against
65,256 at 16³. Correct numbers, wrong question: a finer partition must emit more boundary duplicates.
And the deduplicated bit patterns cannot be compared either, because a chunk computes a corner as
origin + cell_size · iwith its ownoriginand its owni, andM-32already measured that disagreement at one ulp — so bit equality across partitions would fail on correct code for a reason this ledger knows. The control is now the set of surface points quantised tocell_size × 1e-6: four orders finer than any real surface movement, four orders coarser than an ulp near 4.0 (≈ 8.9e-16). - The duplication control asserted
((c+1)/c)³against total field calls and fired at 1.627144 against 1.423828. The gap is a second consumer of the field the registration did not name:edge_positioncallsunit_gradientper vertex. The control is now a two-term model —chunks × (c+1)³ + stencil × vertices— which asserts the grid term exactly and derives the stencil from the remainder. It comes back 6 on every one of the twelve arms, which is a stronger statement than asserting 6 would have been. - The dig path missed the surface. A path through the world centre missed
fbm_terrain's sheet entirely; a path at one probed height then missedgyroid's surface everywhere except the probe's ownx, because the gyroid undulates inyfaster than a 3-cell brush is wide. The height is now probed per edit at that edit's ownx— which is also what a player does. - The edit box assumed the layout's origin was zero.
((world − radius) / cell_size).floor()was right until the world was centred on the fields' own domain, after whichmark_editscanned a region 64 cells away from the brush. Throughlayout.cell_ofnow, which is the only thing that knows.
All four surfaced as the same assertion: VOID: chunk N marked no dirty chunk in 11 edits. That is
M-44's rule doing exactly its job four times in one harness — a zero that could not have been non-zero
is not a measurement, and the instrument said so instead of printing a fast time for doing nothing.
Would be shown wrong by: an optimum below 2³ — the curve is rising at 2³ on both fields, so 1³ should
be worse still, but it is untested; a field whose optimum is not 4³, which would restore C2; or a
mark_ms that scales with the partition, which would mean mark_edit is doing per-chunk work this sweep
did not see.
P-62 — registered for R-060, before the harness exists
The predicate is already in the tree, and reading that before registering changed what the experiment
is. validate::isotopy::cell_is_certified shipped under T-015 and is exactly the registered form —
0 ∉ □F(C) ∨ ⟨□∇F(C), □∇F(C)⟩ > 0, Plantinga & Vegter SGP 2004. So P-62 is a measurement of shipped
code, like P-71's C2, not a build. What has never been done is the part that makes it an experiment:
checking it for soundness against this crate's own tunnel classifier.
Why the bounds are exact rather than interval arithmetic, which is the module's own argument and worth
restating because it is what makes C1 decidable. The surface Marching Cubes approximates is not the
analytic field, it is the trilinear interpolant of the eight corner values. F is then a convex
combination of those corners, so 0 ∉ □F(C) is exactly "all eight corners share a sign" — clause one is
free and identifies inactive cells. Each partial derivative is bilinear in the other two coordinates,
so its exact range is the min and max of four corner differences. And h cancels: the predicate tests the
sign of a sum of three squares, so h² factors out and the arithmetic runs on raw corner differences.
No interval library, no sampling, no slack — against the surface the extractor actually emits.
The ground truth C1 is checked against is one this crate owns and the PV literature does not. A-020's
classifier reads tunnels and twelve-vertex contours off the trilinear directly; M-214 recorded 2,053
tunnels and 173 twelve-vertex contours in 396,000 cells, and M-222 established that χ falls by exactly
two per tunnel. A cell containing a tunnel is a cell whose patch is not a graph, so a certificate on
one is unsound by construction. M-214's counts are what make C1 a kill-shot rather than an M-44 pass
over a case the fixture never reaches — and the harness reports the tunnel population per field, so a zero
is shown to have been able to be non-zero.
| clause | prediction | falsified by |
|---|---|---|
| C1 | zero certified cells that the classifier calls a tunnel or twelve-vertex contour, over eight fields at 17³/33³/65³ | one such cell — a single unsound certificate kills the direction |
| C2 | certified fraction of surface cells above 50% on sphere, torus, box_exact at 33³, rising monotonically with resolution on all eight |
below 50% on any of the three, or non-monotone on any field — which would mean the predicate measures arithmetic slack, not geometry |
| C3 | the predicate costs under 5% of marching_cubes extraction at 65³ |
above 5%, making it a debug gate rather than a shippable capability |
Registered caveat, not a discovery. C1 guarantees the patch is a graph, not that its planar domain
is connected — a graph over a disconnected planar region still has several components. PV close that
globally with a balanced octree this crate does not have, so the honest claim is "no hidden topology in
this cell", never "exactly one component". Lin & Yap document the same gap
(10.1007/s00454-011-9345-9). No golden hash moves: the predicate is read-only and no extractor calls
it.
🔬 M-378 — C1 and C2 HELD, C3 FALSIFIED: zero unsound certificates over 2,389 tunnel cells where the predicate refuses 95% of the population, and the cost is 21% because a standalone pass gathers corners the extractor already has (P-62, R-060)
M. cargo bench --bench experiment_p62, docs/experiments/p-62.csv, 25 rows, f64, Zen 3. The
shipped validate::cell_is_certified (T-015) cross-tabulated against A-020's trilinear classifier on
the same corner values, over the eight reference fields at 17³/33³/65³ plus a 400,000-cell random
population arm. Fields come from for_each_reference_field!, not a retyped list.
| clause | registered | measured |
|---|---|---|
| C1 zero unsound certificates | 0 | HELD — 0 over 2,389 tunnel / twelve-vertex cells |
| C2 yield > 50% on three named at 33³, monotone on all eight | both | HELD — 1.0000 / 1.0000 / 0.8698, and rising on all eight |
| C3 predicate under 5% of extraction at 65³ | < 0.05 | FALSIFIED — 0.2107 worst |
C1's population is the whole result, and the first fixture did not have one. The eight reference fields
at 17³–65³ produce seven tunnel cells in 172,032 — a zero over seven is a hair from M-44's vacuous
zero, not the kill-shot the registration describes. M-214's 2,053 tunnels came from 400,000 random
cells, so that is the arm that was added. It lands almost exactly on M-214:
M-214 |
here | |
|---|---|---|
| cells | 396,000 | 396,865 active |
| tunnels | 2,053 | 2,202 |
| twelve-vertex contours | 173 | 180 |
Different seed, same rates — which corroborates both the classifier and the fixture. And the predicate is
extremely discriminating on that population: it certifies 19,571 of 396,865 active random cells,
i.e. it says no to 95.07% of them, against 100.00% on sphere at every resolution. So C1's zero
is not a predicate that says yes to everything; it is a predicate that refuses 377,294 adversarial cells,
accepts 19,571, and not one of the accepted ones contains a tunnel.
C2, and the monotonicity is the more informative half:
| field | 17³ | 33³ | 65³ |
|---|---|---|---|
sphere |
1.0000 | 1.0000 | 1.0000 |
torus |
1.0000 | 1.0000 | 1.0000 |
thin_plate |
1.0000 | 1.0000 | 1.0000 |
fbm_terrain |
1.0000 | 1.0000 | 1.0000 |
box_exact |
0.7297 | 0.8698 | 0.9362 |
csg_difference |
0.6926 | 0.8566 | 0.9275 |
gyroid |
0.8484 | 0.9294 | 0.9636 |
noise_cavity |
0.3589 | 0.4859 | 0.8002 |
Every field is non-decreasing, which is what C2's falsifier was watching for: a non-monotone sequence would
mean the predicate was reading the arithmetic's slack rather than the field's geometry, and there is no
slack to read — both bounds are exact for a trilinear. The four fields at 1.0000 are flat, not rising,
and the clause was registered as "rises monotonically", so the harness tests ≥ rather than >. That is
the honest reading of a saturated field: sphere at 17³ is already fully certified and cannot rise.
noise_cavity is the field that shows the predicate is measuring geometry. It goes 0.3589 → 0.4859 →
0.8002, the largest climb of any field, and it is the only field that produced tunnels at all (3 at 17³,
4 at 33³, 0 at 65³). Refinement is what converts a cell whose patch has hidden topology into eight cells
whose patches are graphs — which is precisely the PV convergence argument, measured here rather than cited.
C3 is falsified at 4.2× the ceiling, and the decomposition says why:
| field (65³) | predicate ms | bare gather ms | extract ms | share | share with gather removed |
|---|---|---|---|---|---|
thin_plate |
0.7209 | 0.5101 | 3.4218 | 0.2107 | 0.0616 |
box_exact |
0.7627 | 0.5116 | 3.8130 | 0.2000 | 0.0658 |
torus |
0.7605 | 0.5120 | 4.0624 | 0.1872 | 0.0612 |
csg_difference |
0.7771 | 0.5117 | 4.2717 | 0.1819 | 0.0621 |
sphere |
0.7474 | 0.5075 | 4.2511 | 0.1758 | 0.0564 |
noise_cavity |
1.3600 | 0.5081 | 19.2885 | 0.0705 | 0.0442 |
gyroid |
1.0266 | 0.5115 | 15.1811 | 0.0676 | 0.0339 |
fbm_terrain |
0.8712 | 0.5133 | 51.0242 | 0.0171 | 0.0070 |
The bare eight-corner gather is 0.51 ms on every single arm — flat, because it is the same 262,144 cells × 8 loads whatever the field — and the predicate's own arithmetic is the remaining 0.21 to 0.85 ms. So two thirds of the standalone cost is re-reading corners the extractor has already read to index its case table. A version fused into the extractor's existing gather would pay 0.0658 worst, which is still above 5% but by 1.3 points rather than 16. That is reported and is explicitly not substituted for the verdict: the clause is about the standalone predicate, the harness measured the standalone predicate, and C3 is falsified.
The registered caveat, restated because it bounds what C1 means. A certified cell's patch is a graph
over a coordinate plane, not necessarily one component — a graph over a disconnected planar domain
has several. PV close that globally with a balanced octree this crate does not have, and Lin & Yap
document the same gap (10.1007/s00454-011-9345-9). So what C1 licenses is "no hidden topology in this
cell", never "exactly one component".
Two fixture defects, both caught by controls. The population arm above; and the refusal control was
per-field and fired on sphere at 17³, which refuses nothing — a correct outcome, not a broken
instrument. What has to be shown is that the predicate can refuse, which is a statement about the
predicate and therefore about the sweep, so the control is global. A third control asserts that no cell is
classified as a tunnel while the case table calls it inactive: 0 across all 2,792,064 cells examined,
which is how the harness knows both halves are reading the same corner values rather than two samplings.
Would be shown wrong by: one certified cell containing a tunnel, at any resolution or on any population; a non-monotone yield sequence on any field; or a fused implementation measuring above the 0.0658 reported here, which would mean the gather subtraction is optimistic.
P-64 — registered for R-062, before the harness exists
The split is what makes this tractable, and it is registered rather than discovered. Bit-blasting IEEE
754 to SAT is the adversarial case for a model checker; a harness over eight nondeterministic f32 corner
values is 256 bits of unconstrained float, precisely the shape Kani is worst at. But this crate's
correctness risk is not in the arithmetic. CLAUDE.md rule 5 names it exactly: "wrong case tables produce
meshes that look fine and are subtly non-manifold." That is combinatorics over eight sign bits — 256
states, trivial for BMC. So: verify the combinatorics, keep testing the arithmetic.
| clause | prediction | falsified by |
|---|---|---|
| C1 | Kani proves all four properties over all 256 patterns, interior rule off, under 10 minutes | a timeout, or a property that cannot be expressed against the sign abstraction — the second is the more informative outcome and means the abstraction is wrong, not the tool |
| C2 | it finds nothing the existing suite does not cover — registered as the expected result | Kani finding a reachable violation, which is a ✗ entry and the most valuable outcome available |
| C3 | turning the interior-ambiguity rule on keeps C1 under 30 minutes | a blow-up, which localises the state explosion to the interior rule and is itself a finding about its branching |
Why C2 is worth running even though it is expected to find nothing. A proof and a passing property test
are different objects. M-208–M-213 is five pre-registered claims that were true on seven reference
fields and false on the eighth — sampling found the counterexample only because the eighth field existed in
the fixture. Over 256 states there is no eighth field to forget.
VOID condition, registered: each harness must report its check count. A proof over an empty check
set is M-44's vacuous zero in formal clothing — "verification successful, 0 checks" is not a proof of
anything, and the harness has to be able to say so.
Scope note, registered. Neither tool touches vertex placement. Placement stays under proptest and
golden hashes. The honest scope is "the table cannot be indexed wrongly", not "the mesh is
correct". Kani is a dev tool with no runtime footprint, so hard rule 3 is not engaged — cargo tree -p
isomesh -e normal is unchanged at two packages, and the gate still reads it. No published use of Kani
on geometry or graphics code was found, which makes this novel as well as useful.
🔬 M-379 — C1, C2 and C3 all HELD: the case table is proved indexable over all 256 sign patterns in 2.04 s and over all 16,384 (pattern, mask) pairs in 161 s — but only after the state explosion was localised to segment_links' walk, which exhausted 32 GB (P-64, R-062)
M. cargo bench --bench experiment_p64, docs/experiments/p-64.csv, 3 rows, Kani 0.67.0 / CBMC,
Zen 3 (the registration named an M5; M-005's contention block applies, so this ran here and says so).
Proofs live in marching_cubes::proofs behind cfg(kani); the bench shells out to cargo kani per
harness and records the solver's own check count, failure count, verdict and time.
| clause | registered | measured |
|---|---|---|
| C1 all four properties, 256 patterns, interior off, < 10 min | < 600 s | HELD — 62 checks, 0 failed, SUCCESSFUL, 2.04 s |
| C2 finds nothing the suite does not cover | no violation | HELD — 0 failed checks across both real harnesses |
| C3 interior rule on, < 30 min | < 1800 s | HELD — 63 checks, 0 failed, SUCCESSFUL, 161.10 s over 16,384 pairs |
The four properties, and the third is the load-bearing one.
- Shape —
count ≤ MAX_TRIANGLES,centroids ≤ MAX_CENTROIDS, so a caller's stack array cannot overflow.D-021earlier this phase is what happens when such a bound is a sampled maximum. - Every code nameable — each code is a cube edge below
CENTROID_BASEor a centroid index below this case's owncentroidscount. - Every named edge is cut. A property of the pair (table, sign pattern), not of the table alone.
extraction.rsplaces a vertex for whatever edge the table names, by interpolating that edge's two corner values — so a triangle naming an uncut edge asks for a crossing that does not exist. That is a vertex at a meaningless position, not a bounds error, which is exactly the failureCLAUDE.mdrule 5 describes as "looks fine and is subtly non-manifold". - No degenerate triangle — three distinct codes. Stated over codes rather than positions on purpose: two distinct edges can carry the same position when the crossing sits on a shared corner, and that is a placement question this file does not touch.
The finding that outlives the verdicts: the state explosion is in the walk, not in the sign bits. The
first version pointed Kani straight at triangulate(segment_links(case, joined)) with both arguments
nondeterministic — the obvious harness, and the one the registration implies. CBMC ran out of memory:
| steps of program expression | 10,230,639 |
| verification conditions generated | 909,347 |
| remaining after simplification | 550,658 |
| symbolic execution | 885.05 s |
| equation postprocessing | 270.78 s |
| outcome | out of memory, 32 GB |
And the CASES harness beside it verifies in 2.03 s. That gap is not the 256-state sign space, which
is trivial. It is segment_links' data-dependent twelve-edge walk: every step's successor depends on
the previous step's value, so symbolic execution cannot merge paths and unrolls the product. C1's
registered second falsifier was "a property that cannot be expressed against the sign abstraction, which
means the abstraction is wrong" — this is a third shape neither the registration nor I anticipated:
the abstraction is right and the function is the wrong thing to bit-blast.
The fix splits the work between the two engines each good at half of it, and the composition is still a
proof over the whole input space. const evaluation runs the real constructor on all 16,384
(case, mask) inputs — exhaustive by construction, by the same evaluator that builds the shipped CASES
— and Kani then proves the four properties over the stored results with a nondeterministic index, which is
a lookup. Nothing is sampled and nothing is assumed about the walk. Cost: cfg_attr(kani,
allow(long_running_const_eval)) at the crate root, which is a compile-time budget lint tuned to catch
accidental infinite loops, allowed only under Kani's compiler so an ordinary build would still catch a
runaway const-eval in segment_links. 256 × 256 was the first table and rustc refused it outright;
256 × 64 — every mask face_bit can produce — evaluates.
The control, because a vacuous proof prints the same word as a real one. the_properties_can_fail is
#[kani::should_panic]: it corrupts one live triangle to [0, 0, 0] and requires the assertions to fire.
71 checks, 2 failed, SUCCESSFUL (encountered one or more panics as expected). If a property ever
drifts into a tautology, that harness fails while the two real ones keep printing SUCCESSFUL. The bench
additionally asserts checks > 0 per harness, because "VERIFICATION:- SUCCESSFUL over zero checks" is
M-44's vacuous zero in formal clothing — and it was a registered VOID condition, not a discovery.
A defect this experiment introduced and then made impossible. P-64's first CSV recorded a property
column reading "shape, nameable, edge-is-cut, non-degenerate" and silently shifted every later column
by three places in two of three rows: checks landed under patterns, the verdict under
failed_checks. Row count right, header right, dataset garbage — and D-017's provenance gate cannot
catch this, because the header is fine. Run::record now refuses any value containing a comma, a quote
or a newline. Quoting was considered and rejected: every column in every experiment is a number, an
identifier or a boolean, and RFC 4180 would oblige every reader of the committed CSVs to implement it.
All 56 committed CSVs were audited by column count; exactly one was affected and it was never
committed.
And a defect in the verification rather than the code, worth recording because it is the same shape.
The broken file reached a commit because the check was cargo fmt --all && cargo clippy … ; echo 'lint
ok' — the echo after a semicolon. cargo fmt failed on the syntax error, clippy never ran, and "lint
ok" printed anyway. The replacement grep -E '^error' | head -12 && echo CLEAN failed the same way,
because head exits 0 on empty input. Both are now the command's own exit status. M-44 in the
tooling: a check that cannot report failure is not a check.
Scope, per the registration and restated because it is the honest boundary. Neither the proofs nor the
bench touch vertex placement. Placement stays under proptest and the 216 golden hashes. What is proved
is "the table cannot be indexed wrongly", not "the mesh is correct". Kani is a dev tool behind
cfg(kani), so hard rule 3 is untouched — cargo tree -p isomesh -e normal still reads 2.
Would be shown wrong by: a reachable violation of any of the four properties; a check count of zero
with a SUCCESSFUL verdict; the sabotage control passing without failures; or an AMBIGUOUS_FACES change
that lets joined_mask set a bit outside the six face_bit positions, which would put real inputs
outside the 64 masks proved here.
P-66 — registered for R-064, before the harness exists
This line died twice, and the registration says why the third attempt is a different mechanism rather
than a third tuning. P-43/✗29 tried one evaluation at the cell centre as an under-sampling witness
and was falsified on both clauses. P-44/✗31 tried the mean residual instead and was falsified out of
sample. Both were value witnesses — they asked whether the trilinear's value at a point disagrees
with the field's. The failure mode they were chasing is not a value disagreement, it is a missed root:
an edge whose two endpoints share a sign while the field crosses zero twice between them, or have opposite
signs while it crosses three times. A value witness cannot see that, because the value can agree at every
sampled point while the root count differs.
The witness is a derivative sign test, from Finken, Li, Wang, Guo & Levine, Topology-Preserving
Meshing of Implicit Scalar Fields via Monotonicity Constraints, arXiv:2608.12142, IEEE Vis 2026 short
paper: if every edge of a PL mesh is monotonic with respect to f, the PL approximation is topologically
consistent with f's critical points. The test is one line — sample ∇f · ê at k points along the edge,
non-monotonic when any two disagree in sign.
Do not port the paper, and that is registered rather than discovered. It is explicitly 2D and the authors say so. Its sampling-density argument, its Theorem 1 case analysis — 3D Morse theory has four critical-point types and a spherical link, not three and a circle — and its separatrix refinement all fail to generalise, and it wants a Hessian this crate's field trait does not expose. Take the edge test alone, as a diagnostic rather than an extraction rule.
What makes this registrable here rather than anywhere else is the oracle.
subgrid::roots::all_roots already finds all roots along an edge — M-94 resolved a slab at 1/1000 of
edge length, M-168 gave each crossing an identity, M-169 established when identity-based sharing is
complete. So the root count per edge is a known quantity in this repository, and the test is scored
against it rather than against a hunch. That is the difference between this and the two attempts that died.
| clause | prediction | falsified by |
|---|---|---|
| C1 | at k = 5, every edge the root finder reports with > 1 root is flagged non-monotonic — zero false negatives |
one multi-root edge called monotonic |
| C2 | false-positive rate below 20% at k = 5 on the six smooth fields, falling as k rises |
above 20% on any of the six, or a rate that does not fall with k — which would mean it measures sampling noise |
| C3 | non-monotonic edge fraction falls monotonically with resolution on all eight, and is highest on thin_plate — the field whose sub-cell features Marching Cubes structurally cannot see (M-100) |
a non-monotone sequence, or thin_plate not ranking first |
VOID condition, registered. If the oracle reports no multi-root edge, C1's "zero false negatives"
is a zero over an empty population — M-44 again. The multi-root edge count is a recorded column and must
be non-zero somewhere in the sweep. And the oracle's own resolution is a stated limit rather than an
assumption: all_roots divides each edge into a fixed number of intervals and cannot see a root pair
closer together than one of them, so the oracle sample count is recorded per row.
Consequence if it holds. A chunk can report "this grid under-resolves this field, here" as a number,
per chunk, cheaply — the missing input to the LOD decision that M-121's 3.14-cell surface pop and
M-72's aliasing both want and neither has. No golden hash moves: the test is a diagnostic and no
extractor calls it.
💥 ✗53 / M-380 — all three clauses FALSIFIED, each for a different and useful reason: the witness is sound at k = 17 and not at k = 5, C2's second half was backwards, and thin_plate ranks last on the metric C3 predicted it would top (P-66, R-064)
M. cargo bench --bench experiment_p66, docs/experiments/p-66.csv, 120 rows, f64, Zen 3. Every
axis-aligned grid edge of the sample lattice — 13,872 / 104,544 / 811,200 at 17³ / 33³ / 65³ — on the
eight reference fields, k swept over 2/3/5/9/17, scored against subgrid::roots::all_roots at 128
intervals per edge.
| clause | registered | measured |
|---|---|---|
C1 zero false negatives at k = 5 |
0 | FALSIFIED — 8 over 2,172 multi-root edges |
C2 FP rate < 20% on the six smooth, falling with k |
both | FALSIFIED on both |
C3 fraction falls with resolution on all eight, thin_plate first |
both | FALSIFIED — falls on all eight, thin_plate is last |
C1 fails at the registered k and holds two steps later, which is the result rather than a caveat:
k |
false negatives | edges flagged |
|---|---|---|
| 2 | 322 | 344,500 |
| 3 | 94 | 375,691 |
| 5 | 8 | 385,038 |
| 9 | 1 | 387,357 |
| 17 | 0 | 388,159 |
All eight false negatives at k = 5 are on noise_cavity — 5 at 17³, 2 at 33³, 1 at 65³ — the only
field with genuine sub-cell noise, and they fall with resolution as well as with k. So the mechanism is
exactly what a sampling-based derivative test should fail at: a gradient reversal narrower than the gap
between two of the k sample points. The paper's own count is max(2, ⌈‖e‖/w⌉ + 1), i.e. it scales k
with edge length over feature width — and this measurement says the registered k = 5 is below that
threshold on noise_cavity and k = 17 is above it, over 2,172 multi-root edges on eight fields.
C2's second half is not merely false, it is mechanically impossible, and that is a defect in the
registration rather than in the test. Adding a sample point can only add an opportunity for two
projections to disagree, so flagged is monotone non-decreasing in k — 344,500 at k = 2 to
388,159 at k = 17 — and so is the false-positive count. A rate that fell with k would mean the
witness un-flagged an edge it had flagged, which the test cannot do. The clause asked for something the
predicate's own form forbids. fbm_terrain, gyroid and noise_cavity are where it shows: 0.0832 →
0.0872, 0.0267 → 0.0270, 0.1331 → 0.1371 at 65³. What actually falls with k is the false-negative
count, which is C1's column — the registration attached the falling behaviour to the wrong metric.
C2's first half fails on thin_plate, and that is the same finding as C3's, seen from the other side:
| field | FP rate 17³ | 33³ | 65³ | non-monotonic fraction 17³ → 65³ |
|---|---|---|---|---|
sphere |
0.0000 | 0.0000 | 0.0000 | 0.0000 → 0.0000 |
box_exact |
0.0000 | 0.0000 | 0.0000 | 0.0001 → 0.0000 |
torus |
0.0488 | 0.0000 | 0.0000 | 0.0294 → 0.0096 |
csg_difference |
0.0714 | 0.0303 | 0.0175 | 0.0171 → 0.0047 |
gyroid |
0.1167 | 0.0516 | 0.0269 | 0.1525 → 0.0432 |
noise_cavity |
0.5357 | 0.3453 | 0.1365 | 0.1548 → 0.0624 |
fbm_terrain |
0.2962 | 0.1918 | 0.0867 | 0.5441 → 0.2554 |
thin_plate |
0.3889 | 0.4412 | 0.4697 | 0.0035 → 0.0012 |
thin_plate has the lowest non-monotonic fraction of the eight and the highest false-positive rate
at 33³ and 65³. C3 predicted it would top the fraction. It ranks eighth. The reason is that the fraction
is taken over all grid edges, and thin_plate is a thin plate in a mostly-empty volume: almost every
edge is far from the plate, where the field is smooth and monotone. So the non-monotonic fraction
measures how much of the volume has turning gradient, not how badly the surface is under-resolved —
fbm_terrain, whose gradient turns everywhere, tops it at 0.5441.
thin_plate's real signature is that its false-positive rate is the only one that rises with
resolution — 0.3889 → 0.4412 → 0.4697, while all seven others fall, several to exactly zero.
Refinement does not help it, because the plate is thinner than every grid tested. That is M-100
measured from a new direction: a field whose sub-cell features Marching Cubes structurally cannot see
shows up here not as a large number but as a non-converging one.
So the deliverable survives the falsification, with a different formula than the one registered. The
per-chunk under-resolution number M-121's 3.14-cell surface pop and M-72's aliasing both want is
not the non-monotonic fraction over all edges. Two candidates the data supports:
- the non-monotonic rate among single-root edges (the FP-rate column), which ranks
thin_platefirst at 33³ and 65³ and is the only quantity here that fails to converge under refinement; - the false-negative count at fixed
k, which is the direct measure of missed roots and falls to zero byk = 17— but which needs the oracle, so it is an offline diagnostic and not a per-frame number.
Neither is registered, so neither is claimed. They are what the next registration should be about.
Three controls, all M-44-shaped, all non-vacuous. The oracle found 2,172 multi-root edges, so
C1's population is real. The witness flagged 385,038 of 7,436,928 edges at
k = 5, so it can report the bad news; and it left 7,051,890 unflagged, which is the control that
matters most — a witness that flagged every edge would pass C1 trivially, and this one flags 5.18%.
Scope, recorded as a column rather than a footnote. all_roots divides each edge into 128
intervals and cannot resolve a root pair closer together than one of them, so C1's count is scoped to
pairs the oracle can see. A pair inside one interval is invisible to both instruments and cannot produce a
false negative here — but it also cannot be ruled out, and oracle_samples is on every row so a reader
can check what was asked.
Would be shown wrong by: a false negative at k = 17 on any field; a field whose non-monotonic
fraction rises with resolution; or a thin_plate FP rate that starts falling at a resolution above 65³,
which would mean the plate is resolvable after all and M-100's structural claim is a sampling artefact.
P-70 — registered for R-068, before the harness exists, and C1 is already arithmetically unreachable
M-375 earned Part 5 the rule "a clause stated as a ratio of a total must name the share of that total
it can move." This is the first registration to apply it prospectively, and it kills C1 before a line of
WGSL exists. From docs/measurements/gpu_vs_cpu.csv at 129³, committed:
| stage | ms | share of gpu_total_ms |
|---|---|---|
upload_ms |
7.3236 | 87.50% |
geometry_readback_ms |
0.6352 | 7.59% |
scan_ms |
0.3657 | 4.37% |
emit_ms |
0.0253 | 0.30% |
count_ms |
0.0197 | 0.23% |
gpu_total_ms |
8.3694 |
C1 asks for below 7.0 ms, i.e. 1.3694 ms removed. The scan is 0.3657 ms in total. A free scan leaves 8.0037 ms; the literature's own 1.5× ceiling leaves 8.2475 ms. C1 cannot be reached by any change to the scan, and C1's registered falsifier says exactly why in its own words — "which would mean the compaction was not the residue." It is not the residue. The residue is the upload, at 87.5%.
So the experiment measures the mechanism and does not land it, and the reason is the repo's top rule
rather than the arithmetic alone. A second WGSL path in the shipped crate is what CLAUDE.md's one-path
rule forbids, and 4.37% capped at 1.5× — a 1.4% improvement to gpu_total_ms — does not buy an
exception. The subgroup scan is therefore compiled in the bench, from inline WGSL, and never enters
isomesh-gpu. This is E×7's shape from P-71: measured, not landed.
The correctness anchor is three-way, so a transcription cannot drift silently. The bench's Hillis-Steele
entry point is a transcription, and a copy of a shipped shader inside a bench is exactly the second
definition this ledger keeps finding. So its output is required to equal both the shipped
PrefixScan::scan and cpu_prefix_sum on the same input. If the transcription drifts, the crate's own
oracle catches it — not a human reading two shaders side by side.
Two of the paper's findings are recorded whatever this returns, because they foreclose the obvious plan. ARM and Apple GPUs give no forward-progress guarantee, so plain decoupled look-back times out on M1 Max and M3 — single-pass chained scan is off the table on this crate's primary target. And the ceiling is structural: reduce-then-scan moves O(3n), chained scan O(2n), so 50% is the theoretical maximum. Scan is memory-bound and subgroups do not change that.
| clause | prediction | falsified by |
|---|---|---|
| C1 | 129³ extraction below 7.0 ms, from M-150's 9.65 |
above 7.0 ms — "which would mean the compaction was not the residue" |
| C2 | output bit-identical to the current path, same triangles, same order | any difference; a compaction that reorders is a determinism regression and is rejected regardless of speed |
| C3 | the fallback is exercised, not merely present | a fallback that is not tested — M-44's zero-that-could-not-have-been-non-zero in a new place |
Blocker resolved before writing anything. naga validates subgroup_invocation_id only in 1-D
workgroup compute shaders. scan.wgsl is already @workgroup_size(256) dispatched (groups, 1, 1), so
no flattening is needed and the hash risk the registration warned about does not arise. VOID if the
device does not advertise SUBGROUP — every clause would then be about code that did not run — so the
adapter's reported subgroup size is a recorded column. P-71's probe already measured it at 32 on this
RTX 3090.
💥 ✗54 / M-381 — C1 FALSIFIED by arithmetic computed at registration, C2 and C3 HELD: the subgroup scan is real at 1.4114× and reproduces the literature, and it moves the shipped path by 1.27% (P-70, R-068)
M. cargo bench --bench experiment_p70, docs/experiments/p-70.csv, 8 rows, RTX 3090 / Vulkan,
subgroup size 32, SUBGROUP advertised. Both arms compiled from inline WGSL in the bench; median
of 7 after a warm-up, one dispatch per timing.
RE-RUN 2026-08-27, because C3 was scored on nothing. The audit's D-4: "the fallback is exercised, not merely present" was recorded as the bare word HELD, and
p-70.csvhad no column that could have made it false — the predicate wasany(arm == "hillis" && matches_shipped && matches_cpu), which the control five lines above it had alreadyassert!ed for every row.M-44's zero in a new place, in a phase that quotesM-44six times. C3 now has an instrument and the harness had to be re-run to get it, so every timing in this entry is the new file's: the four speedups moved 1.0652 → 1.0544, 1.1281 → 1.1113, 1.3650 → 1.2796, 1.4376 → 1.4114, and the applied effect 1.33% → 1.27%. Nothing about any verdict moves; the re-run is quoted rather than the numbers being kept because✗52's defect was exactly the other choice. A 1.8% run-to-run swing on the headline ratio is itself the reasonM-337's re-audit rule exists — a ratio that moves this much between runs of the same binary is not a gate, and this entry never used it as one: the decision rests on 4.37% and 87.50%, which are integers' worth of stable.
| clause | registered | measured |
|---|---|---|
| C1 129³ extraction below 7.0 ms | < 7.0 | FALSIFIED — a free scan leaves 8.0037 ms |
| C2 bit-identical output | no difference | HELD — both arms match the shipped PrefixScan and cpu_prefix_sum at all four sizes |
| C3 the fallback is exercised | tested, not merely present | HELD, and now on a column that could have said no — the shipped PrefixScan on a second device opened with Features::empty() agrees bit-for-bit with the subgroup arm at all four sizes, and the same comparator refuses a one-element corruption of that answer |
C1 was dead before a line of WGSL existed, and M-375 is why that was known. Part 5's rule —
a clause stated as a ratio of a total must name the share of that total it can move — applied
prospectively for the first time. The bench reads these from
docs/measurements/gpu_vs_cpu.csv rather than quoting them, so the row cannot drift from the artefact:
| stage at 129³ | ms | share |
|---|---|---|
upload_ms |
7.3236 | 87.50% — the residue |
geometry_readback_ms |
0.6352 | 7.59% |
scan_ms |
0.3657 | 4.37% |
gpu_total_ms |
8.3694 |
C1 asks for 1.3694 ms removed and the scan is 0.3657 ms in total. C1's own falsifier says why: "which would mean the compaction was not the residue." It is not. The upload is.
The mechanism is real, and it lands inside the paper's own band on hardware the paper did not test:
| elements | Hillis-Steele ms | subgroup ms | speedup |
|---|---|---|---|
| 65,536 | 0.0502 | 0.0476 | 1.0544× |
| 262,144 | 0.0591 | 0.0532 | 1.1113× |
| 1,048,576 | 0.0956 | 0.0747 | 1.2796× |
| 2,097,152 | 0.1415 | 0.1002 | 1.4114× |
Smith, Levien & Owens measured 1.43× on M1 Max, 1.46× on M3, 1.49× on RTX 2080 Super, 1.33× on RX 7900 XT,
1.35× on Mali-G78, 1.43× on Intel HD 620. 1.4114× on an RTX 3090 at 2²¹ elements sits in the middle of
that band — an independent reproduction on a seventh device. And the speedup grows with n, from
1.05× to 1.41×, which is the memory-bound story the paper argues: at 65K the dispatch overhead dominates and
there is nothing for wave ops to save.
Applied to the shipped path, 1.4114× on 4.37% moves gpu_total_ms from 8.3694 to 8.2628 — 1.27%.
NOT LANDED, and the reason is the repo's top rule rather than the number alone. A second WGSL path in
the shipped crate is what CLAUDE.md's one-path rule forbids, and 1.27% does not buy an exception. E×7
from P-71 is the same shape: mechanism measured, decision recorded, code not merged.
Two naga realities the registration did not anticipate, and they strengthen the decision considerably.
enable subgroups;is rejected outright by naga 29.0.4: "this enable-extension specifies standard functionality which is not yet implemented in Naga." The intrinsics do work without the directive — which WGSL requires — so this shader compiles onwgputoday and would not compile on a spec-conforming WGSL implementation. Any plan to ship subgroups throughwgpuis waiting ongfx-rs/wgpu#5555, and that is a hard portability blocker rather than a preference.subgroupBroadcast's lane index must be a const-expression. The natural idiom — the last lane holds the subgroup total,subgroupBroadcast(lane_prefix + value, sg_size - 1u)— is rejected, becausesg_sizeis a runtime builtin.subgroupAddis a reduction that lands the same value in every lane and needs no broadcast, so the shader pays two wave ops instead of one plus a broadcast. The measured 1.4114× is with that extra reduction.
C2's scope is narrower than registered and the entry says so. The clause reads "bit-identical on all
eight fields — same triangles, same order", and this harness compares prefix-scan output, not meshes.
It cannot compare meshes, because the subgroup scan is not wired into an extractor — wiring it in is the
thing the one-path rule forbids. What is verified is bit-identity on the quantity being changed, at
four sizes, against two independent references. A separate fixture gap found on the way: gpu_vs_cpu.csv
contains only sphere, so C2's "all eight fields" has no committed dataset to be checked against even
for the shipped path.
Controls. Both arms are asserted against cpu_prefix_sum and the shipped PrefixScan::scan at
every size — three-way, so the bench's Hillis-Steele transcription cannot silently drift from the shader it
transcribes. The fixture is 3% non-zero counts, which is M-337's measured active-cell density on a
sphere at 128³, rather than a uniform fill the extractor never produces. And VOID if the adapter lacks
SUBGROUP, asserted rather than assumed.
C3's instrument, since it is the reason this entry was re-run. The fallback is not simulated — a second
headless::Gpu is opened with Features::empty(), and the arm that runs on it is the shipped
PrefixScan, because the fallback is the shipped path and a hillis-only copy of the WGSL would be the
second definition this ledger keeps finding. Four columns carry it: forced_off_subgroup_feature
(false on every row, asserted, or the arm is not running under the condition C3 is about),
forced_off_matches_subgroup_run (true at 65K / 262K / 1M / 2M), and
forced_off_comparator_detects_corruption (true at all four — one element of the fallback's answer is
bumped and the same closure must refuse it, E-208's rule). The index bumped is base + 1 rather than
base, because shifting a block's base moves every term in that block by the same constant and the
identity would survive it — the corruption control needed its own thought, which is the usual shape.
Would be shown wrong by: a speedup above 1.5× at any size, which would exceed the paper's structural
O(3n)→O(2n) ceiling and mean something other than the scan changed; a disagreement with either reference;
or naga implementing enable subgroups;, which would remove blocker 1 and make the not-landed decision
purely about the 1.33%.
P-68 — registered for R-066, before the harness exists
The gap is stated in the crate's own mandate, and three existing findings are the evidence. M-142:
GPU and CPU agree on every triangle and disagree on 6% of vertices by exactly one ULP. M-144:
bit-identity is a property of the cell size, not the port. M-30: an unclamped solve can fling a
vertex 3.18 cells out of its own cell. Every one of those had to be measured after the fact.
Nothing in the crate reports, per vertex, at run time, how wide the interval containing the true crossing
is — which is what a CAD consumer means by "how much should I trust this coordinate".
P-61's centred form is what makes the bound cheap, and that is a dependency between experiments rather
than a coincidence. The offset is d = ((a + b)/2) / (a − b): one quotient, no cancellation, because
a and b straddle zero so a − b is a sum of magnitudes. Its first-order bound is therefore
|d| · (2 + |a−b|_err / |a−b|) · u, where the only inexactness that can compound is in the denominator.
The parameter form t = a/(a−b) followed by lower + t·h accumulates a subtract, a multiply and an add
before the vertex exists, and its bound is correspondingly worse.
The ground truth is exact, and that is what makes C1 a soundness statement rather than a comparison of
two approximations. a and b are f64 samples, hence dyadic rationals. So a + b and a − b are
exact integers over a common power of two, the true d is an exact rational, and the error of the f64
result is computable in i128 with no floating point in the loop. The registration is explicit that a
crossing the i128 reference cannot represent is not judged — and that the count of judged crossings
is a recorded column, because a clause measured on a subset must say which subset.
| clause | prediction | falsified by |
|---|---|---|
| C1 | the bound is sound: over 10⁶ crossings on eight fields at 33³, the exact error never exceeds it. Zero violations | one violation |
| C2 | not vacuous: median bound under 4 ulp, p99 under 64 ulp, on the six smooth fields | a median above 4 ulp — "the bound is a formality rather than information" — or a p99 above 64 |
| C3 | under 3% of extraction wall time enabled, exactly zero off, verified by golden hash | above 3%, or any hash movement with the feature off |
| C4 | on csg_difference the bound is largest exactly at the seam cells M-350 bounded |
no correlation with seam proximity, which would mean the bound tracks magnitude rather than conditioning |
C4 is the clause that makes this more than a CAD feature. M-350 proved a central difference across a
CSG seam is wrong by at most half the crease angle and essentially attains it. If the position bound peaks
at the same cells, the bound is reporting conditioning — and a game that wants to know where its
collider is untrustworthy gets the same number for free. No golden hash moves: the bound is an
additional output and changes no position; a bound that moved a hash would be a bound that changed the
arithmetic it reports on.
💥 ✗55 / M-382 — C1 FALSIFIED by 10 violations in 19,415 and the registered coefficient is off by exactly one unit: 2 is unsound, 3 is sound over the whole population, and the derivation says why. C2, C3 and C4 HELD (P-68, R-066)
M. cargo bench --bench experiment_p68, docs/experiments/p-68.csv, 8 rows, f64, Zen 3. Every
axis-aligned grid edge of the sample lattice at 33³ on the eight reference fields — 19,415 crossings,
19,415 of them judged against exact i128 arithmetic, no refusals.
| clause | registered | measured |
|---|---|---|
| C1 zero violations | 0 | FALSIFIED — 10 |
| C2 median < 4 ulp, p99 < 64 ulp on the six smooth | both | HELD — median 1.0000–1.6000, p99 ≤ 1.9612 |
| C3 under 3% of extraction wall time | < 0.03 | HELD — 0.0034 |
| C4 bound largest at the seam | correlated | HELD — 1.1391× nearer the seam |
The result is not "the bound is unsound", it is "the coefficient is 3".
violations against the registered \|d\|·(2 + \|a−b\|_err/\|a−b\|)·u |
10 |
violations against \|d\|·(3 + \|a−b\|_err/\|a−b\|)·u, same population |
0 |
And the derivation says why, which is what makes 3 a bound rather than a fudge. fl(a + b) carries a
relative error up to u, hence an absolute error up to u·|a + b|. Dividing by (a − b) turns that
into an absolute error of u·|a + b| / |a − b| — and |a + b| / |a − b| is 2|d|, by the definition
of d. So the numerator's rounding contributes two units of u|d|, not one. Add the quotient's own
rounding and the first-order coefficient is 3. The registration counted roundings (sum, halve,
divide → "2 inexact steps") instead of propagating them. The measured shortfall matches: max true error
2.1945 ulp against a max registered bound of 1.9866 ulp.
Where the ten violations are is the corroboration: gyroid 4, noise_cavity 5, fbm_terrain 1 —
zero on all five smooth fields. The undercount only bites where |a − b| is small relative to
|a + b|, i.e. where |d| approaches ½ and the missing u|d| term is largest. That is a mechanism, not
a distribution tail.
C2, and the bound is genuinely informative rather than a formality:
| field | crossings | median bound (ulp) | p99 bound | median true error | max true error |
|---|---|---|---|---|---|
box_exact |
1,350 | 1.0000 | 1.0000 | 0.0000 | 0.0000 |
csg_difference |
1,386 | 1.0000 | 1.8936 | 0.0000 | 0.4990 |
sphere |
1,158 | 1.3590 | 1.9612 | 0.1854 | 0.4862 |
torus |
1,128 | 1.5698 | 1.9404 | 0.2932 | 0.4990 |
thin_plate |
510 | 1.6000 | 1.6000 | 0.4500 | 0.4500 |
gyroid |
5,292 | 1.5070 | 1.9909 | 0.2875 | 2.1022 |
fbm_terrain |
2,069 | 1.5032 | 1.9931 | 0.1049 | 1.8900 |
noise_cavity |
6,522 | 1.4805 | 1.9866 | 0.2616 | 2.1945 |
Median bound 1.0–1.6 ulp against a 4-ulp bar and p99 ≤ 1.99 against 64. box_exact's error is
exactly zero on all 1,350 crossings — its crossings land on samples, a + b is exactly zero, d is
exactly ±½, and the arithmetic is exact. A bound reporting ≈1 ulp there is loose, and honestly so: it is
a bound, not an estimate.
C4 is the clause that makes this more than a CAD feature, and it holds at 1.1391×. Splitting
csg_difference's crossings at the median distance to the seam — |f_box + f_sphere|, which is where the
max ties — the half nearer the seam carries a 13.9% larger mean bound. So the bound tracks
conditioning, not magnitude: M-350 proved a central difference across a CSG seam is wrong by at most
half the crease angle and essentially attains it, and the same locality is visible in the position. A
game that wants to know where its collider is untrustworthy gets the number for free.
C3 held only after its denominator was corrected, and that is M-375's rule firing in the other
direction. The clause reads "under 3% of extraction wall time". Measured against the crossing alone
the bound reads 0.6915 — the crossing is 1.08 ns and the bound adds 2.42 ns, so it is 2.2× the
crossing it annotates. That number is true and about the wrong total. Against extraction: 0.0468 ms
added to 13.9928 ms over eight fields at 33³ = 0.33%, because a crossing is a rare event in an extraction
that samples the whole grid. Both are reported; only the second answers the clause.
C3's "exactly zero when the feature is off" is trivially true and the entry says so rather than claiming it. No feature was added: the bound is computed in the bench, the crate is unchanged, and the 216 golden hashes are therefore untouched by construction. Landing a per-vertex bound buffer doubles vertex memory, and that is the owner's decision.
P-71's ring andP-70's subgroup scan are the same shape — mechanism measured, decision surfaced, code not merged.
Three defects in the exact reference, all caught by the judged count being a recorded column. This is
the discipline P-66 established paying off immediately.
d == 0was refused.decompose(0.0)is(0, 0), so the exponent shift came out-1and every symmetric edge went unjudged — precisely the edges where the error is exactly zero.- An endpoint of exactly
0.0carriesf64's subnormal exponent-1074, which dragged the common exponent there and made the other endpoint's shift 1019. That refused all 1,350 ofbox_exact's crossings and 1,167 ofcsg_difference's 1,386. - With that shift negative,
(ea − e) as u32wrapped to four billion, so the> 70guard passed andchecked_shlrefused instead — the same symptom by a different route, which is why fixing (2) alone changed nothing. A zero mantissa is zero at every scale and takes no shift; naming that case is the fix, and relying on the shift arithmetic was the defect.
Judged before the fixes: 16,768 of 19,415 — and the 2,647 missing were not a random sample. They
were every crossing that lands on a sample, i.e. every crossing whose error is exactly zero, concentrated
entirely in box_exact (0 of 1,350 judged) and csg_difference (219 of 1,386). After: 19,415 of
19,415. Had the count not been a column, the bound's median would have been reported over a population
with its exact cases removed — and that bias runs in the direction that flatters the bound.
Two more controls. two_sum's exactness is asserted in i128 on six adversarial pairs, because the
bound's denominator term otherwise rests on a six-line function copied into a bench. And a sabotage arm:
a bound ten times too small must produce violations on the same data, or C1's zero says nothing about the
comparison's ability to fire.
Would be shown wrong by: a violation against coefficient 3 on any field or resolution; a median bound
above 4 ulp; a seam ratio at or below 1; or a box_exact non-zero error, which would mean the exact
reference disagrees with arithmetic that is provably exact.
P-65 — registered for R-063, and blocked at the door: the paper is unacquirable
The hook is real and the blocker is specific. Error::UnresolvedSixSaddle is the one configuration this
crate refuses to mesh: a cell whose contours run past Grosso's Corollary 6 bound has no published
triangulation, so extract returns an error rather than emitting a hole (A-002b, A-020, M-228).
M-231 established that the [9,3] cell is not a topological subcase but a singular face the strict
interior test lets through, and M-233 recorded exactly what is missing: a singular face needs a third
routing and the resolution mask has two.
MCPro is the paper that says it built the third routing. Stahl & Grosso, GRAPP 2025,
10.5220/0013309800003912. No lookup table at all: it classifies each face's bilinear restriction via
the asymptotic decider into hyperbola / singular cross / single line / degenerate plane, divides the face
into quadrants around the asymptote centre, assembles face segments into a per-cell halfedge structure,
solves for the interior saddles, and builds the inner hexagon that decides tunnel-versus-disk. Validation:
all 20,000 Etiene et al. (2012) cases on Betti numbers and Euler characteristic.
One disclosure from the paper this crate would have to carry, and it changes a gate rather than adding
one. A trilinear isosurface can genuinely be non-manifold — singular vertices and edges are real
features of the interpolant — so MCPro guarantees a topologically correct triangulation of a possibly
non-manifold surface. On a field that produces a singular face, is_manifold() failing is correct
behaviour, not a defect. That is a sharper statement than CGAL's TMC row.
Blocked, and the block is part of the registration. Six acquisition routes were attempted through
home-still. The catalog entry for 10.5220/0013309800003912 is a 383-character SciTePress landing page
reporting conversion.server = html-parser, total_pages = 1, chunks_indexed = 1 — there is no
open-access PDF (M-371). Running this would require inventing the quadrant subdivision, the halfedge
assembly and the third routing from an abstract, which CLAUDE.md rule 5 forbids. The registration
records the question; the harness waits on the paper.
Effort and risk, stated at registration rather than discovered. This is the largest item in the source
document, and the determinism risk is specific: asymptotic-decider comparisons near zero are exactly where
f32 and f64 diverge, and M-43 established that the decider needs no division and no epsilon. That
property must be shown to survive the procedural construction, or the golden hashes become
scalar-dependent — which would be a worse regression than the blocker it removes.
P-67 — registered for R-065, and blocked on C3: two clauses are runnable and the third is the reason not to split
P-54 held and left a structural question open. M-354 measured affine arithmetic rejecting 3.85×
more cells than intervals on gyroid, and exactly zero more where min/max destroys the
correlation. But the form it used grows a noise symbol per non-affine operation, so its size is a
function of the tape — which for a twelve-brush edit log means an allocation whose size depends on the
scene, inside a no_std crate whose whole pitch is that it does not do that.
Reduced affine arithmetic fixes the symbol count: all condensed error folds into one accumulated term,
so the form is [R; N+1] — no allocation, fixed operation sequence, which is the determinism property that
matters here.
Blocked on C3, and the honest move is not to split the experiment. C1 (≥ 90% of the full form's
rejection rate at 3 retained symbols) and C2 (zero allocation, op count independent of tape length) could
both be run against this crate's own P-54 baseline. C3 cannot: it exists to reproduce Knoll's
measured 1.5–2× / 3–4× band and his superquadric inversion — the case where intervals win — and
10.1111/j.1467-8659.2008.01189.x has no open-access PDF; paper_download reported "No open-access PDF
found" (M-371). Reproducing a band from a summary is exactly ✗21's failure, where a property was
lifted from a summary rather than from the thing itself.
Running two of three clauses and calling it P-67 would be answering a different registration. C3 is
also the most informative clause here, because Knoll's exception is the part of his result that is a
mechanism rather than a measurement: intervals beat affine forms where the bound overestimation is low,
and box_exact is this crate's low-overestimation field. A P-67 without C3 would measure that RAA is
cheaper without ever testing where it is not.
M-383 — the bench that cannot compile off Linux, and every gate that would see it runs on Linux (D-025)
M. cargo check -p isomesh --benches fails on macOS/arm64 and has since 045dba7 — 49
commits, 2026-08-26. benches/experiment_p69.rs:52 was a bare use common::counters::Probe;, and
benches/common/mod.rs:26 gates that module on #[cfg(target_os = "linux")] because
perf_event_open has no macOS equivalent a bench can reach. rustc says exactly that: "could not
find counters in common", with the note "found an item that was configured out". Measured with
the gate's own command, not a proxy — cargo clippy --workspace --all-targets -- -D warnings, which
is preflight.sh's root: clippy step and the CI lint job's, reports error[E0432] and "could not
compile isomesh (bench "experiment_p69") due to 3 previous errors".
Two of those three errors are not defects, and treating them as defects would have been the
expensive move. The same run reports E0308 twice, at 210:37 and 211:23, both "expected type
parameter R, found f64" against a Timed whose four fields are all f64. They are inference
cascade from the unresolved Probe, not arithmetic. What settles it is a cross-target check:
cargo check -p isomesh --benches --target x86_64-unknown-linux-gnu compiles the whole bench set
clean, and cargo clippy at -D warnings on that target does too. The cross-target run is the
instrument; without it the choices were to guess, or to "fix" arithmetic that was already correct
and ship that to the platform where it runs.
Why nothing saw it, and it is M-293's shape in a third costume. Every CI job that compiles a
bench runs on Linux: the lint job's cargo clippy --workspace --all-targets and the MSRV job's
cargo check --workspace --all-targets, both ubuntu-latest. The test matrix does include
macos-latest — and it deliberately does not compile benches, running cargo test --workspace --lib
--tests, with a comment stating that the lint job "still type-checks all 74 benches". That
reasoning is sound on Linux and silently false off it: the only platform where the bench fails is the
only platform no bench-compiling job runs on. M-293 was a target the local command did not
compile; M-304 was a compiler version that differed. This is a platform that differs, and
the reading is the same one all three produce — a green CI and a local gate that had been red long
enough to look like furniture.
Fixed in the shape three benches already use, rather than in a new one. experiment_p12,
experiment_p15 and a024_aliasing each put their counter-using code inside a
#[cfg(target_os = "linux")] mod and refuse loudly from main on anything else. experiment_p69
now does the same, and the refusal is not a style choice: cycles_per_sample and ghz are in P-69's
records, and common::experiment::Run::record panics on a registered column that is missing — so
family.rs's other option, recording the columns as unavailable, is not open to this bench without
amending a registration to fit the machine it happens to be on.
scripts/p69_asm.sh still finds its symbols, checked rather than assumed. It greps the emitted
.s for asm_probe and matches ^(\S*(?:row_loop|push_loop)\S*):$; nesting the items one module
deeper lengthens the mangled path and leaves both substrings intact.
Would be shown wrong by: a macOS CI job that compiles benches, which would have caught this on
contact and make the local gate redundant rather than load-bearing. Not added here — it is a workflow
change, and preflight.sh's own header already records that the CI-versus-local duplication is the
repository owner's call.
M-384 — a gate that is red locally and green in CI, which is M-304 read backwards (D-026)
M. preflight.sh's isomesh depends on libm and nothing else step has never passed on this
machine, and could not have. It compared "$(cargo tree -p isomesh -e normal | wc -l)" against 2
as a string, and BSD wc right-pads its output where GNU wc does not:
$ cargo tree -p isomesh -e normal | wc -l | sed -n l
2$
So the test was " 2" = "2", false on macOS and true on Linux for every possible dependency
tree — the step could report neither a pass it had earned nor a failure it had found. The graph it
guards is correct and always was: isomesh v0.0.10 and libm v0.2.16, nothing else.
The mechanism is the duplication this script's own header warns about, and it had already
drifted. preflight.sh is not what CI runs — ci.yml carries its own copy of the dependency
gate, and the header says so in as many words: "here there are two — this script and
.github/workflows/ci.yml — and they can drift". They had. CI counts distinct packages,
cargo tree -p isomesh -e normal --prefix none | sort -u | grep -c ., and compares numerically with
-ne. preflight.sh counted tree lines and compared as text. Two gates for one rule, asking
different questions, and only one of them padding-immune — CI's, by accident, because grep -c does
not pad and -ne would have tolerated it anyway.
It is M-304 with the sign flipped, and the flipped sign is the worse one. M-304 was a green
local run and a red CI: a gate reporting success it had not earned. This is a red local run and a
green CI: a gate reporting failure it had not earned, about a fact that was never in question. Both
are one defect class — a verdict that depends on the host rather than on the repository — but a step
that is always red is a step that gets read past, and this one sat directly beside root: clippy,
which was also red, for a real reason, and for 49 commits (M-383).
Rule earned, and it is narrower than "test on both platforms". wc is not the only tool whose
output format is a property of the host rather than of the answer. A shell gate must compare
numbers as numbers, or count with something that does not pad. [ "$x" = 2 ] is a string
comparison wearing arithmetic's clothes; [ "$x" -eq 2 ] would have been immune, and grep -c
avoids the question entirely. The neighbouring no bevy in the resolved graph step already used
grep -c and has always been correct, which is why exactly one of the two adjacent gates was red.
Fixed by copying CI's pipeline character for character rather than by stripping the spaces. That is the one-path form: the local gate and the remote gate now compute the same number the same way, so the next divergence has to be introduced deliberately instead of inherited.
Would be shown wrong by: finding that GNU wc -l also pads under some option or locale, which
would mean this was red everywhere and merely unread rather than platform-dependent. Not seen here —
but note it was never observable from CI either way, because CI never ran this line.
Phase 24 — thirty registrations for the game, each before its harness
Source: docs/research/2026-08-27-thirty-experiments-for-the-game.md — Phase 23 read back, then thirty
pre-registrations aimed at what a player would notice. The lens changed and the filter with it: Phase 23 was
about mathematics and logic, and a row is only here if it improves something visible. Every one was checked
against the 2026-08-18 novelty table and its rejected list, the mechanics dossier's Tier-3 losers,
BACKLOG.md's "deliberately not in scope", and the 2026-08-23 dossier's twenty-five foreclosures.
Phase 15's protocol applies in full, and all thirty P- entries are registered in
crates/isomesh/src/experiment.rs before any harness commit. Experiments are bench-local:
crates/isomesh/src/** is read-only apart from the registrations, except where an experiment is a source
change and says so at registration (P-83, P-101).
✗51 earned a Part 5 rule and it is applied here rather than remembered: a clause stated as a ratio of
a total must name the share of that total it can move. Every clause below carries a SHARE line, and every
registration carries a VACUITY CONTROL naming the column that proves the fixture could have failed —
P-70's C3 is the precedent for what happens without one.
Dependencies, stated once. P-85 runs before P-81 and P-84. P-77 runs before P-76 and P-91.
P-88 rides P-87. Everything else is independent.
Group A - rendering and shading, the gap by omission
Across all six gameplay research docs there is no proposal touching global illumination, shadowing, volumetrics, atmospherics, or a material system beyond the phase field, the pseudonormal, the off-surface shading canary and decals-from-the-log-map. Lighting appears twice: as a failure symptom, and as an analogy. Eight registrations are there, and it is where this crate's constraints buy most — every cost in the SDF-rendering literature is constructing the field, and this crate has it.
P-73 — registered for R-073, before the harness: The angle-weighted pseudonormal is the wrong fix, and the gradient is both better and the only bit-exact option
Ticket: R-073 (S). Records: field, resolution, weighting, median_angle_error_deg, p99_angle_error_deg, gradient_median_deg, ratio_to_gradient, canary_mean_abs_f, canary_rank_correlation, worst_decile_triangles, hashes_moved_connectivity, hashes_moved_gradient, c1_holds, c2_holds, c3_holds.
Hypothesis. THE HOOK IS A PROPOSAL IN THIS REPOSITORY'S OWN DOCS. The mechanics dossier proposes the angle-weighted pseudonormal at 'under 2 degrees difference on good triangles, over 15 degrees on radius-ratio under 0.15, about 40 lines'. Jin, Lewis and West 2005 (10.1007/s00371-004-0271-1, 140 citations) scored six connectivity weightings -- equal, angle, sine-and-edge-length-reciprocal, adjacent-triangle-area, edge-length-reciprocal, sqrt-edge-length-reciprocal -- against the analytic normal, and on MARCHING-TETRAHEDRA OUTPUT EVERY ONE OF THEM HAS A MEDIAN DISCREPANCY OF 5-20 DEGREES at the highest resolution they tested. Their diagnosis is spatial aliasing in irregular implicit tessellation, which is M-72's mechanism seen from the shading side. NormalStrategy already has AnalyticGradient and CentralDifference; this measures whether a third is worth having. (C1) On eight reference fields at 33^3 and 65^3, every connectivity weighting has a median angular error against the analytic gradient of at least 3x CentralDifference's at the cell size, and thin_plate and noise_cavity are the worst. (C2) mean |f(v)| -- the off-surface shading canary the dossier proposes in two lines -- PREDICTS the per-vertex angular error, rank correlation above 0.7 on at least six of eight fields. (C3) THE DETERMINISM ARGUMENT, INDEPENDENT OF QUALITY: angle weighting needs acos, libm's acos has no architecture selection, and a connectivity-weighted normal is therefore a golden-hash liability on a crate committing 216 of them. Measured: the connectivity route moves at least one hash between the M5 and the Zen 3 and the gradient route moves none. SHARE: C1 and C2 move the whole normals stage; C3 moves nothing and is a correctness clause.
Falsified by. C1 by any weighting within 3x, which would mean the 2005 result does not transfer to trilinear output and the dossier's proposal is right. C2 by a rank correlation below 0.7 on three or more fields, which would mean the canary and the error are different phenomena and the canary is not a proxy for shimmer. C3 by zero hash movement on the connectivity route, which would be the more interesting result and would remove the determinism objection entirely. VACUITY CONTROL: the fixture must contain triangles in the bottom decile of the aspect-ratio distribution on every field, reported as a column, or C1 is measuring well-shaped triangles only.
P-74 — registered for R-074, before the harness: Ambient occlusion and soft shadows traced against the field the mesh came from
Ticket: R-074 (M). Records: field, resolution, rays_per_pixel, march_steps, ao_ms_field, ao_ms_ssao, seam_pixels, silhouette_pixels, seam_mae_field, seam_mae_ssao, halo_mae_field, halo_mae_ssao, resident_ms, rebuild_ms, c1_holds, c2_holds, c3_holds, adapter.
Hypothesis. NOTHING IN SIX GAMEPLAY DOCUMENTS PROPOSES A LIGHTING FEATURE, and this is the cheapest one available because the expensive half is already paid. RTSDF (10.5220/0010996200003124, arXiv 2210.06160) measures on an RTX 2080 Ti at 1024^2: jump flood 2.09 ms, ray trace 4.60 ms, total frame 10.22 ms at 97 fps -- and 2.09 ms of that is BUILDING a 128^3 SDF the game does not have. nvblox (10.1109/icra57147.2024.10611532) measures 0.8-7.3 billion distance queries per second, about 3 ns per query, on an RTX 3090 Ti, after paying 0.4 ms per frame to integrate the TSDF. This crate's field is analytic, resident, and already evaluated on the GPU at M-155's 0.54 ms for a 129^3 grid; isomesh-gpu/src/jump_flood.rs already exists. (C1) Screen-space AO by sphere-tracing the resident field costs under 2.0 ms at 1920x1080 on the Zen 3 / RTX 3090 rig, with 8 rays per pixel and a 16-step cone march. (C2) Against a mesh-based SSAO baseline on gyroid and fbm_terrain, field-traced AO has NO darkening error at chunk seams and no haloing at silhouettes, measured as mean absolute difference against a 512-ray offline reference; SSAO's seam and halo error is non-zero on both. (C3) The construction cost RTSDF pays is ZERO here, measured as the difference between total frame cost with the field already resident and the same trace after a jump-flood rebuild. SHARE: C1 moves the whole AO budget, currently paid in full by a mesh-based pass.
Falsified by. C1 by above 2.0 ms. C2 by SSAO matching it, which would mean the field buys nothing a depth buffer does not already have. C3 by a non-zero resident cost, which would mean the field is not reusable in the form the tracer wants and there is a conversion nobody costed. VACUITY CONTROL: the seam and silhouette pixel sets must be non-empty and reported as counts, because a scene with no visible seam cannot distinguish the two methods.
P-75 — registered for R-075, before the harness: Material weights carried at the vertex, against the edit log walked at the fragment
Ticket: R-075 (M). Records: log_bucket, brushes, materials, boundary_vertices, weights_ms, extract_ms, weights_share, frame_ms_vertex, frame_ms_fragment, speedup, misclassified_points, misclassified_fraction, misclassified_within_one_cell, c1_holds, c2_holds, c3_holds.
Hypothesis. M-138 MEASURED THE PRICE OF EXACT PAINT: every sample walks the edit log, at 2.33x the cost per chunk. That is per SAMPLE. A shading pass pays it per FRAGMENT, every frame, at screen resolution. The alternative is bounded per-vertex material weights -- an [f32; 4], L1-normalised, the de facto standard in voxel renderers -- computed once during extraction from the same walk. Nobody has published the comparison; the only public arithmetic for a real pipeline is a blog post costing 4 materials x 3 triplanar planes x 5 maps = 60 texture fetches per fragment, with NO TIMING BEHIND IT. SCOPE, stated at registration: this is weights carried as a VERTEX ATTRIBUTE, which is additive and breaks nothing. Whether Sdf grows a phase concept (the PhaseTree proposal) is a public-API decision and is NOT part of this. (C1) Per-vertex weights, computed inside the existing extraction walk, cost under 5% of extraction. (C2) At 1920x1080 on game_dig's scene, per-vertex weights beat a per-fragment log walk by at least 4x in frame time, and the gap WIDENS with edit-log length across M-50's four buckets (1-15, 16-30, 31-45, 46-60 brushes). (C3) Interpolating weights across a triangle is not exact: the material misclassification rate against the field at 10^6 surface points is under 2%, and is concentrated within one cell of a material boundary. SHARE: C1 moves the vertex-attribute stage, currently zero; C2 moves the whole material shading stage.
Falsified by. C1 by above 5%. C2 by under 4x, or by a gap that does not widen with log length -- the second means the fragment path is not paying M-138's cost and the premise is wrong. C3 by above 2%, or by misclassification that is not boundary-local, the latter meaning the weights are not a resampling of the field but a different quantity. VACUITY CONTROL: the scene must contain at least two materials with a boundary crossing the visible surface, reported as a boundary-vertex count.
P-76 — registered for R-076, before the harness: One stochastic triplanar plane instead of three, and what it costs the temporal budget
Ticket: R-076 (M). Records: arm, fetches_per_fragment, fragment_ms, frame_ms, history_rejected_static, history_rejected_digging, mae_vs_reference_static, mae_vs_reference_digging, frames_after_edit, biplanar_fetches, biplanar_fragment_ms, c1_holds, c2_holds, c3_holds.
Hypothesis. TRIPLANAR AND STOCHASTIC FILTERING COMPOSE MULTIPLICATIVELY AND NOBODY STATES THE PRODUCT. Three planes x three stochastic taps is nine fetches per map; bevy_isomesh/examples/triplanar.wgsl already pays the three. Stochastic Texture Filtering (arXiv 2305.05810) and Heitz-Neyret histogram-preserving blending (10.1145/3233304, 'over 20x faster' than procedural-noise state of the art, HARDWARE NOT NAMED) both trade fetches for temporal accumulation. The conflict is the finding worth registering: A DESTRUCTIBLE WORLD HAS ALREADY SPENT ITS TEMPORAL BUDGET, because geometry that changes rejects history. This registration is gated on P-77, which measures that rejection; running it first would price the saving without pricing the debt. (C1) Selecting one triplanar plane per pixel stochastically drops the fetch count by exactly 3x and the fragment cost by at least 2x at 1920x1080. (C2) With TAA resolving the stochastic choice, the ghosting cost under an active dig is WORSE than the fetch saving is worth: measured as mean absolute error against a 3-plane reference in the 8 frames following an edit, above the error of the same scene with no digging. (C3) Biplanar mapping -- two planes, no stochastic term, no temporal debt -- gets at least half the saving of C1 with none of C2's cost. SHARE: C1 moves the material shading stage, which P-75's C2 will have measured.
Falsified by. C1 by under 2x. C2 by no difference between digging and static, which would mean history rejection is not the bottleneck and stochastic filtering is free here after all. C3 by under half, which makes the honest recommendation 'keep three planes'. VACUITY CONTROL: the dig arm must produce a non-zero history-rejection count from P-77's instrument, or C2 cannot fire.
P-77 — registered for R-077, before the harness: How much temporal history a dig destroys, and whether 0.2 ms buys it back
Ticket: R-077 (M). Records: arm, stroke_rate_hz, steady_rejection_fraction, post_edit_rejection_fraction, ratio, frames_elevated, kdop_ms, kdop_recovered_fraction, rejected_in_brush_box, rejected_total, concentration_fraction, c1_holds, c2_holds, c3_holds.
Hypothesis. THE ONE MEASURED MITIGATION IN THIS AREA IS CHEAP AND THE PROBLEM IT MITIGATES HAS NEVER BEEN MEASURED UNDER DESTRUCTION. k-DOP clipping (10.1145/3681758.3697996) replaces TAA's axis-aligned neighbourhood clamp with a tighter k-discrete-oriented polytope at 0.2 ms overhead (GPU NOT NAMED IN THE ABSTRACT), and its framing is that prior bounding-box methods are 'only situationally effective'. Separately, Epic's account of virtual shadow maps in Fortnite says animated deformation invalidates shadow pages and that they ABANDONED CACHING FOR DIRECTIONAL SUN SHADOWS ENTIRELY -- with no invalidation cost published anywhere. This experiment measures the destruction half; P-79 measures the shadow half. (C1) In game_dig, the fraction of TAA history samples rejected in the frame after a brush stroke is at least 5x the steady-state rejection rate, and the elevated rate persists for at least 3 frames. (C2) k-DOP clipping recovers at least half the rejected samples at under 0.3 ms. (C3) The rejection is SPATIALLY CONCENTRATED at the brush, not global: over 80% of rejected samples fall within the brush's screen-space bounding box dilated by one dig radius. SHARE: C1 is a rate, not a ratio of a total; C2 moves the TAA resolve stage.
Falsified by. C1 by under 5x, or by a single-frame spike -- either means destruction is not a temporal problem, and this row and P-76's C2 close together. C2 by under half, which would mean the rejections are genuine disocclusions rather than clamp conservatism and no clipping scheme can help. C3 by under 80%, which would mean an edit disturbs the whole frame and a localised mitigation cannot work. VACUITY CONTROL: the steady-state arm must have a non-zero rejection rate, or the 5x ratio is division by a floor.
P-78 — registered for R-078, before the harness: How many light probes one dig invalidates
Ticket: R-078 (M). Records: log_bucket, probe_density, world_cells, brush_support_cells, probes_invalidated, invalidation_factor, gather_ms_field, gather_ms_mesh, gather_speedup, breakthrough, air_components_before, air_components_after, probes_invalidated_breakthrough, c1_holds, c2_holds, c3_holds.
Hypothesis. PROBE-BASED GI IS THE ONLY GI FAMILY THAT TOLERATES GEOMETRY CHANGING EVERY FRAME, AND ITS COST UNDER A DESTRUCTIBLE WORLD IS UNMEASURED. The best rigorous measurement available is a bachelor's thesis (Dell'Ova, BTH 2025, DOI UNVERIFIED) finding that 87-96% of radiance-cascade frame time is the GATHER pass -- cost is dominated by tracing the scene, not by the cascade structure. That matters because this crate can trace an SDF instead of a BVH, which is what P-74 measures. But the question a game asks first is how much of the cache a dig dirties, and the crate already owns the instrument: M-311's dirty-cell set and M-314's edit-proportionality decomposition. (C1) The probe invalidation set is EDIT-PROPORTIONAL, not volume-proportional: the number of probes whose visibility changes tracks the brush's dilated support with a constant factor under 4, across M-50's four edit-log buckets and three probe densities. (C2) Tracing the field beats tracing the extracted mesh for probe updates by at least 3x at equal ray count. (C3) A dig that opens a new air component -- M-311's union-find merge, the banked breakthrough event -- invalidates STRICTLY MORE probes than a dig of the same volume that does not. SHARE: C2 moves the gather pass, which the thesis puts at 87-96% of GI cost.
Falsified by. C1 by a factor above 4, or by a count that grows with world size at fixed edit size -- the second kills probe GI for this game outright and is worth knowing in an afternoon. C2 by under 3x. C3 by no difference, which would mean the topological event has no lighting signature and the banked breakthrough event cannot drive a lighting response. VACUITY CONTROL: the breakthrough arm must actually merge two air components, asserted from the union-find rather than assumed from the brush.
P-79 — registered for R-079, before the harness: Shadow-map page invalidation per edit, which nobody has published
Ticket: R-079 (M). Records: field, light_direction, brush_volume_cells, brush_projected_area, pages_invalidated, invalidation_constant, changed_pixels_full, changed_pixels_localised, shadow_ms_cached, shadow_ms_uncached, stroke_rate_hz, c1_holds, c2_holds, c3_holds.
Hypothesis. EPIC'S OWN ANSWER TO DEFORMING GEOMETRY WAS TO STOP CACHING. The Fortnite virtual-shadow-map write-up gives exactly one quantitative figure -- a light-loop optimisation from 1.56 ms to 1.08 ms -- and describes invalidation qualitatively: sun movement causes 'quite significant shadow page table changes frame to frame', animated deformation invalidates pages, and directional sun shadows were left uncached. FOR A WORLD WHERE THE GEOMETRY IS BEING DUG AWAY THAT IS THE RELEVANT PRECEDENT AND THE NUMBER IS MISSING FROM THE LITERATURE ENTIRELY. (C1) In game_dig with a cached shadow atlas, one brush stroke invalidates a page count proportional to the brush's PROJECTED area from the light, with a constant under 3 -- not to the brush volume and not to the scene. (C2) Invalidating only the pages the brush's light-space bounding volume touches produces a PIXEL-IDENTICAL shadow to a full re-render, on all eight reference fields. (C3) The saving is worth having: cached-with-invalidation beats uncached by at least 2x in shadow cost under a continuous dig at game_dig's throttled 12.5 strokes per second. SHARE: C3 moves the shadow rendering stage only.
Falsified by. C1 by a constant above 3, or by scene-proportional invalidation. C2 by any pixel difference, which would mean the conservative bound is wrong and localised invalidation is unsound. C3 by under 2x, which vindicates Epic's decision and closes the direction with a number they did not publish. VACUITY CONTROL: the light must be positioned so the brush casts a shadow into the visible frame, asserted by a non-zero changed-pixel count on the full-re-render arm.
P-80 — registered for R-080, before the harness: The LOD residual as a normal map, so coarse chunks keep their detail as shading
Ticket: R-080 (M). Records: field, lod_level, coarse_vertices, residual_agree_fraction, residual_p95_cells, angle_lod0_vs_lod2_no_map, angle_lod0_vs_lod2_with_map, changed_vertices, bake_ms, map_bytes_per_chunk, c1_holds, c2_holds, c3_holds.
Hypothesis. M-72 IS THE FINDING THIS IS BUILT ON AND NOBODY HAS EXPLOITED IT. Sub-cell features do not vanish under coarsening, they ALIAS -- thin_plate goes 4,088 to 1,016 to 248 to 56 triangles across LOD 0-3 -- and the dossier's response is to make the disappearance authorable. There is a second response: the difference between the fine surface and the coarse one is a VECTOR FIELD THIS CRATE CAN EVALUATE, because it owns the analytic field at both scales. Bake it into a tangent-space normal map per coarse chunk and the geometry fades while the shading does not. The sweep found NO MEASURED STUDY of normal-mapping detail onto a coarse isosurface at all. (C1) For each coarse-LOD vertex, the direction from the coarse surface to the nearest fine-surface point is computable from the field alone -- one gradient and one root refinement, no fine mesh -- and agrees with the true nearest point to within 0.1 cells on 95% of vertices at LOD 1 and 2. (C2) A normal map baked from that residual reduces perceived detail loss: mean angular difference between LOD-2 shading-with-map and LOD-0 shading is under 10 degrees on fbm_terrain, against over 25 degrees for LOD-2 without. (C3) WHERE IT MUST FAIL, STATED IN ADVANCE: it cannot work on thin_plate or gyroid at LOD 3, because a normal map cannot restore a SILHOUETTE and both fields lose topology rather than curvature -- predicted above 25 degrees on both, with the map. SHARE: C2 moves the shading half of the LOD budget only; triangle counts are unchanged by construction.
Falsified by. C1 by under 95%, or by an error that grows with LOD level faster than the cell size. C2 by over 10 degrees with the map, or under 25 without -- the second would mean coarsening does not cost shading detail on this field and the premise is wrong for terrain. C3 by the map working on thin_plate or gyroid at LOD 3, which would be a much stronger result than the row claims and would need explaining. VACUITY CONTROL: the LOD-0 reference must differ from LOD-2 by more than 25 degrees somewhere, reported as a changed-vertex count, or C2 is comparing two identical shadings.
Group B - collision and physics
The framing number: the collider check is 45% of the pipeline, larger than contouring (M-135), and the docs call it "the unexamined 45%". P-85 points ✗52's attribution instrument at it and decides which of the others is worth doing.
P-81 — registered for R-081, before the harness: A capsule against the field, instead of a capsule against the triangles
Ticket: R-081 (M). Records: field, chunk_cells, queries, gss_iterations, query_us_field, query_us_trimesh, speedup, contacts_bit_identical, differing_contacts, ghost_contacts_trimesh, ghost_contacts_field, seam_crossings, c1_holds, c2_holds, c3_holds.
Hypothesis. THE DOCS ALREADY PROPOSE SDF COLLISION AND CITE THE WRONG PAPER FOR THE GAME'S ACTUAL CASE. The cited source is Liu et al. 10.1016/j.cagd.2024.102305, which is SDF-vs-SDF for two comparable solids -- a strictly harder problem needing interval arithmetic, which is a determinism liability. The game's case is a small analytic proxy against one enormous static field, and that is Macklin, Erleben, Mueller, Chentanez, Jeschke and Corse, 10.1145/3384538: per-element local optimisation between an SDF isosurface and mesh elements, comparing projected gradient descent, Frank-Wolfe and golden-section search, with GSS WINNING ON THE 1-D EDGE PROBLEM. Their decisive line, on 129k-triangle rigid shells: 'this mesh-based collision took approximately 15 ms per-step, compared to under 0.5 ms using SDF-based contact', 48-445 microseconds per timestep, CUDA on a GTX 2080 Ti. DISCOUNTED HONESTLY AT REGISTRATION: their 30x is GPU-parallel against a deep BVH over 129k triangles; this crate's baseline is a much smaller per-chunk parry3d TriMesh on CPU, so single-digit x is the prediction. THIS ROW IS GATED ON P-85, which decides whether the 45% is query cost or construction cost. (C1) Capsule-vs-field by GSS costs under 20 microseconds per query on the Zen 3 and beats the shipped TriMesh path by at least 3x on fbm_terrain at 33^3 chunks. (C2) A fixed iteration count with no data-dependent branching gives bit-identical contact points across the M5 and the Zen 3, on 10^6 queries. (C3) Ghost contacts -- collisions against internal edges between adjacent triangles -- are STRUCTURALLY ABSENT from the field query: non-zero on the TriMesh path over M-106's 495-seam-crossing fixture, exactly zero on the field path. SHARE: C1 moves the query half of the collider's 45%, and P-85 will have measured how large that half is.
Falsified by. C1 by under 3x, which would mean the TriMesh path's cost is collider CONSTRUCTION rather than query and this attacks the wrong half -- in which case P-85's answer is what matters. C2 by one differing contact, which puts the method behind the same wall as every other float-sensitive path. C3 by zero on both, which would mean avian3d already handles it and Jolt's v5.0.0 internal-edge-removal work and avian#612 are solving a problem this crate does not have. VACUITY CONTROL: the TriMesh arm must report a non-zero ghost-contact count, or C3 cannot fire.
P-82 — registered for R-082, before the harness: Tunnelling through a wall you just made thin
Ticket: R-082 (M). Records: wall_thickness_cells, speed_cells_per_step, shots, tunnels_discrete, tunnels_ccd, us_per_element, elements, linear_fit_r2, toi_capsule_spheres, toi_capsule_mesh, toi_disagreement_cells, cost_ratio_spheres_vs_mesh, c1_holds, c2_holds, c3_holds.
Hypothesis. A DIGGER IS THE FASTEST THING IN THE GAME AND THE WALL IN FRONT OF IT IS GETTING THINNER EVERY FRAME. That is the exact configuration discrete collision cannot survive, and there is now a CPU-only measured answer: Pelletier-Guenette, Mercier-Aubin and Andrews, 10.1145/3747862 (SCA 2025) -- spatio-temporal local optimisation for first time of impact, a modified Frank-Wolfe with golden-section search over barycentric coordinates AND TIME, with adaptive triangle subdivision giving multiple contacts per triangle. Intel i9, single CPU thread, CPU-only: an 888-triangle shuriken at 0.4 ms total, 11.13 microseconds mean per triangle; 100K triangles at 0.96 microseconds per triangle. It beats Macklin 2020's discrete detection on all their tests -- SELF-ADJUDICATED, since no standard triangle-SDF CCD benchmark exists, and that is stated here rather than discovered. (C1) At the speed a game_dig projectile travels, the discrete path tunnels through a wall of thickness t below v*dt and the CCD path does not, over 10^4 randomised shots at a wall swept from 2 cells down to t/h = 0.05 (subgrid's floor, M-95). (C2) Cost per moving element stays under 25 microseconds and is LINEAR in element count. (C3) A capsule approximated by 8 swept spheres reaches the same first-time-of-impact as a 200-triangle capsule mesh, to within one cell, at 10x less cost. SHARE: C2 moves a single dynamic body's collision budget, not the whole frame.
Falsified by. C1 by the discrete path not tunnelling, which would mean the game's speeds are below the threshold and this is premature. C2 by superlinear cost, or above 25 microseconds. C3 by a disagreement above one cell, which would mean the proxy is too coarse and the cheap version of this does not exist. VACUITY CONTROL: the discrete arm must tunnel at least once, reported as a count, or C1 is comparing two methods that both work.
P-83 — registered for R-083, before the harness: Mass, centre of mass and inertia from the triangles already emitted
Ticket: R-083 (S). Records: field, resolution, volume, volume_reference, volume_rel_error, com_rel_error, inertia_rel_error, convergence_order, asymmetry_pre, asymmetry_post, bit_identical_across_machines, mass_props_ms, extract_ms, share, c1_holds, c2_holds, c3_holds.
Hypothesis. NOTHING IN THE LITERATURE COMPUTES MASS PROPERTIES FROM AN SDF ANALYTICALLY, AND NOTHING BENCHMARKS IT. The nearest usable result is Hartmann and Ewougsi Tekeu, 10.1007/s00707-025-04419-1: inserting T = x tensor x into the divergence theorem converts the volume integral for the inertia tensor into a PURE SURFACE INTEGRAL, evaluated analytically per triangle with linear shape functions. No wall-clock timings, but the operation count is below tetrahedral volume discretisation at equal resolution. This crate emits the surface; the integral is one pass over data it just produced, with no mesh round-trip to parry3d. IT IS ALSO THE ONLY ROW IN GROUP B THAT IS CORE-CRATE ELIGIBLE -- pure arithmetic, no_std, allocation-free, generic over Real. (C1) Volume, centre of mass and the inertia tensor agree with a dense voxel reference to 1e-4 relative on all eight reference fields at 33^3, and the error falls at h^2. (C2) DETERMINISM AND THE TRAP THE PAPER NAMES: float summation is non-associative, so a fixed triangle iteration order is required for hash stability; and the paper's own discretisation yields a NON-SYMMETRIC inertia tensor despite the continuous form being symmetric, fixed by averaging off-diagonals. Both are measured: fixed order gives bit-identical tensors across machines, and the pre-symmetrisation asymmetry is non-zero. (C3) It costs under 2% of extraction. SHARE: C3 moves the whole mass-properties stage, currently paid by parry3d after a mesh handoff.
Falsified by. C1 by worse than 1e-4, or a convergence order below 1.5 -- the second would mean the surface integral is not seeing the geometry the volume integral sees. C2 by zero asymmetry, which would mean the crate's triangles are better behaved than the paper's and the symmetrisation step can be dropped. C3 by above 2%. VACUITY CONTROL: the reference must be a dense voxel integration at a resolution that itself converges, reported with its own h^2 fit, or C1 is measuring the reference.
P-84 — registered for R-084, before the harness: Convexity preserved rather than recovered, against M-116's 241 ms
Ticket: R-084 (L). Records: field, chunk_cells, brushes, fragments, fracture_ms_per_fragment, fracture_ms_worst, convex_cells_before, convex_cells_after, cell_growth_ratio, orderings, distinct_partitions, partition_hash, c1_holds, c2_holds, c3_holds.
Hypothesis. A-027 ALREADY PROPOSES THIS AND DOES NOT CITE THE PAPER THAT MEASURED IT. Mueller, Chentanez and Kim, 10.1145/2461912.2461934 (TOG 2013): split the geometry into non-overlapping convex regions OFFLINE, then at runtime align a convex fracture pattern to the impact and intersect it against the precomputed compound. The invariant is that CLIPPING A CONVEX SHAPE AGAINST A CONVEX CELL YIELDS CONVEX PIECES, so runtime decomposition never happens. Measured: 'the time to fracture small to average sized objects is typically negligible, i.e. below 10 ms', staying below 50 ms throughout, reaching 20k compounds and 32k convexes -- on a Core i7 at 3.07 GHz with a GTX 680. AND THE 2026 STATE OF THE ART HAS NOT IMPROVED ON IT: M-297 said no published convex decomposition runs at interactive rates and that holds -- VisACD (arXiv 2604.04244) is a GPU method averaging 16.97 seconds per model against CoACD's 36.31 s, four orders of magnitude off a frame budget. (C1) A brush intersected against a convex-cell partition of a chunk produces convex fragments in under 10 ms per fragment, against M-116's 241-272 ms. (C2) THE MULTIPLAYER CLAUSE, and the one that makes this crate's version better than Mueller's: the convex-cell partition is a PURE FUNCTION OF THE EDIT LOG -- eight same-kind brushes in all 40,320 orderings give one partition, bit-for-bit, reproducing M-36 at the cell level. (C3) Piece count stays bounded: a chunk that has taken 60 brushes (M-50's largest bucket) has under 4x the convex cells of an unedited one. SHARE: C1 moves the whole destruction-collider stage.
Falsified by. C1 by above 25 ms, which is still 10x better than M-116 and would still be worth landing -- the clause is set at 10 to make the 2013 number the bar rather than a comfortable one, and the entry must report both. C2 by more than one partition, which would mean the decomposition introduces order-dependence the field does not have and breaks the coordination-free story M-36 bought. C3 by above 4x, the failure mode that turns this into a memory problem instead of a time problem. VACUITY CONTROL: the 40,320-ordering arm must actually reach every ordering, asserted by count, which is M-36's own fixture.
P-85 — registered for R-085, before the harness: Point the attribution instrument at the 45%
Ticket: R-085 (S). Records: field, chunk_cells, triangles, copy_ms, construct_ms, bvh_ms, handoff_ms, total_ms, residual_ms, largest_stage, largest_share, cost_per_triangle, seam_boundary_edges, degenerate_triangles, c1_holds, c2_holds, c3_holds.
Hypothesis. ✗52 IS THE TEMPLATE AND IT IS THE MOST TRANSFERABLE THING PHASE 23 PRODUCED. P-71 predicted the GPU synchronisation would be dominated by the count wait, measured it, and found the GEOMETRY COPY at 60% of the whole extraction instead. THE COLLIDER STAGE HAS NEVER HAD THAT TREATMENT. It is 45% of the pipeline, larger than contouring (M-135), and nobody knows whether it is BVH construction, triangle copying, parry3d's constructor, or the weld that M-69 and ✗18 argue about. Independent corroboration exists and is weaker than this will be: Godot Voxel Tools' performance documentation says 'creating a collider from a mesh is actually much more expensive than meshing itself (about 3 to 5 times)', WITH NO ABSOLUTE TIMINGS AND NO HARDWARE. THIS IS THE CHEAPEST ROW IN THE PHASE AND IT DECIDES WHICH OF P-81 AND P-84 IS WORTH DOING. (C1) Decomposed into copy, construct, BVH-build and handoff, ONE STAGE IS OVER 50% of the collider cost at 33^3 and 65^3 chunks on fbm_terrain and gyroid. (C2) The dominant stage is NOT the one the docs assume: Godot's docs blame BVH construction; predicted here it is the triangle copy, by analogy with ✗52's finding that the copy dominated on the GPU side for the same structural reason -- the bytes have to move. (C3) The cost is NOT proportional to triangle count alone: at fixed triangle count, gyroid's collider costs at least 1.5x sphere's, because seam boundary edges (M-69's 72 per seam) and degenerate slivers are per-field. SHARE: this experiment measures shares and moves nothing.
Falsified by. C1 by four stages each under 50%, which would mean the cost is diffuse and there is no single lever -- a null worth having, and it would redirect the group toward P-81's query-side attack. C2 by BVH construction dominating, which vindicates the folklore and is equally useful. C3 by proportionality to triangle count, which would make the whole stage predictable from a number the extractor already reports and is the best possible outcome for the scheduler. VACUITY CONTROL: the four stages must sum to the measured total within 5%, reported as a residual column, or the decomposition is missing a stage.
P-86 — registered for R-086, before the harness: How many of a character's stops are geometry artefacts
Ticket: R-086 (M). Records: field, steps, seam_crossings, stops_total, stops_on_worst_decile, worst_decile_fraction, stops_per_triangle_seam, stops_per_triangle_interior, seam_excess_ratio, stops_field_path, aspect_ratio_p10, c1_holds, c2_holds, c3_holds.
Hypothesis. M-115 FOUND THAT A MOVING BODY IS STOPPED HARDER AND MORE OFTEN BY ORDINARY TERRAIN THAN BY A CHUNK JOIN, AND LEFT THE HARDER QUESTION OPEN: how many of those stops are REAL. The crate records degenerate near-zero-area triangles as a metric rather than a gate, because Marching Cubes genuinely emits slivers whenever a grid corner sits near zero -- that is the algorithm, not a bug. But a sliver is exactly what a capsule controller catches on, and M-185 already found that completing the crossing identity turned a sliver into a repeated-index triangle the extractor now declines to emit. NOBODY HAS CONNECTED THE RECORDED METRIC TO THE GAMEPLAY SYMPTOM. This is also where the literature is thinnest: there is essentially no peer-reviewed work on capsule-vs-isosurface locomotion at chunk seams, and M-115 is better evidence than anything published. (C1) Over game_capsule_walk's 495 seam crossings plus a 10^4-step randomised walk on fbm_terrain, at least 20% of controller stops occur on a triangle in the bottom decile of the aspect-ratio distribution. (C2) Stops are NOT concentrated at chunk seams, confirming M-115 from the controller's side rather than the body's: seam-adjacent triangles carry no more stops per triangle than interior ones. (C3) The field query path from P-81 removes ALL of C1's stops, because it never sees a triangle. SHARE: this is a rate, not a ratio of a total.
Falsified by. C1 by under 20%, which would mean slivers are not what stops a character and the recorded metric has no gameplay consequence -- a genuine null and worth the afternoon. C2 by a seam excess, which reopens M-133's 'not reliably seam-closing' as a gameplay defect rather than a topology one. C3 by any surviving stop, which would mean the terrain genuinely stops the character there and C1 was measuring geometry that is correct. VACUITY CONTROL: the walk must produce a non-zero stop count on both arms, and the bottom aspect-ratio decile must be non-empty, both reported as counts.
Group C - navigation
The navigation direction here is costed and the cost is fatal — the docs put PLMSS at 0.36 s on 24 threads, which they call 20–40× over a frame. There is a measured third option at ~1 ms on a laptop.
P-87 — registered for R-087, before the harness: An octree that repairs itself locally, against a Morse-Smale route this project already costed at 0.36 seconds
Ticket: R-087 (M). Records: field, world_cells, chunk_cells, edits, dirty_cells, repair_cells, repair_factor, octree_update_ms, graph_update_ms, total_ms, cells_before_merge, cells_after_merge, reduction, topology_changes, c1_holds, c2_holds, c3_holds.
Hypothesis. THE NAVIGATION DIRECTION IN THIS REPOSITORY IS COSTED AND THE COST IS FATAL. The docs propose deriving the encounter graph from field topology via Morse-Smale segmentation and record the price: PLMSS at 256^3 takes 4.40 s single-threaded, 0.36 s on 24 threads, which the docs themselves call '20-40x over a 16 ms frame'. Recast is worse in a different way -- a 2026 devlog measures Unreal's navmesh generation at a constant ~5 ms and a ~10 FPS drop for a relatively simple sublevel, and Recast rebuilds a tile by voxelising collision geometry, so this game would voxelise a mesh it generated from voxels. THERE IS A THIRD OPTION NOBODY IN THESE DOCS HAS CONSIDERED AND IT IS MEASURED. Massonnat and Verbrugge, 10.1109/CoG60054.2024.10645669 (IEEE CoG 2024): an octree splits cells containing obstacles, adjacent cells merge by a Hertel-Mehlhorn-inspired greedy method WHILE PRESERVING CONVEXITY, and A* runs on the resulting coarse graph with visibility pruning and a 3-D funnel; extended to dynamic environments with LOCAL octree and graph updates plus a cell-repairing strategy. Measured on an Intel Core i7-12700H laptop: octree update 0.22-1.36 ms, local graph update 0.03 ms, about 1 ms total, with cell reduction up to an order of magnitude (28,190 to 303). The convexity-preserving merge is the same trick as P-84's fracture invariant; two subfields arriving at it independently is a signal. (C1) Built on the sign field and the active-cell bitmap -- never on triangles -- the local repair after P-72's eleven-edit dig trace costs under 2 ms at 4^3 chunk granularity. (C2) The repair set is EDIT-PROPORTIONAL, tracking M-311's 925 dirty cells with a constant factor under 3, and does not grow with world size at fixed edit size. (C3) Convexity-preserving merge gives at least 5x cell reduction on fbm_terrain and gyroid, and gyroid -- topologically the hardest of the eight -- is the one where it does worst. SHARE: C1 moves the whole navigation-rebuild stage, currently unbuilt.
Falsified by. C1 by above 2 ms, which puts it in Recast's band and removes the reason to prefer it. C2 by world-proportional growth -- the same falsifier as P-78's C1 and for the same reason. C3 by under 5x on either field, or by gyroid not being the worst, which would mean the reduction tracks something other than topological complexity. VACUITY CONTROL: the dig trace must change the free-space topology at least once, asserted from the union-find rather than from the brush, or the repair is measuring a no-op.
P-88 — registered for R-088, before the harness: Clearance for free from the octree, without maintaining a medial axis
Ticket: R-088 (M). Records: fixture, samples, known_clearance_samples, narrow_passage_samples, within_one_voxel, within_fraction, overstatements, max_overstatement_cells, lambda_flips, changed_samples, flip_factor, flips_outside_repair_set, c1_holds, c2_holds, c3_holds.
Hypothesis. THE HIGHEST-VALUE GAMEPLAY FEATURE IN THE MECHANICS DOSSIER IS BLOCKED ON A SUB-PROBLEM THE DOSSIER ITSELF NAMES AS THE HARD ONE. CALIBRE -- every creature carries a half-width lambda, reachable space is the connected component of {r >= lambda} -- needs rho maintained under material removal, and the docs say plainly that 'the genuinely hard sub-problem is maintaining rho itself under material removal', with the defining paper (Chazal and Lieutier 10.1016/j.gmod.2005.01.002) unobtainable and O-19 still open on which direction the lambda-filter runs. AN OCTREE OF FREE CELLS GIVES A CLEARANCE LOWER BOUND WITH NO MEDIAL AXIS AT ALL: a cell of side s that is entirely empty admits a sphere of radius s/2, and P-87's merged convex regions give a larger bound directly. M-346 already established the crate can state a clearance rather than only a connection, with exactly zero error where the answer is known. This asks whether the octree route reaches the same number cheaply enough to ship. RIDES P-87 and is not runnable without it. (C1) The octree clearance lower bound is within 1 VOXEL of the true clearance on at least 90% of sampled points across M-346's fixtures -- the same bar the dossier set for CALIBRE's oracle check. (C2) Lambda-membership flips after an edit are AT MOST 4x the changed samples -- again the dossier's own registered bar -- and the flip set is computable from P-87's repair set with no extra traversal. (C3) IT IS CONSERVATIVE IN THE SAFE DIRECTION: the bound NEVER overstates clearance, over 10^6 samples. A creature is never told it fits where it does not. SHARE: this is an accuracy and a rate, not a ratio of a total.
Falsified by. C1 by under 90%, which means the bound is too loose to gate a passage and CALIBRE still needs rho. C2 by above 4x, or by a flip set that is not a subset of P-87's repair set. C3 BY ONE OVERSTATEMENT -- this is one-sided and a single violation kills it, because a gameplay gate that lies in the permissive direction is worse than no gate. VACUITY CONTROL: the sample set must include points whose true clearance is known analytically (M-346's fixtures) and points in dug passages narrower than 2 cells, both reported as counts.
Group D - streaming, LOD and memory
M-377's 51× is the largest game-relevant number in Phase 23 and it arrived with an unpriced bill: 4³ carries 51.6% more vertex data than 64³ for the same surface, and ✗54 has since measured upload at 87.50% of the GPU total.
P-89 — registered for R-089, before the harness: Below 2 cubed
Ticket: R-089 (S). Records: field, chunk_cells, world_cells, chunks, sample_duplication, predicted_ms, measured_ms, model_error, mark_ms, remesh_ms, total_ms, dirty_chunks_total, c1_holds, c2_holds.
Hypothesis. M-377'S OWN OPEN QUESTION, AND IT IS AN HOUR OF WORK. The granularity curve is still RISING at 2^3 on both fields, so 1^3 should be worse -- the sample-duplication penalty ((c+1)/c)^3 is 8.0 at c = 1 against 3.375 at c = 2 -- but it is untested, and M-377 is the entry that established that a boundary minimum is not an answer. The same entry derived a two-term model that gets a stencil of exactly 6 on all twelve arms, so the model is available to be extrapolated against rather than merely fitted. (C1) 1^3 is worse than 2^3 on both gyroid and fbm_terrain, confirming the interior optimum at 4^3. (C2) The measured cost at 1^3 matches M-377's two-term model to within 10%. SHARE: this experiment measures a curve and moves nothing; it settles whether M-377's 51x is a shape or a sample.
Falsified by. C1 by 1^3 winning, which would mean the duplication model is wrong and the whole granularity result needs re-deriving. C2 by above 10%, which means the model does not extrapolate and the 4^3 optimum is a coincidence of the sampled points. VACUITY CONTROL: M-377's own assertion is inherited verbatim -- 'VOID: chunk N marked no dirty chunk in 11 edits' -- and the 1^3 arm must mark dirty chunks on every edit or the row is void.
P-90 — registered for R-090, before the harness: Per-block edit-list culling, at a block of 64 cells
Ticket: R-090 (M). Records: field, chunk_cells, brick_cells, brushes, bricks, survivors_chunk_level, survivors_brick_level, additional_removed, bricks_differing_from_parent, bytes_per_brick, speedup_chunk_only, speedup_both, c1_holds, c2_holds, c3_holds.
Hypothesis. DREAMS' HIERARCHICAL EVALUATOR CULLS OVER 99% OF NAIVE EDIT EVALUATIONS BY MAINTAINING A PER-BLOCK EDIT LIST (Evans, SIGGRAPH 2015 Advances -- 1 to 100,000 edits per sculpture, 10-100 M voxels evaluated per second on a PS4, culling efficiency over 99% against brute force). This crate's equivalent is P-39's Lipschitz brush pruning at 3.36x median, measured at CHUNK granularity. M-377 has now moved the optimum chunk to 4^3 -- SIXTY-FOUR CELLS. The question the two results create together is whether pruning still pays when the brick is that small, or whether the per-brick bookkeeping eats it. (C1) At 4^3 granularity, Lipschitz pruning still gives at least 2x on M-50's 46-60 brush bucket. (C2) Carrying a per-brick surviving-brush list costs under 8 BYTES PER BRICK amortised across the dig trace, using ✗41's finding that 1,507 survivors cut to 73 necessary. (C3) The two culls COMPOSE rather than overlap: pruning at chunk granularity then at brick granularity removes strictly more than either alone, on the eleven-edit trace. SHARE: C1 moves the field-evaluation share of remesh, which M-377 measured as essentially all of remesh_ms.
Falsified by. C1 by under 2x, which would mean P-72's optimum and P-39's win are in tension and the granularity choice has a hidden cost. C2 by above 8 bytes, which at 4^3 granularity is a real memory line item -- a 128^3 world is 32,768 bricks. C3 by no additional removal, which would mean the chunk-level cull already found everything and the brick level is bookkeeping for nothing. VACUITY CONTROL: the trace must contain bricks whose surviving-brush set differs from their parent chunk's, reported as a count, or C3 cannot fire.
P-91 — registered for R-091, before the harness: Geomorph against dither, in units of pixels
Ticket: R-091 (M). Records: field, switch_distance, method, p99_pixels_of_pop, max_pixels_of_pop, pop_cells, bytes_per_vertex, history_rejected_static, history_rejected_lod, history_rejected_lod_and_digging, sum_of_parts, superadditivity, c1_holds, c2_holds, c3_holds.
Hypothesis. TWO ROWS OF THE EXISTING DOCS MEET HERE AND NEITHER NAMES THE HEAD-TO-HEAD. Item 3.6 proposes Lengyel's one-scalar geomorph at 6 bytes per vertex instead of 12 and predicts it FAILS on gyroid and succeeds on fbm_terrain -- 'geomorph on terrain, not on caves'. Item 3.8 proposes switching LOD at the distance where p99 pixels-of-pop falls under one pixel, against M-121's measured pop of up to 3.14 cells. The comparison nobody has run is geomorph against the other standard answer, dithered or alpha-to-coverage cross-fade. THE SWEEP FOUND NO BENCHMARK FOR ANY DITHERED LOD BLEND ANYWHERE. The one measured argument in the literature favours morphing and it is a BANDWIDTH argument rather than an aesthetic one: Haydel, Yuksel and Seiler (10.1145/3618359) chose morphing over stochastic LOD because stochastic causes 'significantly increased data movement' spikes at transitions -- though their hardware is a CYCLE-ACCURATE SIMULATION OF TRaX, NOT A REAL GPU, which is why the argument that survives the port is the structural one and not the number. GATED ON P-77, which measures history rejection. (C1) Geomorph gets p99 pixels-of-pop under 1.0 on fbm_terrain at the current switch distance and FAILS on gyroid, reproducing 3.6's prediction. (C2) Dithered cross-fade gets a LOWER p99 pop than geomorph on gyroid -- because it does not need a coarse-mesh counterpart along p + t*n, which a triply-periodic field denies it -- and a HIGHER cost, measured as P-77's temporal-history rejection. (C3) Dither's cost lands in the same budget destruction has already spent: rejection under dithered LOD plus active digging is MORE THAN THE SUM of each alone. SHARE: C1 and C2 move the LOD transition only; C3 moves the TAA resolve.
Falsified by. C1 by either half -- geomorph failing on terrain would kill it outright, and succeeding on gyroid would be a better result than predicted and needs explaining. C2 by dither also failing on gyroid, which would mean neither transition works on cave topology and the honest answer is a hard switch at a distance where nobody looks. C3 by additivity, which would mean the two effects are independent and dither is affordable after all. VACUITY CONTROL: the no-transition arm must show a measurable pop, reported in pixels, or both methods are being compared against an invisible baseline.
P-92 — registered for R-092, before the harness: Regenerate, do not transmit
Ticket: R-092 (M). Records: field, chunk_cells, triangles, extract_ms, ns_per_triangle, meshopt_bytes, meshopt_decode_ms, meshopt_ns_per_triangle, field_plus_log_bytes, size_ratio, log_bucket, replay_edits, bytes_differing, c1_holds, c2_holds, c3_holds.
Hypothesis. THE BAR IS PUBLIC AND LOW. meshoptimizer decodes sponza -- 184k vertices, 262k triangles -- in 1.92 ms on a Core i7-8650U at 2 GHz, against Draco's 169 ms. That is about 7.3 NANOSECONDS PER TRIANGLE, SINGLE-THREADED, TO DECODE, and decoding produces geometry and nothing else. This crate's extraction produces the geometry AND the material weights AND the gradient normals from a field plus an edit log that is far smaller than any encoding of 440k triangles. And M-31's bit-exact cross-platform determinism turns that from a gamble into a protocol: both endpoints extract the same mesh from the same field, and the golden hashes prove it. THE SWEEP FOUND NOTHING PUBLISHED ON THIS. (C1) Marginal extraction cost per triangle is under 7.3 ns on the Zen 3 for marching_cubes at 33^3 chunks, i.e. re-extracting is cheaper than decoding an encoded mesh of the same output. THIS IS GENUINELY UNCERTAIN and is why it is measured rather than asserted: M-20's 4.75 ns per SAMPLE and ✗51's 10.68 ns per sample extraction marginal do not settle a per-TRIANGLE figure. (C2) The field plus edit log for a dug chunk is at least 20x smaller than meshopt's encoding of that chunk's triangles, across M-50's four log buckets. (C3) Extraction from the same field and log on the M5 and the Zen 3 produces byte-identical output over a 10^4-edit trace -- M-31 at 216 fixtures extended to a long replay, which is a different regime. SHARE: C1 is a per-triangle cost, compared like for like against a published per-triangle cost on named hardware.
Falsified by. C1 by above 7.3 ns, which closes the argument with a number and is the outcome to expect if the surface-to-triangle ratio is unfavourable. C2 by under 20x, which would mean long edit logs approach the size of the geometry they produce and the argument has a crossover the log-trimming ticket must respect. C3 BY ONE DIFFERING BYTE, which is the single most important negative result available here and would end the direction. VACUITY CONTROL: the encoded-size arm must use a real encoder on the real triangles, not an estimate, and its decode time must be measured on this machine rather than quoted from the blog post.
P-93 — registered for R-093, before the harness: What the 4 cubed optimum costs the GPU upload
Ticket: R-093 (M). Records: field, chunk_cells, edits_per_second, remesh_ms, upload_ms, weld_ms, total_ms, raw_vertices, distinct_surface_points, vertex_duplication, crossover_edits_per_second, mixed_granularity_ms, mixed_speedup, visible_chunk_changes, c1_holds, c2_holds, c3_holds.
Hypothesis. M-377 NAMED THIS COST AND DID NOT PRICE IT. At 4^3 the trace carries 51.6% MORE VERTEX DATA than 64^3 for the same 53,110 distinct surface points -- 81,548 against 53,788 -- with the duplication ratio running 2.2122x at 2^3 down to 1.0128x at 64^3. The entry says plainly that this is 'the number a consumer paying for GPU upload should weigh against the 51x edit win', and ✗54 has since measured what upload actually costs: 7.3236 ms of an 8.3694 ms GPU total, 87.50%. SO THE WEIGH-OFF IS NOW COMPUTABLE AND IT HAS NEVER BEEN COMPUTED. (C1) There is a CROSSOVER: below some edits-per-second rate, 64^3 wins on total frame cost despite the 51x edit penalty, because the upload dominates. Predicted to exist between 1 and 20 edits per second -- game_dig throttles the stroke to 12.5 per second, which is inside that window. (C2) Welding closes the duplication (M-377 says it does) at a cost that is itself granularity-dependent, and at 4^3 the weld costs MORE than the upload it saves. (C3) A per-chunk granularity -- coarse for static chunks, fine for actively-dug ones -- beats both fixed choices by at least 1.5x on the eleven-edit trace with a moving camera. SHARE: C1 weighs the remesh stage against the upload stage, whose shares M-377 and ✗54 have both measured.
Falsified by. C1 by no crossover in 0.1-100 edits per second, which would mean 4^3 wins unconditionally and the granularity decision is settled rather than a trade. C2 by the weld being cheaper, which resolves the trade in 4^3's favour and makes C1's crossover a curiosity. C3 by under 1.5x, in which case one global granularity is the right answer and the scheduler stays simple. VACUITY CONTROL: the upload arm must actually upload -- asserted against ✗54's own gpu_vs_cpu.csv row rather than quoted, per P-70's precedent -- and the camera arm must move enough to change the visible chunk set, reported as a count.
Group E - the edit log, which is the save file, the undo stack and the wire format
These measure the edit log, not a network layer. BACKLOG.md closes networked and concurrent editing out and that is not being reopened. The log is the crate's own data structure, it is what a save file is, and its properties have never been measured.
P-94 — registered for R-094, before the harness: How big is a dig, in bytes
Ticket: R-094 (M). Records: session_minutes, strokes, edits, bytes_uncompressed, bytes_per_edit, world_cells, chunk_cells, bytes_per_edit_at_other_world_size, coaxial_brushes, surviving_brushes, collapse_ratio, overlapping_pairs, bytes_zstd, bytes_entropy_coded, compression_advantage, c1_holds, c2_holds, c3_holds.
Hypothesis. NO PEER-REVIEWED PAPER MEASURES BANDWIDTH OR STORAGE FOR A DESTRUCTIBLE WORLD. Voxel Plugin and Godot Voxel Tools both document edit-replication designs with no numbers; the only public datum anywhere is Teardown's ~1 Mbit per client, from a blog post, and their reason for replicating COMMANDS rather than voxels is stated directly: 'commands are the same regardless of object size'. The 08-11 doc estimates 100k operations x 48 B = 4.80 MB against 1.7 GB per-voxel, from CALM; that is an ESTIMATE, not a measurement, and the crate now has the machinery to make it one. SCOPE, stated at registration because BACKLOG.md closes networked editing out and that is not being reopened: this measures the EDIT LOG, which the crate owns, which is what a save file is, and which undo rewinds. No sockets, no clock, no session model. (C1) A one-hour game_dig session at the throttled 12.5 strokes per second produces an edit log under 2 MB uncompressed, and the per-edit cost is CONSTANT in world size and in chunk granularity -- the property that makes the log the right representation. (C2) Coaxial and nested edits collapse: a tunnel dug as 200 overlapping capsules along one axis compresses under max to fewer than 40 surviving brushes, reproducing ✗41's survivor arithmetic (1,507 to 73) on a realistic trace rather than a fixture. (C3) Entropy-coding the log beats a general-purpose compressor by at least 2x, because brush parameters are strongly correlated along a stroke. SHARE: this measures sizes and moves nothing.
Falsified by. C1 by either half -- size growth with world size would mean the log is carrying position precision it does not need. C2 by fewer than 3x collapse, which would mean the log grows with play time in a way trimming cannot fix. C3 by under 2x, which means zstd is the answer and no bespoke format is worth writing. VACUITY CONTROL: the trace must be a real session capture rather than a synthetic sweep, and the coaxial arm must actually overlap -- reported as the pairwise-intersection count -- or C2 is compressing disjoint brushes.
P-95 — registered for R-095, before the harness: Undo, and the checkpoint cadence nobody has measured
Ticket: R-095 (M). Records: field, edits, checkpoint_every_k, undo_ms, refold_ms, crossover_n, crossover_stable_across_fields, predicted_k_from_m50, measured_k, worst_undo_ms, undos_crossing_checkpoint, hash_mismatches, c1_holds, c2_holds, c3_holds.
Hypothesis. THE 08-11 DOC NAMES THIS GAP IN ONE LINE: 'out-of-order arrival forces a re-fold from checkpoint; needs checkpoint cadence measured.' It is also the feature a volumetric editor is unusable without, and game_editor exists. M-50 already measured the fold's cost curve -- 0.158, 0.354, 0.525 and 0.589 ms for logs of 1-15, 16-30, 31-45 and 46-60 brushes -- so the cadence should be DERIVABLE rather than tuned, and that is what makes this a prediction rather than an implementation. (C1) Undoing the last edit costs strictly less than re-folding from a checkpoint whenever fewer than N edits separate them, and N is measurable and STABLE ACROSS FIELDS. (C2) M-50's cost curve gives the cadence directly: checkpoints every k edits hold worst-case undo under 16 ms, and k FALLS OUT OF the 0.158 / 0.354 / 0.525 / 0.589 ms bucket measurements rather than being tuned. (C3) Undo is BIT-EXACT: undoing then redoing an edit returns the golden hash to its previous value, over a 10^3-edit trace with interleaved undo. SHARE: C2 is denominated in a frame, which is the budget undo has to fit in.
Falsified by. C1 by no crossover, which would mean undo is always a re-fold and the checkpoint cadence is the only knob. C2 by a k that does not predict from M-50 -- i.e. undo cost is not the same function as evaluation cost, which would be a finding about the fold rather than about undo. C3 by one mismatch, which would mean the log is not a faithful history and the save format is lossy. VACUITY CONTROL: the interleaved-undo trace must include undos that cross a checkpoint boundary, reported as a count, or C3 tests only the cheap path.
P-96 — registered for R-096, before the harness: How far apart are smooth union's 40,317 answers
Ticket: R-096 (S). Records: blend_radius_k, orderings, distinct_results, coincident_orderings, max_hausdorff_cells, mean_hausdorff_cells, p99_hausdorff_cells, spread_vs_k_slope, max_deviation_from_seam_cells, shell_10k_cells, points_outside_shell, c1_holds, c2_holds, c3_holds.
Hypothesis. M-38 IS THE MEASUREMENT THAT DECIDES WHETHER SMOOTH BLENDING CAN EVER BE ORDER-FREE, AND IT ONLY COUNTED. Smooth union gives 40,317 distinct results from 40,320 orderings -- against hard union's 1 (M-36) and mixed add/subtract's 11 (M-37). Counting distinct results says the operator is order-dependent. IT DOES NOT SAY THE RESULTS ARE DIFFERENT IN ANY WAY A PLAYER COULD SEE, and that is a completely different question with a completely different consequence: if the spread is sub-voxel then smooth union is effectively commutative at gameplay tolerance even though it is not bit-commutative, and the ordering authority M-38 seemed to demand is not needed. One day, on a fixture that already exists, and it changes a protocol decision. (C1) Across all 40,320 orderings of the eight-brush fixture, the MAXIMUM symmetric Hausdorff distance between any two resulting meshes is under 0.1 cells. (C2) The spread SCALES WITH the blend radius k and vanishes as k approaches 0, recovering M-36's exact commutativity in the limit -- so k is the knob, and there is a k below which smooth union is gameplay-commutative. (C3) The spread is SPATIALLY CONFINED to within 10k of a seam between two brushes, matching the |smin_k - min| <= k*ln(n) bound the 2026-08-23 memo derived and measured at max deviation 0.135 against a bound of 0.208. SHARE: this measures a distance, not a ratio.
Falsified by. C1 by above 0.1 cells, which confirms M-38's implication and means smooth-union edits carry a hard ordering requirement. C2 by a spread that does not fall with k, which would mean the order-dependence is not the blend and is something else entirely. C3 by spread outside that shell, which would mean the bound does not localise and the memo's k-as-a-length interpretation is wrong. VACUITY CONTROL: M-38's own fixture is inherited and its 40,320 orderings must all be reached, asserted by count -- and the three orderings that COINCIDE in M-38 must still coincide here, or the harness is not reproducing M-38.
P-97 — registered for R-097, before the harness: Determinism at replay scale, not at fixture scale
Ticket: R-097 (M). Records: field, edits, same_kind_edits, mixed_edits, smooth_union_edits, bytes_differing, first_differing_edit, first_differing_operator, bisection_steps, replay_ms, sum_of_per_edit_ms, linearity_constant, c1_holds, c2_holds, c3_holds.
Hypothesis. M-31 IS 216 GOLDEN HASHES ON EIGHT REFERENCE FIELDS. A SAVE FILE IS A HUNDRED THOUSAND EDITS. These are different regimes and nothing has tested the second. Teardown's team is the only public account and their arc is a warning: they FIRST REWROTE DESTRUCTION IN FIXED-POINT INTEGER ARITHMETIC, then found floating point workable with precautions -- 'floating point operations were considered unsafe for deterministic purposes. That is still true to some extent, but the picture is more nuanced.' They were not committing cross-platform hashes. This crate is, so its bar is higher and its evidence should be too. THE VALUE OF THIS EXPERIMENT IS ENTIRELY IN THE FAILURE CASE: a divergence at edit 60,000 that fixture testing cannot reach is the single worst bug this crate could ship. (C1) A 10^5-edit trace replayed on the M5 and the Zen 3 produces byte-identical meshes on all eight fields. (C2) If C1 fails, the divergence is LOCALISED: the first differing edit is identifiable by bisection and its brush parameters name the operation responsible. (C3) Replay cost is LINEAR in log length with a constant under 1.2x the sum of per-edit costs M-50 measured -- i.e. replay does not have a hidden superlinearity. SHARE: C3 is denominated in the sum of per-edit costs, which M-50 measured directly.
Falsified by. C1 by one differing byte -- and that outcome is the point of the row, not its failure. C2 by a divergence that bisection cannot localise, which would mean the fold accumulates rather than diverges and no per-operation fix exists. C3 by above 1.2x, which would put a ceiling on session length independent of correctness. VACUITY CONTROL: the trace must exercise all three operator classes M-36, M-37 and M-38 distinguish -- same-kind, mixed add/subtract, and smooth union -- reported as three counts, because a trace of only same-kind brushes is the case already known to be order-free.
Group F - Phase 23's own leftovers
Five follow-ons the Phase 23 entries named and did not file, plus the audit item that was downgraded rather than fixed.
P-98 — registered for R-098, before the harness: The fused certificate, at 0.0658
Ticket: R-098 (S). Records: field, resolution, fused_predicate_ms, standalone_predicate_ms, bare_gather_ms, extract_ms, fused_share, standalone_share, certified_cells_fused, certified_cells_standalone, set_difference, unsound_certificates, tunnel_cells, twelve_vertex_cells, extra_passes, c1_holds, c2_holds, c3_holds.
Hypothesis. M-378 NAMED THIS AND EXPLICITLY REFUSED TO SUBSTITUTE IT FOR THE VERDICT. The Plantinga-Vegter predicate costs 21% of extraction standalone, against a registered 5% ceiling -- but the BARE EIGHT-CORNER GATHER IS 0.51 ms ON EVERY SINGLE ARM, and two thirds of the standalone cost is re-reading corners the extractor has already read. A version fused into the extractor's existing gather would pay 0.0658, which is still above 5% but by 1.3 points rather than 16. The entry states that as a number and files nothing. This is that ticket. (C1) Fused into the extraction gather, the predicate costs AT MOST 0.0658 of extraction at 65^3 on all eight fields -- the figure M-378 derived, used as a bar rather than a target. (C2) The certification result is IDENTICAL to the standalone predicate on all 25 rows of p-62.csv plus the 400,000-cell random arm -- same certified set, same zero unsound. (C3) At 0.0658 it is shippable as a default rather than a debug gate: the certified fraction is reportable per chunk at NO EXTRA PASS, and a consumer can read 'this chunk is 87% certified' from the existing report. SHARE: C1 is a share of extraction, which is exactly how M-378 stated it.
Falsified by. C1 by above 0.0658, which would mean the derivation double-counted something and the fused cost has a term the decomposition missed. C2 by any difference, which would mean fusing changed the arithmetic and the soundness proof does not carry over. C3 by needing a second pass to aggregate, which puts it back above the ceiling. VACUITY CONTROL: the random arm from p-62.csv is inherited verbatim -- 2,202 tunnel and 180 twelve-vertex cells -- because the eight reference fields alone gave seven tunnel cells in 172,032, which M-378 itself called 'a hair from M-44's vacuous zero'.
P-99 — registered for R-099, before the harness: The under-resolution witness, on the metric the data supports
Ticket: R-099 (M). Records: field, resolution, k, single_root_edges, multi_root_edges, non_monotonic_single_root, rate_single_root, rate_all_edges, rank_single_root, rank_all_edges, converges, false_negatives, false_positives, oracle_samples, c1_holds, c2_holds, c3_holds.
Hypothesis. ✗53 FALSIFIED ALL THREE CLAUSES AND SAID WHAT THE NEXT REGISTRATION SHOULD BE ABOUT. Two candidate reformulations survive the data: the non-monotonic rate AMONG SINGLE-ROOT EDGES -- which ranks thin_plate first and is the only quantity in the run that fails to converge -- and the false-negative count at fixed k, which needs the oracle and is therefore offline. The entry registers neither on purpose: 'Neither is registered, so neither is claimed.' ✗53's two registration defects are both corrected here rather than repeated: C2's second half asked for a false-positive rate that FALLS with k, which is mechanically impossible because adding a sample point can only add an opportunity to disagree; and C3's metric was taken over ALL grid edges, so it measured how much of the VOLUME has turning gradient rather than how badly the SURFACE is under-resolved, which is why thin_plate -- a thin plate in a mostly-empty box -- ranked eighth. (C1) The non-monotonic rate among SINGLE-ROOT edges ranks thin_plate FIRST of eight at 33^3 and 65^3, where the all-edges rate ranked it eighth. (C2) It FAILS TO CONVERGE on thin_plate and converges on the other seven, reproducing ✗53's observation that thin_plate's false-positive rate is the only one that rises with resolution (0.3889, 0.4412, 0.4697). That non-convergence is the signal an LOD decision wants. (C3) THE CLAUSE ✗53 GOT BACKWARDS, STATED CORRECTLY: false NEGATIVES fall with k -- 322, 94, 8, 1, 0 at k in {2,3,5,9,17} -- and false positives are monotone NON-DECREASING in k by construction. Both are asserted in the direction the predicate's form allows. SHARE: this is a rate; it moves nothing and gates the LOD decision M-121 and M-72 both want an input for.
Falsified by. C1 by any other ranking, which would mean the denominator was not the problem and the whole witness family is measuring the volume rather than the surface. C2 by convergence on thin_plate, or by non-convergence on a second field. C3 by a non-monotone false-positive count, which would mean the implementation is not the predicate. VACUITY CONTROL: ✗53's oracle_samples column is inherited -- 128 intervals -- and the caveat with it: a root pair inside one interval is invisible to both instruments and cannot produce a false negative here, but also cannot be ruled out.
P-100 — registered for R-100, before the harness: Is there a cell decomposition that is octahedrally invariant
Ticket: R-100 (M). Records: field, resolution, decomposition, tetrahedra_per_cell, elements_vertex_exact, worst_component_ulp, triangles, triangles_vs_six_tet, triangles_vs_marching_cubes, open_edges, seam_configurations, hausdorff, c1_holds, c2_holds, c3_holds.
Hypothesis. M-372 FOUND THE OBSTRUCTION AND NAMED IT AS STRUCTURAL. Marching Tetrahedra improves from {6, 12} to a flat 12 OF 48 AND STOPS, because a six-tetrahedron decomposition of a cell is not octahedrally invariant -- its diagonals cut different edges after a relabelling -- and NO PLACEMENT RULE REACHES THAT. That is a statement about the DECOMPOSITION, not about the extractor, and decompositions that are invariant exist: the barycentric (Kuhn/Freudenthal) subdivision into 24 tetrahedra is invariant under the full octahedral group by construction. P-3 already verified that Kuhn tiles face-to-face only if every cell picks the same main diagonal, and M-51 measured classic MT at about 3x the triangles for about 4% worse geometry, so the cost side is known and the question is whether invariance is worth paying for. (C1) A 24-tetrahedron barycentric decomposition reaches 48 OF 48 on all eight fields at both resolutions, where the six-tet split reaches 12. (C2) It costs at most 2x the six-tet split in triangle count -- and since M-51 already measured a 3x penalty over Marching Cubes, the COMBINED penalty must stay under 6x, which is the number a consumer actually pays. (C3) It STILL TILES across chunk seams with zero open edges, which is the property M-132 measured for the subgrid extractor and the reason Marching Tetrahedra is in this crate at all. SHARE: C2 is a triangle count, compared against M-51's already-measured baseline.
Falsified by. C1 by under 48, which would mean the obstruction is not the decomposition and M-372's diagnosis needs revising. C2 by above 2x, which prices invariance out for a game and leaves it a CAD-only option. C3 by any open edge, which kills it outright regardless of C1. VACUITY CONTROL: the six-tet arm must reproduce p-61.csv's flat 12 of 48 before the 24-tet arm is believed, reported side by side.
P-101 — registered for R-101, before the harness: Can the duals be made equivariant by canonicalising the accumulation
Ticket: R-101 (M). Records: field, resolution, extractor, accumulation_key, elements_vertex_exact, elements_vertex_exact_baseline, worst_component_ulp, exact_key_ties, hausdorff_delta, hashes_moved, hashes_moved_expected, c1_holds, c2_holds, c3_holds.
Hypothesis. M-372 SAYS THE DUALS ACCUMULATE CROSSINGS IN AN ORDER THAT AXIS RELABELLING PERMUTES, AND POINTS AT M-177. But M-177 is about NEGATION equivariance -- 'reordering cannot buy negation equivariance, and the obstruction is structural' -- and octahedral relabelling is a different group action. THE EVIDENCE THAT THE TWO ARE NOT THE SAME CASE IS IN p-61.csv: dual_contouring and manifold_dual_contouring already reach 48 on 3 OF 16 ROWS, which a structural obstruction would not permit. So the open question is narrow and cheap: does accumulating in a RELABELLING-INVARIANT order -- sorting the crossings by a key that is a function of the cell's geometry rather than of the axis indices -- take the duals from 3 of 16 to 16 of 16? Note M-24 and M-175: magnitude-ordered sums were real and insufficient once, and 'ties need no tie-break' survived 9,600 trials and fell to the first test about the tie itself -- so the key must be total and its tie-break must itself be invariant, which is registered here rather than discovered. (C1) With crossings accumulated in an order keyed on (|value|, |offset|) with an invariant tie-break, dual_contouring reaches 48 on at least 12 OF 16 rows. (C2) IT IS FREE: no golden hash moves except through the accumulation order itself, and the Hausdorff error is unchanged to 1e-12 -- the same shape as ✗49's C3. (C3) manifold_dual_contouring does WORSE than dual_contouring, because its cycle partition introduces a second order-dependence the accumulation key cannot reach. SHARE: C2 is a geometric change of zero, asserted rather than hoped.
Falsified by. C1 by under 12, which would mean M-177's obstruction does cover this case and the duals are structurally out of reach. C2 by any geometric change, which would mean the reordering is not a reordering. C3 by the two matching, which would be a stronger result and would mean the cycle partition is already invariant. VACUITY CONTROL: p-61.csv's three already-passing dual rows must still pass, and the tie-break must be exercised -- a count of exact ties in the key is a required column, because M-175 is the precedent for a tie-break that is never tested.
P-102 — registered for R-102, before the harness: ✗43's rate, this time with an artefact
Ticket: R-102 (S). Records: seed, size, configurations, unclosed_post_fix, unclosed_pre_fix, interior_apexes, interior_vertices, has_inner_hexagon_rejects, arm, void, c1_holds, c2_holds, c3_holds.
Hypothesis. THE ONE AUDIT ITEM THAT WAS DOWNGRADED RATHER THAN FIXED. ✗43 claims '2 of 8,064 not closed before the fix, 0 of 8,064 after' and the sweep that produced it exists in no bench, no test and no CSV; the entry now says so honestly, which leaves the claim that the per-ring apex fix GENERALISES with no evidence behind it and no ticket to produce any. That is CLAUDE.md hard rule 4 and it is the ✗35 failure mode in its third occurrence. P-63 has since built exactly the machinery this needs -- an exhaustive sign sweep with a fixture-can-fail control and a magnitude-seed protocol reported per seed and never pooled. (C1) Over all 8,064 configurations (16 x 8 x 9 x 7 sizes from 6^3 to 12^3), the post-fix extractor produces ZERO unclosed meshes, on four independent magnitude seeds reported per seed and never pooled. (C2) THE CONTROL THE ORIGINAL LACKED: the pre-fix single-apex fan produces exactly 2 at 6^3 and zero elsewhere, reproducing the claim the entry could not support. (C3) The +/-1 magnitude arm is a BAD FIXTURE here for the reason M-374 found -- has_inner_hexagon's strict 0 < x < 1 rejects, so interior vertices go to zero -- and the harness reports it as VOID rather than as a pass. SHARE: this experiment reproduces a rate and moves nothing.
Falsified by. C1 by any unclosed mesh, which reopens ✗43. C2 by a different count, which would mean the original figure was wrong as well as unreproducible -- and that is a finding about the entry rather than about the fix. C3 by the unit arm reporting a pass, which is M-44 in a new place and would mean the void detector does not work. VACUITY CONTROL: interior apexes must be non-zero on every generic arm, reported per seed, exactly as M-374 reports 282,084 to 283,694.
Phase 24 — the results, thirty entries against thirty registrations
Every row below was pre-registered in crates/isomesh/src/experiment.rs before its harness existed, its
harness was committed before it ran, and its dataset was re-run on a clean tree after every harness in
the phase had landed — so each # commit line names a commit a reader can check out, and
scripts/csv_provenance.sh passes with no new entry on its dirty-tree list.
That re-run is not a formality and it is the phase's first durable method finding. The first pass ran
with twenty-five harnesses building concurrently, and on the quiet tree one clause's verdict flipped
(✗57's full-coverage AO bar), one briefed mechanism was destroyed by an 84% clock move (✗69), one
whole-trace figure moved 1.67× on the identical binary (✗67), one triangle-count trend changed sign
(M-393), and one arm's least-squares fit went from unquotable to sound (✗72). Every entry below states
which of its numbers moved and re-grounds any conclusion that a clock had been carrying — which is ✗24's
rule (a wall-clock ratio is not a gate) and M-281's (a millisecond is a property of the binary)
applied thirty times in one sitting rather than argued once.
Twenty-four of the thirty carry a falsified clause. Six were registered as expected nulls and the nulls arrived. Reading the falsifications rather than the checkmarks is the point: several of them refute the registration's own premise rather than its prediction, and four refute a figure this repository or a cited paper had already published.
💥 ✗56 / M-385 — C1 FALSIFIED on 28 of 60 testable rows and separately VACUOUS on 6 of 16 cases, C2 FALSIFIED at 0 of 7 fields, C3 FALSIFIED at 0 of 18 hashes moved: the 2005 result does not transfer to trilinear output on this crate's noisy fields, and the determinism objection does not exist — but the connectivity route still loses to what the crate already ships, so the dossier's ~40-line pseudonormal should not be built (P-73, R-073)
M. cargo bench --bench experiment_p73, docs/experiments/p-73.csv, 112 rows (113 with the
header), 78 columns, f64, Zen 3 (amd-ryzen-9-5900x-12-core), with an Apple M5 / aarch64 as C3's
second machine. Eight reference fields at 33³ and 65³ × six connectivity weightings plus CentralDifference
at the cell size, every arm scored against field.gradient(vertex) over one shared vertex population in
one build and one run (M-281). Nothing in src/ changed and no NormalStrategy variant added — the six
weightings live in the bench, which is what a row that exists to stop a change looks like. Committed at
3a554ed, clean tree, an ancestor of HEAD.
Every number below is read from the committed
docs/experiments/p-73.csvat3a554ed, whose header carries no(WORKING TREE DIRTY). The clause verdicts and the mechanism were first worked out from a dirty pre-run of the same harness at63c7161; the clean re-run moved nothing. Every angle, count, rank correlation and 64-bit hash reproduced to the last printed digit, becauseM-280is satisfied by construction here: no clock appears anywhere in this experiment. There is nowall_ms, nons/sampleand no ratio of two timings — every column is an angle, an exact-arithmetic count, a Spearman rho or an FNV-1a hash, so there is nothing for a governed CPU to move. The only thing that changed between the two runs is the provenance stamp itself.
| clause | registered | measured |
|---|---|---|
C1 every connectivity weighting is ≥ 3× CentralDifference's median angular error at the cell size, on eight fields at 33³/65³, and thin_plate and noise_cavity are the worst |
≥ 3× on all 96 rows | FALSIFIED — c1_rows_at_least_3 = 32 of c1_rows_testable = 60, so 28 rows are under 3×; c1_worst_two_as_registered = false at both resolutions. Separately VACUOUS on 6 of 16 cases: gradient_median_deg is exactly 0.000000 and ratio_to_gradient is 0/0 |
| C2 mean |f(v)| predicts the per-vertex angular error, rank correlation above 0.7 on at least six of eight fields | ρ > 0.7 on 6 of 8 | FALSIFIED — c2_fields_above_bar_at_res = 0 at both 33 and 65, out of c2_testable_fields_at_res = 7. Best ρ anywhere in the file is 0.584622; fbm_terrain is negative. VACUOUS on box_exact |
| C3 the connectivity route moves at least one golden hash between the M5 and the Zen 3, and the gradient route moves none | ≥ 1 and 0 | FALSIFIED — hashes_moved_connectivity = 0 of hashes_connectivity_total = 18; hashes_moved_gradient = 0 of 3. Not blocked: second_machine = apple-m5-arm64, second_machine_note = ok, second_machine_toolchain = 1.96.1 against local_toolchain 1.98.0 |
SHARE, recomputed out loud. The registration's line is "C1 and C2 move the whole normals stage; C3 moves nothing and is a correctness clause."
- C1's ratio is not an Amdahl ratio and has no share cap.
ratio_to_gradientdivides two angular-error distributions taken over the same vertex population, each denominated in itself, so1/(1 − share/factor)does not bind, the range is[0, ∞)and the registered 3× is arithmetically reachable. What arithmetic could not reach is a case whose denominator is zero, and six of sixteen are:gradient_median_degis exactly0.000000onbox_exact,csg_differenceandthin_plateat both resolutions. No bar on a ratio is reachable there at any share, which is why those 36 rows are scored VACUOUS rather than counted as either verdict. C1 is falsified on the merit of 60 finite ratios, not on 36 NaNs. - C2's rank correlation has no share cap either. Spearman's rho is bounded to
[-1, 1]and its standard error over the 510–28,882 vertices per case is under 0.005, so 0.7 is far outside sampling noise. Its vacuity risk is at the other end — identically zero|f(v)|means every rank ties and rho does not exist — and it fired: onbox_exact,canary_mean_abs_fis0.000000e0withcanary_zero_vertices=scored_vertices= 1350 and 5766, so every Marching Cubes vertex is exactly on the surface andcase_c2_verdictreadsvacuous. - C3 moves nothing and is a correctness clause, as registered. Its exposure is the second machine, not a share, and the second machine ran.
C1's ratios, ratio_to_gradient by (field, resolution) × weighting. Bold is under the 3× bar
(row_ratio_at_least_3 = false).
| field | res | gradient_median_deg |
equal | angle | sine | area | edge | sqrt |
|---|---|---|---|---|---|---|---|---|
sphere |
33 | 0.075608 | 19.53 | 13.66 | 7.70 | 29.43 | 9.27 | 10.97 |
sphere |
65 | 0.020085 | 32.51 | 19.17 | 15.39 | 52.47 | 18.43 | 22.22 |
torus |
33 | 0.854352 | 3.67 | 2.64 | 2.77 | 6.41 | 2.91 | 2.47 |
torus |
65 | 0.216057 | 5.95 | 3.60 | 3.46 | 8.85 | 4.25 | 4.10 |
box_exact |
33/65 | 0.000000 | NaN | NaN | NaN | NaN | NaN | NaN |
csg_difference |
33/65 | 0.000000 | NaN | NaN | NaN | NaN | NaN | NaN |
thin_plate |
33/65 | 0.000000 | NaN | NaN | NaN | NaN | NaN | NaN |
gyroid |
33 | 0.000001 | 2.78e6 | 2.10e6 | 2.16e6 | 3.95e6 | 2.32e6 | 2.12e6 |
gyroid |
65 | 0.000001 | 1.56e6 | 1.06e6 | 1.14e6 | 2.23e6 | 1.30e6 | 1.19e6 |
fbm_terrain |
33 | 21.150470 | 0.986 | 0.985 | 0.989 | 1.008 | 0.990 | 0.992 |
fbm_terrain |
65 | 10.559946 | 1.077 | 1.055 | 1.043 | 1.167 | 1.038 | 1.040 |
noise_cavity |
33 | 18.309318 | 1.221 | 1.217 | 1.162 | 1.330 | 1.160 | 1.179 |
noise_cavity |
65 | 4.847019 | 1.687 | 1.560 | 1.499 | 1.963 | 1.510 | 1.532 |
The registered falsifier is "any weighting within 3×". Twenty-eight of the sixty testable rows are
within 3× — every one of the 24 fbm_terrain and noise_cavity rows, plus four of six on torus at 33³
(angle, sine, edge, sqrt). Read case_c1_verdict per row, not per case: on torus 33³ it says held
on equal and adjacent_triangle_area and falsified on the other four, which is the column disagreeing
with itself inside one case and is exactly the shape of a bar that four weightings clear and two do not.
gyroid's millionfold is an identity, not a result, and is not quoted as one. Its
gradient_median_deg is 0.000001 — one microdegree, which is floating-point round-off and not a
measurement of a reference error. For f = sin x cos y + sin y cos z + sin z cos x,
(f(x+h) − f(x−h))/2h = (sin h / h) · ∂f/∂x, and the same scalar sin h/h multiplies all three
components, so it cancels under normalisation and the central difference's direction is exact. The file
confirms that to nine decimals from its own cell_size: cd_magnitude_ratio_median is 0.968402874 at
cell_size 0.437500000 and 0.992043799 at 0.218750000, against sin(0.4375)/0.4375 = 0.9684028736 and
sin(0.21875)/0.21875 = 0.9920437993. So gyroid's twelve held rows are a connectivity error divided by
machine epsilon. They hold on the clause's own terms and are worthless as evidence for it; the number
to read there is the absolute one, median_angle_error_deg 2.532198° on the angle arm at 33³ and
0.907948° at 65³ — squarely in the same band as sphere and torus, i.e. small.
thin_plate: the prediction was right, its mechanism was wrong, and both halves are on the record.
Before the run, the bench's own header argued that C1 would be unreachable there because CentralDifference
differences over a step h = 0.125 at 33³ against a plate whose full thickness is 0.025 — the stencil
steps clean through the plate and out the other side — so gradient_median_deg would not be a small
reference error but a second broken instrument. The conclusion held and the mechanism did not.
cd_magnitude_ratio_median reads exactly 0.100000000 at cell_size 0.125000000 and exactly
0.200000000 at 0.062500000; those are thickness / 2h = 0.025/0.25 and 0.025/0.125, so both cases
independently derive the same 0.025 thickness from the file, and the stencil really is 10× and 5× too
coarse in magnitude. But gradient_median_deg there is not large, it is exactly 0.000000. A slab is
axis-aligned, so the differencing error is confined to the one axis the normal already points along and the
two tangential differences are exactly zero either way — and a normal is a direction. C1 dies on
thin_plate by 0/0, not by a large denominator. The magnitude is 10× wrong and the direction is bit-exact
in the same column pair.
The vacuity is not the same fact three times. box_exact, csg_difference and thin_plate are exact
signed distances to axis-aligned boxes; near a face the field reduces to |x_j| − b_j, which is piecewise
linear, Marching Cubes' linear edge interpolation is exact on a linear field, and a central difference of
a linear function is its derivative. So the median error of every one of the seven arms is exactly
0.000000 and cd_magnitude_ratio_median = 1.000000000 on box_exact and csg_difference. Where the
signal survives is the tail, and ratio_p99_to_gradient says which of the three still carries one:
| field | res | p99_angle_error_deg, angle arm |
p99 of central_difference |
ratio_p99_to_gradient |
|---|---|---|---|---|
box_exact |
33 | 28.886463 | 0.000000 | inf |
box_exact |
65 | 22.500000 | 0.000000 | inf |
csg_difference |
33 | 37.591897 | 12.563261 | 2.992209 |
csg_difference |
65 | 34.447553 | 13.581722 | 2.536317 |
thin_plate |
33 | 18.450505 | 0.000000 | inf |
thin_plate |
65 | 5.654966 | 0.000000 | inf |
box_exact 65³ is worth one line because three of its six p99 values are exact rational tangents:
18.434949 = atan(1/3), 22.500000 = 45/2 and 26.565051 = atan(1/2) (the other three read
18.337950, 20.368969 and 22.500000). Those are the angles you get by averaging unit axis vectors at an
edge or a corner, which is what a connectivity weighting does and the gradient never does. On the one field
where the central difference's p99 is exactly zero, the connectivity route's is 22.5° — the mechanism
the dossier calls a feature and the analytic gradient calls an error, and the entry does not adjudicate
which a shader wants.
Where the 2005 paper's numbers do appear, they appear on both routes at once, and that is the mechanism.
fbm_terrain and noise_cavity are the two fields with surface structure at the cell scale (cell_size
0.500000000 and 0.125000000 at 33³). There every weighting is 20.84–24.35° at 33³ and 7.27–12.32° at
65³ — squarely inside Jin, Lewis & West's 5–20° band, and their diagnosis, spatial aliasing in irregular
implicit tessellation, is the right one. But CentralDifference at the same cell size reads 21.150470°
and 18.309318°. The aliasing is a property of the sampling, not of the weighting, so both routes eat
it and the ratio collapses to 0.985–1.687. On the smooth analytic fields the connectivity route is
0.309086–5.478382°, well below the 2005 band, while the central difference converges as O(h²) —
cd_magnitude_ratio_median on sphere goes 0.996393278 → 0.999095484, a factor-4 reduction in 1 − r for
a factor-2 in h — so there the ratio is large. C1 is falsified from both ends simultaneously: the
ratio fails where the paper's absolute numbers hold, and holds where the paper's absolute numbers fail.
Two consequences the registration got backwards. The sub-claim "and thin_plate and noise_cavity are the
worst" is false: field_rank_by_error (1 = largest field_mean_connectivity_median_deg) at 33³ is
noise_cavity 1, fbm_terrain 2, gyroid 3, torus 4, sphere 5, box_exact 6, csg_difference 7,
thin_plate 8 — thin_plate is the field on which every method is exact, and it is last at 65³ too.
And in the direction nobody registered, on fbm_terrain at 33³ five of six weightings beat
CentralDifference: ratio_to_gradient 0.985260–0.991917, i.e. the connectivity route is 0.8–1.5% more
accurate than a cell-size difference. Those five rows are the only ones under 1.0 in the whole matrix.
C2, canary_rank_correlation on the angle arm — the dossier's own weighting.
| field | ρ @33³ | ρ @65³ | canary_mean_abs_f @33³ |
canary_max_abs_f @33³ |
case_c2_verdict |
|---|---|---|---|---|---|
sphere |
0.396059 | 0.205721 | 7.148188e-4 | 1.701129e-3 | falsified |
torus |
0.375156 | 0.438110 | 1.299332e-3 | 6.293799e-3 | falsified |
box_exact |
0.000000 | 0.000000 | 0.000000e0 | 0.000000e0 | vacuous |
csg_difference |
0.358219 | 0.584622 | 1.336310e-4 | 2.422590e-3 | falsified |
thin_plate |
0.062145 | 0.038215 | 3.061277e-18 | 3.469447e-18 | falsified |
gyroid |
0.279837 | 0.335371 | 6.423566e-3 | 1.465830e-1 | falsified |
fbm_terrain |
−0.147513 | −0.117851 | 1.986061e-2 | 2.277246e-1 | falsified |
noise_cavity |
0.352912 | 0.384173 | 2.453411e-2 | 1.943451e-1 | falsified |
Zero of seven testable fields clear 0.7 at either resolution; the registered falsifier is "below 0.7 on
three or more fields" and it is below on all seven. The best correlation anywhere in the file, over all
six weightings and both resolutions, is 0.584622 (csg_difference, 65³, angle). On fbm_terrain the
sign is wrong at both resolutions and on all six weightings, −0.117851 to −0.160652: the vertices
furthest off-surface have smaller angular error there. canary_max_abs_f shows the canary has real
spread on every field except box_exact (0.0) and thin_plate (3.469447e-18), so this is not an instrument
floor. mean |f(v)| is not a proxy for shading shimmer.
One asymmetry worth keeping, because it is a different feature and a different ticket. On csg_difference
the same canary predicts the central difference's error at ρ = 0.912948 and 0.963016
(canary_rank_correlation on the central_difference rows). The canary is a strong proxy for a
finite-difference error near a CSG seam and a poor one for a connectivity error anywhere. C2 asked about
the connectivity error.
C3, scored on what is actually in the file. The second machine ran; nothing here is BLOCKED.
| column | value |
|---|---|
hashes_moved_connectivity / hashes_connectivity_total |
0 / 18 |
hashes_moved_gradient / hashes_gradient_total |
0 / 3 |
hashes_moved_std_acos / hashes_std_acos_total |
2 / 3, hashes_moved_std_acos_fixtures = sphere+torus |
acos_sweep_libm_local / _remote |
76b929f7ad69da18 / 76b929f7ad69da18 — identical, acos_sweep_moved_libm = 0 |
acos_sweep_std_local / _remote |
3b9f2096421087a2 / a7874df0d6fc48dc — different, acos_sweep_moved_std = 1 |
hash_fixtures, codegen_control_ran, hashes_moved_codegen |
sphere+torus+box_exact, true, 0 |
port_acos_matches_libm, program_matches_bench |
true, true |
second_machine / _note / _toolchain, local_toolchain |
apple-m5-arm64 / ok / 1.96.1, 1.98.0 |
Zero movement on all eighteen connectivity hashes across sphere, torus and box_exact at 33³, computed
on an Apple M5 and a Zen 3. The registered falsifier is "zero hash movement on the connectivity route",
and the registration itself named that as "the more interesting result". The determinism objection to a
connectivity-weighted normal does not exist, and the mechanism is one line of src/real.rs: Real::acos
was added at S-006 precisely because "libm is the only source of that angle that stays bit-identical across
platforms", and it is wired to libm::acos. libm 0.2.16's acos is generic pure-Rust f64 arithmetic
whose only helper is sqrt, and src/math/arch/mod.rs selects sqrt per architecture — fsqrt on
aarch64+neon, sqrtsd on x86-64+sse2, both required by IEEE-754 to be correctly rounded, hence identical.
The registration's premise ("libm's acos has no architecture selection") is true and its inference
runs backwards: no architecture selection means portable. The measurement then prices the objection the
registration meant: had the crate used std's acos — glibc here, Apple's libm there — the sweep hash
differs and hashes_moved_std_acos is 2 of 3. The liability is real for a crate on the platform's libm
and zero for this one, and the whole difference is the S-006 decision. Only the angle weighting needs a
transcendental at all; MWSELR takes sin α = |e₁ × e₂| / (|e₁||e₂|) from the cross-product magnitude, so
five of the six weightings have no exposure in the first place.
The vacuity control, its registered column and value, and why that value proves the fixture could have
failed. The registered column is worst_decile_triangles, asserted non-zero per field: its minimum
over all 112 rows is 224 (thin_plate 33³) and it is never zero. That column under the per-field
reading is n/10 for any non-empty mesh, so the only thing it can catch is a case that meshed nothing —
which is worth catching and is stated rather than dressed up. The number that makes it mean something is
worst_decile_triangles_below_pooled_p10, the strict reading against one pooled distribution
(radius_ratio_p10_pooled = 0.242312, radius_ratio_median_pooled = 0.817624, over 202,538 triangles
summed across the sixteen cases), and it reads exactly 0 on two fields:
| field @33³ | worst_decile_triangles |
worst_decile_max_radius_ratio |
min_radius_ratio |
triangles_below_0p15 |
..._below_pooled_p10 |
|---|---|---|---|---|---|
sphere |
234 | 0.334234 | 0.060373 | 38 | 108 |
torus |
228 | 0.169510 | 0.014469 | 184 | 276 |
box_exact |
336 | 0.787694 | 0.787694 | 0 | 0 |
csg_difference |
506 | 0.787694 | 0.047541 | 24 | 42 |
thin_plate |
224 | 0.828418 | 0.828418 | 0 | 0 |
gyroid |
1064 | 0.170613 | 0.000000 | 948 | 1438 |
fbm_terrain |
396 | 0.197376 | 0.000097 | 304 | 490 |
noise_cavity |
1325 | 0.225693 | 0.000000 | 861 | 1411 |
On box_exact and thin_plate, min_radius_ratio equals worst_decile_max_radius_ratio at both
resolutions — every triangle on those meshes has the same near-equilateral shape, 0.787694 and 0.828418 —
and triangles_below_0p15 is 0. So on those two fields C1 is measuring well-shaped triangles only,
exactly as the registration warned, and it says so in the column rather than being discovered in prose. On
the other six fields the same column reads 42–6537 and min_radius_ratio reaches 0.000000. A zero that
sits beside a 6537 in the same column is a measurement, not an unreached configuration — which is M-44's
rule satisfied by the control that the registration itself demanded. (One reader's caveat: on box_exact
65³ worst_decile_triangles reads 11520 of 11528 triangles. That is a tie artefact — the mesh has
essentially two triangle shapes, so "at or below the 10th percentile" sweeps almost everything.
worst_decile_max_radius_ratio = 0.828427 is the number that says what happened.)
Five fixture defects the harness's own controls caught, none of them found by review.
gradient_median_degis exactly0.000000on six of sixteen cases, so C1's ratio is0/0there. This is only legible becausezero_error_verticesandcd_magnitude_ratio_medianwere added to explain the zero instead of hiding it: on the angle armzero_error_verticesis 1014/1350 and 5046/5766 onbox_exact, 831/1386 and 4295/6012 oncsg_difference, 390/510 and 1798/2046 onthin_plate. The run's first shape asserted the strict pooled decile per field and panicked onbox_exact33³ — the correct finding delivered by the wrong mechanism, since a field with uniformly good triangles invalidates the clause on that field, not the harness.case_c1_verdict/case_c2_verdictnow carryvacuous, with the aggregatec1_testable_cases(10) asserted non-zero so sixteen vacuities could not pass silently.- The pre-run SHARE prediction about
thin_platewas wrong in its mechanism, and the control that caught it iscd_magnitude_ratio_median= 0.100000000 / 0.200000000 sitting next togradient_median_deg= 0.000000. The arithmetic in the prediction was right; the conclusion drawn from it — a large denominator — is refuted by the measurement. The prediction is kept beside the correction in the bench header rather than replaced. thin_plate's canary is round-off, not signal.canary_max_abs_f= 3.469447e-18, and the case is still scored C2-testable (case_c2_testable=true) and reports ρ = 0.062145 — a correlation over machine epsilon. Excluding it does not change C2's verdict (0 of 6 against a bar of 6 of 8), but nobody should read that 0.062 as a measurement.gyroid's ratio column is1e6-scaled by a1e-6denominator. Onlycd_magnitude_ratio_median=sin h / hto nine decimals, checkable againstcell_sizein the same row, distinguishes "the reference is exact" from "the reference is broken" — which is theM-289failure mode in the opposite direction, and the reason the entry quotes the absolute error there instead.M-289was the named trap on this path and four independent controls refuse it.reference_matches_extraction=trueon 112/112, so the reference normal is bit-identical to the one the extractor already stored and this harness has no private idea of the gradient.ref_fd_median_deg= 0.000000000 on every row,ref_fd_p99_degat most 1.207e-06,ref_fd_over_half_deg= 0 everywhere — the angle to a fourth-order central difference ofsampleat 1e-6 of the domain extent, an independent gradient to ten digits on all eight fields.ref_closed_form_max_deg≤ 1.207e-06 on the five fields with a closed form written from the geometry,-1on the three without. Andmwaat_crate_status=matchwithmwaat_mismatch_vertices= 0 on 112/112 anchors the area arm bit-identically to the shippedNormalStrategy::AreaWeightedFaces. Population accounting:nonmanifold_edges,ref_degenerate_excluded,cd_degenerate_excludedandweight_degenerate_excludedare 0 on every row;boundary_vertices_excludedis non-zero on exactly one field,fbm_terrainat 190 of 2069 and 390 of 8638, which is the field whoseclosed_in_domain()isfalse. C3's admissibility is three more:port_acos_matches_libm,program_matches_bench(all 23 of the standalone program's hashes equal the ones computed in-process through the crate) andhashes_moved_codegen= 0 withcodegen_control_ran=true, so a cross-machine difference could not have been attributed to the 1.96.1/1.98.0 toolchain skew.
What changed as a result: nothing in src/, and that is the finding — do not build the angle-weighted
pseudonormal. The owner's question was whether the ~40 lines are worth having, and on which fields. Four
answers, in the order they matter.
- Refuse it on quality, not on determinism — the determinism argument is dead. C3 is falsified;
Real::acosalready exists and is already portable, and a connectivity weighting would move none of the crate's 216 golden hashes. Any future proposal must not be refused on this ground, and this entry is where that is written down so the argument is not recycled. - It loses to what is already there, on both incumbents. Where
Sdf::gradientexists,AnalyticGradientis exact by construction and the connectivity route's error is themedian_angle_error_degcolumn: 0.309086° to 24.354097° on the five fields where any method errs, and 0.000000° on the three where none does. Nothing beats zero. Where only samples exist the incumbent isCentralDifference, and the connectivity route is worse on 55 of 60 testable rows and better on 5 — all five onfbm_terrainat 33³, by 0.8–1.5%. A 1% win on one field at one resolution does not buy a fourthNormalStrategyvariant. - On which fields it would and would not help, stated plainly. It would not help on
sphereortorus, where the ratio is 2.469927× to 52.467910× against a route that is already accurate to 0.020085–0.854352°; nor ongyroid, where the ratio is meaningless but the absolute connectivity error is 0.907948–4.768898° against a central difference exact to a microdegree. It cannot help onbox_exact,csg_differenceorthin_plate, where Marching Cubes is exact and the connectivity route is the only arm that introduces error at all — its p99 runs 5.599259° to 39.539038° across the six weightings, where the central difference's is 0.000000 on two of the three. It is competitive onfbm_terrainandnoise_cavity, the noisy fields a destructible game actually ships, at 0.985–1.687×, because there the aliasing dominates both routes equally. So the 2005 result does not transfer to trilinear output on this crate's noisy fields, and the dossier's proposal is not obviously wrong — it is merely not obviously worth 40 lines and a fourth variant. That is the null, reported as a completed result. - The off-surface canary should not be built either, and the two-line version proposed in the dossier
is the wrong two lines. C2 is falsified 0-of-7 at both resolutions with the wrong sign on
fbm_terrain. Whatmean |f(v)|is good for is a finite-difference error near a CSG seam, ρ = 0.912948 / 0.963016 oncsg_difference— a different feature, a different ticket, and worth registering separately if anyone wants it.
One number in the dossier this row does not test, said so it is not mistaken for tested: the dossier's
two-sided claim is "under 2° difference on good triangles, over 15° on radius-ratio under 0.15". P-73
scores no per-vertex stratification by incident-triangle quality, so that claim is unscored. What the file
bounds either side of it: on sphere 33³, 38 of 2312 triangles (1.64%) are below 0.15 and the angle arm's
p99_angle_error_deg is 2.114728°, so the worst percentile there is nowhere near 15°; on noise_cavity
33³ the same column is 116.533880°. Both halves of the dossier's claim are field-dependent, and a proper
test needs a stratification P-73 does not register.
Would be shown wrong by: one hash moving on the connectivity route between any two architectures, which
would restore the determinism objection and re-tier C3; a field on which a connectivity weighting beats
CentralDifference by more than the 1.5% seen on fbm_terrain at 33³, which would make the ~40 lines
purchasable; a reference field with a non-zero gradient_median_deg on which every weighting is still ≥ 3×
— C1's registered shape has never been tested on a noisy field with a working denominator, because the
only two fields with cell-scale structure are the two where the denominator is 21.15° and 18.31°; or a
shading measurement, rather than an angle-against-the-gradient measurement, showing that box_exact's
22.5° p99 is what a shader wants at a box edge, which would mean the connectivity route's largest
disagreement with the analytic gradient is a feature and this entry measured the wrong quantity on the three
exact fields.
💥 ✗57 / M-386 — C1 HELD at 0.3996 / 0.1363 ms and still holds at 0.9406 / 1.2215 ms
once the 42.49% / 11.16% coverage is corrected out, but the bar is an absolute millisecond and its own
verdict flipped between two runs of one binary; C2's comparative half HELD — SSAO's MAE is 1.52–19.09×
the field arm's on all six sets — while both of its absolute halves are FALSIFIED; and C3 is FALSIFIED by
10.41 / 12.74 ms of construction the hypothesis said was already paid, because raw_lipschitz is
1.4140 / 2.1793 and a sphere trace on the resident field is unsound (P-74, R-074)
M. cargo bench --bench experiment_p74, docs/experiments/p-74.csv, 2 rows, f32, NVIDIA
GeForce RTX 3090 / Vulkan on amd-ryzen-9-5900x-12-core. gyroid and fbm_terrain on a 128-cell world
in 32-cell chunks (samples_per_axis 129, 64 chunks), extracted, concatenated and rasterised at 1920×1080
into a real Depth32Float depth attachment plus two Rgba32Float G-buffer targets, then AO estimated
three ways over one shared camera and one uploaded direction table: 8 rays × 16 steps sphere-tracing the
jump-flooded field on the GPU, 8-sample normal-oriented-hemisphere SSAO against that depth buffer, and a
512-ray parry3d reference against the extracted mesh. ao_ms_field / ao_ms_ssao are GPU timestamp
spans, median of 7 (clock = gpu-timestamp-ao/wall-c3); resident_ms, rebuild_ms and gbuffer_ms
are wall clock around submit-and-wait, because C3 spans a CPU-visible round trip no GPU span can see
(M-280). Committed at 175e702, no (WORKING TREE DIRTY) in the header, an ancestor of HEAD. This
is the first lighting measurement in the repository.
The committed clean re-run moved every clock on this row and it withdrew one of the briefed conclusions. The pre-run this entry was drafted against was dirty and reported
ao_ms_field0.895584 / 0.297952,ao_ms_field_full_coverage2.107926 / 2.669887, andc1_holds_full_coveragefalse on both — i.e. "C1 HELD as measured and FALSIFIED at full coverage". That conclusion is withdrawn: it was true only of the superseded run. In the committed file the GPU spans are 2.24× and 2.19× smaller, full coverage reads 0.940647 / 1.221536, andc1_holds_full_coverageis true on both. Every wall clock moved the other way in the same re-run —resident_ms×2.83 / ×3.45,rebuild_ms×1.43 / ×1.65,gbuffer_ms×7.3 / ×11.8 — which is what a quieter device and a busier host look like from two clocks at once, and is not a claim this row can settle. Not one integer moved:hit_pixels881,000 / 231,408,marches7,048,000 / 1,851,264,march_exhausted0 / 10,249,seam_pixels84,375 / 17,938,silhouette_pixels5,120 / 7,642,raw_lipschitz,sphere_lipschitz,conversion_bytesand all nine MAE columns are byte-identical across the two runs.M-279's rule is satisfied — the new run agrees with the old one on everything that is not a clock — and the replacement for the withdrawn claim is below, denominated in those integers.
| clause | registered | measured |
|---|---|---|
| C1 field-traced AO under 2.0 ms at 1920×1080, 8 rays, 16 steps | < 2.0 ms | HELD — ao_ms_field 0.399648 (gyroid) / 0.136320 (fbm_terrain); still HELD at 0.940647 / 1.221536 corrected to full coverage, margin 2.13× / 1.64× |
| C2a SSAO does not match it (the registered falsifier) | SSAO ≥ field on the two named sets | HELD — SSAO's MAE exceeds the field arm's on seam, silhouette and whole image, on both fields: 3.93× / 2.26×, 19.09× / 1.52×, 11.36× / 2.14×. c2_holds = true |
| C2b field-traced AO has NO darkening error at chunk seams | 0 | FALSIFIED — seam_mae_field 0.021313 / 0.034184 |
| C2c field-traced AO has no haloing at silhouettes | 0 | FALSIFIED — halo_mae_field 0.007323 / 0.028428 |
| C3 the construction cost RTSDF pays is ZERO here | rebuild_ms − resident_ms = 0, and a zero resident cost |
FALSIFIED — rebuild_minus_resident_ms 10.408696 / 12.735174 ms, and resident_ms 2.676582 / 1.201640 is not zero either. c3_holds = false on both |
| vacuity control: seam and silhouette sets non-empty, as counts | > 0 | seam_pixels 84,375 / 17,938; silhouette_pixels 5,120 / 7,642, with both negative arms at exactly 0 |
The SHARE recomputation, computed and printed before the harness ran, and it is the best thing on this
row. C1 is an absolute bar and not a ratio, so there is no ✗51 denominator to be unreachable behind —
the registered SHARE is "the whole AO budget, currently paid in full by a mesh-based pass", which is
100%. What had to be checked instead is whether 2.0 ms is arithmetically available at all, and the two
published anchors the registration itself cites both say no:
| anchor | implies at 1920×1080, 8 rays, 16 steps |
|---|---|
queries the configuration demands (queries_per_frame) |
265,420,800 per frame |
| 2.0 ms at that count | 132.71 G queries/s |
| nvblox's best measured rate, 7.3 G/s on an RTX 3090 Ti | 36.4 ms |
| nvblox's worst, 0.8 G/s | 331.8 ms |
| RTSDF's own 4.60 ms trace at 1024², scaled to 2.07 Mpx and to a 3090 | ≈6.06 ms |
| 8 trilinear loads per query, all resident in L1 (~17.8 TB/s aggregate) | 0.48 ms |
| the same traffic all the way out to VRAM (936 GB/s) | 9.1 ms |
265,420,800 = 1920 × 1080 × 8 × 16, and 265,420,800 / 2.0 ms = 132.71 G/s. The bar sits outside both
published anchors and inside the spread of the memory hierarchy — 4.17× above the 0.48 ms an
all-L1-resident trace would take and 4.55× below the 9.1 ms the same traffic costs from VRAM. It was
reachable only if three things held at once: a flat 129³ f32 grid is a far cheaper query than a
block-hashed TSDF lookup; the 8.586756 MB grid (distance_bytes 8,586,756 against 6 MB of L2) is carried
by locality rather than capacity; and sphere traces terminate early rather than running all 16 steps.
The run landed in the L1-bound regime: at full coverage 0.940647 / 1.221536 ms is 1.96× / 2.54× the
all-L1 figure and 9.67× / 7.45× under the VRAM one — an order of magnitude nearer the cache end. Against
the two anchors it is 38.70× / 29.80× faster than nvblox's implied 36.4 ms and 6.44× / 4.96× faster than
RTSDF's scaled 6.06 ms.
And that is exactly why the nominal query count is a ceiling and not a count, which is C1's mechanism.
Read at face value, 265,420,800 queries in 0.940647 ms is 282.17 G/s, 38.65× nvblox's best measured
rate; no plausible per-query win is 38×. The resolution is on the row: march_exhausted is 0 of
7,048,000 marches on gyroid and 10,249 of 1,851,264 — 0.5536% on fbm_terrain, so essentially
every sphere trace converges before its 16th step and the 16-step product is never issued. A sphere trace
steps by the true distance (Hart 1996, 10.1007/s003710050084), so 16 steps is not the binding constraint
at a 32-cell radius. The remaining difference is representational: an indexed load out of a resident flat
array is not the same operation as nvblox's block-hashed lookup.
Coverage, and the part of C1 that is run-independent. The pass dispatches all 2,073,600 pixels but a background pixel returns before it traces anything, so the clock only ran where there was surface:
| field | hit_pixels |
hit_fraction |
ao_ms_field |
ns_per_traced_pixel |
ao_ms_field_full_coverage |
c1_holds_full_coverage |
|---|---|---|---|---|---|---|
gyroid |
881,000 | 0.424865 | 0.399648 | 0.4536 | 0.940647 | true |
fbm_terrain |
231,408 | 0.111597 | 0.136320 | 0.5891 | 1.221536 | true |
881,000 / 2,073,600 = 0.424865 and 231,408 / 2,073,600 = 0.111597; 0.399648 × 10⁶ / 881,000 = 0.4536 ns.
ns_per_traced_pixel is on the row so a reader recomputes at their own coverage instead of trusting the
scaling: full-coverage ms = ns_per_traced_pixel × 2,073,600 / 10⁶, which reproduces 0.9406 and 1.2216
from the two columns independently.
The linear extrapolation is justified rather than assumed, on three grounds from the file. (1) At
7,048,000 and 1,851,264 marches the pass is far above any launch-overhead regime, and the scaling charges
the fixed dispatch cost a second time, so it over-estimates rather than flatters. (2)
march_exhausted_fraction 0.000000 / 0.005536 says the mean step count per ray is set by convergence, not
by the cap, so adding traced pixels adds rays at the same depth rather than deepening the existing ones.
(3) The two rows are themselves a two-point test in the extrapolated variable: coverage differs by
3.81× (0.424865 / 0.111597) while ns_per_traced_pixel differs by only 1.30× (0.5891 / 0.4536),
and in the direction that makes the sparser field dearer per pixel — so the residual non-linearity over
a near-4× coverage range is under 30% and biased against the extrapolation.
What C1's verdict is actually worth, which is the replacement for the withdrawn claim. The coverage
correction is a property of the fixture — two integer counts over an integer count, identical in both runs.
Whether the corrected figure clears 2.0 ms is not: the same binary on the same host answered
c1_holds_full_coverage false and then true, at 2.107926 / 2.669887 and then 0.940647 / 1.221536. This
is ✗24's rule and M-281's in a new costume — a wall-clock ratio is not a gate; gate the count the
ratio samples, and an absolute millisecond is worse than a ratio because it does not even cancel the
machine. So the durable content of C1 is not the boolean but ns_per_traced_pixel, hit_pixels and
march_exhausted, from which the bar is re-decidable on any coverage and any adapter. A verdict that
flips between two runs of one binary should never have been the headline, and the registration wrote it as
one.
C2, with the comparative claim and the absolute claims scored separately, because they disagree.
| set | px sampled | reference mean | field mean | SSAO mean | mae_field |
mae_ssao |
ideal-8-ray mae_floor |
field ÷ floor | SSAO ÷ field |
|---|---|---|---|---|---|---|---|---|---|
gyroid seam |
1,536 | 0.016099 | 0.010173 | 0.075440 | 0.021313 | 0.083790 | 0.019723 | 1.081× | 3.93× |
gyroid silhouette |
1,536 | 0.007323 | 0.000000 | 0.138955 | 0.007323 | 0.139813 | 0.007323 | 1.000× | 19.09× |
gyroid whole image |
1,536 | 0.012390 | 0.006348 | 0.171245 | 0.015661 | 0.177979 | 0.014631 | 1.070× | 11.36× |
fbm_terrain seam |
1,536 | 0.048847 | 0.021973 | 0.110121 | 0.034184 | 0.077349 | 0.036381 | 0.940× | 2.26× |
fbm_terrain silhouette |
1,536 | 0.045729 | 0.029867 | 0.056522 | 0.028428 | 0.043289 | 0.028940 | 0.982× | 1.52× |
fbm_terrain whole image |
1,536 | 0.075784 | 0.052246 | 0.117719 | 0.037490 | 0.080079 | 0.038258 | 0.980× | 2.14× |
The registered falsifier is not met and the registered claim is still false. "SSAO matching it" does
not happen — SSAO is above the field arm on all six sets — so c2_holds is true. But the clause as written
says field-traced AO has no seam darkening and no haloing, and seam_mae_field and
halo_mae_field are non-zero on every row. Scoring one verdict over both halves would have hidden which
one the row supports.
What kind of error the non-zero is, and this is what the mae_floor column is for. seam_mae_floor
and halo_mae_floor are the same 8 directions cast against the mesh by parry3d against the same
512-ray reference: the error an ideal 8-ray method posts from discretisation alone. The field arm sits at
1.081× / 0.940× the floor at seams, 1.000× / 0.982× at silhouettes and 1.070× / 0.980× over the
whole image — three of six below it. On gyroid's silhouettes the field arm and the ideal mesh-traced
8-ray arm both read exactly 0.000000 over all 1,536 pixels. So the field representation contributes no
measurable error beyond the ray count: C2b and C2c are falsified by the 8-ray budget, not by the field.
And SSAO's error is not a seam artefact either, which the all_* control set is what caught. Any
method with a uniform bias posts a non-zero MAE on any subset, so a seam-set MAE alone cannot test a claim
about seams. Measured against the whole-image control, SSAO's seam error is 0.471× / 0.966× and its
silhouette error 0.786× / 0.541× of its error everywhere else — at or below its error away from the
named locations. SSAO is uniformly over-dark: all_ssao_mean ÷ all_reference_mean = 13.82×
(gyroid) and 1.55× (fbm_terrain). Reading that global bias as the registered seam artefact would
have been a local conclusion drawn from a uniform error.
Both arms are biased and they are biased in opposite directions, which is the honest form of "the field
wins". all_field_mean ÷ all_reference_mean is 0.512× / 0.689× — the field arm under-darkens by
as much as SSAO over-darkens on fbm_terrain — and the mechanism is arithmetic: an 8-sample Bernoulli
estimator's quantum is 0.125 against true occlusion of 0.012390 / 0.075784, i.e. 10.1× / 1.65× coarser
than the signal, so most pixels round to zero in both 8-ray arms at once. That is also why the field arm
and the mesh floor agree to six decimals rather than to within Monte Carlo noise: the 8 directions are one
fixed cosine-weighted Hammersley set, uploaded from Rust and read by both the WGSL trace and the
parry3d caster, in the same Duff tangent frame, so the two arms cannot sample different hemispheres.
C3, scored on resident_ms and rebuild_ms as they stand in the file.
| field | resident_ms |
rebuild_ms |
rebuild_minus_resident_ms |
vs RTSDF's 2.09 ms flood | flood_build_ms |
distance_upload_ms |
conversion_ms |
conversion_bytes |
raw_lipschitz |
|---|---|---|---|---|---|---|---|---|---|
gyroid |
2.676582 | 13.085278 | 10.408696 | 4.98× | 8.281948 | 1.332881 | 9.614829 | 17,173,512 | 1.414040 |
fbm_terrain |
1.201640 | 13.936814 | 12.735174 | 6.09× | 7.965775 | 1.393392 | 9.359167 | 17,173,512 | 2.179314 |
The clause says the construction cost is zero here. It is 10.408696 and 12.735174 ms —
4.98× and 6.09× the 2.09 ms RTSDF pays on older silicon for the same job, and conversion_ms alone
(flood_build_ms + distance_upload_ms) is 73.5% and 67.2% of the rebuild. FALSIFIED, and the registered
falsifier's stated meaning is also met on the nose: "the field is not reusable in the form the tracer
wants and there is a conversion nobody costed."
Read literally, "a non-zero resident cost" is a degenerate test, and the harness says so.
resident_ms is wall clock around a submit-and-wait of the trace, so it can never be zero — 2.676582
and 1.201640 ms are 6.70× and 8.81× the GPU span inside them, which is round-trip latency and not
construction. The run-independent reading of the clause is raw_lipschitz: a sphere trace is sound exactly
when the field is 1-Lipschitz, and the crate's resident Sdf is 1.414040 (Gyroid, sin·cos sums) and
2.179314 (FbmTerrain) per cell. Above 1 the march overshoots and the jump flood is a mandatory
conversion, not an optimisation — so c3_holds = raw_lipschitz <= 1.0 is false on both. The positive arm
is sphere_lipschitz = 1.000000: an exact SDF on the same grid through the same function, so "1.41 > 1,
therefore a conversion is needed" does not rest on an instrument that has only ever been seen failing.
flood_lipschitz 1.036510 / 1.084507 confirms the flood delivers what the tracer wants.
And the conversion is charged twice, which is the number that should leave this row.
conversion_bytes = 17,173,512 = 2 × distance_bytes (8,586,756): JumpFlood::build returns
Vec<f32>, so the distances the flood has already written into a device buffer are read back to the CPU
and written straight back. That round trip is what makes the crate's construction 5–6× RTSDF's on faster
silicon.
The vacuity control the registration names, and why its values prove the fixture could have failed.
| column | gyroid |
fbm_terrain |
what it is |
|---|---|---|---|
seam_pixels |
84,375 | 17,938 | the registered count — geometric band around interior chunk-boundary planes |
silhouette_pixels |
5,120 | 7,642 | the registered count — view-distance discontinuity |
seam_pixels_one_chunk |
0 | 0 | the identical G-buffer reclassified with the interior plane list emptied |
silhouette_pixels_flat |
0 | 0 | the same classifier over an image where every pixel hits at one constant distance |
seam_pixels_screen |
14,741 | 5,817 | an independent second definition — chunk-id discontinuity between screen neighbours |
Both registered sets are non-empty and asserted so, and seam_pixels < hit_pixels is asserted too, so the
seam set is not the whole image. The two zeros are what make the two counts readings rather than
tallies (M-44): seam_pixels_one_chunk runs the same classifier over the same pixels with the world
described as one chunk and returns exactly 0, and silhouette_pixels_flat runs the same silhouette
classifier over a constant-distance image and returns exactly 0. Both are assert_eq!(…, 0), so a
classifier that could not say no would fail the run rather than print a confident count. seam_pixels_screen
cross-checks the geometric band against a second definition instead of trusting it.
A second vacuity gate had to be added after the first run, and it is the one that caught the fixture:
assert!(reference_mean > 1/512) on each set. The reference means are now 8.24 and 3.75 quanta on
gyroid (0.016099, 0.007323 × 512) and 25.01 and 23.41 on fbm_terrain (0.048847, 0.045729) — so the
MAEs below are differences from something rather than from nothing.
What the depth buffer is, and why it is a faithful stand-in. A real one. The 64 per-chunk
MeshBuffers are concatenated into one vertex buffer (position, normal, chunk id) and one index buffer and
rasterised through a wgpu render pipeline at 1920×1080 into a Depth32Float depth attachment
(depth_write_enabled, depth_compare: Less, cleared to 1.0) plus two Rgba32Float G-buffer targets —
world position + chunk id, world normal + hit mask, a = -1 as the miss marker; gbuffer_ms 2.399620 /
2.351719 is that pass's own wall clock and nothing more. SSAO reads the depth attachment as a
texture_depth_2d and the normal target, and nothing else; it reconstructs world positions from NDC depth
through an inv_view_proj derived analytically rather than numerically inverted. It is faithful because it
is what a depth prepass over this crate's output produces: the same triangles (triangles 101,280 /
65,254 over vertices 53,874 / 34,860), the same hardware rasteriser, the same depth format a deferred
renderer would bind. Nothing about the image is synthesised. The one arm that is synthetic — the
constant-distance image — exists only as the silhouette classifier's negative control and is labelled as
such. field_start_inside = 0 of 881,000 and 0 of 231,408 says the flooded field and the
rasterised mesh agree about which side of the surface every primary hit is on, so the three arms are
estimating one quantity over one population. adapter = NVIDIA GeForce RTX 3090 on backend =
Vulkan, as the registration requires.
Four fixture defects, every one caught by this harness's own controls rather than by review.
- The first run was vacuous and the CSV would have looked perfect. At
ao_radius_cells = 8the 512-ray reference came back 0.0000 ongyroidover 1,536 seam and 1,536 silhouette pixels — and so did the field arm, soseam_mae_fieldandhalo_mae_fieldread exactly 0.000000 and C2 scored a flawless HELD. PureM-44: a perfect method and a broken one both score zero against a reference with nothing in it. The cause was geometric rather than a bug —Gyroidat scale 1 has channels about π/2 wide, so a hemisphere of radius 0.25 world units genuinely sees no opposite wall.ao_radius_cellsis now 32.000 (one world unit, comparable to the field's own feature size) andeps_cellswas decoupled fromao_radius_cells / march_steps, because tying them made epsilon 2 cells at the wider radius, which stops the march on a surface it has not reached and invents occlusion; it is now 0.500. Then the gate that should have been there from the start. - C3's predicate was the harness's invention, not the registration's.
resident_ms < rebuild_ms × 0.05made the verdict a function of how much of the frame the surface happened to cover, and reported FALSIFIED ongyroidand HELD onfbm_terrainin one run for a reason with nothing to do with the clause. Replaced with the registered falsifier, instrumented asraw_lipschitzwithsphere_lipschitz= 1.000000 as the positive arm. - A seam-set MAE alone cannot test a claim about seams. The
all_*control set — the same three estimators over a stride sample of every visible pixel — is what turned "SSAO's seam error is 0.083790" into "SSAO's seam error is 0.471× its error everywhere else, so there is no seam artefact". - The shader's traced population and the CPU classifier's could have disagreed silently, which would
have put every per-set number over the wrong population. The shader counts the pixels it actually traced
and
assert_eq!matches it against the CPU count: 881,000 and 231,408, equal on both rows.
What changed as a result: nothing landed, and the null is the conclusion. Do not build this as
registered. No source change; crates/isomesh/src/** and crates/isomesh-gpu/src/** are untouched, and
R-074 is not one of Phase 24's registered source tickets. The field trace is 5.30× / 3.88× dearer than
the SSAO pass measured beside it on the same rows (0.399648 vs 0.075392; 0.136320 vs 0.035168, and the same
ratio at full coverage since both scale by one hit_fraction) and buys 11.36× / 2.14× lower whole-image
mean absolute error against ground truth, and 1.52–19.09× across all six sets — a real trade, worth having
on the record. But the hypothesis's premise, "the expensive half is already paid", is inverted:
raw_lipschitz > 1 means the resident field must be flooded before it can be traced at all, and
conversion_ms is 9.614829 / 9.359167 ms — 4.60× / 4.48×
RTSDF's 2.09 ms construction, and 24.1× / 68.7× the trace it enables (10.2× / 7.7× at full coverage).
On a static scene the field wins on quality per millisecond; on a destructible one — the only scene this
crate is for — that conversion is paid on every dig and the depth buffer, which the rasteriser rebuilds for
free every frame, wins outright. The one-path rule plus a 4–5× cost increase over the baseline does not buy
an exception; P-70/P-71's precedent is to measure it, surface the decision and stop.
Two decisions this surfaces without opening them here. First, if field-traced AO is ever wanted, the
prerequisite is a device-resident JumpFlood output — a build_into that leaves the distances where
the flood wrote them — which removes 17,173,512 bytes and the larger part of the rebuild in one change and
helps anything else that wants the distance field on the GPU. Second, and cheaper: the 8-ray budget, not
the representation, is what limits quality here, proved by the six mae_floor ratios of 0.940–1.081.
Anyone tempted to improve field AO by refining the field is optimising the term that is already at the
floor; the lever is rays, and a per-pixel-rotated kernel needs TAA to resolve, which P-76's C2 and P-77
both argue a destructible world has already spent.
Registered deviations, stated rather than absorbed. The "16-step cone march" is implemented as a
16-step sphere trace: the step length is the distance to the nearest surface floored at eps_cells, so
the marched sphere radius is the cone (Hart 1996), and a ray reaching d < eps inside the radius is
blocked — a binary visibility, which is what the 512-ray mesh reference measures, so all three arms
estimate one number. A soft Quilez-style accumulator would have produced a quantity the reference does not
measure. No total frame time is claimed for a pipeline that does not exist: RTSDF's 10.22 ms / 97 fps is
quoted as the source's number and never as this machine's. The MAEs are over 1,536 pixels per set by
uniform stride across the sorted set (seam_sampled / halo_sampled / all_sampled = 1536), while the
registered seam_pixels / silhouette_pixels are the full counts the vacuity control asks for; 512
rays × 4,608 pixels × 2 fields through parry3d's BVH is reference_ms 338.594 / 420.928 ms. SSAO's error
magnitude is radius-dependent and the radius is the clause's 32 cells, so 13.82× over-darkening is a
large-radius figure — the sign of the comparison does not depend on it, the magnitude does. The
registration names only the Zen 3 / RTX 3090 rig, which is this host, so nothing on this row is BLOCKED.
Would be shown wrong by: a raw_lipschitz at or below 1 on any field this crate ships, which would
make the flood optional and restore the hypothesis's premise in one number; a march_exhausted_fraction
near 1, which would mean the 16-step cap is binding and the nominal 265,420,800 queries are really being
issued, invalidating C1's mechanism at any coverage; a seam_mae_field above its seam_mae_floor by more
than the two-arm agreement's own spread, which would mean the field representation contributes seam error
of its own after all rather than inheriting the 8-ray residue; an SSAO arm whose seam or silhouette MAE
exceeds its whole-image MAE, which would restore the registered seam artefact rather than a uniform bias;
or a device-resident flood output that brings conversion_ms under the trace it enables, which is the one
change that would make C3's clause worth re-registering.
🔬 M-387 — C1, C2 and C3 all HELD: per-vertex material weights cost 3.11–3.16% of extraction and the share is flat across a 4× log, they beat a per-fragment log walk by 12.93× to 40.89× widening monotonically across M-50's four buckets, and interpolation misclassifies 0.18–0.35% of the surface with 99.36–99.73% of it inside one cell of a boundary — and C1 held only because the surface has half the vertices the pre-run estimate assumed, which had predicted it FALSIFIED (P-75, R-075)
M. cargo bench --bench experiment_p75, docs/experiments/p-75.csv, 4 rows, scalar f32,
Zen 3 (cpu_mhz 4200.114 on every row). game_dig's 8×4×8 chunks of 16³ cells — 1,257,728
samples, 256 · 17³ — over M-50's 60-carve ISOMESH_AUTOCARVE=60 trace with one Edit::Spray
after every third carve, swept in that trace's own four brush buckets (15 / 30 / 45 / 60, giving
log_len 20 / 40 / 60 / 80). Median of reps = 3 for C1, median-of-ratio of shade_reps = 9 for
C2 so the two absolute times beside a speedup come from one run (M-281). Committed at
cfb58df, header clean — no (WORKING TREE DIRTY) — and an ancestor of HEAD.
RE-RUN, and every number below is the clean file's. The original harness ran at
63c7161with the header stamped(WORKING TREE DIRTY)and ~25 sibling agents building; that run is not quoted here, because an entry that quotes numbers no committed file contains is✗35's and✗52's defect. Every integer and every deterministic column reproduced exactly —vertices24470 / 25471 / 25482 / 25482,triangles,visible_triangles,visible_pixels,clipped_triangles,boundary_vertices,boundary_vertices_all,materials,brushes_biting,field_walk_mismatches, every misclassification column,pixel_disagreement,within_one_cell_fractionandl1_max_error— which isM-279's rule satisfied: the new run agrees with the old on everything that is not a clock. Every clock moved, and two things the old run concluded do not survive.weights_sharewas 2.86–3.12% and is 3.11–3.16%;speedupwas 12.812 / 21.853 / 30.875 / 40.305 and is 12.934 / 22.476 / 31.730 / 40.893;extract_mswas 59.964 / 164.033 / 252.418 / 184.709 — non-monotone in the log — and is 71.677 / 98.242 / 141.101 / 212.029, monotone. The two withdrawn claims are named in C2 below.
| clause | registered | measured |
|---|---|---|
| C1 per-vertex weights inside the existing extraction walk cost under 5% of extraction | < 0.05 | HELD — 0.031337 / 0.031591 / 0.031397 / 0.031135, worst 3.16%, a 1.5% band across a 4× log |
C2 at 1920×1080 on game_dig's scene, weights beat a per-fragment log walk by ≥ 4×, and the gap widens across M-50's four buckets |
≥ 4× and monotone | HELD — 12.934 / 22.476 / 31.730 / 40.893, speedup_widens = true. Per-pixel shading cost over a visibility buffer, not engine frame time |
| C3 misclassification against the field at 10⁶ surface points is under 2% and concentrated within one cell of a material boundary | < 0.02, "concentrated" (no number registered) | HELD — 0.001830 / 0.003407 / 0.003463 / 0.003463, and 99.73 / 99.59 / 99.36 / 99.36% inside one cell, against this harness's stated reading of "concentrated" as ≥ 0.95 |
The pre-run prediction was C1 FALSIFIED, and it is on record in the bench header as it was written. The SHARE arithmetic registered before the harness existed is
weights_share ≈ (vertices / samples) · (per-vertex walk / per-sample extraction step)
and the estimate put the surface at order 4·10⁴ vertices, so vertices / samples ≈ 4%, which with
a second factor above one predicted ~6% against a 5% bar. The measured surface is 25,482
vertices, so vertices / samples = 25,482 / 1,257,728 = 0.020260 and the share came in at 3.11–3.16%.
C1 held because the estimate was wrong about the vertex count by 2×, not because the clause was
unreachable — the clause was live in both directions and the shape of the arithmetic was right. This
is M-19's rule earning its keep: the prediction being committed before the run is what makes the miss
readable instead of a tidy story about why 3% was obvious.
The share's second factor is above one, not below, and its denominator is currently zero. C1's
numerator is the whole vertex-attribute stage, and in game_dig that stage does not exist:
insert_attribute is called for ATTRIBUTE_POSITION, ATTRIBUTE_NORMAL and an all-zero
ATTRIBUTE_UV_0 (game_dig.rs:2088-2095) and nothing else, triplanar.wgsl:119-126 derives its three
strata per fragment from the interpolated normal and the world height, and isomesh::paint::shade
(paint.rs:254) exists but no example calls it. So the clause is "a new cost, as a fraction of
extraction", starting from nothing. And the surcharge over vertices / samples runs the wrong way:
PaintStack::sample skips sprays without evaluating their shapes — its own doc says "meshing a
painted world costs one match arm more … and not a field evaluation more" (paint.rs:228-241) —
while a material weight has to evaluate every one of them.
| bucket | log_len |
vertices |
vertices/samples |
weights_share |
surcharge |
|---|---|---|---|---|---|
| 1 | 20 | 24,470 | 0.019456 | 0.031337 | 1.611× |
| 2 | 40 | 25,471 | 0.020252 | 0.031591 | 1.560× |
| 3 | 60 | 25,482 | 0.020260 | 0.031397 | 1.550× |
| 4 | 80 | 25,482 | 0.020260 | 0.031135 | 1.537× |
The mechanism for C1 is that numerator and denominator are the same walk, which is why the share is
flat where both absolutes are not: over the 4× log, extract_ms grows 2.958× (71.677 → 212.029)
and weights_ms grows 2.939× (2.246 → 6.601) — the two growth factors differ by 0.65%, so
their ratio cannot move. The residual 1.54–1.61 surcharge is the sprays the per-vertex walk must
evaluate and the per-sample walk skips (log_len / brushes = 80/60 = 1.333 on every bucket) plus
base_weights and the argmax. Per-vertex weights are cheap for a purely geometric reason: the
surface is 2D inside a 3D sample grid, and there are ~49× fewer vertices than samples.
A variant was built and put back, and its numbers are the bench header's, not this CSV's. A spray-free arm — the same 60 carves, no
Edit::Sprayat all — reportedweights_share = 0.0203againstvertices / samples = 0.020260, i.e. with the sprays skipped a per-vertex weight costs exactly one sample's worth of walk and the share is the vertex-to-sample ratio. It also reportedboundary_vertices = 244andmisclassified_points = 3624. It is not committed as an arm because C2's premise requires the sprays, and it owes an E× row in Part 4b — those three numbers appear in no CSV and are quoted here as the bench header's, per✗39's rule about which artefact a number came from.
The instrument, in full, and what it is not. crates/isomesh must not depend on Bevy
(CLAUDE.md hard rule 2), so there is no renderer here and no frame time is invented anywhere.
C2's two numbers are per-pixel shading cost over a real visibility buffer, explicitly not engine
frame time. The harness software-rasterises the extracted mesh at 1920×1080 (screen_pixels
2,073,600) through game_dig's own camera — eye (0, 1.70, 6.0) (game_dig.rs:947), yaw 0 and pitch
−0.15 (game_dig.rs:698-701, applied at :2450), Bevy's default 45° vertical field of view — keeping
the nearest fragment per pixel with its triangle index and its perspective-correct
barycentrics. visible_pixels is 1,110,155 of 2,073,600 = 53.54%; the remaining 963,445 are sky
and cost nothing in either path, as a real deferred pass would also skip them. clipped_triangles is
5,179 on every row — triangles dropped whole for a vertex behind the near plane, on the row rather
than assumed away, because the camera sits 1.2 units above the hilltop.
The fairness of the split is the load-bearing part, and it is arithmetic rather than assertion.
| charged to | column | bucket 1 / 2 / 3 / 4 |
|---|---|---|
| neither — the varyings both paths pay identically (interpolated world position and normal) | interp_ms |
14.277 / 12.574 / 13.278 / 20.217 |
| neither — the geometry pass both paths share | raster_ms |
19.157 / 19.772 / 19.864 / 27.663 |
| the vertex path | frame_ms_vertex |
6.396 / 6.337 / 6.277 / 7.108 |
| the fragment path | frame_ms_fragment |
82.725 / 142.426 / 199.184 / 290.662 |
The interpolation is computed once, outside both timers. On hardware that is the interpolator, and
charging it to one side would be charging the comparison — interp_ms at bucket 4 is 20.2 ms against a
6.4 ms vertex path, so putting it on the vertex side alone would move the speedup from 40.89 to 10.65
and putting it on the fragment side would move it to 43.7. It is on the row so a reader can do either
sum. The vertex path interpolates the four-channel weight attribute from the triangle's three
vertices, renormalises and takes the argmax; the fragment path recomputes the same quantity exactly
— the stratum blend from the interpolated normal and height, then one walk of the whole edit log,
compositing every spray's coverage ramp(shape(p), softness) · ramp(|f_prefix(p)|, depth) · alpha
(paint.rs:182-217).
Every game_dig constant is restated with its source line, because this bench cannot link
bevy_isomesh:
| quantity | value | source |
|---|---|---|
| chunk edge | 16 cells | game_dig.rs:125 |
| cell size | 0.125 | game_dig.rs:127 |
| chunks | 8×4×8 | game_dig.rs:137 |
| layout origin | (−8, −5.4, −8) |
game_dig.rs:955-969 |
| terrain | y − (0.35·sin(0.9x)·cos(0.7z) + 0.15·sin(2.1x)) |
game_dig.rs:171-175 |
| brush radius | 0.25 | game_dig.rs:1056 |
carve n centre |
(−0.9 + 0.30n, 0.55 − 0.045n, 2.2 − 0.34n) |
game_dig.rs:665-668 |
| stratum blend | up·shallow, (1−up)·shallow, 1−shallow |
triplanar.wgsl:119-126 |
| slope ramp | smoothstep(0.55, 0.82, n.y) |
triplanar.wgsl:76-77, 123 |
| depth ramp | smoothstep(−1.6, −0.4, p.y) |
triplanar.wgsl:83-84, 124 |
| spray widths | radius 0.75, softness 0.10, depth 0.05 |
paint.rs:50-55 (the module's own example) |
The five sandbox walls are not in the mesh and that is deliberate: they are Bevy cuboids outside the
field (game_dig.rs:805-841) carrying a forced concrete layer, so they walk no log in either path and
adding them would only add pixels the two paths shade identically — which flatters the vertex path.
C2's "widens" half is nearly implied by construction, and the registration's own falsifier says so.
The vertex path's cost is independent of log length by design — it reads three vertex attributes —
and the fragment path's is monotone in it by construction, because it is one walk of the log. So
speedup = fragment / vertex cannot fail to widen unless the fragment path is flat in log length,
which is precisely the falsifier the registration names: "the fragment path is not paying M-138's
cost and the premise is wrong." The clause therefore has content only as a check on the instrument,
and the column that carries that check is fragment_ns_per_log_entry.
| bucket | log_len |
vertex_ns_per_pixel |
fragment_ns_per_pixel |
fragment_ns_per_log_entry |
speedup |
speedup / log_len |
|---|---|---|---|---|---|---|
| 1 | 20 | 5.7611 | 74.5168 | 3.7258 | 12.934 | 0.6467 |
| 2 | 40 | 5.7080 | 128.2939 | 3.2073 | 22.476 | 0.5619 |
| 3 | 60 | 5.6546 | 179.4203 | 2.9903 | 31.730 | 0.5288 |
| 4 | 80 | 6.4026 | 261.8211 | 3.2728 | 40.893 | 0.5112 |
What the column can tell you: the walk is the cost. fragment_ns_per_log_entry is 2.99–3.73 ns and
never near zero, so the per-pixel cost is a few nanoseconds per log entry and not a constant with a
walk-shaped label on it. The registered falsifier — a fragment path flat in log length — would show
this column collapsing toward fixed / log_len, i.e. falling as 1/log_len: 3.7258 → 1.86 → 1.24 →
0.93. It does not.
What it cannot tell you: the shape of the slope, because it is an absolute per-pixel nanosecond and
therefore carries the machine. In the clean run it is not monotone — it falls 3.7258 → 3.2073 →
2.9903 and then rises to 3.2728. That bucket-4 rise sits beside a vertex_ns_per_pixel of 6.4026
against bucket 3's 5.6546, +13.2% on work that is bit-identical: buckets 3 and 4 share
vertices = 25,482, triangles = 45,890, visible_triangles = 17,357, visible_pixels = 1,110,155,
clipped_triangles = 5,179 and brushes_biting = 26, and differ only in log_len (60 → 80) and
sprays (15 → 20) — which the vertex path never reads. raster_ms rises 19.864 → 27.663 (+39%) and
interp_ms 13.278 → 20.217 (+52%) on that same frozen geometry. Three columns charged to shared
work moving together on identical input is the signature of a machine-wide excursion, not of a loop.
Two claims from the dirty pre-run are withdrawn here, and the replacements are grounded on the integers.
- Withdrawn: "the growth is sub-linear and
fragment_ns_per_log_entryfalls monotonically 3.695 → 3.134 → 2.968 → 2.853." True of the superseded run only; the clean file rises at bucket 4. The run-independent replacement isspeedup / log_len, which is a within-row ratio of two timers taken back-to-back in one rep divided by an integer, so no clock survives it: 0.6467 / 0.5619 / 0.5288 / 0.5112, monotone falling. The fragment path's cost per log entry does fall; the machine-carrying column is simply the wrong place to read it. - Withdrawn: the least-squares decomposition "
fragment_ns_per_pixel = 22.47 + 2.5785 · log_len, so 2.58 ns is per entry against a 22.5 ns fixed part." Refitting the clean four points gives 7.75 + 3.065 · log_len — the intercept moves by 2.9× off a four-point fit with one excursion in it, so the decomposition is not a reportable quantity.M-19's rule ("a fitted coefficient means nothing until it is compared to the data's own range") andM-21's ("a physically impossible fitted parameter is the model telling you it is wrong") both apply: the intercept here is under-determined and the honest statement is the raw column plus the ratio form.
The controlled pair is what remains, and it is the cleanest thing in the file. Buckets 3 and 4 hold
every geometry integer fixed and change log_len by 4/3. speedup goes 31.730 → 40.893, a factor
of 1.289 — below 4/3 = 1.333, so the fragment path's growth is sub-linear in the log, and well
above 1.000, so it is not flat. Both halves of C2's instrument check, from one pair of rows with a
frozen fixture. Against the only public arithmetic in this area — a blog post costing 4 materials × 3
triplanar planes × 5 maps = 60 texture fetches per fragment with no timing behind it — this says the
vertex-attribute route costs 5.65–6.40 ns/pixel of arithmetic and zero extra fetches, and the
exact-paint route costs 74.5–261.8 ns/pixel of pure ALU before a single texture fetch: 290.7 ms for
one 1920×1080 pass on one Zen 3 core at an 80-entry log.
C3, and the locality half is the informative one.
| bucket | misclassified_points / 10⁶ |
fraction | within one cell | within_one_cell_fraction |
naive-axis probe |
|---|---|---|---|---|---|
| 1 | 1,830 | 0.001830 | 1,825 | 0.997268 | 1,603 → 87.60% |
| 2 | 3,407 | 0.003407 | 3,393 | 0.995891 | 2,631 → 77.22% |
| 3 | 3,463 | 0.003463 | 3,441 | 0.993647 | 2,670 → 77.10% |
| 4 | 3,463 | 0.003463 | 3,441 | 0.993647 | 2,670 → 77.10% |
The rate is 5.8× to 10.9× inside the registered 2% ceiling. The registration says "concentrated within one cell" with no number, so this harness states its reading in the code — `local_fraction
= 0.95
(experiment_p75.rs:1222-1225) — because a clause with no threshold cannot be scored; at 99.4% it holds under any reading above 0.95. The **approximation** is the barycentric blend of three vertex weights, i.e. what a rasteriser hands a fragment. The **reference is the field's own answer** at the same world position with the normal fromSdf::gradientnormalised — literallymarching_cubes::unit_gradient(mod.rs:739-743), andPaintStackdoes not overridegradient, so it is the same expression the extractor used for the vertex normals. No mesh quantity enters the reference, which is what makes every counted disagreement interpolation and nothing else. 10⁶ points are sampled uniformly **by area** over the extracted mesh via a cumulative-area CDF and the √-barycentric method,splitmix64seeded0x5075000000000001`, no new dependency.
The mechanism, and the breakdown says the result is not carried by one term. misclassified_paint
is 1,680 / 2,907 / 2,941 / 2,941 — 84.9–91.8% of the total, with misclassified_paint_local
99.39–99.88% of that — and it is boundary-local because the spray's lateral falloff (softness 0.10) is
under one cell (0.125): a nearly-step boundary cannot be resolved by interpolation across a sub-cell
triangle, so the error is exactly a one-cell band along each spray's boundary ring.
misclassified_blend is 150 / 500 / 522 / 522 — 8.2–15.1%, blend_local 98.00–100% — and is the
stratum blend's own nonlinearity: base_weights is smoothstep in the normal and in height, and
interpolating smoothstep(n_y) across three vertices is not smoothstep of the interpolated n_y.
Both kinds of boundary are populated, so the locality result does not rest on one term. The rate
is small for the reason the pre-run arithmetic gave: ten sprays inside the sandbox, each a 0.75-radius
ball with a boundary ring of about 4.7 units, put roughly 10 · 4.7 · 0.125 ≈ 5.9 unit² of a surface of
order 280 unit² within one cell of any boundary — about 2%, so a 2% misclassification rate would
have required misclassifying essentially the whole band and a rate above 2% would have required
misclassification off the band. Both directions were live.
The registered vacuity control is boundary_vertices, and it reads 294 / 526 / 526 / 526. It is
counted over the visible mesh only — a vertex belongs to a triangle that produced at least one pixel
in the visibility buffer, and some mesh edge at that vertex changes the argmax material — and it is
assert!ed non-zero before any row is written (experiment_p75.rs:1184-1190), with the message naming
the consequence: "the misclassification rate is measured over a single-material scene and every clause
is vacuous." The other registered half, materials >= 2, is asserted at :1191; it reads 4 on
every row, counted by the exact classifier over visible pixels, so it is ground truth rather than
the approximation's opinion of itself.
Why the value proves the fixture could have failed, and the honest limit. The count moves with the
fixture — 294 at fifteen brushes against 526 at thirty — so it is a measurement of the scene rather
than a constant, and boundary_vertices_all (the same count without the visibility restriction) is
444 / 955 / 962 / 962, so the restriction removes 33.8% / 44.9% / 45.3% / 45.3% of the world's
material-boundary vertices: the restriction bites, and it is the restriction that could have zeroed the
column. But this control is satisfied rather than at risk and the entry says so rather than
letting an audit find it: the spray-free variant still reported boundary_vertices = 244 (bench
header, not this CSV), because game_dig's stratum blend already puts a grass/dirt boundary on the
tunnel walls via the slope and depth ramps. What would zero this column is a camera pointed away from
the dig, not an absence of materials — which is a real failure mode for a harness that hard-codes an
eye position, and is what the assertion actually defends. The control that is at risk on the paint is
field_walk_mismatches, below.
Five fixture defects, every one caught by this harness's own controls rather than by review.
- C3's first locality probe was the wrong probe, and it would have scored the clause FALSIFIED.
Version one probed the exact classifier six times at one cell along each world axis, holding the
normal fixed at the interpolated one. That reading is still on the row as
misclassified_within_one_cell_axis— 1,603 / 2,631 / 2,670 / 2,670, i.e. 87.60 / 77.22 / 77.10 / 77.10% of the misclassified points, three of four buckets below any reasonable "concentrated" bar and all four below 0.95: C3 FALSIFIED on locality. Two independent blind spots, both in the instrument: (a)base_weightsdepends on the surface normal (triplanar.wgsl:123), so part of the material boundary lives in normal space and a probe that freezes the normal cannot see it; and (b)depthis 0.05, under half a cell, so every painted point trivially loses its paint one cell out alongyand scored "local" for free — the probe was simultaneously too blind and too permissive. The reported probe walks the surface: four steps of one cell in the tangent plane of the field's normal, each pulled back onto the zero set with one Newton stepq -= f(q)·∇f(q)/|∇f(q)|², each re-classified with the field's own normal there. That gives 99.36–99.73%. The naive reading is kept beside it because the two disagreeing is the finding: a locality claim is only as good as the direction the probe moves in. Both columns are in the committed file, so this is✗39's rule satisfied — the repaired instrument's values and the old instrument's are each read from the artefact rather than recalled. - C3's reference was initially a mesh quantity, not the field. Version one classified the reference
with the interpolated normal, so the "ground truth" shared the approximation's own error. Fixed to
Sdf::gradientnormalised, which at a vertex makes reference and attribute agree by construction — so every counted disagreement is interpolation. This isM-289's rule: a reference implementation used as ground truth needs the same scrutiny as the thing it checks. - C2's first timing scheme was destroyed by machine contention and produced a non-monotone fragment
cost. With three interleaved reps and independent medians,
frame_ms_vertex— a loop whose work is bit-identical across buckets 3 and 4 — read 10.24 / 10.27 / 6.09 ms andframe_ms_fragmentwent 221.8 → 307.5 → 253.7, i.e. down for a longer log.raster_msandinterp_msmoved with it, which is how the excursion was known to be machine-wide rather than in the loops. Fixed:SHADE_REPS = 9, both paths back to back inside one rep, and the reported triple is the rep whose ratio is the median, so the two absolutes beside aspeedupcome from one run (M-281).speedup_min/speedup_maxput the residual spread on the row — bucket 4 is 23.219 to 50.521, a 2.18× band around a median of 40.893. The clean re-run shows the fix is partial and the diagnostic still works: bucket 4 carries a residual excursion of exactly the same signature (raster_ms+39%,interp_ms+52%,vertex_ns_per_pixel+13.2% on frozen geometry), and it lands only in columns charged to neither path or in the vertex path's absolute — thespeedupcolumn stays monotone because it is a within-rep ratio. That is the median-of-ratio rule earning its keep on a run it was not designed against. M-50's own 60-carve trace is largely inert, and this isM-50's defect rather than this harness's.brushes_bitingis 11 / 26 / 26 / 26:AutoCarve::centreleaves the sandbox atn = 30(x = 8.1 > 8,z = −8.0) and never returns, and the first four centres are in the air above the hill, so of the 60 brushesM-50binned only 26 ever touch solid rock inside the world — the rest lengthen the log every sample walks and change no geometry at all. Visible in the file:verticesis 25,471 at 30 brushes and 25,482 at both 45 and 60, andtriangles,visible_triangles,visible_pixelsandclipped_trianglesare identical across buckets 3 and- This is very likely the mechanism behind
M-50's own "3.7× for 7× the log, and flattening". Two consequences: (i) it is a good property for C2, because geometry is frozen while log length quadruples, which is the cleanest possible within-one-run comparison and is what makes the bucket-3/4 pair above readable; (ii) any future re-use of that trace as a geometry fixture is measuring a trace that stopped digging a third of the way through. - The pre-run SHARE arithmetic was wrong by 2× and predicted the wrong verdict, and the prediction is
committed. Estimated ~4·10⁴ vertices → share ~6% → C1 FALSIFIED; measured 25,482 vertices →
2.026% of samples → 3.11–3.16% → C1 HELD. The arithmetic's shape was right — the share is
(vertices/samples)times a ~1.54 surcharge — and only the vertex count was wrong.
Two integrity controls beyond the registered one, and both could have failed.
field_walk_mismatches is 0 on every row: the timed weight walk carries the field through every
carve itself and that carried value is compared bit-for-bit against PaintStack::sample at every
vertex. It is the same operation sequence, so zero is the only correct answer, and a non-zero would mean
the thing being timed is not M-138's walk. The zero was verified by mutation rather than
trusted (M-44): swapping brush::apply's two value arguments in the timed walk gives left: 24470,
right: 0 — every vertex — and the assertion aborts before any CSV is written. l1_max_error is
5.960e-8 / 8.941e-8 / 8.941e-8 / 8.941e-8 against an asserted 1e-4; the weight vector is
L1-normalised by construction (up·s + (1−up)·s + (1−s) = 1 identically, and a splat composite
w ← w(1−c) + e_m·c preserves the sum), so this measures accumulated rounding — and it is non-zero,
hence a live number rather than a structural one. pixel_disagreement is 3,444 / 3,670 / 3,670 / 3,670
of 1,110,155 visible pixels (0.31–0.33%), which also guarantees neither shading loop was optimised away.
What changed as a result: nothing in src/, deliberately. crates/isomesh/src/** and
crates/isomesh-gpu/src/** were not touched, the public API was not touched, and the PhaseTree /
Sdf-phase question was not entered — the registration scoped it out as a public-API decision, and this
is "measure it, surface the decision, and stop". The only tree change is an append-only [[bench]]
stanza in crates/isomesh/Cargo.toml.
The recommendation is BUILD IT, as a vertex attribute, and the number that justifies it is not the 40×. It is that the cost is 3.11–3.16% of extraction, flat in log length, for a saving that grows without bound as the player digs: at an 80-entry log the exact-paint fragment path costs 261.8 ns/pixel of pure ALU before a single texture fetch, which is 290.7 ms for one 1920×1080 pass on one Zen 3 core.
Two things not to build, both priced from columns in this file. (i) Do not derive the weights from
per-corner material walks and let the extractor's existing edge interpolation carry them — it looks
like the "inside the existing walk" reading and it is ~8 corner walks per crossed cell against one
walk per vertex, an order of magnitude more, landing far above C1's 5%. The whole reason C1 holds is
that the surface is 2D inside a 3D sample grid. (ii) Do not bake game_dig's normal-driven stratum
term into the attribute. It is misclassified_blend — 150 / 500 / 522 / 522, 8.2–15.1% of the
misclassification — and it is error for nothing: smoothstep(n_y) is cheap per fragment and the
fragment already has n_y as a varying. Bake only the log-driven term, the part that actually needs
the walk. C3 held anyway; this is the term to leave out.
Would be shown wrong by: a speedup below 4× at any log length, or a speedup that stops widening
— either would mean the fragment path is not paying M-138's cost and the premise is wrong; a
fragment_ns_per_log_entry collapsing as 1/log_len, which is the same falsification read off the
per-entry column; a fixture whose surface carries a materially larger vertices / samples ratio than
0.0203 — the share is that ratio times ~1.54, so a surface at 3.2% of samples puts C1 at the 5% bar; a
within_one_cell_fraction below 0.95 under a probe that walks the surface rather than the world axes,
which would mean the interpolated weights are not a resampling of the field but a different quantity; a
non-zero field_walk_mismatches, which would mean the timed walk is not PaintStack's; or the same
comparison on a real GPU, where the vertex path costs an extra attribute fetch per vertex and per-pixel
ALU is not the currency it is on one Zen 3 core — this entry measures shading arithmetic on a CPU
visibility buffer and claims nothing about a hardware rasteriser's frame time.
🔬 M-388 — C1 HELD (18 = 3 × 6 exactly, cost 2.1115×), C2 HELD on its own falsifier while the clause as worded is VACUOUS, C3 HELD at 0.5000 exactly and 0.5429 in wall clock — and every falsifier failing still leaves the answer keep three planes, because stochastic selection manufactures 39,495 extra history rejections in a scene with no dig against the dig's own 8,483 (P-76, R-076)
M. cargo bench --bench experiment_p76, docs/experiments/p-76.csv, 171 rows (4 # lines, one
header, 9 stage = material_shading + 162 stage = taa_resolve), f32 field and shading with f64
clocks and error accumulation, amd-ryzen-9-5900x-12-core, 24 threads, cpu_mhz_start 4200 →
cpu_mhz_end 4199. Two stages over game_dig's own scene: a fetch-for-fetch transcription of
triplanar.wgsl's LAYER_BLEND path timed single-threaded over the 1,111,025 visible fragments of
a ray-cast 1920×1080 visibility buffer in the pose the demo opens in, and P-77's software TAA resolve
at 960×540 with exact motion vectors, three shading streams sharing one G-buffer per world, over the
8 frames following one subtracted sphere. Committed at 9dffb6c — the header carries no
(WORKING TREE DIRTY), and 9dffb6c is an ancestor of HEAD (b2b481e).
The reported run was a dirty pre-run taken while ~25 sibling agents were compiling, and this entry is the clean-tree re-read. Every number that moved is a clock or a clock-derived ratio; every number stage B produces reproduced exactly, because the temporal instrument contains no timer at all —
history_rejected_static66,310,history_rejected_digging74,793, all sixmae_*columns,mae_sampling_excess_ratio_dig_over_static2.0247,zero_proof_rejected0,zero_proof_stochastic_rejected23,248,estimator_mean_signed_error_sampled0.000019 andvisible_fragments1,111,025 are identical to the superseded report's. That isM-279's rule satisfied in the strongest available form: the new run agrees with the old one on everything that is not a clock, and C2's whole verdict is in the part that is not a clock. The moves, and three withdrawals they force, are below.
| clause | registered | measured |
|---|---|---|
| C1 fetch count drops by exactly 3× | 3×, as an identity | HELD — 18 = 3 × 6 in integers, c1_fetch_ratio_is_exactly_3 = true |
| C1 fragment cost drops by ≥ 2× at 1920×1080 | ≥ 2.0 | HELD — 2.1115 median, 2.1128 fastest-pass; a clock, not a gate (✗24, M-281), and not a fetch-count claim (below) |
| C2 dig-time ghosting is worse than the fetch saving is worth | no exchange rate exists | VACUOUS — no instrument in the file can decide an MAE against a millisecond |
| C2 as the registration's own falsifier: MAE digging above MAE static | any difference | HELD — 0.00393754 > 0.00375816, delta +0.00017938 (+4.77%) |
| C3 biplanar gets ≥ half C1's saving, in fetches | ≥ 0.5 | HELD by equality — 6/12 = 0.5000 exactly, forced by construction |
| C3 the same, in wall clock | ≥ 0.5 | HELD by 0.0429 — 0.5429 median, 0.5417 fastest-pass |
| C3 with none of C2's cost | none | HELD as scored (bipl_delta < stoch_delta), but "none" is false: +0.00013232 is 73.8% of +0.00017938 |
Four columns will be misread if this is not said. (1)
c1_holds,c2_holdsandc3_holdsreadtrueon all 171 rows, including the five unscored shading arms and everytaa_resolverow — they are row-invariant verdicts, not per-arm ones, andc1_holds = truebesideshading/stf_3tap_3plane_3stratum_pointsays nothing about that arm. (2) On the 162taa_resolverowsfetches_per_fragment= 6,fragment_ms= 205.524547 andframe_ms= 383.587859 are stage A's stochastic-arm values repeated — the bench says so atexperiment_p76.rs:2738-2739— not a cost of the resolve, which is never timed. (3)scored_armistrueon 4 of the 9 shading rows and on all 162taa_resolverows, because those rows inherit the stochastic arm's flag; it marks which shading configuration a clause is denominated in, not which rows were measured. (4)estimator_worst_fragment_error_sampled= 0.010473 is 5.2×estimator_bias_tolerance= 0.0020 and the control did not fail: the gate is on the mean (estimator_mean_signed_error_sampled= 0.000019, 0.19 σ from zero against a 20 σ tolerance at the stated 1e-4 standard error), because unbiasedness is a statement about a mean and a max over 4,096 fragments is an extreme-value statistic.
Stage A — the nine arms, one interleaved sweep, shade_reps = 9, median reported:
| arm | planes × strata × taps | fetches | texels | fragment_ms |
reps_ms_min |
spread | frame_ms |
fetches_tallied |
|---|---|---|---|---|---|---|---|---|
triplanar_3plane_3stratum_bilinear |
3 × 3 × 1 | 18 | 72 | 433.960563 | 432.6497 | 4.5439 | 809.937331 | 19,998,450 |
stochastic_1plane_3stratum_bilinear |
1 × 3 × 1 | 6 | 24 | 205.524547 | 204.7776 | 9.7495 | 383.587859 | 6,666,150 |
biplanar_2plane_3stratum_bilinear |
2 × 3 × 1 | 12 | 48 | 309.936397 | 309.2218 | 7.3021 | 578.460532 | 13,332,300 |
stochastic_1plane_1stratum_bilinear |
1 × 1 × 1 | 2 | 8 | 123.163308 | 123.0000 | 1.1405 | 229.870107 | 2,222,050 |
stf_3tap_3plane_3stratum_point |
3 × 3 × 3 | 54 | 54 | 571.483575 | 569.1686 | 5.8511 | 1066.608169 | 59,995,350 |
stf_1tap_3plane_3stratum_point |
3 × 3 × 1 | 18 | 18 | 428.221675 | 427.1150 | 12.4784 | 799.226359 | 19,998,450 |
stochastic_1plane_stf_1tap_point |
1 × 3 × 1 | 6 | 6 | 203.310169 | 202.8283 | 17.0074 | 379.454978 | 6,666,150 |
walls_concrete_3plane_1layer_bilinear |
3 × 1 × 1 | 6 | 24 | 197.416041 | 197.2986 | 0.7682 | 368.454268 | 6,666,150 |
alu_and_call_only_control |
3 × 3 × 1, no texel | 0 | 0 | 252.069736 | 251.9870 | 1.5613 | 470.459085 | 19,998,450 |
The exactness control is integers only and it is what makes C1's first half an identity rather than a
measurement. fetches_tallied is incremented once per fetch inside the timed pass, and on every arm
it equals the analytic per-fragment count times visible_fragments: 18 × 1,111,025 = 19,998,450,
6 × 1,111,025 = 6,666,150, 12 × 1,111,025 = 13,332,300, 54 × 1,111,025 = 59,995,350,
2 × 1,111,025 = 2,222,050. So no arm silently skipped a fetch and no arm's fast number is a fast number
for doing less. 18 = 3 × 6 holds in integers on any machine, and c1_fetch_ratio_is_exactly_3 is
true — asserted, not timed. The ALU control's own tally is 19,998,450 at zero texels, which is the
proof that it really makes all eighteen calls and only skips the loads.
The registration's count of the baseline is wrong by 3× and the bench found it before measuring. The
hypothesis prices "three planes × three stochastic taps" as "nine fetches per map" and says
triplanar.wgsl "already pays the three". game_dig builds the terrain material with
settings.z = LAYER_BLEND = -1.0, which takes the shader's else branch: layer_ar samples all three
planes once per stratum and layers_na samples all three strata for each of three planes, so the
terrain fragment issues 9 + 9 = 18, and the unnamed third factor makes the product
planes × strata × taps. At the registration's own three taps that is stf_3tap_fetches = 54, not
nine. The 3× survives intact because the plane count factors out of both maps: 2 × 3 × 3 over
2 × 1 × 3 is 18/6 = 3 exactly.
The SHARE line, recomputed
Registered SHARE: "C1 moves the material shading stage, which P-75's C2 will have measured."
R-075 measured the material selection sub-stage over its own 1920×1080 visibility buffer at the
same pose — docs/experiments/p-75.csv, frame_ms_fragment = 82.725191 ms for the log-walk path at
log_len = 20 and frame_ms_vertex = 6.395743 ms for the vertex-attribute path, over
visible_pixels = 1,110,155 — and labelled them "shading cost … not frame time". This row measures
the material sampling and blending sub-stage over 1,111,025 fragments. The two counts differ by
870 pixels, 0.078%, from a rasteriser and a ray-caster built independently, so the two rows are
denominated in the same pixels and this row uses P-75's label unchanged.
C1's measured saving is 433.960563 − 205.524547 = 228.436016 ms. As a share of what it is denominated in:
| denominator | ms | C1's share |
|---|---|---|
| the sampling-and-blending sub-stage alone | 433.960563 | 52.64% |
plus P-75's recommended vertex-attribute selection path |
440.356306 | 51.88% |
plus P-75's log-walk selection path at log_len = 20 |
516.685754 | 44.22% |
Nothing in the SHARE line is unreachable: the clause is denominated in "the fragment cost", which is
fragment_ms, and C1's 2× is asked of the sub-stage it names rather than of a frame.
What arithmetic reached before the run: 18/6 = 3 exactly; C3's 6/12 = 0.5000 exactly; the cost ratio's ceiling of 3 as the fixed cost goes to zero; and the 18-not-3 correction above.
What arithmetic could not reach, and the answer is the row's most transferable finding. Whether the
fixed cost is small enough for a 2× needed a measurement, and the bench modelled it as a fetch-count
claim: t(k) = F + kS, ratio = t(18)/t(6) ≥ 2 ⟺ 6S ≥ F. The least-squares fit over the four bilinear
stratum-blend arms at k = 2, 6, 12, 18 reproduces from the file — Sxy/Sxx over
(2, 123.163308), (6, 205.524547), (12, 309.936397), (18, 433.960563) gives
fit_slope_ms_per_fetch = 19.186701 and fit_intercept_ms = 85.872544, fit_r2 = 0.998758
— so fit_six_fetch_cost_ms = 6 × 19.186701 = 115.120206 ≥ 85.872544 and
c1_cost_reachable_6s_ge_f = true with a 1.3406× margin.
And this harness's own ALU control refutes that model. alu_and_call_only_control is the baseline's
full 3-plane, 3-stratum control flow — every projection, both pow weight sets, all three whiteout
blends, the lighting — plus all eighteen fetch calls' address arithmetic and tallies, with
texels_per_fragment = 0 (Filter::NoTexel at experiment_p76.rs:964-968). It measures
alu_control_ms = 252.069736 ms, which is 2.94× the fitted F of 85.872544; the fit's intercept
is 34.1% of the fixed cost measured directly, because the four fit arms differ in plane and stratum
count as well as fetch count and the slope has absorbed the difference. Read off the two rows:
- the baseline's texel loads are 433.960563 − 252.069736 = 181.890827 ms, 41.92% of the pass;
- removing every texel load while keeping the baseline's plane and stratum shape caps the ratio at 433.960563 / 252.069736 = 1.7216× — below the registered 2×.
So C1's cost half is not reachable from the fetch count at all, and the 2.1115 it does reach is paid
by the ALU the two dropped planes stop executing: two of three plane weight sets, two of three whiteout
blends, two of three layers_na accumulations, and twelve of eighteen fetch calls. This is ✗51's rule
— a clause stated as a ratio of a total must name the share of that total it can move — applied to a
clause whose own harness supplies the share. Both ratios are within one interleaved sweep of one binary,
which is the only form M-281 permits, and neither transfers to a GPU.
C2, and precisely what "not scoreable as literally worded" means
C2 fuses a comparison with an operationalisation and they are not the same claim.
The comparison is "the ghosting cost under an active dig is WORSE than the fetch saving is worth".
It has a dimensionless mean absolute error on one side and milliseconds on the other. The file carries
both sides — stochastic_temporal_delta_mae = +0.00017938 and
triplanar_fragment_ms − stochastic_plane_fragment_ms = 433.960563 − 205.524547 = 228.436016 ms —
and carries no column, and the registration no constant, that converts one into the other. No
reading of the 171 rows can decide it in either direction. A clause with no instrument is VACUOUS,
never HELD, and this one is vacuous for the strongest possible reason: the two quantities have different
dimensions.
The operationalisation in the same sentence, and the only test the registration's own falsified_by
names — "no difference between digging and static" — is instrumented, and it is exactly what
c2_holds encodes: mae_vs_reference_digging 0.00393754 > mae_vs_reference_static 0.00375816.
That HELD.
The distinction cuts against the technique, which is why it must not be resolved in the clause's
favour. If the literal comparison were scoreable and true it would say the fetch saving is not worth
buying, so a HELD C2 is an argument against building this, and reading c2_holds = true as "the
clause holds" would convert a null into an endorsement. What the file gives a reader instead of an
exchange rate is the magnitude, against the pass's own signal level (mean_r/mean_g/mean_b on the
baseline arm = 0.305015 / 0.388943 / 0.305486, mean 0.333148): the whole post-dig MAE is 1.18% of
mean image level and the dig-attributable part of it is 0.054%.
The registered temporal columns, dig_at_feet_static, frames_after_edit = 8, 4,133,904 history
samples per stream per world:
| stream | world | frame_rejected |
fraction | window MAE vs 3-plane reference |
|---|---|---|---|---|
reference_3plane |
static | 66,310 | 0.01604053 | 0.00366139 (mae_taa_floor_static) |
reference_3plane |
digging | 74,793 | 0.01809258 | 0.00374159 (mae_taa_floor_digging) |
stochastic_1plane |
static | 105,805 | 0.02559445 | 0.00375816 (mae_vs_reference_static) |
stochastic_1plane |
digging | 114,924 | 0.02780036 | 0.00393754 (mae_vs_reference_digging) |
biplanar_2plane |
static | 66,505 | 0.01608770 | 0.00383510 (mae_biplanar_static) |
biplanar_2plane |
digging | 75,060 | 0.01815717 | 0.00396742 (mae_biplanar_digging) |
Every one of these is the exact aggregate of the eight frame_plus_* rows beneath it, which is worth
saying because it makes the registered columns auditable line by line: the digging reference stream's
per-frame counts 12,777 + 9,883 + 9,607 + 8,976 + 9,310 + 9,497 + 6,406 + 8,337 = 74,793, its static
twin's 8,164 + 8,537 + 8,731 + 8,437 + 8,944 + 9,271 + 6,105 + 8,121 = 66,310, and the eight
frame_mae values average to the window MAE to all eight reported digits on all six rows.
Subtracting the floor is what turns C2 into a mechanism. The raw +4.77% is mostly TAA's own
ghosting, which the deterministic 3-plane stream pays too: the floor's own dig delta is
0.00374159 − 0.00366139 = +0.00008020, i.e. 44.7% of the +0.00017938. What is left is
sampling-attributable, and it doubles: mae_sampling_excess_static 0.00009678 →
mae_sampling_excess_digging 0.00019595, mae_sampling_excess_ratio_dig_over_static = 2.0247.
The P-77 linkage, stated in both directions, because the two registrations disagree
P-77's committed file (docs/experiments/p-77.csv, 4724b9d) on the same arm this row reuses:
steady_rejection_fraction = 0.00490399 — the briefed denominator, confirmed —
post_edit_rejection_fraction = 0.01422016, ratio = 2.8997 against a registered 5×,
frames_elevated = 1, c1_holds = false. This row's deterministic static fraction,
rejection_fraction_static = 0.01604053, is 3.27× P-77's on the same instrument and camera, for a
stated reason: P-77 shaded with fbm albedo and the geometric normal, while here the whiteout blend
perturbs the normal and the high-frequency content enters the sun, rim and specular terms as well.
- By
P-76's own falsifier, C2 is not falsified: there is a difference, and it is in the registered direction. - By
P-77's falsifier — "C1 by under 5x, or by a single-frame spike — either means destruction is not a temporal problem, and this row and P-76's C2 close together" —frames_elevated= 1 is that spike, andP-77therefore already closed this clause before it ran.
Both readings are true of the committed files, and this row's per-frame table is what reconciles them: the rejection spike is one frame and the image error it causes is not. Per-frame excess of the digging world over the static one, headline arm:
| frame | frame_rejected excess, deterministic stream |
MAE excess, stochastic stream |
|---|---|---|
| +0 | 4,613 | +0.00026727 |
| +1 | 1,346 | +0.00021252 |
| +2 | 876 | +0.00018796 |
| +3 | 539 | +0.00017063 |
| +4 | 366 | +0.00015864 |
| +5 | 226 | +0.00015271 |
| +6 | 301 | +0.00014369 |
| +7 | 216 | +0.00014158 |
| sum / mean | 8,483 | +0.00017938 |
Frame +0 carries 4,613 of the 8,483, 54.4% of the whole eight-frame excess and 3.43× frame
+1 — P-77's single-frame spike, reproduced on an independently built signal. The MAE excess does the
opposite: it is elevated on all eight frames and decays monotonically, 8 for 8, from
+0.00026727 to +0.00014158, ending at 53% of where it started rather than at zero. The mechanism is the
resolve's own memory: ALPHA = 0.1, so the exponential blend's effective sample count is
(2 − 0.1)/0.1 = 19 frames, and an error injected in one frame is still on screen after eight. So
P-77's C1 is correctly falsified — destruction is not a multi-frame rejection problem — and that
does not close C2, because C2 measures the image consequence and the image consequence outlives the
rejection by the length of the history. Two rows, opposite verdicts on the same clause, and the
disagreement is exactly the 19-frame blend.
C3, and the integer that makes "no temporal debt" real and "none of C2's cost" false
C3's threshold is arithmetically forced to be exactly half: biplanar drops one plane of three and
stochastic selection drops two, so 18 − 12 = 6 against 18 − 6 = 12 and c3_saving_ratio_fetches =
0.5000. The clause is met by equality, holds only because the registered inequality is non-strict,
and cannot discriminate anything — no biplanar implementation could have failed it. In wall clock
c3_saving_ratio_ms = (433.960563 − 309.936397)/(433.960563 − 205.524547) = 0.5429, and
c3_saving_ratio_ms_min_based = 0.5417; the margin is 0.0429, which fixture defect 4 below exceeds.
"No temporal debt" is true and it is an integer. In the static world biplanar rejects 66,505 against the deterministic stream's 66,310 — +195 — while the stochastic arm rejects 105,805, +39,495. Biplanar's manufactured rejection is 1/202.5 of the stochastic arm's. In the zero-proof arm biplanar rejects 0, exactly as the deterministic stream does.
"None of C2's cost" is false, and the file says by how much. biplanar_temporal_delta_mae =
+0.00013232 against stochastic_temporal_delta_mae = +0.00017938: biplanar carries 73.8% of the
stochastic arm's dig-induced MAE delta, not none. Subtract the deterministic floor's own +0.00008020 and
it still carries 0.00005212 against 0.00009917 — 52.6%. The reason is that dropping a plane also
changes which projection the whiteout normal is built from, and a dig changes the normal.
And biplanar's error is a bias, which is the half that inverts C3's recommendation. In the
zero-proof arm — camera frozen, jitter off, no dig, 24 warm-up frames — frame_mae on the biplanar
stream reads 0.00088446 on all eight frames, identical to eight decimal places, which is a converged
systematic difference and not variance; the stochastic stream fluctuates over 0.00085120–0.00085983
around mae_ideal_stochastic = 0.00085509; the deterministic stream sits at mae_ideal_reference =
0.00000179, and its per-frame values climb 0.00000176 → 0.00000181 across the eight rather than
decaying, which is the drift signature of the f32 YCoCg round-trip rather than a convergence residual.
So under maximally favourable conditions biplanar's converged bias (0.00088446) is larger than the
stochastic arm's residual (0.00085509), by 1.034×, and in the headline arm biplanar's excess over the
TAA floor is 1.79× the stochastic arm's (mae_biplanar_excess_static 0.00017371 against
mae_sampling_excess_static 0.00009678). TAA removes variance; it does not remove a bias. C3 is right
that biplanar has no temporal debt and wrong to imply it therefore has no cost.
frame_ms is a registered column and there is no renderer
crates/isomesh must not depend on Bevy, so there is no engine here and no frame time is invented.
frame_ms is the per-fragment shading cost scaled to full coverage, fragment_ns_per_fragment ×
1920 × 1080 / 1e6, and the arithmetic is checkable on any row: 390.5948 × 2,073,600 / 1e6 = 809.9373
against the column's 809.937331. Equivalently frame_ms = fragment_ms × 2,073,600 / 1,111,025 =
fragment_ms × 1.86638 on every row — 205.524547 × 1.86638 = 383.588 against 383.587859 — so the
column is an exact restatement of fragment_ms and carries no independent measurement. It is the
material shading stage's cost for a 1080p frame in which every pixel is terrain: no geometry pass, no
lighting pass, no post, and P-75's label verbatim.
No clause is scored VACUOUS on frame_ms's account, because no registered clause reads it — C1's
second half is about "the fragment cost", which is fragment_ms, timed over the real 1,111,025-fragment
visibility buffer. The honest warning is the other way round: nothing downstream should quote frame_ms
as a frame time or as a second data point, and on the 162 taa_resolve rows it is not even this stage's
number.
The vacuity control, its column, and why its value is a measurement
Column history_rejected_digging, value 74,793 — non-zero, so C2 can fire. It is counted on the
deterministic 3-plane stream, which makes it P-77's own quantity rather than a new one, and it is
the exact integer sum of the eight per-frame counts listed above.
Why that value proves the fixture could have failed (M-44): zero_proof_rejected = 0, from a
third arm, zero_proof_no_jitter_static, with the camera frozen and the TAA jitter off. Every one of its
eight frame_rejected cells reads 0 over a frame_population summing to 4,130,616 — same instrument,
same CLAMP_EPS, same field, same resolve — so the reprojection becomes the identity, the history
converges on the current frame, and the resolve rejects exactly nothing. The bench asserts
zero_proof × 100 < rejected_digging, i.e. 0 < 74,793. An instrument that reaches a hard zero when there
is nothing to reject is an instrument whose 74,793 is a reading and not a floor.
frame_mean_clip_sisNAon exactly the zero-proof reference and biplanar streams, and that is the control working, not a missing measurement. It is a mean over rejected samples, and those streams rejected none, so the population is empty. The stochastic stream in the same arm reads 0.475225 over its 23,248 rejections.
A second reading from the same arm is itself the row's central result.
zero_proof_stochastic_rejected = 23,248. With a perfectly frozen camera, no jitter, no dig and 24
frames of warm-up, the stochastic stream still rejects 23,248 history samples, because the plane choice
changes every frame — where the deterministic stream rejects 0. Stochastic filtering manufactures its
own history rejection before any dig or any camera motion is charged for. In the headline arm the same
mechanism reads 39,495 extra rejections in the static world against the dig's own 8,483 on the
deterministic stream: the technique's self-inflicted temporal cost is 4.66× the cost of the
destruction it was registered to be priced against.
What actually empties the temporal budget is walking, and it is in the file. dig_at_feet_walk
rejects 1,527,479 of 4,132,370 samples — frame_rejection_fraction 0.36963752 — standing on the
same field with no dig at all, at frame_mean_reproj_px 7.2514; digging moves that to 0.36779548,
down by 0.50%. So the registered headline, "a destructible world has already spent its temporal
budget", is true and true for the wrong reason: at game_dig's own 2.5 units/s the dig is invisible
beside locomotion. That reproduces P-77's own saturation finding (0.86644885 at its resolution) on an
independently built signal, and it is why the headline arm and not the walking arm carries C2 — a ratio
between two saturated numbers measures nothing.
Fixture defects this harness's own controls caught
- The registered "unbiased" control was asserting the wrong contract, and the truth is a finding.
The first version compared 256 draws of the single-plane arm's shaded colour against the 3-plane
arm's and demanded they agree; it failed at 0.02229 — which is now in the file as
shading_bias_worst_fragment= 0.022287. It was right to fail:normalize,max(0, ·),powfand the roughness clamp are nonlinear, so the estimator is unbiased in the maps it samples and biased in the colour it shades. That isarXiv:2305.05810's own title — filtering after shading — and it means a share of the stochastic error is a bias no accumulation removes.shadenow returns the sampled maps alongside the colour; the gate is on their mean (estimator_mean_signed_error_sampled= 0.000019 againstestimator_bias_tolerance= 0.0020) and the residual is reported (shading_bias_mean_signed= 0.000084). - Dropping the clamp's
epsmade the zero-proof arm reject 31,274 samples. SimplifyingP-77'sDop<3>to a plainAabbsilently dropped its1e-5dilation.from_ycocg(to_ycocg(c))is the identity in real arithmetic and not inf32, so the history drifts ~1e-7 per frame, and at any pixel that is its own 3×3's extremum in some channel the box boundary passes exactly through the current colour and clips that 1e-7 tos ≈ 0. With the paper's1e-5restored the same arm readszero_proof_rejected= 0 andM-44's control is a control. The residual is visible in the file: the zero-proof reference stream'sframe_maeclimbs 0.00000176 → 0.00000181 across the eight frames, which is that drift with the clip no longer firing on it. 6S ≥ F, notS ≥ F. The reachability line printed the wrong inequality: the ratio ist(18)/t(6), so the fixed cost competes with the six fetches the stochastic arm still pays, not with one.c1_cost_reachable_6s_ge_fis the corrected column, and the SHARE section above records that even the corrected inequality is about a fittedFthe ALU control refutes.plane_weightswas hoisted above the plane-mode match, charging the biplanar arm threepow(abs(n), 4)it never issues — Quilez's weighting replaces that blend. With the charge in, C3's ms saving ratio read 0.4715 on the superseded run, below the 0.5 bar: the defect decided the clause. Moved inside the arms that use it, the same ratio read 0.5847 there and 0.5429 on the committed clean tree. The defect was worth 0.1132 against a committed margin of 0.0429 — 2.64× the margin, which is the pre-run prediction that C3's wall-clock half is decided by fixture detail rather than by mechanism, confirmed the hard way.- Five timed repetitions were not enough to see the clause. At
shade_reps= 5 the baseline arm's max-minus-min was 26% of its own median with siblings compiling, against a threshold only 10% below the ratio. Nine interleaved reps,reps_ms_minandreps_ms_spreadon every shading row, and a fastest-pass ratio beside the median. On the committed clean tree the baseline'sreps_ms_spreadis 4.5439 on a 433.960563 median — 1.05% — and median and minimum now agree to 0.062%.
What the clean re-run moved, and three withdrawals it forces
| quantity | column | superseded dirty pre-run | committed 9dffb6c |
|---|---|---|---|
| C1 cost ratio, median | c1_cost_ratio |
2.0092 | 2.1115 |
| C1 cost ratio, fastest pass | c1_cost_ratio_min_based |
2.1122 | 2.1128 |
| fit-predicted ratio | fit_predicted_ratio_18_over_6 |
2.1231 | 2.1455 |
fitted fixed cost F |
fit_intercept_ms |
89.75 | 85.872544 |
fitted 6S |
fit_six_fetch_cost_ms |
114.94 | 115.120206 |
| fit quality | fit_r2 |
0.9939 | 0.998758 |
| C3 ms saving, median | c3_saving_ratio_ms |
0.5847 | 0.5429 |
| C3 ms saving, fastest pass | c3_saving_ratio_ms_min_based |
0.5424 | 0.5417 |
| bilinear-minus-point, per texel | bilinear_minus_point_ns_per_texel |
−0.2691 | +0.0957 — sign flipped |
| 1-plane 1-stratum arm | fragment_ms |
122.07 | 123.163308 |
| baseline within-run spread | reps_ms_spread |
~51 at 5 reps | 4.5439 at 9 |
| clock | cpu_mhz_start / cpu_mhz_end |
4200 / 4200 | 4200 / 4199 |
| provenance | # commit |
working tree dirty | 9dffb6c, clean, ancestor of HEAD |
Nothing else moved. Every integer, every MAE and every rejection count is identical, which is what makes the three withdrawals below withdrawals of reasoning rather than of data.
Withdrawn 1 — "the extra texels a bilinear tap quad reads cost at or below zero". The bench doc and
the report both state this, and the committed run reads bilinear_minus_point_ns_per_texel = +0.0957,
positive. The signed number is not a measurement in either direction: the two arms it is computed from
differ by 433.960563 − 428.221675 = 5.738888 ms, which is smaller than the point arm's own
reps_ms_spread of 12.4784 ms, so this harness cannot resolve the cost of the three extra texels at
all and its sign is set by the run. What replaces it is a count comparison taken inside one interleaved
sweep: stf_3tap_3plane_3stratum_point reads 54 fetch instructions and 54 texels against the
baseline's 18 and 72 — three quarters of the texel traffic — and measures 571.483575 against
433.960563, 1.32× slower. So on this machine the clock follows the instruction count and not the
texel count, and a GPU's texture unit prices these the other way round: one instruction, four taps, one
L1 lookup. Neither machine's wall clock generalises; fetches_per_fragment and texels_per_fragment
do, which is why both are columns.
Withdrawn 2 — "the measured ratio exceeds the pure-fetch prediction because the stochastic arm's F
is smaller". Measured 2.1115 (median) and 2.1128 (fastest) against fit_predicted_ratio_18_over_6 =
2.1455: the measurement is 1.58% below the prediction, not above — and it was below on the
superseded run too (2.0092 and 2.1122 against 2.1231), so the claim was never true of any run this
harness produced. The four-point linear model in the fetch count already accounts for all four arms to
within 1.6% at fit_r2 = 0.998758; the plane-count-dependent ALU the model cannot see does not show up
as a measurable extra saving on top of it.
Withdrawn 3 — "the median-based ratio landed 0.46% above the 2.0 threshold, and the median convention
is capable of flipping the boolean". That was a property of a contended tree. On the quiet tree the
median (2.1115) and the least-contended estimator (2.1128) agree to 0.062% and both sit 5.6%
above the bar, so the convention no longer decides anything. The objection that replaces it is not a
margin but a denominator: per the SHARE section, alu_control_ms = 252.069736 makes the texel traffic
41.92% of the baseline pass and caps a fetch-count-only saving at 1.7216× — under the registered 2× — so
C1's cost half was never a fetch-count claim, and the run-independent part of C1 is the integer identity
18 = 3 × 6 and nothing else (M-282, ✗24: gate the count, print the clock).
What changed as a result
Do not build stochastic plane selection into bevy_isomesh's triplanar material. Every registered
falsifier failed to fire and the row still says don't, on integers rather than on clocks:
- It manufactures 39,495 history rejections in a static scene against the dig's own 8,483 — 4.66× — and 23,248 with the camera frozen and the jitter off, where the deterministic stream rejects 0. The debt the registration expected destruction to have already spent is spent by the mitigation.
- Its error does not converge.
mae_ideal_stochastic= 0.00085509 againstmae_ideal_reference= 0.00000179 — 478× — under ideal conditions and 24 warm-up frames, and part of it is a bias no accumulation removes (shading_bias_mean_signed0.000084, worst fragment 0.022287). - Its saving is a clock. 2.1115× on this CPU instrument, with
Fhere beingP-77's geometric lighting plus a Blinn-Phong lobe rather thanapply_pbr_lighting— Bevy's fixed cost is larger, so a real pipeline's ratio is lower than 2.1115 — and the ALU control says the fetch count cannot pay for 2× on its own.
Do not adopt biplanar on C3's strength either. Its "at least half" is exactly half by construction, so the clause cannot discriminate; its steady-state error is 1.79× the stochastic arm's post-TAA error; its ideal-arm error is a converged bias of 0.00088446, larger than the stochastic arm's residual; and it carries 73.8% of the stochastic arm's dig-induced MAE delta rather than none.
Cut the stratum factor instead, and the file already measures the arm.
shading/walls_concrete_3plane_1layer_bilinear is three planes and one stratum:
fetches_per_fragment = 6 and texels_per_fragment = 24, the same two integers as the
stochastic single-plane arm, at 197.416041 ms against that arm's 205.524547 in the same interleaved
sweep — with no stochastic term, therefore no manufactured rejection and nothing for TAA to pay off.
Source arithmetic rather than a CSV number, and flagged as such: Ground's height is
0.35·sin(0.9x)·cos(0.7z) + 0.15·sin(2.1x), so it lies in [−0.5, 0.5], and with
SHALLOW_Y_LO = −1.6, SHALLOW_Y_HI = −0.4 the shader's shallow = smoothstep(−1.6, −0.4, y) is
≥ 0.9803 everywhere on the undug surface — so the deep-dirt stratum's weight is ≤ 0.0197 while all
three planes of both maps are sampled for it, 6 of the 18 fetches, for under 2% of the result. A
per-fragment branch around a textureSample is a WGSL validation error, which is why the shader cannot
skip them; a uniform branch or a two-stratum blend is legal and costs no image quality.
P-77's instrument is confirmed reusable, with one correction to propagate. CLAMP_EPS = 1e-5 is
load-bearing rather than decoration (defect 2); anything else gated on this resolve inherits it.
And nothing downstream should quote frame_ms. It is fragment_ms × 1.86638 on every row, and on
the 162 taa_resolve rows it is stage A's stochastic-arm number rather than anything the resolve did.
Would be shown wrong by: a GPU measurement in which the texel count rather than the
fetch-instruction count sets the clock, which would reverse the stf_3tap ordering and restore the
texel argument the registration priced backwards; a resolve whose blend is short enough that an
eight-frame window outlives it, which would make the rejection spike and the image error coincide and
reinstate P-77's single-frame reading of this C2; a stochastic plane selector whose static-scene
rejection count is at or below the deterministic stream's, which would remove the manufactured-rejection
objection entirely; a three-plane single-stratum terrain material measuring above the stochastic
single-plane arm at the same six fetches, which would remove the recommendation's alternative; or an
exchange rate between image MAE and milliseconds registered anywhere in this repository, which would
make C2's literal clause scoreable — and could then score it either way.
Recommendation, in a form the owner can act on: pay for three triplanar planes and one stratum, not one plane and three strata — six fetches either way, and only the three-plane arm needs no TAA to converge.
💥 ✗58 / M-389 — C1 FALSIFIED both ways at 2.8997× against a fixture ceiling of 2.9852 and a single-frame spike; C2's recovery half FALSIFIED at exactly 0 on all 140 rows by the paper's own containment guarantee, its cost half VACUOUS; C3 FALSIFIED at 67.23% while the mechanism it tests holds at 1.000000 — a dig's temporal debt is one frame, and under locomotion there is no history left to owe (P-77, R-077)
M. cargo bench --bench experiment_p77, docs/experiments/p-77.csv, 140 rows (10 arms × one
*/steady_window + one */post_edit_window + twelve */frame_plus_N), 58 columns, f32,
amd-ryzen-9-5900x-12-core at cpu_mhz 4200, 24 threads for the ray-cast pass and one for the clamp
passes on purpose. A software TAA resolve over a ray-cast depth buffer of game_dig's own field with
exact motion vectors, four neighbourhood volumes evaluated on the same fetched history sample, control
and treatment worlds run in lockstep over one camera path and one jitter sequence. Committed at
abffc18; the file's own stamp reads # commit 4724b9d on amd-ryzen-9-5900x-12-core at
2026-08-28T00:51:04Z — no (WORKING TREE DIRTY) — and 4724b9d is an ancestor of HEAD.
Every number below is read from the committed file, and the clocks are not the ones R-077 reported. That run was
63c7161 (WORKING TREE DIRTY)with ~25 sibling harnesses compiling on the same box, and its own note said so. Every integer and every ratio reproduces exactly — 30,409 / 6,200,866, 7,348 / 516,731, 2,568, 5,098, 4,940, 160, 4,792, 5,105, 2,884, 4,611,ratio2.8997,paired_frame_ratio2.8614,ratio_ceiling_from_footprint2.9852,concentration_fraction0.672292,concentration_edit_attributable1.000000,frames_elevated1, everykdop_recovered_fraction_rgb_axes, and the whole reprojection curve — which isM-279's rule satisfied: the new run agrees with the old one on everything that is not a clock. The clocks moved by 2×.kdop_mson the headline arm was reported at 130.9826 ms and reads 62.6205;kdop_ms_per_megapixel252.7 → 120.7957;clamp_ratio_dop_over_aabb2.2659 → 2.0746, and the across-arm band 1.55–2.55 → 1.7881–2.1922. So the report's stated cause for the wide band — sibling contention,M-280— is itself confirmed by the quiet re-run, and the band across the nine jittered arms is now 2.0549–2.1922, a 6.7% spread. No verdict moved:kdop_msis three orders above C2's bar on either run, which is the point of scoring that half VACUOUS rather than false.
| clause | registered | measured |
|---|---|---|
| C1a post-edit rejection ≥ 5× steady | ≥ 5.0 | FALSIFIED — 2.8997, against a fixture ceiling of 2.9852 that was computed before the run |
| C1b the elevated rate persists ≥ 3 frames | ≥ 3 | FALSIFIED — frames_elevated = 1. A single-frame spike, which is the falsifier's own second condition |
| C2a k-DOP recovers ≥ half the rejected samples | ≥ 0.50 | FALSIFIED — 0.00000000 on all 140 rows; 0 by containment, and the source says so |
| C2b at under 0.3 ms | < 0.3 ms | VACUOUS — no GPU TAA resolve pass exists in this crate. Satisfied from the source at tier V: +50 µs on an RTX 3090 |
| C3 > 80% of rejections inside the dilated brush box | > 0.80 | FALSIFIED — 0.672292. On the edit-attributable denominator the same quantity is 1.000000 |
The SHARE recomputation, and both magnitude clauses were beyond this fixture's arithmetic before a
single frame was rendered. The registration's SHARE line says only "C1 is a rate, not a ratio of a
total; C2 moves the TAA resolve stage." Read as a rate, C1's ceiling is post ≤ 1.0, so 5× needs a
steady rate under 0.20 and the headline arm's 0.0049 leaves 200× of headroom. That is the wrong
ceiling. The dig can only add a rejection at a pixel whose signal it changed, and §"C3 is not
independent of C1" below proves that set lies inside the brush's projected silhouette, so
ratio ≤ 1 + changed_pixels / steady_rejected
which the harness emits per arm as ratio_ceiling_from_footprint. On the headline arm that is
(2,568 + 5,098)/2,568 = 2.9852 — 59.7% of the registered 5× — and the run achieved 2.8997,
97.1% of its own ceiling. C1 did not fail because the dig is gentle. It failed because a 0.25-radius
brush at game_dig's own aim distance changes 5,098 of 516,731 pixels = 0.99% of the frame against a
floor that rejects 0.49%, and 1 + 0.99/0.49 is not 5.
| arm | walk u/s | mean reproj px | steady rejection | ceiling | ratio | frames elevated |
|---|---|---|---|---|---|---|
dig_at_feet_static (headline) |
0.00 | 0.6117 | 0.00490399 | 2.9852 | 2.8997 | 1 |
demo_pose_static |
0.00 | 0.6115 | 0.01159249 | 1.0603 | 0.9338 | 0 |
dig_at_feet_walk_quarter |
0.62 | 1.8607 | 0.58710621 | 1.0163 | 1.0028 | 0 |
dig_at_feet_walk_half_speed |
1.25 | 3.6183 | 0.75028189 | 1.0123 | 0.9984 | 0 |
dig_at_feet_walk_half_res (480×270) |
2.50 | 3.6413 | 0.75223568 | 1.0106 | 1.0063 | 0 |
demo_pose_walk |
2.50 | 4.2121 | 0.65138010 | 1.0004 | 1.0028 | 0 |
dig_at_feet_walk |
2.50 | 7.2424 | 0.86644885 | 1.0093 | 1.0038 | 0 |
dig_at_feet_walk_held (3 brushes) |
2.50 | 7.2424 | 0.86644885 | 1.0093 | 1.0038 | 0 |
dig_at_feet_walk_untextured |
2.50 | 7.2424 | 0.98662845 | 1.0082 | 0.9984 | 0 |
zero_proof_no_jitter_static |
0.00 | 0.0000 | 0.00000000 | void, see below | NaN | 0 |
The largest real ceiling anywhere in the fixture is 2.9852, and the second largest is 1.0603. C1's 5× was unreachable on every arm, and on eight of ten it was unreachable by a factor of five.
C3's 80% was unreachable for the same reason, one substitution later. From the identity below,
concentration ≤ (R − 1 + b)/R, so clearing 0.80 needs R ≥ (1 − b)/0.20. Per arm that is 4.2075 to
4.9680, against a ceiling that never exceeds 2.9852. Two of the three registered clauses were
decided by the fixture's own footprint, and the harness ran anyway and reported the number (the ✗51
rule).
C1, and the persistence half is the more interesting failure. Headline arm, standing still at pitch
−0.6 rad looking at the rock underfoot — game_dig's default state, since the walk is key-driven and the
demo opens with no key held:
| offset | population | rejected | control | paired_frame_ratio |
changed px | mean clip s |
deep clips (s < 0.5) |
|---|---|---|---|---|---|---|---|
| +0 | 516,731 | 7,348 | 2,568 | 2.8614 | 5,098 | 0.340765 | 4,818 (65.6%) |
| +1 | 516,748 | 3,117 | 2,460 | 1.2671 | 5,105 | 0.808022 | 311 (10.0%) |
| +2 | 516,735 | 3,203 | 2,810 | 1.1399 | 5,103 | 0.788500 | 396 (12.4%) |
| +3 | 516,749 | 2,874 | 2,616 | 1.0986 | 5,109 | 0.810035 | 279 (9.7%) |
| +4 … +11 | ~516,740 | 1,810–3,136 | 1,563–2,867 | 1.1001–1.1580 | 5,096–5,110 | 0.776–0.800 | 227–441 |
frames_elevated counts frames at or above 2 × steady = 0.00980798; frame +0 reads 0.01422016 and
frame +1 reads 0.00603195, so the count is 1.
The one-frame debt is not a threshold artefact, and the tenth arm proves it with the floor removed.
On zero_proof_no_jitter_static — same fixture, camera frozen and TAA jitter off, so the reprojection
is the identity — the dig rejects 4,792 of 516,327 samples (0.928% of the frame) on the edit frame and
exactly 0 on each of frames +1 through +11, while the hole is still there: frame_changed_pixels reads
5,105 on all twelve frames. Eleven zeros in a column whose first entry is 4,792.
Why, and it is because clipping works. The resolve moves the stale history onto the shell of the
current neighbourhood in the frame the disocclusion appears, and the shell is by construction inside the
local range, so the next frame's reprojected sample is already valid. The geometry being permanently
different does not extend the debt; only the transition costs anything. frame_mean_clip_s_over_rejected
says the same thing from the other side: 0.086461 on the floorless arm's edit frame, rising to
0.776–0.810 on the headline arm's frames +1 onward.
The 0.086461 belongs to the floorless arm, not to the headline arm, and R-077's prose ran the two together. On the headline arm the edit frame reads 0.340765, because 2,568 of its 7,348 rejections are the shallow locomotion floor. Subtract that floor at its own measured mean —
(7,348 × 0.340765 − 2,568 × 0.831331) / 4,780= 0.0772 — and the dig's own clip depth agrees with the floorless arm's directly-measured 0.086461 to 11%. Both say the same thing: the dig's rejections are deep.
C2's recovery half is zero by construction, and the paper's own words are the proof. Section 3 of
10.1145/3681758.3697996 (Ikkala, Lauttia, Jääskeläinen & Mäkitalo, SIGGRAPH Asia 2024 Technical
Communications), as transcribed in the bench's header:
"As a general-purpose approach, we include the X, Y and Z axes and optimize the rest of the axes to achieve tightest bounds around a unit sphere. This approach should never be looser than an AABB."
A k-DOP that contains the AABB's own axes is a subset of that AABB, so every colour the AABB rejects
the k-DOP also rejects, and the set a k-DOP "recovers" from an AABB in the same colour space is empty
by construction. kdop_recovered_fraction reads 0.00000000 on all 140 rows and
frame_recovered_dop26_ycocg reads 0 on all 140 — against 30,409 baseline rejections in the headline
arm's window and 5,370,840 in the walking arm's.
C2 as registered inverts its source, and the sentence the registration paraphrases is the one that says so. The paper's framing is the opposite direction — Figure 1's caption, same transcription:
"neighborhood clipping with an AABB often allows colors which don't fit in the color neighborhood; this results in ghosting"
k-DOP clipping reduces ghosting by rejecting more, never by recovering. The direction the source
actually claims is measured here as frame_extra_rejected_dop26_ycocg: 2,884 samples the YCoCg AABB
accepted and the 26-DOP rejected, on the headline edit frame's 7,348 baseline rejections — the 26-DOP
rejects 39.2% more. On dig_at_feet_walk, 27,441 extra on 449,842.
The zero is a containment property, not a dead counter, and the harness carries the arm that proves
it. dop26_rgb is the same 13-axis polytope in RGB, which does not contain the YCoCg baseline's axes.
kdop_recovered_fraction_rgb_axes: 0.58225803 on the quarter-speed arm (177,651 samples),
0.42659628 at half resolution (41,777), 0.17634858 on dig_at_feet_walk (79,329), and
0.00435493 (32 samples) even on the headline static arm. The recovery counter demonstrably reports
non-zeros; the zero next to it is the theorem.
C2's cost half is about a pass that does not exist in this crate — VACUOUS, and the number comes from
the source at tier V. crates/isomesh must not depend on Bevy (CLAUDE.md hard rule 2), so there is
no renderer and no GPU resolve stage here. kdop_ms is the single-threaded CPU wall-clock of this
harness's own 13-axis clamp pass over its own pixel population — 62.6205 ms for 516,731 pixels — and it
is labelled that way in the bench header, in the printed headline and here. It is not a GPU TAA resolve
cost and is not offered as one.
The machine-independent figure is clamp_ratio_dop_over_aabb — 2.0746 on the headline arm,
2.0549–2.1922 across the nine jittered arms. The per-pixel cost is stable to 1.2% across a 4× change
in pixel count and a 1.9× change in populated pixels: kdop_ms ÷ population reads 121.0, 121.2,
121.0, 121.3, 121.7, 122.4 ns/px on dig_at_feet_walk, dig_at_feet_static,
dig_at_feet_walk_half_res, dig_at_feet_walk_quarter, demo_pose_walk, demo_pose_static — about
508–514 cycles at the cpu_mhz = 4200 on the row for 9 samples × 13 axes, so ~4.3 cycles a dot
product, which is what a scalar loop should cost. kdop_ms_per_megapixel is over frame pixels rather
than populated ones, which is why the two demo_pose_* arms read ~64–65 against ~121: at pitch −0.15 the
horizon is in frame and roughly half the pixels never hit the surface.
What the source supplies, which the registration missed. The registration's "0.2 ms overhead (GPU
NOT NAMED IN THE ABSTRACT)" is correct about the abstract and the body resolves it: Section 4 puts
the 0.2 ms on a GTX 1080 Ti (32-DOP 0.662 ms against AABB 0.452 ms, +0.210 ms) and states that on an
RTX 3090 the AABB methods take around 160 µs and 32-DOP 210 µs — a +50 µs delta. That is
a factor of 6 under C2's 0.3 ms bar and a factor of 4 under the 0.2 ms the abstract quotes, so
C2's cost half is satisfied — from the paper, at tier V, not from this harness. Anyone citing 0.2 ms
for this rig's GPU class is citing the wrong number by 4×. Provenance, stated because the ledger's rule
is to verify the source separately from the number: the paper is not in the local corpus —
distill_search returns nothing for it and docs/research/2026-08-27-thirty-experiments-for-the-game.md
line 472 records only the abstract-level note "GPU not named in the abstract; flag when citing" — so
these Section 3, Section 4 and Figure 1 readings rest on the harness author's reading of the paper as
transcribed verbatim into crates/isomesh/benches/experiment_p77.rs:40-58, not on a corpus artefact.
The two ratios are consistent rather than contradictory: the source's own is 0.662/0.452 = 1.465 on a 1080 Ti and 210/160 = 1.313 on a 3090, against this CPU pass's 2.0746. A scalar CPU loop pays linearly in axis count; a GPU pays a large fixed cost for the nine texture fetches and its ratio is therefore lower.
C3 is not independent of C1, and the entry has to show why or a reader will count it as a second test.
Subtracting a sphere is f' = max(f, −(|p − c| − r)). Outside the sphere the second term is negative, so
a solid point stays solid and an air point is untouched: the zero set changes only inside the brush.
A ray whose depth changed therefore passed through the brush, so every changed pixel lies inside the
brush's projected silhouette disc — which the harness asserts, and
frame_changed_outside_silhouette = 0 on all 140 rows. Writing b for the dilated box's area
fraction and R for the frame-paired ratio, the concentration is (R − 1 + b)/R: the dig's rejections
are all inside the box, and a fraction b of the steady floor's are too.
The arithmetic, all four numbers from the file. R = 7,348/2,568 = 2.861371 (paired_frame_ratio
2.8614), b = 0.09179126 (box_area_fraction):
predicted (R − 1 + b)/R = 0.682597 ← computed before the run; R-077 reported 0.6826
measured 4,940/7,348 = 0.672292 ← `concentration_fraction`
residual 0.010305
The residual is not slack — it is a column. The dilated box holds 160/2,568 = 6.2305% of the
steady floor's rejections against 9.1791% of the frame's area, because the box sits on the rock
underfoot where the floor's rejection density is below average. Correct for that and the identity is
exact to six decimals: (b × 2,568 − 160)/7,348 = 0.010305. So the uniform-b prediction was high by
precisely the box's under-representation of the floor, and nothing else.
The mechanism C3 was written to test held completely. concentration_edit_attributable = 1.000000
— the treatment rejected 7,348 and the frame-paired control 2,568, so 4,780 rejections are
edit-attributable; in the box the treatment has 4,940 and the control 160, so 4,780 are
edit-attributable there too. 4,780 of 4,780. It reads 1.000000 on all twelve frames of the window
(frame_concentration_edit_attributable) and 1.000000 on the floorless arm, where the denominator has no
floor at all (4,792 of 4,792). What the registered form measures instead is C1: its denominator is
every rejection in the frame, and 2,568 of the 7,348 are the locomotion/jitter floor, of which 2,408 fall
outside the box and drag the fraction to 0.6723.
The registered vacuity control, its column, its value, and why that value could have been zero.
Registered text: "the steady-state arm must have a non-zero rejection rate, or the 5x ratio is division
by a floor." Column: steady_rejection_fraction, and frame_rejected on the */steady_window rows.
Value on the headline arm: 0.00490399 — 30,409 rejections over 6,200,866 history samples, asserted
steady_rejected > 0 for every jittered arm before any number is reported, with the assertion message
naming the clause it protects.
A non-zero assertion is worthless unless the zero was attainable (M-44), so the harness carries the
arm where it is attained. zero_proof_no_jitter_static is the same fixture with the camera frozen and
the TAA jitter off, so the reprojection is the identity and the history converges to the current frame.
It rejects exactly 0 over 6,195,924 samples, frame_mean_reproj_px 0.0000, and the harness
asserts zero_proof × 100 < headline_steady_rejected — the zero arm must be two orders of magnitude
below or the non-zero rate is a property of the harness rather than of the resolve. Printed at run time:
P-77 vacuity control: steady rejections 30409 with jitter, 0 without -- the zero was reachable. That
is what makes 0.00490399 a measurement: the same code path, one knob away, reports 0 over six million
samples, so the headline arm's 30,409 is the resolve rejecting history and not the instrument idling.
Four columns read false, true, NA or a large number for a reason other than the clause behaving
that way, and each is quoted here so no reader misparses the file.
c1_holds=falseandratio=NaNonzero_proof_no_jitter_staticis a void gate, not a failure.c1 = evaluable && ratio >= 5.0 && frames_elevated >= 3, andevaluableissteady > 0.0, which isfalseon that arm by design — it is the arm whose steady rate is zero. The ratio is recorded asNaNrather than as an infinity a reader might quote, andc1_evaluable=falseis the column that says which.
ratio_ceiling_from_footprint=5106.0000on that same arm is a floored denominator, not a ceiling. It is(c₀ + changed)/c₀withc₀ = control_rejected.max(1), and the truec₀is 0, soc₀became 1 and the column reports(1 + 5,105)/1. It is not a bound on anything.
c2_holds=falseon all 140 rows is two different statements wearing one column. It isrecovered >= 0.5 && kdop_ms < 0.3. The first conjunct is a genuine falsification at exactly 0. The second is 62.6205 ms of single-threaded CPU clamp pass compared against a 0.3 ms GPU resolve budget — a category error, not a clause failing, which is why the cost half is scored VACUOUS above and settled from the source instead.
concentration_edit_attributable=NAon six arms is an empty share, not a missing measurement. It isΔbox/Δtotaland is emitted asNAwhenΔtotal ≤ 0. On the six walking arms the dug world rejected fewer samples than the undug one —dig_at_feet_walkreads 449,842 against the control's 450,140, apaired_frame_ratioof 0.9993 — because at an 86.6% floor the dig's 4,169 changed pixels are below the noise. That is itself the finding for those arms: under locomotion a dig is not merely a small effect on TAA history, it is not detectable at all.
frame_dop_ms=0.0000on the twenty*/steady_windowand*/post_edit_windowrows is a gap in the aggregator, not a zero-cost pass.agg()sumsaabb_msand does not sumdop_ms. The registeredkdop_mscolumn is the edit frame's and is correct; the per-frameframe_dop_msvalues are the ones to read. Similarly,frame_mean_clip_s_over_rejected=NaNon elevenzero_proofrows is a mean over zero rejections.
The instrument, described precisely because R-076 and R-091 both denominate clauses in it.
crates/isomesh must not depend on Bevy, so there is no renderer — but TAA history rejection is a
per-pixel geometric predicate, and the predicate is implemented in full rather than approximated.
P-76 has already inherited its containment result (experiment_p76.rs:1345: "P-77 showed a k-DOP
that contains the AABB's own axes is a subset of it and recovers exactly zero") and P-91 names it as
the source of its rejection predicate and its jitter pattern.
- The field is
game_dig's, verbatim:height = 0.35·sin(0.9x)·cos(0.7z) + 0.15·sin(2.1x); brushes are subtracted spheres of radius 0.25,game_dig's defaultWorld::radius. - The camera is
game_dig's:Transform::from_xyz(0.0, 1.70, 6.0),Look { yaw: 0.0, pitch: −0.15 }, walk 2.5 units/s, Bevy's defaultPerspectiveProjection(45° vertical FOV). - The depth buffer is
game_dig's own ray caster, transcribed:AIM_NEAR0.30,AIM_FAR25.0,AIM_STEPS128,AIM_HIT0.01,LIPSCHITZ1.25, same sandbox box test. Tracing the field rather than the extracted mesh is what the demo does and for the demo's reason — the field is the thing being edited, so it cannot go stale. - Motion vectors are exact, not approximated: the previous-frame screen position is the world hit point projected through the previous frame's view including the previous frame's jitter. The geometry is static between frames except where a brush landed, so this is the motion vector a renderer would write.
- The signal is three independent channels of geometry-only radiance — warm sun in
max(0, n·l), cool sky inn.y, a view-dependent rim, then distance fog — modulated by 8 octaves of value noise on the world hit point atgame_dig's own 1.5-unit albedo tile, so it is a texture on the surface and reprojects exactly. A grey signal would put every neighbourhood on the diagonal of colour space, where an AABB is a cube and any oriented volume wins for free; fog is in because a hole revealing a farther surface must move the signal, which is the mechanism under test. - The resolve is Karis's: 10-entry R2 jitter (Roberts 2018), bilinear history fetch requiring four
valid taps, rectification by clipping — a ray from the current colour to the history colour stopped
at the volume's shell, which is the operation Section 3 describes — and
history = lerp(clipped, current, 0.1). A sample is rejected when the clip moved it. 24 warm-up frames at 60 Hz, 12-frame window. - Four volumes, one fetched history sample:
aabb_rgb(Lottes 2011),aabb_ycocg(Karis 2014, the baseline, because that is what production TAA does),dop26_ycocganddop26_rgb— Klosowski et al. 1998's 13-axis 26-DOP, dilated by the paper's owneps = 1e-5. The paper's 32-DOP has 16 axes; more axes only tighten the volume and tightness is what decides C2, so 13 is conservative rather than weaker. populationexcludes pixels with no usable history — off-screen, behind the near plane, or reprojecting onto a miss or a partly-invalid bilinear footprint.no_historymakes the excluded set visible: 81–2,281 per frame, at most 0.83% of population. (R-077 reported "780–2,272, under 0.5%"; the committed file's range is wider on both ends.)
The row's real product is the reprojection curve, because that is the budget the two dependent rows will spend. Steady-state history rejection is a function of mean reprojection displacement and almost nothing else, with the knee exactly where a 3×3 neighbourhood's ±1 px reach ends:
| mean reproj px | arm | steady rejection | mean clip s |
|---|---|---|---|
| 0.0000 | zero_proof_no_jitter_static |
0.00000000 | NaN (no rejections) |
| 0.6115 | demo_pose_static |
0.01159249 | 0.795711 |
| 0.6117 | dig_at_feet_static |
0.00490399 | 0.831331 |
| 1.8607 | dig_at_feet_walk_quarter |
0.58710621 | 0.779579 |
| 3.6183 | dig_at_feet_walk_half_speed |
0.75028189 | 0.677436 |
| 3.6413 | dig_at_feet_walk_half_res (480×270) |
0.75223568 | 0.632035 |
| 4.2121 | demo_pose_walk |
0.65138010 | 0.736737 |
| 7.2424 | dig_at_feet_walk |
0.86644885 | 0.566452 |
| 7.2424 | dig_at_feet_walk_untextured |
0.98662845 | 0.482990 |
Two independent routes to the same displacement agree to 0.26%, which is the strongest evidence in the row that displacement is the variable. Halving the walk speed gives 3.6183 px and 0.75028189; halving the resolution instead gives 3.6413 px and 0.75223568 — over a 4× change in pixel count. The half-res arm also pins the resolution scaling directly: 3.6413 against half of 7.2424 = 3.6212, high by 0.56%, so displacement is linear in resolution and 1920×1080 reads ~14.5 px. (Extrapolation, not measured — the fixture's largest measured displacement is 7.2424.)
So the budget, stated as the two dependent rows need it. Standing still, 99.51% of history
survives and a dig costs 0.93% of the frame for one frame. Walking at game_dig's own 2.5 units/s
while looking at ground underfoot, 13.4% survives before anything is dug, and a dig is not
detectable in it at all (paired_frame_ratio 0.9993). Any proposal that relies on TAA to resolve a
stochastic or dithered choice must be evaluated in the standing-still regime, because in the walking
regime the history is already gone and the choice will never be resolved.
Five fixture defects this harness's own controls caught, in the order they fired.
- A level camera renders an empty depth buffer. Caught by
assert!(c.population > 0), whose message names theM-44failure it protects.game_dig'sTransformalone carries no rotation, and a level ray from an eye at 1.70 never meets a height field whose maximum is 0.50 — the first version of the harness would have reported a zero over an unreached configuration. Fixed by applying the demo's actual openingLook::pitchof −0.15, and −0.6 for the dig pose. Both are arms. - A smooth signal makes the colour neighbourhood a needle and saturates the predicate. Run 1 shaded
from normals and fog alone and measured a steady-state rejection rate of 95.5% (a first-run figure
recorded in the bench's doc comment; it is not in the committed CSV, whose untextured arm reads
0.98662845 with the detail switched off by the
albedo_detailcolumn). A 3×3 AABB over nine samples of a smooth gradient spans one pixel of that gradient, so any sub-pixel reprojection error leaves it. This is the most transferable finding in the row: any TAA-rejection measurement on content with no energy near the pixel rate measures its own shading model. Fixed by the world-space albedo detail, which is whatgame_dig's own textured terrain supplies. - Even with the detail in, a walking camera saturates at 86.6%, and a ratio between two saturated
rates measures nothing. Caught by
frame_mean_reproj_px, added as a diagnostic after defect 2: 7.2424 px per frame at 960×540, where a 3×3 neighbourhood can validate history that moved one. That is a fact about locomotion, not about digging. Fixed by turning the fixture into a sweep in reprojection displacement and taking the registered columns fromHEADLINE_ARM— the only arm whose denominator has headroom. The bench header states explicitly that the arm was not chosen for a better verdict: every arm is falsified on C1, and the eight non-headline arms are falsified by a factor of five rather than by 1.7×. - A binary "the clamp moved it" predicate hides whether the rejection was knife-edge. Caught by
adding
frame_rejected_half(s< 0.5) andframe_mean_clip_s_over_rejected, and it carries the whole answer to C2's mechanism: the dig's rejections ares= 0.086461 with 4,611 of 4,792 deep — genuine disocclusions — while the locomotion floor's ares= 0.831331 with 2,057 of 30,409 deep — conservatism. Without that column C2 would have been "falsified by containment" with no evidence about which of its two named explanations was true. - A mutation test of the containment control, run deliberately to prove it bites. Halving
Cam::silhouette_radiuspanics with "frame +0 has 1719 changed pixels outside every brush silhouette, so either the projection or the brush placement is wrong -- subtracting a sphere cannot move the zero set outside the sphere" — 1,719 of 4,169 changed pixels flagged. The mutation was reverted; the committed radius is the exact silhouette-cone radiustan(asin(r/d))/tan(fov/2) · H/2. Soframe_changed_outside_silhouette= 0 on all 140 rows is a zero that could have been large, which is what makes C3's containment algebra a measurement rather than a restatement of its own premise.
What changed as a result, and it is a null reported as a completed result.
- Nothing in the crate, and nothing should.
crates/isomesh/src/**andcrates/isomesh-gpu/src/**are untouched. The row is a bench and a CSV. - Do not build k-DOP clipping for this game. Not because it is expensive — the source puts it at
50 µs on an RTX 3090 — but because it cannot address the thing this row measured. It recovers 0
and rejects 39.2% more, and the rejections a dig causes are deep clips (
s= 0.086461), which is exactly the condition C2's own falsifier says means "the rejections are genuine disocclusions rather than clamp conservatism and no clipping scheme can help." "Do not build this" is the conclusion, and the row reached it by the falsifier's own stated route rather than around it. If a tighter volume is ever adopted here it would be for the locomotion floor, where the mean clip is shallow (0.831331) — a different experiment with a different registration. - This row and P-76's C2 close together, which the registration pre-committed to. C1 failed "by under 5x" and "by a single-frame spike" — 2.8997 and one frame. P-76's C2 asks for ghosting cost "in the 8 frames following an edit", and there is no eight-frame window: the debt is one frame, with eleven measured zeros after it on the floorless arm. Recommend P-76 be reduced to C1 and C3 and its C2 closed with this row's number.
- The budget
R-076andR-091were gated on is the reprojection curve above, and the column isframe_mean_reproj_px. Both must be evaluated standing still, because walking there is no history to spend. - A source correction to carry. The 0.2 ms in this registration is a GTX 1080 Ti figure from Section 4, not a nameless one, and the RTX 3090 delta in the same section is 50 µs. Anyone re-citing this paper for this rig should quote 50 µs — a 4× correction.
Would be shown wrong by: a rejection elevated for three or more frames on any fixture, which would
mean the one-frame debt is a property of ALPHA = 0.1 or of this clip-to-shell rectification rather than
of clipping in general — the sharpest version is a resolve that clamps to the shell's nearest point
instead of clipping along the ray, since the two differ in exactly where the corrected history lands; a
k-DOP whose axis set excludes the baseline's own axes reporting a non-zero kdop_recovered_fraction
against a same-space AABB, which would break the containment argument rather than the measurement (the
dop26_rgb control shows this is a statement about axis sets and not about polytopes); a fixture whose
brush changes more than four times as many pixels as its steady floor rejects, which is where C1's 5×
becomes arithmetically reachable and the clause becomes a measurement instead of a footprint;
frame_changed_outside_silhouette reading non-zero on correct code, which would mean the silhouette-cone
projection rather than the brush is wrong; or a real GPU TAA resolve in a Bevy-side crate measuring the
26-DOP pass at over 0.3 ms, which is the only thing that could make C2's cost half a falsification here
rather than a V-tier satisfaction.
💥 ✗59 / M-390 — C1's factor bound FALSIFIED at 3.36–8.38 with c1_holds true on 18 of 72 rows, C1's world-size falsifier HELD at 1.391× against a world that grew 8.00×, C2 FALSIFIED inverted on 72 of 72 rows — the parry3d BVH over the extracted mesh is 1.95–7.27× faster than sphere-tracing the field — and C3 HELD on 36 of 36 pairs at 1.25–2.53× on two digs matched to 171 samples exactly (P-78, R-078)
M. cargo bench --bench experiment_p78, docs/experiments/p-78.csv, 72 rows, f32 (parry3d is
f32-only, so an f64 field arm would have put a precision difference inside C2's ratio), AMD Ryzen 9
5900X (Zen 3), cpu_mhz 3,639.7 on every row. The fixture is gyroid caves at period 12 inside a block
sealed at [2.25, W − 2.25], with one sealed air pocket — a radius-5 ball of air inside a 3-cell shell
at the fixed world position [16, 16, 16] — swept over 3 worlds (32³/48³/64³ cells at fixed cell size)
× 4 M-50 log buckets (8/23/38/53 subtracted spheres of radius 3) × 3 probe spacings (2/4/8 cells) × 2
arms (breakthrough, matched-volume control). The committed provenance line is # commit abffc18 on
amd-ryzen-9-5900x-12-core at 2026-08-28T00:51:51Z — no (WORKING TREE DIRTY) — and abffc18 is an
ancestor of HEAD.
Every number below is read from the committed
docs/experiments/p-78.csvatabffc18, and the superseded run's numbers are not reproduced here (✗35,✗52). The R-078 report was written from a dirty pre-run at63c7161taken while ~25 sibling harnesses were compiling, and a first "re-run on a clean tree" commit (a2c5ff7) still carried# commit 1610af0 (WORKING TREE DIRTY); both are replaced by this file. The comparison is the useful part: between1610af0andabffc18, 51 of the 57 columns are byte-identical on all 72 rows. The six that move are exactly the clock-derived ones —cpu_mhz(4,102.2 → 3,639.7),gather_ms_field,gather_ms_mesh,gather_speedup,extract_ms,bvh_build_ms— which isM-279's rule satisfied: the new run agrees with the old one on everything that is not a clock. Against the report's63c7161run:cpu_mhz3,823–3,917 → 3,639.7;gather_speedup0.097–0.445 median 0.201 → 0.137479–0.513805 median 0.2446; the inverted figure 2.25–10.35× median 4.98× → 1.95–7.27× median 4.09×; field 2,859–3,369 ns/ray → 1,198–3,704; mesh 659–713 → 469–693;mean_steps_per_ray26.6–28.5 → 25.15–29.65; ns per field sample 107–118 → 47.6–125.6. Two reported conclusions are withdrawn on those moves and replaced below: the "at least 2.25× faster" floor, and the fitted "1,214 ns intercept, so an empty log is still 1.81× slower". The verdicts are unchanged, and every integer the verdicts rest on reproduced exactly.
| clause | registered | measured |
|---|---|---|
| C1a the invalidation set tracks the brush's dilated support with a constant factor under 4, across four log buckets and three probe densities | invalidation_factor < 4.0 |
FALSIFIED — 3.356643 … 8.376731; c1_holds true on 18 of 72 rows, and on 0 of the 36 breakthrough rows |
| C1b "or by a count that grows with world size at fixed edit size" — the falsifier that kills probe GI outright | no growth in probes_invalidated |
HELD — worst growth 1.391×, while world_cells grows 8.00× and probes_air_before 9.58–10.46× |
| C2 tracing the field beats tracing the extracted mesh by at least 3× at equal ray count | gather_speedup ≥ 3.0 |
FALSIFIED, inverted — 0.137479 … 0.513805, median 0.2446, c2_holds true on 0 of 72; the BVH wins by 1.95–7.27×, so the clause misses by 5.8–21.8× in ratio, median 12.3× |
| C3 a dig that opens a new air component invalidates strictly more probes than a same-volume dig that does not | strictly more | HELD — 36 of 36 pairs, ratio 1.2500–2.5333, median 1.8947, on arms matched at dug_samples = 171 exactly |
Three verdict columns read
falsefor reasons that are not a clause failing, and none of them should be read as one. (1)pocket_connected_beforeisfalseon all 72 rows: that is the precondition holding — the edit log never leaked into the sealed pocket. (2)pocket_connected_afterisfalseon all 36 control rows: that is the control arm doing its job, and it is asserted, not observed. (3)c1_holdsisfalseon all 24s = 8rows and that is quantisation, not width — see the conditioning paragraph:probes_in_support_actualis literally 0 on the twelves = 8breakthrough rows and 1 on the twelve controls, so at that density the factor's denominator is an expectation (0.5586–0.7051 probes) and not a population. Afalsethere says the lattice is too coarse to answer, not that the invalidation is wide.
The SHARE recomputation, and one clause arithmetic could not reach before the run.
C2's registered share is the gather pass at 87–96% of radiance-cascade frame time (Dell'Ova, BTH 2025,
DOI UNVERIFIED — flagged at registration, flagged in the bench header, flagged again here). C2 is
reachable because it is a ratio on the gather itself rather than on a frame: a 3× gather win is
1/(0.13 + 0.87/3) = 2.38× at 87% and 1/(0.04 + 0.96/3) = 2.78× at 96% on total GI cost by
Amdahl. Nothing about the arithmetic makes 3× unreachable, and the measurement missed in the other
direction.
C1 needed a unit decision, and the registration's literal reading is density-dependent by
construction. probes_invalidated is a count of probes and brush_support_cells a count of cells,
so the literal quotient of the two registered columns has a probe lattice in it. Its ceiling — every probe
in the world invalidated — is probes_total / brush_support_cells, and the CSV carries it as
factor_ceiling_literal on every row:
| world | s = 2 | s = 4 | s = 8 |
|---|---|---|---|
| 32³ | 11.38–14.32 | 1.42–1.79 | 0.18–0.22 |
| 48³ | 38.29–48.34 | 4.79–6.04 | 0.60–0.76 |
| 64³ | 90.77–114.57 | 11.35–14.32 | 1.42–1.79 |
Four of the nine (world, density) pairs — 32 of the 72 rows — have a literal ceiling below 4, so on
those rows the literal ratio could not have reached 4 even if every probe in the world had been
invalidated. A fifth, (48³, s = 4), tops out at 4.79–6.04 and would have needed 66–83% of every
probe in the world to reach the bar. Scoring C1 on that quotient would have been M-44's vacuous zero
in a ratio's clothing.
(The bench header and the R-078 report both say "seven of the nine". That is not what the committed
column says, and it is not what the header's own predicted table says either — with the ~10³ support it
assumed, five of nine fall below 4. The file's count is four of nine pairs / 32 of 72 rows, and it is
the one quoted here. ✗39's rule: after fixing an instrument, re-read the column from the artefact.)
So invalidation_factor is recorded in probe units — probes_invalidated / (brush_support_cells / s³),
the invalidated probe count over the number of probes the dilated support itself contains. That is
algebraically probes_invalidated · s³ / brush_support_cells, i.e. an implied volume ratio, whose
numerator is emitted directly as invalidated_volume_cells. Its ceiling is
world_cells / brush_support_cells = 91.0222 … 916.5874 — density-independent, identical for both
arms of a pair up to the support, and assert!(ceiling > 4.0) fires per row. Above 4 was always
reachable, and it was reached on 54 of 72 rows. Both readings are in the file:
invalidation_factor_literal runs 0.013850–1.047091 and never comes near 4 anywhere.
The conditioning is not the same at all three densities, and that decides which rows are evidence.
probes_in_support_expected is brush_support_cells / s³ and the CSV carries it: about 45 probes at
s = 2 (35.75–45.13), 5.6 at s = 4 (4.4688–5.6406) and 0.70 at s = 8 (0.5586–0.7051). So one
invalidated probe is worth 0.02, 0.18 and 1.43 factor units respectively, and the 4.0 threshold
sits at 179.5, 17.9–22.6 and 2.23–2.82 probes. At s = 8 the factor is quantised in steps
larger than a third of the bound being tested, an s = 8 row cannot distinguish a wide invalidation from a
narrow one, and the integers say so twice over: probes_invalidated is exactly 4 on all twelve s = 8
control rows and exactly 5 on all twelve breakthrough rows, at every world size and every log length.
s = 2 is the density at which C1 is decided; s = 8 is reported because the registration asked for
three densities, and read as quantisation rather than as evidence.
The sharpest form of that caveat is invalidated_volume_cells, which is the same physical region measured
at three granularities. For the control arm it is 1,128–1,360 cells at s = 2 and 960–1,088 at
s = 4 — a 1.42× spread across two densities and three world sizes — and exactly 2,048 at s = 8,
which overstates the same dig's s = 2 reading by 1.51–1.82× and its s = 4 reading by
1.88–2.13×, purely because a probe there carries a 512-cell cube.
C1a is falsified, and the mechanism is the edit log rather than the brush. brush_support_cells is
286 on every control row and 359–361 on every breakthrough row — the measured brush is radius 4 in both
arms and its support does not move with the log. What moves is the probe count:
s = 2, control arm |
log 8 | log 23 | log 38 | log 53 |
|---|---|---|---|---|
probes_invalidated (32³ / 48³ / 64³) |
141 / 142 / 142 | 141 / 142 / 142 | 147 / 150 / 150 | 166 / 170 / 170 |
invalidation_factor (32³ / 48³ = 64³) |
3.944 / 3.972 | 3.944 / 3.972 | 4.112 / 4.196 | 4.643 / 4.755 |
c1_holds |
true | true | false | false |
So an ordinary, non-topological dig of radius 4 sits on the bound and crosses it as the edit log grows:
the factor is monotone in log_brushes at a fixed support, because prior brushes have already opened the
rock around the measured brush and more probes therefore have a ray that moves. The 4.0 bar is crossed
between M-50's second and third buckets, and the closest margin anywhere is 1.00 probe out of the 143.0
the bar sits at (M-44's rule: record the margin, not the verdict). At s = 4 the control arm holds on all
12 rows at 3.357–3.804, with a closest margin of 0.88 probes out of 17.9 — the same physical region,
read through a coarser lattice, landing on the other side of the bar. The bound is not a property of the
dig; it is a property of the dig, the log length and the lattice together, which is why it is the wrong
gate. Every breakthrough row is above 4 at every density: 5.06–8.38 at s = 2, 4.10–7.09 at s = 4.
What the factor does say, run-independently, is that the invalidated region is edit-local. Converted to
an equivalent ball, the control arm's invalidated volume has radius 6.12–6.87 cells against a support
whose equivalent radius is 4.087, so the invalidated set is the support dilated by 2.03–2.79 cells —
consistent at s = 2 and s = 4, at all three world sizes, across a 6.6× range of edit-log length. The
breakthrough arm dilates by 2.65–4.55 cells. That is a bounded, local, world-independent region measured
two ways; it is simply not bounded by the number 4 in probe units.
C1b HELD, decisively, and this is the clause that mattered. At fixed edit size the world grew 8.00×
in cells (32,768 → 262,144) and the live probe population grew 9.58–10.46× (probes_air_before
1,293 → 5,301 → 13,521 at s = 2, bucket 1-15), while probes_invalidated grew by at most 1.391× over
all 24 (bucket, density, arm) triples. The growth is confined to one step: 23 of the 24 triples are
exactly constant from 48³ to 64³ — the exception is (46-60, s = 2, breakthrough) at 376 → 378, two
probes. s = 8 is exactly constant on all 24 rows.
| bucket 16-30 | 32³ | 48³ | 64³ | 64/32 |
|---|---|---|---|---|
s = 2 breakthrough |
271 | 332 | 332 | 1.225× |
s = 2 control |
141 | 142 | 142 | 1.007× |
s = 4 breakthrough |
26 | 36 | 36 | 1.385× |
s = 4 control |
15 | 15 | 15 | 1.000× |
s = 8 breakthrough / control |
5 / 4 | 5 / 4 | 5 / 4 | 1.000× |
The residual is attributed by the arm contrast rather than asserted. The control arm barely grows at all
(≤ 1.024× everywhere) while the breakthrough arm grows 1.199–1.391×, and both digs sit near a wall of the
32³ world — edit_center is 6.26_6.12_14.10 for the control, 4.01 cells inside the x face at 2.25, and
17.41_16.00_23.88 for the breakthrough, 5.87 cells inside the 32³ z face at 29.75. So proximity to the
boundary is not what separates them. What separates them is range: a widening changes rays only within a
couple of cells of the brush, whereas a breakthrough opens a shell and every probe that gains a sight line
into the pocket is invalidated however far away it is. A long-range set is the one a small world clips,
and 48³ already contains it — which is why adding 64³'s 151,552 further cells and 8,220 further live probes
adds nothing.
One deliberate design choice makes that clause honest and is worth stating. Max ray distance is the
world diagonal √3·W, not a bounded gather radius. A finite gather radius would have made C1b true by
construction — no probe outside the radius could ever be invalidated, so the count could not grow with the
world whatever the geometry did. That is the M-44 trap inside C1's second falsifier, and the fixture
declines it: the ray budget grows with the world and the count still does not.
The instrument, because "probes whose visibility changes" needed an operational definition. There is no
Bevy renderer in crates/isomesh and there must not be, so a probe is invalidated exactly when one of its
gather rays lands somewhere else — which is the operation a probe update actually performs. Probes sit on a
lattice at spacing s offset to cell centres; a probe is live where the field is air (value >= 0, the
crate's own convention, cube::is_inside being value < 0). Each live probe casts dirs_per_probe = 32
rays on a fixed Fibonacci sphere, so before and after are the same gather. Each ray is sphere-traced
with a global Lipschitz divisor — the gyroid is not a distance field and |g| must not be used as one;
∂g/∂x = scale·(cos a·cos b − sin c·sin a) is bounded by 2·scale, so |∇g| ≤ 2√3·scale = 1.8138 at
period 12, and every other operand (box, sphere, annulus) is exact with constant 1, so the divisor is
max(2√3·scale, 1). Per-ray outcome is a hit distance, MISS, UNRESOLVED (the 96-step budget exhausted:
unresolved_frac_field 0.0066–0.0212, and it is deterministic, not an error) or DEAD (probe not in
air). A probe is invalidated when its liveness flips or any of its 32 outcomes changes kind or moves more
than hit_tol_cells = 0.5. The count has no numerical floor: where the brush does not dominate,
max(f, −sphere) returns f bit-identically, so an unaffected ray is bit-identical before and after.
32 directions under-resolves a real DDGI probe's 64–256 and the bias is downward, i.e. toward C1
holding — stated rather than hidden.
C2 is falsified in the opposite direction on every row, and the mechanism is a count, not a clock.
gather_speedup = gather_ms_mesh / gather_ms_field runs 0.137479–0.513805 and c2_holds is false on
all 72 rows. Restated usefully: at equal ray count — rays_field == rays_mesh is asserted per row and
true on all 72, over 992 … 437,632 rays — the parry3d BVH over the extracted mesh is 1.95× to 7.27×
faster than sphere-tracing the field. Per M-280 the clock is on every row and the verdict is a ratio;
per M-281 both arms are timed in the same loop iteration of the same build, min of 2 passes.
The mechanism is that the field arm's per-ray work grows linearly with the edit log and the mesh arm's
does not grow at all. At s = 2, median ns per ray over the two arms:
| world | log 8 | log 23 | log 38 | log 53 | growth |
|---|---|---|---|---|---|
| 32³ field | 1,254 | 1,944 | 2,645 | 3,368 | 2.69× |
| 32³ mesh | 516 | 516 | 521 | 522 | 1.010× |
| 48³ field | 1,353 | 2,095 | 2,838 | 3,587 | 2.65× |
| 48³ mesh | 601 | 602 | 602 | 605 | 1.006× |
| 64³ field | 1,409 | 2,172 | 2,938 | 3,704 | 2.63× |
| 64³ mesh | 645 | 646 | 644 | 647 | 1.002× |
mean_steps_per_ray is flat within a world (26.3–26.9 at 32³, 28.4–28.7 at 48³, 29.6 at 64³), so none of
the field arm's growth is extra tracing — it is all per-sample cost. The run-independent statement is the
integer the timing is a proxy for (✗24): a field ray costs mean_steps_per_ray × (2 + log_brushes)
primitive SDF evaluations, which is 270 at log 8 rising to 1,491 at log 53, a 5.5× growth that
no machine changes. A mesh ray costs one BVH descent, and the BVH's own scaling is visible in the same file:
mesh_tris grows 9.1× (18,844 → 171,840) for a 1.25× cost (516 → 645 ns), which is a logarithm.
There is therefore no edit-log length at which the field arm catches up, and it does not need
extrapolating to say so: at the shortest log in M-50's range the field arm is already 2.18–2.43× slower
per ray (1,254/516, 1,353/601, 1,409/645). The R-078 report's fitted "85.1 ns per brush per ray, 1,214 ns
intercept, so even at an empty log the field is 1.81× slower" is withdrawn — the same fit on the committed
file gives 49.2 ns per brush per ray and a 942 ns intercept, i.e. 1.56×, and a conclusion that moves by
1.6× with the clock should not have been carried on a fit when the measured shortest-log ratio says the
same thing without one.
A prior finding reproduces on the way, which is what makes the field arm's growth readable rather than
surprising. M-50 measured cost per re-meshed chunk against edit-log length on the same four buckets
and read 0.158 / 0.354 / 0.525 / 0.589 ms, calling it "3.7× for 7× the log, and flattening" and
concluding that "the BrushStack walk is a real cost and not proportional at these lengths". This
harness measures a different work unit (ns per gather ray, ≈27 samples) through the same walk over the same
bucket midpoints of 8 and 53 brushes and reads 2.63–2.69× against M-50's 3.73× (0.589/0.158):
sub-proportional in both, same shape, same conclusion. Per sample it is 47.80 → 125.56 ns, i.e.
2.63× for 5.5× the primitives per sample (10 → 55). Two instruments on two work units agreeing on
the shape is M-279's rule satisfied, and it is why the C2 mechanism does not rest on this run's clock.
Both arms are proved to be looking at the same scene, because a gather ratio is worthless otherwise.
Both are driven from one liveness vector and one direction set. hit_frac_field 0.9788–0.9934,
hit_frac_mesh 0.9969–1.0000, hit_agree_frac 0.9777–0.9921 (asserted > 0.8), and
hit_median_delta_cells 0.0287–0.0778 — the two arms agree on the hit point to under a tenth of a cell.
The mesh is not fast because it misses (it hits more often) and the field is not slow because it stalls.
The honest counter-case, recorded so nobody has to guess. If the mesh must be rebuilt per edit, the
accounting flips at fine probe density and only there. Median extract_ms + bvh_build_ms is
9.35 + 5.90 = 15.2 ms at 32³, 32.47 + 21.31 = 53.8 at 48³ and 77.75 + 53.30 = 131.1 at 64³.
Against that, gather_ms_field / (gather_ms_mesh + extract_ms + bvh_build_ms) is 2.66 / 2.70 / 2.70 at
s = 2 — the field wins, because at that density the gather is huge — and 0.48 / 0.61 / 0.71 at s = 4,
0.153 / 0.148 / 0.155 at s = 8. But this is not C2: C2 is denominated in the gather pass, and the
crate re-meshes only dirty chunks (M-50, M-314), so a full-world re-extract per edit is a strawman. The
build is reported as its own columns rather than folded into the gather, because the gather is the 87–96%.
The registered vacuity control, which is the crux of the row: the breakthrough arm must actually merge two
air components, asserted from the union-find rather than assumed from the brush. Repair::merges is
touched.len() — the number of pre-existing components the newly-air blob touched — so 1 is an
ordinary widening, 0 is an isolated bubble in bulk rock (which adds a component), and only >= 2 is
M-311's join. Measured: on all 36 breakthrough rows merges = 2 exactly,
air_components_before → air_components_after is 2 → 1 or 3 → 2 (always a drop of exactly one),
pocket_connected_before = false and pocket_connected_after = true. On all 36 control rows
merges = 1 exactly, components are 2 → 2 or 3 → 3 (unchanged), and pocket_connected_after is
false. That value proves the fixture could have failed, for three separate reasons. First, the
arms are chosen by the union-find, not checked afterwards: the breakthrough direction is searched over 64
Fibonacci candidates and accepted only if merges >= 2 && components() < before && connected(pocket, main),
and the control over 96 directions × 3 standoff radii = 288 candidates, accepted only if
merges == 1 && components() == before && !connected, then narrowed by argmin |dug − dug_breakthrough|.
Second, both searches can come back empty — each has its own expect and either stops the run — and
the control's did, twice: expect("no candidate dig widened exactly one air component at a comparable
volume") is what halted the first two runs, and defect 1 below is why. Third, the same instrument reads
1 on one arm and 2 on the other arm of the same pair, so neither number is a zero that could not have
been non-zero: a control reading 2 would not have been a control at all. Before every measured edit the
harness also asserts components() >= 2 and !connected(pocket, main) — so the edit log never leaked into
the pocket — and that the pocket is a real cavity: pocket_air_samples = 515 on every row, which is
exactly the number of lattice points inside radius 5 of a lattice-centred ball, against the 523.6-cell
continuum volume the assertion's bar is computed from. The shell is intact and unnibbled, not merely
non-empty. main_component_samples runs 8,959 → 103,023, so the "main air network" the pocket joins is the
labyrinth and not another pocket.
C3 HELD on 36 of 36 pairs and the volume match is exact, not approximate. dug_samples is 171 on
every row of both arms: the two digs turn exactly the same number of samples from solid to air, so C3's
"a dig of the same volume" is an integer identity and the effect is pure topology. probes_invalidated
(breakthrough) > probes_invalidated_control on all 36 pairs, ratio 1.2500–2.5333, median 1.8947.
The probe gap is 86–211 (median 172) at s = 2 and 8–23 (median 19) at s = 4; the implied volume
gap is 688–1,688 cells (median 1,376) at s = 2 and 512–1,472 (median 1,216) at s = 4, of the
order of the pocket's own 515 air samples plus the probes outside that gain a sight line through the new
hole. The mechanism is that a breakthrough does two things a widening cannot: every probe inside the
newly connected pocket suddenly has rays that escape instead of terminating on the shell, and every probe
on the far side that had the shell in the way now sees into the pocket. Both sets change, in both
directions, which is why the effect is ~1.9× rather than marginal. probes_born — probes that were rock
before and air after — is 23 against 21 at s = 2 and 4 against 2 at s = 4, so liveness flips are a
small part of it and most of the gap is rays moving.
C3's weak spot, stated rather than smoothed. At s = 8 the "strictly more" is 5 against 4 — one
probe — on all 12 pairs. It never inverts, but a one-probe difference at a spacing where the dilated support
holds 0.56–0.71 probes and probes_in_support_actual is 0 is a quantisation-scale signal, not a
measurement. C3's evidence is the s = 2 and s = 4 rows, where the gap is 86–211 and 8–23.
Four fixture defects, three caught by the harness's own controls and one by review, all named because each changed an instrument.
- The first fixture inset the sealing block 6.25 cells on every face, which put only 22.6% of the world
inside it and cut the air labyrinth into interleaved fragments. With three air components at 32³ the
control-arm search reported 0 of 159 candidate digs usable and the run stopped. The fix was the
block, not the level set: at
BLOCK_INSET= 2.25 the air inside is 2–3 components including the pocket, 64 of 64 breakthrough directions merge and 112 of the control candidates widen exactly one component. The canonicaliso = 0is kept and there is no level-set fudge in the fixture. brush_support_cellswasvalue_changed_cellsfirst, and the no-clipping control refused it.max(f, −sphere)moves the value wherever−sphere > f, andfreaches −30 deep inside the sealed block, so a brush's value support is tens of cells across and grows with the world, because the block's interior distance does. A quantity that grows with world size cannot be the denominator of a clause about world-proportionality — it would have hidden exactly the effect C1b is looking for. It is nowM-314'soutput_changed_cells("cells whose triangles change: this is the set that genuinely needs re-meshing"), which is local to the ball by construction.value_changed_cells_in_regionis still emitted, named for the fact that within the given region it is a window on an unbounded set: it reads 625 on every control row against an output-changed 286, and 547 on every breakthrough row against an output-changed 359–361 — larger where the other is smaller, which is the clearest possible proof they are different quantities.- The arm predicates misread
merges. The first draft asked for>= 1on the breakthrough arm and== 0on the control, which is "any dig" against "a dig that opens a new bubble" — both wrong, becauseRepair::mergescounts pre-existing components touched. Readinggrow_fromrather than guessing is what fixed it, and the corrected predicates are the vacuity control quoted above. - Caught by review, not by a control: C2's same-scene columns (
hit_frac_field,hit_frac_mesh,hit_agree_frac,hit_median_delta_cells) were added after the first successful run, because a ratio between two arms is worthless if the arms are not tracing the same geometry and nothing in the harness had asserted that they were.hit_agree_frac > 0.8is now an assertion. Recorded as the one defect here that a control did not find.
Two further controls held on all 72 rows and are worth naming because they are cheap and they are the reason
the numbers above are believable: two instruments, one number — the harness builds its own per-cell
bitmap (it needs one, to say which probes sit inside the support) and asserts both its output-changed
popcount and its value-changed count equal M-314's EditReport fields; and nothing is measured over
an empty set — probes_live > 0 (31 … 13,676) and brush_support_cells > 0 per row.
What changed as a result.
- Probe GI is viable for this game and the reason is C1b, not C1a. The cache a dig dirties does not scale with the world: 8.00× the cells and 9.58–10.46× the live probes buy at most 1.391× the invalidated probes, and nothing at all beyond 48³. The registered constant is wrong — it is 3.36–4.76 for an ordinary dig at the two densities that can resolve one, rising with the edit log, and 4.10–8.38 for a breakthrough — but "edit-proportional, not volume-proportional" is the load-bearing half and it survives with margin.
- Do not gate anything on
invalidation_factor < 4. It is a ratio whose value depends on the probe lattice, the edit-log length and the arm; ats = 8its denominator is an expectation of 0.70 probes against an actual population of 0. The quantity worth gating is the one that is machine- and lattice-independent:invalidated_volume_cellsats = 2, which is the support dilated by 2.03–2.79 cells for a control dig at every world size and every log length. - Do not build probe re-gathers by sphere-tracing the field. At equal ray count the BVH over the
extracted mesh wins on 72 of 72 rows, by 1.95–7.27×, and the field arm's per-ray primitive count grows
5.5× across M-50's log range while the BVH's grows logarithmically in triangles. The exception is
narrow and stated: if the whole world must be re-extracted per edit and probes are at
s = 2, the field wins by 2.66–2.70× — which is not a configuration this crate is in, because it re-meshes dirty chunks. - The banked breakthrough event can drive a lighting response. It is a real, measurable 1.25–2.53× (median 1.89×) spike in probe-update work, concentrated on the frame the union-find reports the merge — which is exactly the frame the game already knows about. It does not have to be discovered by the GI system.
Would be shown wrong by: probes_invalidated rising between 48³ and 64³ by more than the two probes one
triple moved, on a world grown further at fixed edit size — that is C1b's falsifier and it is the one that
would kill probe GI here; a probe lattice at s = 2 on which the control arm's invalidated_volume_cells
leaves the 1,128–1,360 band, which would mean the invalidated region is not edit-local after all; a machine
or a parry3d version on which gather_speedup reaches 3.0 at any log length, which would need the field
arm's 270-primitive-per-ray floor to cost less than one BVH descent; a breakthrough pair where
probes_invalidated is not strictly greater at s = 2 or s = 4, which would remove the topological
event's lighting signature; or a merges of 1 on a breakthrough row or 2 on a control row, which would mean
the two arms were never the two things they are named after.
💥 ✗60 / M-391 — C1 FALSIFIED at 20.3718 against a bar of 3, C2 FALSIFIED by 4 texels on one row with a 66-of-96-arm geometric leak underneath it, C3 HELD at 3.96× on game_dig's own brush and FALSIFIED on 189 of 384 rows — so for a world being dug away, page invalidation is a quantisation and not an area, and Epic's uncached choice is right at the wheel's maximum and wrong at the default (P-79, R-079)
M. cargo bench --bench experiment_p79, docs/experiments/p-79.csv, 392 rows (384 dig + 8
buried-control), f64, Zen 3 (amd-ryzen-9-5900x-12-core, cpu_mhz 4197.4 on every row). Eight
reference fields × four light directions × three brush radii (2, 8, 16 cells — game_dig's default, its
wheel's middle, its wheel's maximum) × four page sizes (16/32/64/128 texels), one subtractive sphere
stroke each, aimed at the surface point the light can see nearest the middle of its own frame. Committed
at 02ffe13, clean tree, an ancestor of HEAD.
Every number below is read from the committed
docs/experiments/p-79.csvat02ffe13, whose header carries no(WORKING TREE DIRTY). The clause verdicts were first taken from a dirty pre-run of the same harness with ~25 siblingcargobuilds live, and every integer column reproduced exactly —pages_invalidatedat all twelve (radius, page) cells,changed_pixels_full221 / 11,853 / 55,464, the single 4-texel C2 failure, the 89/96 and 66/96 leak counts, all eightmax_change_excess_cells, all eight buried clearances, the −0.093% calibration, and the 194/190 and 383/1 verdict counts. Every wall clock moved, and two conclusions moved with them; both are withdrawn and replaced below.One integer tally differs and the committed file is authoritative: at the registered configuration the superseded analysis reported
invalidation_constant20.3718 on 28 rows and 40.7437 on 4, where the file reads 29 and 3 —torus/grazinghaspages_invalidated1, not 2. Nothing on the extraction or field path separates the two trees (the only source commits between them addisomesh::massand itserror.rsvariant), and the superseded analysis recorded its own Python kernel as having been clobbered by a sibling agent mid-session, so this reads as a mis-tally rather than a run difference. It changes no verdict:c1_holdsis false on all 32 rows either way.
| clause | registered | measured |
|---|---|---|
| C1 pages invalidated ∝ projected area, constant < 3, not volume, not scene | constant < 3 | FALSIFIED — 20.3718 on 29 of the 32 registered-configuration rows and 40.7437 on 3, i.e. 6.79× to 13.58× the bar; c1_holds false on all 32 of them and on 190 of the 384 dig rows. Both negative halves HELD |
| C2 localised invalidation is pixel-identical to a full re-render, all eight fields | any pixel difference | FALSIFIED — pixel_diff_localised_vs_full = 4 on fbm_terrain/oblique/r = 16 cells/page = 16 texels (39,251 against 39,247). And the page-independent instrument says the bound is unsound on 66 of 96 arms, 6,985 texels |
| C3 cached-with-invalidation beats uncached by ≥ 2× at 12.5 strokes/s | ≥ 2× | HELD at the registered configuration — median 3.9607, range 2.2814–6.8727, 32/32 rows. FALSIFIED over the sweep: c3_holds false on 189 of 384, median 2.0827, min 0.9327 |
What the instrument is, because every number here is a texel count and none of them is an engine frame
time. There is no Bevy and no wgpu — crates/isomesh must not depend on Bevy — so the virtual shadow
map is built from first principles out of geometry this crate produces. The geometry is the crate's own
MarchingCubes extraction over a 64-cell grid on each field's canonical domain, the same triangles a
renderer would be handed. The depth image is an orthographic light-space depth buffer, 896×896 texels
(112 cells at 8 texels a cell; 64·√3 = 110.85, so the frame circumscribes the domain cube from every
direction and the texel size is identical across the direction sweep), filled by a scanline rasteriser
that takes the smallest dot(p − centre, light_dir) over every triangle covering the texel centre and
+∞ where none does. That is a shadow map's definition rather than an approximation of one, and
orthographic projection makes depth linear in screen space so the barycentric interpolation is exact.
The pages are square blocks of 16/32/64/128 texels, and 128 is UE5's physical virtual-shadow-map page,
so it is the primary arm — at game_dig's 12.5 cm cell an eighth-of-a-cell texel is 1.6 cm, the order
of the screen-pixel footprint a UE5 clipmap level targets in a first-person view. 896 is divisible by all
four page sizes, so pages_total (3,136 / 784 / 196 / 49) is not a fiction.
The two arms share one code path, which is what makes the C2 diff readable as a result.
render(mesh, light, buf, clip) is the full pass with clip the whole frame and the localised pass with
clip the invalidated page block; the localised arm clears those pages, tests every triangle's
light-space AABB against them, and rasterises the survivors clipped to them. There is no second
rasteriser whose disagreement with the first could be mistaken for a result. The per-triangle cull is
O(triangles) in both arms — it is exactly the light loop Epic's one published figure optimised from
1.56 ms to 1.08 ms — so it is charged to the cached arm rather than wished away. What is not charged is
a GPU's draw-call submission and hierarchical-culling overhead, so the measured C3 ratio is an upper
bound on the achievable saving: the direction that favours the hypothesis, stated so the verdict reads
with it in mind.
shadow_ms_cached and shadow_ms_uncached are the cost of this rasteriser at a named page size and
resolution — milliseconds of shadow-pass work per second of continuous digging, 12.5 × the localised
pass and 12.5 × the full pass at 896² texels and the row's own page_texels. stroke_rate_hz reads
12.5 on all 392 rows and shadow_ms_cached is 12.5 × shadow_ms_localised_pass to the last printed
digit (2.18478 against 12.5 × 0.17478). No frame rate is invented anywhere in this harness. They are
not engine frame times.
The SHARE recomputation, worked out in cells before any code was written, and it is the most
transferable thing in the row. C1's constant is pages_invalidated / (π r² / page_area), and for a
sphere that is a pure quantisation ratio with no physics in it. A projected disc of diameter d pages
has an axis-aligned page footprint between ⌈d⌉² and (⌊d⌋+2)², so the constant is bounded below by
4/π = 1.2732 and rises without limit as the brush shrinks below one page. The pre-run table, in
cells, with the one-cell dilation the registered pages_invalidated column uses, against what the run
measured:
| brush radius | page = 2 cells | 4 cells | 8 cells | 16 cells (UE5's 128 texels) |
|---|---|---|---|---|
2 cells (game_dig default) — predicted |
2.86 – 5.09 | 5.09 | 5.09 | 20.37 |
| 2 cells — measured median | 5.0930 | 5.0930 | 20.3718 | 20.3718 |
| 8 cells — predicted | 1.61 – 1.99 | 1.99 | 2.86 | 5.09 |
| 8 cells — measured median | 1.9894 | 2.8648 | 5.0930 | 11.4592 |
| 16 cells (wheel maximum) — predicted | 1.44 – 1.61 | 1.61 | 1.99 | 2.86 |
| 16 cells — measured median | 1.6114 | 1.9894 | 2.8648 | 2.8648 |
The prediction for the primary arm was 20.37 and the run measured 20.3718. Where the table quoted a
single value it quoted the best case ⌈d⌉²; the run lands at the envelope's top (⌈d⌉+1)² in nine of
the twelve cells and at its bottom in three, which is where the brush happens to fall relative to a page
boundary and nothing else.
Conclusion stated before the run: "a constant under 3" is arithmetically unreachable at game_dig's
default brush for any page of 4 cells or more, and unreachable at UE5's page for every brush the wheel
can reach except the largest. Both held. The clause is decided by a brush-diameter-to-page-size ratio
the registration never named — ✗51's rule applied before the run rather than after it.
What arithmetic could not reach before the run, said out loud. Of the twelve (radius, page) cells, four sat entirely above the bar and five entirely below it — nine verdicts available with no machine at all. Three straddled it, and they are the diagonal where the dilated brush is about two pages across:
| r cells | page cells | d pages |
⌈d⌉² |
(⌈d⌉+1)² |
constant envelope | bar 3 | measured median | c1_holds true |
|---|---|---|---|---|---|---|---|---|
| 2 | 2 | 3.000 | 9 | 16 | 2.8648 – 5.0930 | straddles | 5.0930 | 0/32 → FALSIFIED |
| 8 | 8 | 2.250 | 9 | 16 | 2.8648 – 5.0930 | straddles | 5.0930 | 2/32 → FALSIFIED |
| 16 | 16 | 2.125 | 9 | 16 | 2.8648 – 5.0930 | straddles | 2.8648 | 32/32 → HELD |
| 2 | 4 | 1.500 | 4 | 9 | 5.0930 – 11.4592 | above | 5.0930 | 0/32 |
| 8 | 2 | 9.000 | 81 | 100 | 1.6114 – 1.9894 | below | 1.9894 | 32/32 |
| 16 | 2 | 17.000 | 289 | 324 | 1.4374 – 1.6114 | below | 1.6114 | 32/32 |
The top three rows are the three cells the run had to decide; the bottom three are examples of the nine it did not, one from each side of the bar.
The run's contribution to C1 is those three rows: two falsified, one held. At the default brush the run
closed the one door arithmetic had left open — page = 2 cells was predicted 2.86–5.09 and came out
5.0930 on 32 of 32 rows, so no page size in the sweep gets under 3 at game_dig's shipped brush.
The law, as an integer identity rather than a fitted curve. pages_invalidated = a·b with both a
and b in {⌈d⌉, ⌈d⌉+1}, d = 2(r + 1 cell)/page_cells, on 384 of 384 rows. That is area plus
perimeter plus a constant term, and the constant term is the whole of C1's failure: a 2-cell brush
inside a 16-cell page invalidates one entire page whatever it does. The 4/π floor is approached and
never attained — the minimum invalidation_constant anywhere in the sweep is 1.6114 (r = 16 cells,
page = 16 texels), and the arithmetic says it cannot be attained, since 4/π needs d → ∞.
A superseded claim, withdrawn — and it is a category error rather than a run difference. The pre-commit report said the
4/πfloor "is hit exactly at page = 2 cells, r = 2 cells (pages_per_projected_area_cell= 1.27324)".pages_per_projected_area_cellis pages per cell², a different quantity frominvalidation_constant: 1.27324 there is5.0930 / 4and coincides with4/πonly because that page happens to be 4 cells². The floor is attained nowhere in the file. The minimuminvalidation_constantover all 384 dig rows is 1.6114, and no fixture ingame_dig's reach could attain 1.2732.
Both of C1's negative halves HELD, decisively. Not scene-proportional: at page = 16 texels
pages_invalidated is a single integer — 16, 100, 324 at the three radii, spread exactly 0 over
all 32 (field, light) combinations each — while triangles_base spans 4,088 (thin_plate) to
58,112 (noise_cavity), a 14.2× range of scene complexity. pages_fraction runs 0.510% of a
3,136-page atlas to 18.367% of a 49-page atlas. Not volume-proportional: over the 2/8/16-cell radius
sweep pages_per_volume_cell varies 25.28× (page 16) to 56.84× (page 128), while
pages_per_projected_area_cell varies 3.16× to 7.11×. Neither normalisation is constant, but the
area one is 8× more stable — the law is area-like and the volume model is dead. Direction: a sphere's
projected area is direction-free and the measurement agrees; at page = 16 texels the within-field spread
of pages_invalidated over the four light directions is 0 at every radius, and every non-zero spread
at coarser pages is on torus alone (its largest, 19 pages at page 32 / r 16) — page straddling
where one field's aim point sits near a boundary, not direction dependence.
C2's four texels are the smaller half of its falsification, and a page-level-only C2 would have returned HELD on 383 of 384 rows for the wrong reason. Whether a too-tight bound leaks across a page boundary depends on where the brush happened to fall inside its page, so C2 is measured a second way that page size cannot rescue: every changed texel's distance from the projected brush centre, reported against three discs. Over the 96 distinct (field, light, radius) arms:
| bound | column | arms with a leak | texels leaked | worst arm |
|---|---|---|---|---|
the undilated brush, r |
changed_pixels_outside_tight_disc |
89 / 96 | 88,865 | 4,033 |
the registered bound, r + 1 cell (game_dig.rs:2682) |
changed_pixels_outside_dilated_disc |
66 / 96 | 6,985 | 394 |
the derived bound, r + 2√3 cells |
changed_pixels_outside_sound_disc |
0 / 96 | 0 | 0 |
pixel_diff_sound is 0 on 384 of 384 rows. So the bound the engine currently uses is geometrically
unsound on two thirds of the arms and page quantisation absorbed it in 383 of 384 rows. Measured worst
reach per field against a 3.4641-cell budget: thin_plate 1.4289, box_exact 1.4480, csg_difference
1.4480, torus 1.7540, sphere 1.9785, noise_cavity 2.3048, gyroid 2.3115, fbm_terrain 2.4769 —
0.825 to 1.430 cell diagonals against a two-diagonal budget, so the derivation is conservative and tight
to within 30%.
The mechanism, and it is the reason "the brush's bounding volume" was never the bound. A subtractive
brush replaces f with max(f, r − |p − c|), so a grid corner p changes value iff |p − c| < r − f(p)
— and for a corner inside the solid, where f(p) < 0, that reaches further than the brush. Moving
a corner moves every marching-cubes vertex on an edge it terminates, because the crossing parameter
t = f_a/(f_a − f_b) is a function of the values and not just their signs. Only cells holding a sign
change carry geometry, so a changed corner is within one cell diagonal of the surface and
|f(p)| ≤ √3·cell·L for an L-Lipschitz field; that puts it inside r + √3·cell·L, and a
marching-cubes triangle is confined to its own cell, whose farthest point is another √3·cell away.
Sound reach = r + √3(1 + L)·cell, which is r + 2√3·cell for the six 1-Lipschitz fields
(FieldBound::lipschitz answers 1 for Exact and Underestimate alike). Making the bound sound costs
2.10% of the C3 ratio at the registered configuration (median 3.9607 → 3.8774) and one extra ring of
pages — pages_invalidated_sound is 1 on 29 rows, 2 on 2 and 4 on 1, so invalidation_constant_sound
runs 20.3718–81.4873 and the sound bound makes C1 worse, not better.
C3 is real at the brush the demo ships with and gone at the wheel's maximum, and it fails on 189 of 384 rows. Both arms are charged at the same 12.5 Hz, so the ratio is the caching benefit alone. The predecessor declined an easy pass here and the decline is load-bearing: a truly uncached directional shadow re-renders every frame while a cached one re-renders only on the 12.5 stroke frames, which would multiply the ratio by frame-rate/12.5 — about 4.8× at 60 fps — and make ≥ 2× unfalsifiable on arithmetic alone. No frame rate was invented, and the clause duly fails.
| brush radius | page 16 | page 32 | page 64 | page 128 (UE5) |
|---|---|---|---|---|
| 2 cells — median ratio (rows ≥ 2×) | 7.5951 (32/32) | 7.6850 (32/32) | 3.9918 (32/32) | 3.9607 (32/32) |
| 8 cells | 2.752 (30/32) | 2.200 (20/32) | 1.522 (5/32) | 1.091 (2/32) |
| 16 cells | 1.317 (4/32) | 1.156 (3/32) | 1.092 (2/32) | 1.088 (1/32) |
At the registered configuration shadow_ms_uncached has median 20.9806 ms per second of dig against
shadow_ms_cached's 5.6639 ms. Two rows come in below 1.0 — torus/low_45/r 16/page 64 at
0.9327 and gyroid/overhead/r 16/page 128 at 0.9395 — where the localised pass is slower than the
full one.
Why C3 is capped, stated so it does not depend on this run's clocks. The saving available is the
integer ratio pages_total / pages_invalidated: 196× (3,136/16) at the default brush and the finest
page, 49× at the default brush and UE5's page, down to 5.44× (49/9) at the wheel's maximum. The
realised ratio_per_stroke captures 1.61% to 43.37% of it, median 11.92%, and on none of the
384 rows does it reach half. The gap is the per-triangle cull, which the cached arm pays in full and
which does not shrink with the page count: fitting shadow_ms_localised_pass = cull + slope ·
pages_fraction per field gives a pure-cull intercept of 0.1532 ms (thin_plate) to 1.7729 ms
(noise_cavity), 12.29% to 40.85% of the full pass, an implied ceiling of 8.14× down to 2.45× however
few pages are invalidated. That fit is a wall clock and is not a gate (✗24, M-281); the integer
statement is the durable one — the shortfall is structural, not a clock artefact, because the ratio
never approaches the texel ratio on any row of either run.
A superseded conclusion, withdrawn, and it is the reason the paragraph above is written around integers. The pre-commit report's fit read 0.226–2.095 ms of cull, 11.6%–52.3% of the full pass, and a ceiling of "8.6× down to 1.9×" — concluding that "on
thin_platethe ceiling is 1.9×, below the registered 2×, before a single page is considered", and that "a 1.44× cull improvement would liftthin_plate's ceiling from 1.9× to 2.7× and put it over the line". On the clean treethin_plate's fitted ceiling is 2.45×, above the bar, so neither statement survives and both are withdrawn.thin_plate's intercept moved 0.226 → 0.1532 ms, −32.2%, and that alone carried its ceiling across the bar — which is what a conclusion denominated in milliseconds is worth. What replaces it is run-independent: the available saving is the integerpages_total / pages_invalidated, 5.44× to 196×; the realised ratio captures at most 43.37% of it on any of the 384 rows, in either run. The cull cap is real in both runs; its per-field value is a clock and no field's ceiling should be quoted against the 2× bar.
Caching a deforming shadow is therefore not a pixel problem, it is a culling problem — which is exactly the term Epic reported optimising and the only number they published.
The registered vacuity control: changed_pixels_full, asserted > 0 on every dig row, with the field,
light and brush radius named in the message. All 384 pass: minimum 221 (torus/overhead/r = 2
cells), median 11,853, maximum 55,464 (thin_plate/overhead/r = 16 cells), zeros 0. The
assertion fires after the CSV is written, so a failure leaves an artefact to read.
And that zero is reachable, which is what makes the control a measurement rather than an M-44 pass —
that is what the buried-control arm is for. One brush per field is placed at the deepest interior point
along the same light ray, and the harness asserts that at least one produces changed_pixels_full == 0.
Six of eight read exactly 0: sphere (clearance 15.9115 cells), box_exact (15.9375),
csg_difference (9.2500), gyroid (4.6336), fbm_terrain (111.0397), noise_cavity (8.6370). A buried
cavity is behind the first hit, so a first-hit depth buffer must not move; if the buffer were a last-hit
buffer, or the frame were mis-registered, or the min-depth composition were wrong, these six rows would
be non-zero. The arm is a control on the control and is not clause evidence.
On the eight
buried_controlrows,c2_holdsreadstrueand it is not a C2 pass. Six of them havechanged_pixels_full == 0, so the localised composite matches the full re-render over an empty change set. For the same reasonmax_change_excess_cellsandexcess_in_cell_diagonalsread-infon those six: that is a maximum over an empty set, not a measurement of a negative reach.c1_holdsreadsfalseandc3_holdstrueon all eight buried rows as well — the same arithmetic applied to a control arm. Every clause count in this entry is over the 384digrows only, which is why they are 194/190, 383/1 and 195/189 rather than the whole-file 194/198, 391/1 and 203/189.
A third control, and nothing else in the harness would catch what it catches. calibrate() runs
before anything is measured: it rasterises the unit sphere and checks the covered-texel count against
π R² / texel², which is that sphere's projected area from every direction. Measured 51,424 texels
(the frame_covered_texels column on the sphere rows) against π / 0.0078125² = 51,472 — an error of
−0.093% against a 3% budget, and the sign is right because the marching-cubes silhouette chords the
true circle inward. Every number in this row is a texel count, and only this control could see a uniform
scale error, a swapped basis or a dropped half-texel offset. frame_covered_texels itself runs 13,712 to
262,114 of 802,816 across the fields and lights.
Six fixture defects, all caught by this harness's own controls rather than by review.
- The first C2 instrument was luck-dependent and would have been written up as HELD. It scored C2 on
pixel_diff_localised_vs_fullalone, which reads 0 on 383 of 384 rows. Adding the page-independent disc measurement turned that into "66 of 96 arms geometrically unsound". The leak reaches at most 2.4769 − 1 = 1.4769 cells past the registered bound, about 12 texels, so at a 128-texel page it only crosses a page boundary when the brush lands within 12 texels of 128 of one. This is the single reason the verdict reads FALSIFIED instead of HELD. - The first sound bound was wrong and the leak instrument said so immediately.
radius + 1 cellwas assumed on the grounds that marching cubes only moves geometry within one cell of a changed corner. False: the crossing parameter depends on values, so a corner well inside the solid still moves its vertices. The wrong bound remains in the CSV aspages_invalidated/changed_pixels_outside_dilated_discbecause it is the bound the registration describes and the one the engine uses. torus's buried row degenerated into its dig row.buried_clearance_cells = 0.0000andchanged_pixels_full = 221, identical to its dig row: along the light ray through the torus's aim point there is no interior point — the ray leaves the solid at the inner rim — sodeepest_interiorreturned the aim point. Visible in the clearance column. A reader must not count that row as a buried measurement.thin_plate's buried row is non-zero by construction. Clearance 0.1500 cells and 1,520 changed texels: a 2-cell brush cuts clean through a 0.4-cell-thick plate, so the "buried" cavity is not buried. Predicted, and self-documenting through the clearance column.gyroid's registered Lipschitz bound over-provisions by 3.35×.FieldBound::Lipschitz { l: 3.4641 }makes the derivation ask for√3 · 4.4641 = 7.7320cells of dilation; the measured reach is 2.3115. Applied literally it would take the default brush's footprint at UE5's page from 1 page to at least 4 —d = 2(2 + 7.7320)/16 = 1.2165, so⌈d⌉² = 4— for nothing.fbm_terrainhas no derivable bound at all. It registersFieldBound::Unbounded, solipschitz()returnsNoneand no light-space invalidation radius can be derived — only observed. Its measured 2.4769 cells is the worst of the eight and still inside two cell diagonals, but that is a property of this fixture and not a guarantee. It is also the field that produced the one non-zeropixel_diff_localised_vs_full. Any shipped localised invalidation over an unbounded field needs a measured margin, not a derived one.
What changed as a result.
- Do not use
radius + cellas a light-space shadow invalidation bound. It is geometrically unsound on 66 of 96 arms and leaks up to 394 texels per arm; page quantisation hid it on 383 of 384 rows, so a page-level test would have shipped it. Useradius + 2√3·cell— zero leak on 384/384, at a cost of 2.10% of the ratio and one extra ring of pages. This is the row's one directly actionable output. - Do not build page-level shadow caching for
game_dig's default brush expecting proportionality. It is not proportional to anything at that size: a 4-cell hole invalidates one whole 16-cell page and the constant is 20.3718. The saving is still worth 3.96× because one page is 1/49 = 2.04% of the atlas, so the mechanism is worth having — but any design or budget written against "invalidation is proportional to projected area" is wrong by an order of magnitude at the brush size the demo ships. - Do not spend the sprint on finer pages. Going from 128 to 16 texels moves the constant from 20.3718 to 5.0930 (4.00×) and the ratio from 3.9607 to 7.5951 (1.92×) — for a 64× larger page table. The crossover where the constant goes under 3 needs a brush at least two pages wide, i.e. radius ≥ 16 cells (2.0 world units) at a 128-texel page, which is the maximum the mouse wheel allows.
- If one thing is built, attack the light loop and not the page count. The available texel saving is 5.44× to 196× and less than 44% of it is ever realised; the cull is what eats the rest, and it is the same term Epic reported taking from 1.56 ms to 1.08 ms.
- Epic's decision is vindicated at the large-brush end and reversed at the small-brush end, and never
because of the pixels. Under 2× on 189 of 384 rows — 118 of the 128 rows at the wheel's maximum, and
0 of the 128 rows at
game_dig's default. For a world being dug with a hand-sized brush, cached-with-invalidation is worth about 3.96× of this shadow pass; at the wheel's maximum it is worth about 1.09× and leaving directional sun shadows uncached is right. That is the number the Fortnite write-up does not contain. - A lead, not a defect claim. The same "values, not signs" reach applies to the crate's own dirty-cell
marking:
mark_edittakes a caller-supplied region andgame_digpassesreach = radius + cell(game_dig.rs:2682,:3864). This measurement says the post-edit field differs out to 1.4289–2.4769 cells beyond the brush surface on these eight fields, which is further than one cell. Not reproduced throughgame_dig's own pipeline and not this ticket — recorded for whoever owns the dirty set.
Would be shown wrong by: a field whose changed geometry reaches beyond r + 2√3·cell, which would
make changed_pixels_outside_sound_disc non-zero and mean no derived bound is safe on any field — the
Unbounded fbm_terrain is the candidate and its 2.4769 cells is only a fixture's value, not a
guarantee; a pages_invalidated that falls outside {⌈d⌉, ⌈d⌉+1}², which would mean the footprint is
not a quantisation of the projected disc and C1's constant is measuring something else; a hierarchical
page-table walk whose cost scales with pages_invalidated rather than with triangles, which would remove
the O(triangles) cull that caps C3 and could carry the ratio toward the 5.44×–196× the texel counts
allow; or a dug world at a brush at least two pages wide, where C1's "under 3" becomes reachable and the
constant is 2.8648 — the wheel's maximum against UE5's page is exactly that case and it holds there
already.
💥 ✗61 / M-392 — C1 FALSIFIED on one field of eight with both halves of its falsifier firing, C2 FALSIFIED by 0.62° against a headroom of 0.94° its own reference left and nobody computed, and C3's prediction HELD on thin_plate at 28.60° while FALSIFIED on gyroid at 13.22° — where the no-map arm is itself only 14.85°, so the clause's premise failed rather than the map succeeding: a mean shading-normal angle over the surviving coarse surface cannot see a silhouette (P-80, R-080)
M. cargo bench --bench experiment_p80, docs/experiments/p-80.csv, 24 rows (eight reference
fields × LOD 1–3), f64, Zen 3 — cpu_mhz reads 4197–4200 on every row (M-280). Fixture: M-72's own
ladder, ChunkLayout::new(64 >> level, h₀, domain_min).at_lod(level) over each field's own
ReferenceField::domain, so the world extent is fixed and only the spacing changes; the residual predictor
is one sample, one gradient, one Newton step, p = v − f(v)·∇f(v)/|∇f(v)|², and the shading comparison is
barycentric vertex-normal interpolation at 16 area-uniform points per coarse triangle, area-weighted, with
no renderer and none faked. Committed at ec31985, no WORKING TREE DIRTY marker, and
git merge-base --is-ancestor ec31985 HEAD passes.
| clause | registered | measured |
|---|---|---|
| C1 the field-only residual direction agrees with the true nearest fine-surface point to within 0.1 cells on 95% of coarse vertices at LOD 1 and 2 | ≥ 0.95 | FALSIFIED — noise_cavity 0.899724 at LOD 1 and 0.836800 at LOD 2. Holds on the other seven fields, worst residual_p95_cells 0.057262 of a 0.1 bar |
C2 LOD-2 shading-with-map within 10° of LOD-0 on fbm_terrain, against over 25° without |
< 10° and > 25° | FALSIFIED on the with-map half — 10.6195°, a miss of 0.6195°. The no-map half HELD at 25.5971°, clearing its floor by 0.5971° |
C3 above 25° with the map on thin_plate and gyroid at LOD 3 |
> 25° on both | HELD on thin_plate at 28.6007°; FALSIFIED on gyroid at 13.2206° — and not because the map worked |
Two verdict columns read
falsefor reasons that are not the clause failing, and neither is a falsification.c2_holdsisfalseon all 24 rows, but C2 is registered on exactly one —c2_registered_rowistrueonly onfbm_terrainat LOD 2. On the sixsphereandtorusrows thefalseis caused by the no-map arm being under 25° (0.0032° to 6.7165°), i.e. by the clause's premise not applying to a field LOD 2 still resolves, not by any map failing. Likewisec3_holdsistrueonnoise_cavityat LOD 2 and 3 (38.4725° and 55.5072°), where C3 is not claimed —c3_registered_rowistrueonly onthin_plateandgyroidat LOD 3. Andc1_holdsistrueonthin_plateat LOD 3 wherec1_registered_rowisfalse. Read the*_registered_rowcolumns first; the*_holdscolumns on other rows are informational.The first report of this experiment quoted a dirty pre-run at
63c7161, taken while ~25 sibling agents were compiling, and every number it quoted has been re-read against the committed clean-tree file. Three moved and all three are clocks:bake_mson C2's registered row 4.5549 → 2.9949 (−34.2%), thebake_msrange across all rows 0.1393–7.3100 → 0.1396–5.6718, andbake_us_per_texel_written0.15–1.50 → 0.1543–1.3517. Every angle, fraction, integer count and byte figure the report quoted reproduced to the last digit it stated, and no verdict moved — which is the shapeM-377's re-run note records, andM-279's rule underneath it: a run that disagrees with its predecessor on anything that is not a clock has a defect, not a variance. No clause in this registration is denominated in milliseconds, which is why a 34% clock move costs nothing here:✗24andM-281are the precedents, the bake cost is printed, and every gate is an angle or an integer.
The ladder is M-72's, and the row proves it rather than asserting it in a comment. lod0_triangles
on thin_plate reads 4,088 and coarse_triangles reads 1,016 / 248 / 56 at LOD 1/2/3 — M-72's
4,088 → 1,016 → 248 → 56, exactly. That is M-279's check in its cheapest form: a new harness's first job
is to agree with the committed measurement where they overlap, and if these four integers had not
reproduced, the experiment would have been measuring a different ladder and no clause about it would have
meant anything.
The SHARE line, recomputed. Registered: "C2 moves the shading half of the LOD budget only; triangle counts are unchanged by construction." Both halves check out, and one of them was only checkable after the run.
- Triangle counts unchanged: TRUE, and verified rather than assumed. The map is a byte array and never
touches
MeshBuffer;coarse_trianglesat a level is identical whether the map is baked or not, and the ladder above is the evidence. - C1 is the only clause denominated as a ratio, so it is the only one
✗51's rule applies to. Its denominator iscoarse_verticesat the registered levels: 510–6,522 at LOD 1 and 126–1,260 at LOD 2. Non-degenerate on every field, so the 95% has a real population to be 95% of. - C1's reachability was computed before the run, and it is a reference-checked-before-the-measurement
case. The clause is only measurable if the ground truth is far tighter than its 0.1-cell tolerance. The
ray-fan analytic reference localises its direction to
θ ≈ cap·0.3ⁿ⁻¹/3afternrefinement rounds, i.e.0.15·0.3⁴/3 = 4.05e-4rad atFAN_ROUNDS = 5; a coarse vertex sits on a straddling coarse edge sod ≤ h/2, which is4 h₀at LOD 3; the position error isd·θ ≈ 1.6e-3 h₀. C1's tolerance is 0.1 coarse cells — 0.2 h₀ at LOD 1 and 0.4 h₀ at LOD 2 — so the reference is 125× and 250× tighter than the tolerance it has to resolve. Post hoc,closed_form_analytic_err_cellsconfirms it on the four fields with a closed form: 0.000000 to 0.001241, the worst beingtorusat LOD 2, which is 0.6% of the LOD-1 tolerance.M-289is the precedent — a reference that was wrong exactly where the measurement was taken, and two hypotheses reported falsified that were both true — and this is the same check run before the verdict rather than after it. - C2's reachability is the thing arithmetic could not reach before the run, and it should have been
reached anyway. What was derivable at registration: C1 holding at 0.1 cells does not bound a shading
normal, because C1 bounds a position and the normal error a position error implies is
0.1·h·κ— onfbm_terrainat LOD 2,h = 1.0and the finest octave's wavelength is 0.5, soκ ≈ 12.6per unit and0.1·h·κ ≈ 1.26rad ≈ 72°. So C2 always needed its own instrument, which is why the harness carrieslod0_self_angle_deg. What only the run supplied is the value of that instrument, and it is below.
C1, on the registered levels. residual_agree_fraction and residual_p95_cells, both in cells at the
level being measured:
| field | agree, LOD 1 | p95 cells, LOD 1 | agree, LOD 2 | p95 cells, LOD 2 |
|---|---|---|---|---|
sphere |
1.000000 | 0.003351 | 1.000000 | 0.002124 |
torus |
1.000000 | 0.009969 | 1.000000 | 0.007722 |
box_exact |
1.000000 | 0.000000 | 1.000000 | 0.000000 |
csg_difference |
1.000000 | 0.002417 | 1.000000 | 0.001556 |
thin_plate |
1.000000 | 0.000000 | 1.000000 | 0.000000 |
gyroid |
0.989607 | 0.006241 | 0.995238 | 0.005461 |
fbm_terrain |
0.990817 | 0.057262 | 0.988571 | 0.048659 |
noise_cavity |
0.899724 | 0.216238 | 0.836800 | 0.425169 |
Seven fields of eight hold with room: the worst residual_p95_cells at a registered level is 0.057262,
which is 1.7× inside the 0.1 bar, and it is exactly 0.000000 on box_exact and thin_plate because a
box's gradient is piecewise constant and one Newton step lands on the face plane with no linearisation
error at all. closed_form_pred_err_cells is 0.000000 on all four closed-form fields, so the predictor
is exact wherever an exact answer exists.
noise_cavity fails, and both halves of C1's falsifier fire on it. The first half is the 95%: 0.899724
and 0.836800. The second is "an error that grows with LOD level faster than the cell size", and it is
visible in two columns at once. residual_p95_world goes 0.02702970 → 0.10629225 from LOD 1 to LOD 2,
a factor of 3.9324, while cell_size goes 0.125 → 0.25, a factor of 2 — so the error grows
1.97× faster than the cell, and that is exactly why residual_p95_cells (already normalised by the
level's own cell) doubles rather than shrinking. residual_max_cells reaches 1.713065 coarse cells.
On the five exact-distance fields the same column shrinks with level.
The mechanism, and it is the step length rather than the root finder. noise_cavity is Perlin noise at
frequency 3.45 with iso 0.25 intersected with a sphere of radius 1.5, and the crate declares it
FieldBound::Unbounded — M-244 is the incident where a guessed Lipschitz constant of 2.598 was caught at
a measured |∇f| of 7.734 on this same field. A gradient magnitude that varies by that much over the level
set makes −f/|∇f|² overshoot, and three Newton steps do not fix it: angle_deep_deg tracks
angle_direct_deg to within 0.11–0.74° on those rows. What does say the field has structure below the
coarse cell is the growth in cells: a single linearisation cannot see it, and it sees less of it the
coarser the cell gets.
And it is not the reference. mesh_vs_analytic_p95_cells on noise_cavity is 0.094866 / 0.077665 /
0.058895 — the mesh reference and the ray-fan analytic reference, which touches the gradient nowhere,
agree to within 0.1 cells where the predictor is off by 0.43. residual_agree_fraction_analytic reads
0.934866 / 0.884984 / 0.870968, i.e. the analytic reference also fails the clause on this field.
analytic_unreached, zero_gradient_vertices, zero_gradient_texels and reference_normal_missing are
0 on all 24 rows.
C2, and the attribution is the entry's substance. All four arms on fbm_terrain, degrees:
| level | no-map | with-map | angle_direct_deg |
angle_deep_deg |
lod0_self_angle_deg |
with-map vs analytic |
|---|---|---|---|---|---|---|
| 1 | 14.1352 | 10.1562 | 8.8247 | 8.7636 | 8.1923 | 10.2908 |
| 2 | 25.5971 | 10.6195 | 10.3492 | 10.3017 | 9.0558 | 10.7895 |
| 3 | 35.3725 | 13.7746 | 12.9068 | 12.8401 | 7.9089 | 14.7469 |
The map's own machinery costs a fraction of a degree. angle_direct_deg is the residual normal
evaluated at the shading point with no texture at all — no triplanar projection, no 8-bit quantisation, no
tangent frame, no bilinear filter, no gutter. On C2's registered row it is 10.3492 against the
with-map arm's 10.6195, so the entire map apparatus costs 0.2703°. The root refinement is not the
limit either: three Newton steps instead of one move it by 0.0475°.
The LOD-0 mesh's own normal interpolation costs about nine degrees, and that is the binding constraint.
lod0_self_angle_deg is the angle between the analytic normal at the LOD-0 nearest point and the LOD-0
mesh's interpolated normal there. On fbm_terrain at LOD 2 it is 9.0558°. So a residual normal that
was exactly right would still score 9.0558° against the reference C2 is registered against, and C2's 10°
threshold left 0.9442° of headroom over the best score the instrument's own reference permits. The
measured shortfall is 0.6195°, which is inside that headroom. The clause was reachable, but only
just, and that margin was never checked at registration — 10 against a floor of 9.06 is a clause with 9%
of its own bar to work in, and the arithmetic that says so needs one column this harness happened to carry
because ✗51's rule made it ask.
The floor is a property of the ladder, not of the map, and the column says so across eight fields:
lod0_self_angle_deg is 0.0001 on sphere, 0.0568–0.0645 on torus, 0.0000–1.2023 on box_exact,
0.3040–1.1805 on gyroid — negligible wherever LOD 0 resolves the field — and 7.9089–9.0558 on
fbm_terrain and 5.5675–6.3564 on noise_cavity, the two fields carrying detail below h₀.
fbm_terrain is four octaves at base frequency 0.25 and lacunarity 2, so its finest octave has wavelength
0.5 = 2 h₀: LOD 0 is at Nyquist for its own finest octave, and a map baked from the analytic field is
carrying detail the reference has already low-passed away. angle_with_map_vs_analytic_deg is 10.7895 on
the same row, so scoring against the analytic normal instead does not rescue the arm — the residual normal
is itself about 10.8° from the analytic normal there, and the floor argument bounds what was achievable
without claiming the residual achieved it.
LOD 0 was not refined to lower that floor, deliberately. LOD0_CELLS is 64 because that is M-72's
grid and ThinPlate::CANONICAL_CELL_SIZE's grid; a finer LOD 0 would reduce lod0_self_angle_deg and
might let C2 pass, and would stop the plate being M-72's plate. The floor's dependence on h₀ is argued
from the committed column across eight fields instead.
C3, and the distinction is the most useful sentence here. thin_plate at LOD 3 comes in at
28.6007° with the map, above the predicted 25 — the prediction HOLDS. gyroid at LOD 3 comes in at
13.2206°, below 25 — the prediction is FALSIFIED. But the registered falsifier reads "C3 by the map
working on thin_plate or gyroid at LOD 3", and the map did not work on gyroid: the no-map arm there
is 14.8487°, so the map removed 1.6281° and neither arm is anywhere near 25. Coarsening gyroid to LOD 3
keeps 556 of 43,116 triangles — 1.29% — and costs only 14.85° of shading normal on the surface that
survives. C3's stated mechanism, "a normal map cannot restore a SILHOUETTE", is true and is not what
C3's number measures: a mean angular difference sampled over the coarse surface never samples where the
surface is missing. The clause's number and the clause's mechanism are two different claims, and only the
number was made falsifiable. A silhouette clause needs a silhouette instrument — coverage, not normals.
thin_plate holds for a reason C3 did not name, and it is M-72 one level up. angle_direct_deg on
that row is 2.0650 and lod0_self_angle_deg is 2.0650 to four decimals: the box gradient is
piecewise constant, so the residual normal is the analytic normal at the nearest fine point and the 2.07°
is entirely the LOD-0 mesh's own interpolation across the plate's edges. The achievable score is 2.07° and
the baked map delivers 28.60° — the parametrisation destroys 26.5° of a 2.07°-achievable result.
fetch_misses is 340 of 896 shading samples (37.9%): over a third of the coarse plate fetches texels
the bake never covered. The plate is 0.4 × 0.0625 = 0.025 world units thick against a texel of 0.0625,
so its rim is sub-texel in the x and z pages; at LOD 3 the whole plate is 0.05 coarse cells thick,
so a large fraction of coarse triangles carry x- or z-dominant interpolated normals and land in the
wrong page. That is aliasing reappearing inside the map's own parametrisation.
When the map helps and when it hurts, angle_with_map_deg − angle_no_map_deg in degrees, negative
being better:
| field | LOD 1 | LOD 2 | LOD 3 |
|---|---|---|---|
sphere |
0.0000 | 0.0000 | 0.0000 |
torus |
+0.0351 | −0.1351 | −2.0175 |
box_exact |
+0.2635 | −2.7416 | −5.7200 |
csg_difference |
+0.2065 | −2.8204 | −6.0436 |
thin_plate |
−0.1896 | −1.7038 | −3.2664 |
gyroid |
+1.1127 | +0.6898 | −1.6281 |
fbm_terrain |
−3.9790 | −14.9776 | −21.5979 |
noise_cavity |
+3.5157 | +0.7334 | −6.8528 |
14 of 24 rows improve, 7 get worse, 3 are flat. It helps most where the coarse loss is large and the
surface is single-valued in its projection, and it hurts exactly where the triplanar projection collapses
depth: map_texel_conflicts is 2,671 of 4,249 written texels on gyroid at LOD 1 (62.9%) and 3,022
of 4,196 on noise_cavity at LOD 1 (72.0%) — more than one surface sheet projects to the same texel and
arbitration keeps one. noise_cavity additionally has 177 / 499 / 830 hemisphere_clamped_texels:
detail normals more than 90° from the coarse normal, which a two-channel tangent-space map cannot represent
at any precision. And it hurts at LOD 1 on box_exact, csg_difference and torus, where the coarse
normal is already exact — angle_no_map_at_vertices_deg is 0.0000 on box_exact at every level — and a
bilinear blur across a sharp edge can only add error.
Cost, with the machine-independent figures beside the clock. map_bytes_per_chunk is 24,576 on
every row (3 pages × 64² texels × 2 u8), against lod0_mesh_bytes of 98,160–1,390,512: 3.99× smaller
than thin_plate's fine mesh, 16.68× than fbm_terrain's, 42.08× than gyroid's, 56.58× than
noise_cavity's. bake_field_samples is 556–7,218 with bake_field_gradients exactly twice that on
every row, counted by a wrapper rather than by arithmetic. bake_ms (median of 3, one chunk) is
0.1396–5.6718 and is printed, not gated. Occupancy at LOD 2 is 6.35%–33.01% of the 12,288 texels
(map_texels_written 780 on thin_plate to 4,057 on gyroid), so most of the 24 KiB is unused and a real
implementation would pack it.
The vacuity control: changed_vertices, and its value on C2's registered row is 5,704 of 15,296
(changed_fraction 0.372908). Registered wording: "the LOD-0 reference must differ from LOD-2 by more
than 25 degrees somewhere, reported as a changed-vertex count, or C2 is comparing two identical shadings."
It is counted over exactly the population C2's two means are taken over — the area-weighted shading
samples — because that is the population it exists to guard, and it is asserted on the rows a registered
verdict depends on, with the literal "somewhere" asserted in main by scanning the values about to be
written to the file. On C3's two registered rows it is 496 of 896 (0.553571) on thin_plate and
1,548 of 8,832 (0.175272) on gyroid.
Why that value proves the fixture could have failed: the same column reads exactly 0 on all six
sphere and torus rows and non-zero on the other eighteen. A unit sphere at h = 0.125 never moves a
shading normal by 25° under one coarsening step, and no other assertion in the harness implies otherwise —
so the column is demonstrated sensitive rather than argued to be. That is M-44's rule satisfied by
demonstration: a zero that could not have been non-zero is not a measurement, and here a zero that was
non-zero on eighteen rows is what makes 5,704 mean something. The second control is
map_perturbation_deg > 0, which catches a decode bug that would leave both C2 arms equal and score a
false HELD wherever the coarse normal was already close: it reads 23.7256 on C2's registered row,
6.9729 and 11.1591 on C3's two. Its honest weakness is on the same six rows: 0.0000 to four decimals on
all three sphere rows, where the assert passes on a strictly positive value that is nearly vacuous,
because on a perfectly resolved sphere the residual normal is the coarse normal and only quantisation
separates them.
Seven fixture defects, each caught by this harness's own controls rather than by review.
- Sampling the shading comparison at coarse mesh vertices would have measured almost nothing, and
would have "falsified" C2 in the opposite direction. At a vertex the interpolated normal is the
vertex normal, which is
normalize(∇f(v))— the exact analytic normal, all octaves included. Onfbm_terrainthe field isy − h(x, z), exactly linear along ayedge, so a coarse vertex on a vertical edge sits exactly on the analytic surface. Measured, both readings on the row:changed_coarse_mesh_verticesis 3 of 525 coarse vertices againstchanged_vertices5,704 of 15,296 area samples, andangle_no_map_at_vertices_degis 2.5090 against 25.5971. A vertex-sampled harness would have reported 2.51° for the no-map arm, failed C2's over-25 half, and concluded that coarsening terrain costs no shading detail — by measuring the one place where it costs nothing.changed_coarse_mesh_verticesis 0 on all fifteensphere/torus/box_exact/csg_difference/thin_platerows, which is how visible the trap is once it is on the row. - The analytic reference was broken, and its own closed-form assert caught it —
M-289exactly. The first complete run halted onsphereat LOD 2 with "the analytic reference is 0.021383 LOD-0 cells from the closed form, so it is not a reference". The ray-fan's local refinement updated the best direction inside the ring loop while the perpendicular basis came from the round's starting direction, socos·bd + sin·sidestopped being a unit vector and the compared ray parameter stopped being a distance; the search stalled near 0.011 rad instead of 4.05e-4. Held fixed for the round, normalised per candidate, winner committed at the end:closed_form_analytic_err_cellsnow reads 0.000000–0.001241. Found by an assert, not by an audit. - The vacuity control was first asserted on rows no clause is claimed on, and halted on
sphereat LOD 1 — correctly, because that zero is a finding about a smooth field rather than a broken fixture. Halting on it would have let the control decide which fields may appear in the dataset. Restructured so the control stops a vacuous verdict (asserted onc2_registered_row/c3_registered_row) whilemainasserts the registered "somewhere" over the emitted rows. The column is now on all 24 rows and reads 0 on six of them, which is stronger evidence of sensitivity than a uniformly passing assert. FAN_ROUNDSis derived, not picked. What the closed-form assert compares is a position, and a residual angular errorθdisplaces the found point tangentially byd·θ— sod·θ²/2being negligible is not enough. Three rounds give≈1.8e-2 h₀at LOD 3, against the1e-2 h₀the assert allows: the reference would have failed its own check. Five give 1.6e-3. The derivation is in the const's doc comment, not in a report.- The registration fixes two column names that are wrong on any row whose level is not 2 —
angle_lod0_vs_lod2_no_mapandangle_lod0_vs_lod2_with_map. They are populated as registered with that row's own comparison, andangle_no_map_deg/angle_with_map_degcarry identical values under names that cannot be misread.changed_verticesis the same shape: it counts shading samples, not vertices, andchanged_fractionandshading_samplesare beside it so the denominator is on the row. - The closed-form columns use
−1as a sentinel rather than a blank, on the four fields that have no closed form here (csg_difference,gyroid,fbm_terrain,noise_cavity), with theclosed_formcolumn naming which formula was used on the other four.−1is unambiguous for a non-negative error. - Dropped populations are counted, not silenced.
degenerate_samples(zero-area coarse triangles or zero-length interpolated normals) is 0 on eighteen rows, 64 on all threegyroidrows and 272 / 864 / 800 onnoise_cavity;map_texels_dilated(the bake gutter) is 88–1,088;hemisphere_clamped_texelsandfetch_missesare on every row. An untouched texel encodes(0, 0), which decodes to the coarse normal exactly, so "no detail here" needs no second execution path.
What changed as a result: nothing was landed, and that is the conclusion. On these eight fields a
triplanar tangent-space normal map baked from the LOD residual is not worth shipping. It improves
shading on 14 of 24 rows and degrades it on 7, it cannot reach C2's bar on the one field the clause was
about even with 15.0° of a 25.6° loss removed, and on the field C3 named it destroys 26.5° of a
2.07°-achievable result. The failure is in the parametrisation, not in the residual — which is the arm
worth reading: angle_direct_deg is 0.1200–1.4511° on box_exact and csg_difference, 2.0650° on
thin_plate at LOD 3 and 4.2840° on gyroid at LOD 3, and is strictly below the baked map's arm on 23
of 24 rows (the exception is sphere at LOD 1, where the two are equal at 0.0032).
Evaluating the residual normal per fragment — one sample and two gradients of the analytic field, no
texture, no UV, no bake, no bytes — is a real result and is not this registration's claim; it needs its
own id, because it costs a per-pixel SDF evaluation (four octaves on fbm_terrain and noise_cavity) and
a shader path the crate does not have. Two registration defects a successor should not repeat: C2's
threshold must be stated relative to the reference's own distance from the field (register the ratio of
the with-map arm to lod0_self_angle_deg, or register the analytic normal as the reference and say so),
and C3's number and C3's mechanism must be the same claim or the clause can hold for a parametrisation
reason and fail for a premise reason, which is exactly what happened.
Would be shown wrong by: a with-map arm under 10° on fbm_terrain at LOD 2 at this ladder, which would
mean the 9.0558° floor is not a floor and lod0_self_angle_deg is measuring the wrong thing; a
residual_agree_fraction at or above 0.95 on noise_cavity at LOD 1 or 2 from the same one-gradient
one-Newton-step predictor, which would put C1's failure in the harness rather than in the step length; a
mesh_vs_analytic_p95_cells above 0.1 on noise_cavity, which would move the failure back into the
reference and make this M-289 again; a silhouette instrument — coverage rather than normals — showing
gyroid at LOD 3 losing more than 25% of its projected area, which would restore C3's mechanism while
leaving its number falsified; or changed_vertices reading 0 on a registered row, which would void the
verdict rather than change it.
🔬 M-393 — C1 HELD at 8.067× and 4.766 µs against a 3× / 20 µs bar, C2 HELD bit-identical over 10⁶ queries across Zen 3 and an Apple M5, C3's TriMesh half HELD at 93,298 ghost contacts and its field half VACUOUS — and P-85 falsifies C1's registered SHARE premise, because the collider's 45% is construction to within 3.12e-5, so this moves a moving body's per-frame collision budget and not the 45% (P-81, R-081)
M. cargo bench --bench experiment_p81, docs/experiments/p-81.csv, 2 rows (four # comment
lines plus one column header above them; 74 columns), f32, Zen 3 (amd-ryzen-9-5900x-12-core), with a
second machine for C2. One 33³ chunk of fbm_terrain on the field's own domain — the same
common::grid that P-85 and M-135 use, 32 cells per axis, cell_size 0.5, welded with
weld::epsilon_for and handed to parry3d::shape::TriMesh — against 20,000 tilted capsule poses that
both arms answer, one arm parry3d::query::contact and the other a fixed-trip golden-section search
over FbmTerrain::sample. Committed at d0c3218, provenance line clean (no (WORKING TREE DIRTY)),
verified an ancestor of HEAD. The gate file docs/experiments/p-85.csv is at 5c55f12, also clean
and also an ancestor.
| clause | registered | measured |
|---|---|---|
C1 GSS capsule-vs-field is under 20 µs/query on the Zen 3 and beats the shipped TriMesh path by ≥ 3× on fbm_terrain at 33³ |
≥ 3× and < 20 µs | HELD — speedup 8.067043 at 33³ and 24.928453 at 65³; query_us_field 4.766243 µs, 4.20× inside the budget |
| C2 a fixed iteration count with no data-dependent branching gives bit-identical contact points across the M5 and the Zen 3, on 10⁶ queries | 0 differing contacts | HELD — contacts_bit_identical true, differing_contacts 0 of 1,000,000, differing_blocks 0 of 64, c2_blocker none. BLOCKED until the peer arm landed |
C3a ghost contacts are non-zero on the TriMesh path over M-106's 495-crossing fixture |
> 0 | HELD — c3_trimesh_holds true, ghost_contacts_trimesh 93,298 of 196,601 contacts |
| C3b ghost contacts are exactly zero on the field path, "because there are no internal edges" | exactly 0 | VACUOUS — ghost_contacts_field = VACUOUS, c3_field_verdict = VACUOUS-field-query-has-no-internal-edges. No instrument exists; three honest ones read 1,600 / 373 / 14,090 |
Three cells in this file read as failures and are not. (1)
c3_holds=VACUOUS, notfalse— the clause has two halves and only one of them is scoreable, so the whole-clause cell carries the weaker of the two andc3_trimesh_holds=truecarries the half that was measured. (2)differing_is_bound=falsemeansdiffering_contacts= 0 is exact rather than an upper bound; a 64-bit digest localises a disagreement only to its 15,625-query block, so a non-zero count would have been recorded asdiffering_blocks × 15,625with this flagtrue. False here is the good outcome. (3) The 65³ row writesNAinc2_holds,c3_holdsand every C2/C3 column: 65³ is an unregistered corroboration arm for C1 only, andNAis there rather than the 33³ arm's values on purpose —M-377'sspreadcolumn is the entry that earned that rule.
The SHARE recomputation, out loud, and it falsifies a registered premise
The registration ends "SHARE: C1 moves the query half of the collider's 45%, and P-85 will have
measured how large that half is." P-85 has run, and its answer is that there is no query half.
docs/experiments/p-85.csv, the fbm_terrain / 33 row, at 5c55f12:
| stage | ms | share of the collider stage | what it is |
|---|---|---|---|
handoff |
3.917282 | 0.816017 | weld + collider::readiness — construction |
bvh |
0.858567 | 0.178850 | Bvh::from_iter, binned — construction |
construct |
0.022090 | 0.004602 | TriMesh::new minus the BVH — construction |
copy |
0.002400 | 0.000500 | positions + triangle_indices — construction |
residual |
0.000150 | 0.000031 | everything the four stages did not name |
total |
4.800489 |
The four stages sum to 3.917282 + 0.858567 + 0.022090 + 0.002400 = 4.800339, and
4.800489 − 4.800339 = 0.000150, which is residual_ms to the digit — the decomposition closes. Every
one of the four is construction, so the largest slice of that 45% that could be a query is bounded by
the residual: s ≤ 0.000150 / 4.800489 = 3.1247e-5.
Amdahl, on the committed file:
collider stage : ceiling 1 / (1 - s) = 1.0000312x
whole pipeline : s' = 0.45 * s = 1.4061e-5 = 1.0000141x
So C1's SHARE line is falsified as a premise — not by this harness, but by P-85 before this
harness existed. M-135's 45% is collider::readiness, a build-time validity walk over a MeshBuffer
paid once per chunk when the chunk is meshed; a character controller's per-frame collision query is not
inside it at all. An infinitely fast field query removes at most 0.0031% of the collider stage and
0.0014% of the pipeline.
What arithmetic could and could not reach before the run. It reached the premise and killed it, which
is ✗51's rule doing its job. It could reach none of the three clauses. C1 is a ratio between two
independently measured per-query costs, not a share of a fixed total, so it is unbounded above and the
3× bar has no arithmetic ceiling; its 20 µs half is an absolute that a per-query measurement answers
directly. C2 is a bit-equality over 10⁶ records and C3 is a count, and neither is denominated in any
total. So the experiment was still worth running, and the bench's doc comment says all of this before
the run rather than after.
Therefore, what a HELD means. C1's 8.067× is real and it is real about a different quantity from the one the registration named: the per-frame collision budget of a moving body, which no row in this repository had ever measured. It must not be quoted as moving the collider's 45%. Anyone who wants to spend this speedup needs that per-frame budget measured first; that measurement does not exist, and it is the missing prerequisite for deciding whether to land the method.
C1, and the ✗24 problem it has
| arm | triangles | query_us_field |
query_us_trimesh |
speedup |
cycles_per_query_field |
cycles_per_query_trimesh |
cycles_speedup |
ghz |
|---|---|---|---|---|---|---|---|---|
c1_33 |
3,944 | 4.766243 | 38.449486 | 8.067043 | 20,089.6 | 160,999.4 | 8.014073 | 4.1821 |
c1_65 |
16,882 | 4.759963 | 118.658518 | 24.928453 | 20,403.3 | 498,465.6 | 24.430595 | 4.1763 |
speedup is taken inside one repeat of one binary (M-281), from the repeat whose speedup is the
median of nine interleaved ones, so the row's three numbers reproduce from each other. The
clock-independent cycles_speedup agrees to 0.66% at 33³ and 2.0% at 65³, so the verdict does not
depend on the governor.
✗24 still applies to the 20 µs half, and the file carries its remedy. A microsecond is a property
of the binary and of the clock (M-281, M-280), and 4.766243 µs is a wall-clock absolute. The
run-independent restatement available in the row is the cycle count: 20,089.6 cycles per query, so
the 20 µs budget is met on any clock above 20,089.6 / 20 µs = 1.0045 GHz. M-280 measured this
machine's amd-pstate-epp powersave range as 1.96–5.62 GHz, so the bar clears at every clock the
machine can reach, and that is the statement that survives a re-run. The 3× half has no such integer in
this file, and a successor should register one — parry's per-query triangle-candidate count against the
field arm's fixed 22 evaluations — because a wall-clock ratio is not a gate.
Two controls the ratio needs beside it. contact_share_field 0.433500 and contact_share_trimesh
0.391900 are both asserted above 0.05, so the ratio is not two arms cheaply agreeing that nothing
touches; and endpoint_minimisers 0.698150 is asserted below 0.90, so 30% of the poses gave the 1-D
optimisation an interior answer to find rather than a monotone slide to the bottom endpoint. An
upright capsule over a heightfield is degenerate in exactly that way, which is why the poses are tilted.
And the honesty column. contact_disagreements is 2,536 of 20,000 poses (12.68%) at 33³ and
1,848 (9.24%) at 65³: the two arms disagree about whether a contact exists at all. fbm_terrain is
y − h(x, z), so the field arm's d = φ / |∇φ| is a first-order Euclidean rectification and the
minimiser of φ is not exactly the minimiser of φ / |∇φ|. The field query is fast, not exact.
Anyone quoting the 8.067× quotes the 12.68% with it.
The mechanism, in the peer numbers rather than in a ratio
The field arm is O(1) in triangle count by construction — 20 GSS iterations plus two bracket
evaluations plus one gradient call, whatever the chunk contains — and parry's arm is a BVH descent
whose cost grows with the geometry. Between the two C1 arms the mesh carries 16,882 / 3,944 = 4.2804×
more triangles, and:
| machine | field 33³ → 65³ | parry 33³ → 65³ | speedup 33³ |
speedup 65³ |
|---|---|---|---|---|
| Zen 3, µs (committed row) | 4.766243 → 4.759963, −0.13% | 38.449486 → 118.658518, 3.0861× | 8.067043 | 24.928453 |
| Zen 3, cycles (committed row) | 20,089.6 → 20,403.3, +1.56% | 160,999.4 → 498,465.6, 3.0961× | 8.014073 | 24.430595 |
Apple M5, µs (p-81-m5-digests.txt) |
2.949046 → 2.967071, +0.61% | 20.736844 → 64.057673, 3.0891× | 7.031713 | 21.589533 |
Three independent readings of parry's sensitivity — 3.0861, 3.0961, 3.0891 — against a field arm that
moves by at most 1.56% and on one reading moves the wrong way. Same shape on both ISAs. That is
why C1's ratio grows with resolution instead of being a fixture constant, and it is Macklin et al.'s
mechanism (10.1145/3384538) at CPU scale: the registration's discount of their GPU 30× to
"single-digit x" was correct at 33³ and conservative at 65³.
The M5 figures are the peer run's, not the committed row's, and are not comparable to it in absolute
microseconds — perf_event_open has no macOS equivalent, so that row has no clock at all. Only the
ratios cross the machine boundary.
C2, and the stub that was refused rather than committed
contacts_bit_identical true, differing_contacts 0 of 1,000,000, differing_blocks 0 of
64 (c2_block 15,625, and 64 × 15,625 = 1,000,000 exactly), c2_blocker none. A record is
(contact point x, y, z, depth) as four raw f32 bit patterns folded FNV-1a-64 over explicit
little-endian bytes, so the digest does not inherit the host's byte order.
local_digest = local_repeat_digest = 0x2be626c099a75222 over two independent passes in one process
(locally_self_consistent true — the floor the cross-machine clause stands on), the branchy control
digest is 0x4067d5c9b10dcc68, and the M5 reproduced both whole-run values.
c2_contacts 453,404 of 10⁶, so the digest is not a digest of rejections.
branch_misses_per_query_field 1.8344 against branch_misses_per_query_branchy 4.4675 — a
2.44× reduction, which makes "no data-dependent branching" a number rather than an adjective.
The stub, and this is the part that is not in the CSV. PEER_BLOCK_DIGESTS briefly existed in the
harness as a 64-entry table of zeros. Left there, contacts_bit_identical would have compared a real
run against nothing and reported true: a fabricated bit-identical result, which is ✗35's failure and
P-70's C3 in one costume. It was deleted and replaced by Option<[u64; C2_BLOCKS]> = None, with the
None arm wired to a BLOCKED verdict and a c2_blocker column naming what was missing. The
intermediate peer CSV then wrote, on disk, contacts_bit_identical=BLOCKED /
c2_blocker=no-peer-digest-table-committed — and only after that were the real M5 digests pasted in.
No placeholder ever reached an artefact, and the BLOCKED row is the evidence rather than the claim.
So C2 was genuinely BLOCKED until the peer arm landed, and it is HELD only because a second machine
actually ran.
The peer arm is a machine, not a model of one. MacBook Air, Apple M5, aarch64-apple-darwin, rustc
1.96.1 (31fca3adb), macOS 26.5.2. The bench source md5 b648e531c0a1ab0964009b020a82ed50 was checked
equal on both machines immediately before the peer build, and the bench was built and run unmodified
— counted already carries a cfg(not(target_os = "linux")) arm and the common::counters import is
cfg-gated, so no macOS patch was needed and none was applied. The cheap cross-check came out right:
the peer printed evals=22000000, exactly 10⁶ × (GSS_ITERATIONS + 2) = 10⁶ × 22, which is the bench's
own assertion and proves the two machines walked the same pose stream and spent the same fixed number of
field samples per query. Without it the digest comparison would be void. The comparison then closes from
four directions: identical whole-run and branchy digests; the Zen 3 reading the table at 0 of 64; the M5
reading the same table at c2 true (0 blocks differ); and all 64 block digests diffed clean from an
independent scratch tree outside the repository, x86-64 against aarch64, block for block rather than only
via the fold.
parry is not bit-portable and the field arm is. internal_edge_contacts reads 172,316 on the Zen
3 (committed row) and 172,315 on the M5: exactly one contact differs. That column is incremented
from classify(&window, index, c.point2, c.normal2) where c comes from
parry3d::query::contact(capsule, triangle), so it is a pure function of parry's witness point and
of nothing in the GSS path — one contact's minimum barycentric coordinate crossed FEATURE_TOL = 1e-3 on
one machine and not the other. So parry 0.30's capsule-vs-triangle narrowphase, which is glam SIMD and
reassociation-sensitive, is not bit-portable across x86-64 and aarch64, while the field arm compared
against it in the same binary on the same two machines is bit-identical over 10⁶ queries. Three
cautions, all load-bearing: it is one contact, so it is evidence of non-portability and not a rate —
no percentage may be put on it; it is not in the digest, so it cannot be read as weakening C2; and it
sets the precision of the C3 cross-machine comparison at ≈ 6e-6. It also answers C2's registered
falsifier from both sides in one fixture — "one differing contact, which puts the method behind the same
wall as every other float-sensitive path" — the wall is real, the TriMesh arm is behind it, the field
arm is not.
C3, whose two halves are different verdicts
A contact is a ghost contact iff all three of: the witness point lies on an edge or vertex of the
triangle (min barycentric ≤ FEATURE_TOL 1e-3); every edge so implicated is internal, shared by
exactly two triangles of the window mesh; and the contact normal lies outside the cone spanned by the
faces meeting at that feature, a − d > 5° where d is the dihedral and a the smallest angle to any
incident face. The fixture is M-106's game_capsule_walk path over streamed fbm_terrain, driven to
seam_crossings 495 (asserted equal), 24,666 steps, 496 windows, as a kinematic sweep rather than
a controller — because a controller's trajectory diverges between the two arms by construction and a
comparison of two collision methods needs both asked the same question.
| column | value | of |
|---|---|---|
contacts_trimesh |
196,601 | contacts over the walk |
edge_witness_contacts |
172,316 | condition 1 — 87.65% of the contacts had a feature witness |
internal_edge_contacts |
172,316 | conditions 1 and 2 — identical, see below |
ghost_contacts_trimesh |
93,298 | the cone test removed 79,018, i.e. 45.86% of the feature population |
ghost_contacts_trimesh_rawdev |
154,941 | the naive "> 5° from every incident face" reading, kept in the file |
ghost_contacts_trimesh_15deg |
68,599 | a 15° excess bar |
ghost_contacts_trimesh_jolt |
33,357 | additionally requiring dihedral ≤ 5°, Jolt's default mActiveEdgeCosThresholdAngle |
ghost_poses_trimesh |
18,948 | 76.82% of the 24,666 steps |
mesh_ghost_excess_max_deg |
114.4951 | worst excess over the local dihedral |
The TriMesh half HELD, and the number has a consequence. 93,298 ghost contacts over one 495-crossing
walk, of which Jolt's default 5° inactive-edge rule reaches only 33,357 — 59,941 sit on active edges
that the cheap default does not touch and would need mEnhancedInternalEdgeRemoval / avian#612. The
registered falsifier for C3 was "zero on both, which would mean avian3d already handles it". It is
93,298, not zero: avian3d does not already handle it, and the problem is this crate's.
The field half is VACUOUS, and this is the interesting one. The registered class is "collisions
against internal edges between adjacent triangles" and the registration's own reason for predicting zero
is "because there are no internal edges". That is a definitional emptiness, not a measurement: the
field query returns ∇φ at a point on the isosurface, and there is no code path by which an edge could
enter it. Three instruments were built to give the clause teeth and all three failed the same way — each
has to import the mesh as its scoring reference, and then measures the mesh's discretisation error
rather than anything the field did:
| column | rule | reading |
|---|---|---|
ghost_contacts_field_projected_rawdev |
project the field's contact onto the mesh; normal > 5° from every incident face | 1,600 |
ghost_contacts_field_projected |
the same, as an excess over the local dihedral | 373 |
ghost_contacts_field_at_mesh_witness |
evaluate ∇φ at the mesh arm's own ghost witness point and apply the identical cone test |
14,090 |
37.8× apart, over one population, from one field. mean_dihedral_deg is 16.7770, so a smooth normal
sitting exactly between two Marching Cubes facets is 8.4° from both — the most correct normal available,
and it trips a naive 5° bar. A quantity whose three honest measurements disagree by that much is not
being measured. Note especially that the tightest of the three, the paired test at the mesh arm's own
witness point, came back at 14,090 and not at zero, with field_ghost_excess_max_deg 95.3055: the
field half was not quietly awarded a pass, it was found to have no instrument. Hence
ghost_contacts_field = VACUOUS with c3_field_verdict naming the reason, all three surrogates kept
in the file as the evidence, and c3_trimesh_holds = true carrying the half that is real. VACUOUS
here, never HELD.
What a successor should register instead. The intrinsic difference between an edge-derived normal and
a surface normal is not their angle to any facet — it is their stability. An edge normal is a
function of where the body is, so it swings tens of degrees when the body moves a millimetre; a surface
normal moves with the surface's curvature. Degrees of normal change per centimetre of body travel is
reference-free, applies identically to both arms, and is the gameplay symptom itself. It is a different
question from the one P-81 registered, so it belongs to a new id rather than to a quiet substitution
here.
The vacuity control
Registered: "the TriMesh arm must report a non-zero ghost-contact count, or C3 cannot fire."
Column ghost_contacts_trimesh, value 93,298, asserted live in main() as
assert!(c3.ghost_trimesh > 0).
That assertion alone is weaker than it looks, and the file says why. c3_trimesh_holds is literally
ghost_trimesh > 0 — the same predicate as the vacuity control — so passing the control and holding
C3's TriMesh half are one measurement, not two. What proves the fixture could have failed is the
sub-populations, each of which the fixture could independently have missed:
- The witness points had to land on features.
edge_witness_contacts172,316 of 196,601 contacts. A capsule that only ever met triangle interiors gives zero here and the count is unreachable. - Those features had to be internal.
internal_edges6,660,389 againstboundary_edges140,682 — a boundary share of 2.07%. Edges are keyed by the raw bits of the two endpoint positions rather than by index; index-keyed edges would have made every chunk-seam edge read as a boundary, condition 2 unsatisfiable there, and the count a guaranteed zero for the wrong reason.M-69's duplicate vertices are bit-identical, which is what makes position keying sound. On this fixture condition 2 removed nothing —internal_edge_contactsequalsedge_witness_contactsat 172,316, and sinceclassifysetsinternal = on_edge && internal, that equality says every feature witness in 24,666 steps sat on an edge shared by exactly two triangles. That is what an oversized window is supposed to produce, and it is precisely why the control for condition 2 has to be theinternal_edges/boundary_edgespair rather than the contact count: the contact count cannot distinguish "condition 2 was satisfiable and always satisfied" from "condition 2 was never tested". - The normals had to leave the cone. The cone test removed 79,018 of 172,316 (45.86%), so it is discriminating rather than a pass-through, and the survivors go up to 114.4951° of excess.
- The winding had to be right.
outward_share0.999981, asserted above 0.99 — a sign-flipped winding inverts every dihedral and every deviation in the harness. nonmanifold_edges11 are excluded bycount != 2, so they can only reduce the count.
Five orders of magnitude of margin, and the M5 reproduced 93,298 / 196,601 / 154,941 / 6,660,389 / 140,682 / 495 exactly, so the control is not an artefact of one ISA's rounding.
The clean-tree re-run: what moved
Both prior reports were written from a dirty pre-run (63c7161 (WORKING TREE DIRTY),
2026-08-28T00:07:43Z) taken while roughly twenty-five sibling agents were compiling. Every number above
is re-read from d0c3218. Every integer reproduced exactly — 93,298 / 196,601 / 172,316 / 154,941 /
68,599 / 33,357 / 18,948 / 6,660,389 / 140,682 / 495 / 24,666 / 496 / 3,944 / 16,882 / 11 / 1,675 /
14,090 / 373 / 1,600 / 453,404, both digests, 0 of 64 blocks and 0 of 10⁶ contacts — which is M-279's
rule satisfied. Only clocks moved, and two of them moved enough to matter:
| quantity | dirty run | clean run |
|---|---|---|
speedup 33³ |
7.989133 | 8.067043 (+0.98%) |
speedup 65³ |
24.985669 | 24.928453 (−0.23%) |
speedup_min 33³ |
6.341401 | 7.990273 (+26.0%) |
speedup_max 33³ |
8.442864 | 8.077843 (−4.3%) |
query_us_field 33³ |
4.876392 | 4.766243 (−2.26%) |
query_us_trimesh 33³ |
38.958143 | 38.449486 (−1.31%) |
query_us_field 65³ |
4.991012 | 4.759963 (−4.63%) |
query_us_trimesh 65³ |
124.703765 | 118.658518 (−4.85%) |
cycles_speedup 33³ |
7.903110 | 8.014073 (+1.40%) |
cycles_speedup 65³ |
23.543932 | 24.430595 (+3.77%) |
branch_misses_per_query_field |
1.9740 | 1.8344 |
branch_misses_per_query_branchy |
4.5873 | 4.4675 |
| branch-miss reduction | 2.32× | 2.44× |
P-85 handoff_share |
0.812955 | 0.816017 |
P-85 construct_share |
0.007298 | 0.004602 |
P-85 total_ms |
4.797392 | 4.800489 |
P-85 residual_ms |
0.000150 | 0.000150 (unchanged) |
Two briefed conclusions are withdrawn, and both were true only of the superseded run.
- Withdrawn: "4.28× the triangles costs the field arm +2.4% (4.876 → 4.991 µs)." On the clean tree the same pair reads 4.766243 → 4.759963, which is −0.13% — the sign flipped. Replaced by: the comparison is made within one row-pair of one binary and stated three ways at once — cycles on the Zen 3 (+1.56%), microseconds on the Zen 3 (−0.13%), microseconds on the M5 (+0.61%) — against parry's 3.0861× / 3.0961× / 3.0891× over the same 4.2804× of geometry. The load-bearing fact is not the field arm's sign, it is that the field arm is O(1) in triangle count by construction while parry is not, and no reading of it exceeds 1.6% against parry's 3.09×.
- Withdrawn: "speedup_min 6.341401, so the bar clears on the worst repeat." True of both runs as a
verdict, but 6.34 is a number the committed file does not contain, and quoting it would be
✗35's defect. Replaced by: the clean row'sspeedup_min7.990273 /speedup_max8.077843 — a 1.1% spread against the dirty run's 6.34–8.44, which is a 33% spread on the identical binary. The worst-repeat statistic moved 26% between the two runs and the integers moved not at all: that pair is itself the argument for✗24, and it is why the durable form of C1's 20 µs half is the 1.0045 GHz clock threshold and not the microsecond.
Two further numbers from the prior reports appear in no committed file and are not quoted here: an
M5 speedup pair of "7.036× / 21.769×" (the committed peer artefact reads 7.031713 and 21.589533,
from a later peer revision), and the dirty run's cycles_per_query_* of 20,418.8 / 161,372.0 at
ghz 4.1819. The committed row's are 20,089.6 / 160,999.4 at 4.1821.
Note also that docs/experiments/p-81-m5-digests.txt itself quotes the dirty committed row (7.989× and
4.876 µs, provenance 2026-08-28T00:07:43Z) when it reports its independent scratch-tree reproduction of
8.032× / 4.785 µs. That reproduction is unaffected — it was a separate tree, separate target/,
separate process with both arms inside one build — and against the clean row's 8.067043 it is
0.43% apart rather than the 0.54% the artefact states. The digest table below that prose is
unaffected in every respect.
The fixture defects the harness's own controls caught
- A 64-entry zero
PEER_BLOCK_DIGESTSplaceholder. It would have scoredcontacts_bit_identicaltrue against nothing. Replaced byOption<[u64; 64]>, withNonescored BLOCKED and ac2_blockercolumn naming the gap; the intermediate peer CSV wrotecontacts_bit_identical=BLOCKED / c2_blocker=no-peer-digest-table-committedon disk before any real digest existed.✗35's failure mode refused rather than committed. - A fabricated zero on the non-Linux row.
countedreturnsNoneoff Linux, and the CSV was writingghz=0.0000andcycles_per_query_*=0.0— against the bench's own doc comment promising "unavailablerather than invented", and exactly the cellP-64is remembered for. Found by the peer run. Six columns now write the literalunavailable:ghz,cycles_per_query_field,cycles_per_query_trimesh,cycles_speedup,branch_misses_per_query_fieldandbranch_misses_per_query_branchy. - Condition 3 was a raw angular deviation and counted two different things on the two arms. On the
mesh arm it finds edge-derived normals; on the field arm it finds Marching Cubes faceting, because
mean_dihedral_deg16.7770 puts a correct smooth normal 8.4° from both facets. Replaced by the excess-over-dihedral form, which is immune by construction and applies identically to both arms;ghost_contacts_trimesh_rawdev154,941 keeps the naive reading in the file so the difference is visible rather than argued. - The field arm's first scoring projected its own contact point onto the mesh.
field_projection_dist_max0.285152 — 0.57 of a cell — is the measurement that the count was dominated by the displacement rather than by the field, since over half a cell onfbm_terrainthe true normal rotates by more than a facet cone is wide. Replaced by the paired test at the mesh arm's own witness point, which came back worse (14,090 against 373) and is what forced the VACUOUS verdict rather than a flattering one. - Upright capsule poses would have made C1's search a comparison. With
xandzfixed over a heightfield,φis monotone inyand the minimiser is always the bottom endpoint. Orientations are sampled over the sphere andendpoint_minimisers0.698150 is asserted below 0.90. - Index-keyed edges would have made C3's
TriMeshcount a guaranteed zero. Every chunk-seam edge would have read as a boundary and condition 2 would have been unsatisfiable there. Keyed by raw endpoint bits instead;internal_edges6,660,389 againstboundary_edges140,682 is the control. internal_edge_contactsdiffering by one across machines — turned from a wart into the parry non-portability result above, once it was traced to parry's witness point rather than to the GSS path.- The unregistered 65³ arm writes
NAin the C2 and C3 columns rather than repeating the 33³ arm's values, which isM-377'sspreaddefect avoided by construction.
What changed as a result
- Do not spend C1 expecting to move the 45%.
P-85measures that 45% as construction to within 3.12e-5, so the Amdahl ceiling from any query-side change is 1.0000312× on the collider stage and 1.0000141× on the pipeline. The 8.067× is real about the per-frame collision budget of a moving body, which is a different and previously unmeasured quantity. Measuring it is the prerequisite for deciding whether to land this, and that measurement does not exist. - The determinism result is the landable one, and it is independent of the speed one. A fixed-trip,
branchless-select GSS over a field whose arithmetic is only
+ − × ÷ floor, with nomul_addanywhere in the query path, gives bit-identical contact points across Zen 3 and Apple M5 over 10⁶ queries and 4 × 10⁶ foldedf32s, at a 2.44× branch-miss reduction against the branchy form. Nothing else float-sensitive in this crate has that property, and the same fixture shows parry does not. - If a mesh collider ships, internal-edge removal is not optional. 93,298 ghost contacts over one 495-crossing walk, 59,941 of them on active edges that Jolt's default 5° threshold does not reach.
- The docs' citation is wrong for this case. Liu et al.
10.1016/j.cagd.2024.102305is SDF-vs-SDF for two comparable solids, a strictly harder problem needing interval arithmetic and therefore a determinism liability. Macklin, Erleben, Mueller, Chentanez, Jeschke and Corse10.1145/3384538is the paper for a small analytic proxy against one enormous static field, with GSS winning on the 1-D edge problem — which is this fixture, because a capsule is an edge with a radius. - A successor id is owed for C3's field half, registered on normal stability per centimetre of body
travel rather than on angle to a facet; and
gss_min_branchyis an E-variant built and kept, owing a Part 4b row — it answers no clause and exists only so that "no data-dependent branching" is a measured branch-miss difference rather than an adjective.
Would be shown wrong by: a per-frame collision-budget measurement showing the query is a negligible
share of a moving body's frame, which would make C1's 8.067× as unspendable as the 45% already is; a
third machine, a different parry3d version or a different rustc producing one differing block out of
64, which falsifies C2 by its own registered bar; a fixture on which parry's per-query cost is flat
in triangle count, which would mean the 8.07 → 24.93 growth is fbm_terrain's BVH shape rather than the
mechanism; or a reference-free instrument for the field arm's ghost class — one that does not import the
mesh as its scoring reference — reading non-zero, which would convert C3's field half from VACUOUS to
FALSIFIED.
💥 ✗62 / M-394 — C1 FALSIFIED by its own falsifier: the capture window is 2R + t, not t, so game_dig's 2-cell body radius makes 2R 4.0 cells against a fastest per-frame step of 2.4588 cells — 0 tunnels over 500,000 shots on all 25 scored thickness×speed combinations, and thinning the wall from 2 cells to a twentieth of a cell changes the zero not at all; C2 HELD at 1.5644 µs/element tested against a 25 µs bar; C3 HELD as registered at 0.1629 cells and FALSIFIED on a convex rim above aspect 8.0, where the registered fixture is support-exact and cannot tell the two apart (P-82, R-082)
M. cargo bench --bench experiment_p82, docs/experiments/p-82.csv, 800 rows, 65 columns,
scalar f64, Zen 3 (amd-ryzen-9-5900x-12-core), CPU-only. Three arms: c1_tunnelling (448 rows —
2 fields × 4 element radii × 7 speeds × 8 wall thicknesses, 10⁴ randomised shots each, 4,480,000
shots), c2_scaling (64 rows — 4 solver budgets × interval-shrink on/off × 8 element counts) and
c3_proxy (288 rows — 3 fixtures × 6 capsule half-heights × 16 orientations). The fixture is
game_dig's own geometry restated as constants with its source lines named: CELL_SIZE = 0.125
(cell_size column), the demo's fixed 16 ms frame (frame_seconds = 0.016000), BODY_RADIUS = 0.25
= 2 cells, and a wall swept from the registered 2 cells down to M-95's 0.05-cell subgrid floor.
Committed at e740138, no (WORKING TREE DIRTY) on the provenance line, and an ancestor of
HEAD (782188c).
| clause | registered | measured |
|---|---|---|
C1 the discrete path tunnels a wall of thickness t < v·Δt at a game_dig speed and the CCD path does not |
tunnels > 0 discrete, 0 CCD, over 10⁴ shots per row | FALSIFIED — 0 of 500,000 discrete tunnels on the 50 scored rows, and 0 of 4,480,000 CCD tunnels anywhere in the sweep. The falsifier's own words: "the game's speeds are below the threshold and this is premature" |
| C2 cost per moving element under 25 µs and linear in element count | < 25 µs, linear | HELD — worst 1.564418 µs/element tested at 1,600 elements (16.0× under the bar), marginal 0.424731 µs/element, linear_fit_r2 0.995687 |
| C3 an 8-swept-sphere capsule reaches the same first ToI as a 200-triangle capsule mesh, within one cell, at 10× less cost | ≤ 1.0 cell, ≥ 10× | HELD as registered — 0.162891 cells worst over the 32 scored wall rows, cost ratio 56.05× / 95.43× median / 144.94×. FALSIFIED on a convex rim above h = 7r (aspect 8.0): 17 of 96 rim rows are a proxy miss of a contact the exact reference confirms, 3 of them with a disagreement floor over the one-cell bar |
c1_holdsreadsfalseon all 800 rows including the 352c2_scalingandc3_proxyrows, andc3_holdsreadstrueon all 800 including the 17 rim rows where the proxy missed a real contact. Both are the run's aggregate verdicts stamped on every row, not per-row measurements. C1 is measured only on the 448c1_tunnellingrows; C3's registered scoring population is the 32 wall rows atgame_dig's own capsule, and the rim arm is reported, not scored — which is why atruesits besideproxy_missed_impact = true. Read the rim verdict fromproxy_missed_impactandtoi_disagreement_floor_cells, never fromc3_holds.
toi_disagreement_cellsis empty on 21 of the 288 C3 rows, and empty is not zero. Those are the 17 rows where the bead proxy reported no impact inside the step and the 4 where the triangle mesh did (proxy_missed_impact/mesh_missed_impact; the two sets are disjoint, 17 + 4 = 21). A difference of two ToIs does not exist when one arm has no ToI, so the disagreement is carried instead bytoi_disagreement_floor_cellson exactly those 21 rows — the travel still remaining after the other arm's contact, which is a lower bound on the disagreement. Everymax_disagreementquoted below for the rim is therefore a maximum over the rows that returned two ToIs, and the misses are quantified by the floor column beside it.
C1: the registration wrote a point particle's threshold
The mechanism was derived before the harness existed, and it is one inequality. The registration
says the discrete path tunnels a wall of thickness t below v·Δt. That is the threshold for a
point. A sphere of radius R is caught by an end-of-frame probe whenever either frame position
lands in the overlap window, and that window is 2R + t wide, so the discrete path tunnels only when
v·Δt > 2R + t.
The CSV carries the window as discrete_threshold_cells, and it equals 2R + t exactly on all 448
c1_tunnelling rows. game_dig's BODY_RADIUS = 0.25 is 2 cells, so 2R = 4.0 cells before the
wall exists at all, while the fastest thing the demo can produce — sprint 9.0 u/s composed with a
full-sandbox-height fall, sqrt(9² + 2·18·8) = 19.209373 u/s — moves 19.209373 × 0.016 / 0.125 =
2.4588 cells per frame (speed_units_per_second 19.209373, speed_cells_per_step 2.458800).
4.0 / 2.4588 = 1.627×: the body's diameter is 1.63 times a whole frame of travel at the very
fastest the game can move, so there is no sub-frame phase in which both frames sit outside the wall.
The wall's thickness is the smaller term. At R = 2 cells the window runs from 6.00 cells at
t = 2 down to 4.05 cells at t = 0.05 — a 97.5% reduction in the wall changes the window by
1.2%. That is why the zero does not move:
t (cells) |
window 2R + t |
step 0.32 | step 1.152 | step 2.1722 | step 2.4588 |
|---|---|---|---|---|---|
| 2.000 | 6.000 | 0 | 0 | 0 | 0 |
| 1.500 | 5.500 | 0 | 0 | 0 | 0 |
| 1.000 | 5.000 | 0 | 0 | 0 | 0 |
| 0.750 | 4.750 | 0 | 0 | 0 | 0 |
| 0.500 | 4.500 | 0 | 0 | 0 | 0 |
| 0.250 | 4.250 | 0 | 0 | 0 | 0 |
| 0.125 | 4.125 | 0 | 0 | 0 | 0 |
| 0.050 | 4.050 | 0 | 0 | 0 | 0 |
(tunnels_discrete, summed over the slab and dug fields at body_radius_cells = 2.000000,
10⁴ shots per field per cell of the table. The 25 combinations where t < v·Δt as the
registration specifies — 3 at the walk step, 6 at sprint, 8 and 8 at the two fall speeds — are 50
rows and 500,000 shots, and every one of them reads 0.)
The threshold by speed, at game_dig's own body radius. Each row is 8 thicknesses × 2 fields ×
10⁴ shots:
speed_name |
u/s | speed_cells_per_step |
tunnels_discrete |
|---|---|---|---|
walk |
2.500000 | 0.320000 | 0 of 160,000 |
sprint |
9.000000 | 1.152000 | 0 of 160,000 |
fall_full_height |
16.970563 | 2.172232 | 0 of 160,000 |
sprint_plus_fall |
19.209373 | 2.458800 | 0 of 160,000 |
projectile_40 |
40.000000 | 5.120000 | 2,331 of 160,000 |
projectile_80 |
80.000000 | 10.240000 | 43,090 of 160,000 |
projectile_160 |
160.000000 | 20.480000 | 101,061 of 160,000 |
The threshold by radius — slab, t = 0.05 cells, the fastest game_dig speed, one row each:
body_radius_cells |
discrete_threshold_cells |
step | tunnels_discrete |
|---|---|---|---|
| 0.00 (the registration's implicit point) | 0.050 | 2.4588 | 9,743 of 10,000 |
| 0.25 | 0.550 | 2.4588 | 7,352 of 10,000 |
| 1.00 | 2.050 | 2.4588 | 500 of 10,000 |
2.00 (game_dig's own) |
4.050 | 2.4588 | 0 of 10,000 |
The step overtakes the first three windows and not the fourth, exactly. The failure C1 registered
needs a small fast thing, not a thin wall — and game_dig has no projectile: it edits the field
through a ray-cast aim, and its only moving body is the player.
The closed form agrees with the instrument on every slab row. Over the 224 slab rows,
sign(tunnels_discrete > 0) matches speed_cells_per_step > discrete_threshold_cells on 224 of
224. On the 224 dug rows it matches on 213, and all 11 disagreements are in the same
direction — the step marginally exceeds 2R + t and no tunnel occurs:
| field | t |
speed | R |
step | 2R + t |
tunnels |
|---|---|---|---|---|---|---|
dug |
0.125 | fall_full_height |
1.0 | 2.172232 | 2.125 | 0 |
dug |
0.050 | fall_full_height |
1.0 | 2.172232 | 2.050 | 0 |
dug |
0.250 | sprint_plus_fall |
1.0 | 2.458800 | 2.250 | 0 |
dug |
0.125 | sprint_plus_fall |
1.0 | 2.458800 | 2.125 | 0 |
dug |
0.050 | sprint_plus_fall |
1.0 | 2.458800 | 2.050 | 0 |
dug |
1.000 | projectile_40 |
2.0 | 5.120000 | 5.000 | 0 |
dug |
0.750 | projectile_40 |
2.0 | 5.120000 | 4.750 | 0 |
dug |
0.500 | projectile_40 |
2.0 | 5.120000 | 4.500 | 0 |
dug |
0.250 | projectile_40 |
2.0 | 5.120000 | 4.250 | 0 |
dug |
0.125 | projectile_40 |
2.0 | 5.120000 | 4.125 | 0 |
dug |
0.050 | projectile_40 |
2.0 | 5.120000 | 4.050 | 0 |
All eleven are the safe direction, and the reason is geometric. The dug field is game_dig's
own 0.5-unit wall with a default-radius spherical brush subtracted from behind, so the residual
thickness is exactly t on the axis only; the pocket is a sphere, and over the half-cell lateral
spread the shots are drawn from, the residual grows off-axis by up to 0.063 cells. A dug wall is
therefore strictly harder to tunnel than the slab formula predicts, and the formula errs conservative
on the geometry the game actually has.
The vacuity control, and why its zero could have been a number
VACUITY CONTROL: the discrete arm must tunnel at least once, reported as a count, or C1 is comparing two methods that both work.
Column: tunnels_discrete per row, tunnels_discrete_total on every row. Value: 1,447,505 discrete
tunnels over 4,480,000 shots, asserted > 0 after the sweep. The scored population returns
0/500,000 — and the same harness, the same two fields, the same shot generator and the same discrete
predicate return 9,743 of 10,000 at radius 0 and 101,061 of 160,000 at game_dig's own 2-cell
radius once the speed reaches 160 u/s. The instrument demonstrably reports tunnels when tunnels
exist, so the scored zero is a property of the body, not of the fixture. That is M-44's rule
satisfied by a population three orders of magnitude wide rather than by an argument.
Two further controls make the counts mean what they say, both asserted:
shots_crossing_solid == shotson all 448 rows (4,480,000 of 4,480,000). Every shot's centre path is sampled at the wall's mid-plane and must readf < 0, so a counted tunnel can never be a shot that missed the wall —M-44's zero wearing a one's clothes.prediction_mismatches = 0on all 448 rows. For an exact slab the discrete predicate is closed-form (|x| − t/2 < R); the harness computes it from the geometry and compares it to what sampling the field actually said. Non-vacuous:tunnels_discrete_predictedspans 0 to 9,975 across the 224 slab rows, so the predicate takes both values and the comparison discriminates. A harness that asserts its arithmetic against itself has asserted nothing; this asserts the arithmetic against the instrument.ccd_toi_error_cells = 0.000000overccd_toi_checks = 2,240,000comparisons, min 10,000 and max 10,000 per slab row. The check-count column exists because a zero error over zero comparisons isM-44's vacuous zero, and it was added after a clean run in which the all-zeros column had no population behind it.sphere_bnb_nodes_high_waterpeaks at 1,869 of an asserted 4,096-node cap, so the solver is bounded rather than allowed to turn a stall into a silent "no collision".
SHARE, recomputed
The registration's SHARE line is "C2 moves a single dynamic body's collision budget, not the whole frame."
- C2's 25 µs is absolute, not a ratio, so
✗51's Amdahl obstruction cannot apply to it. What the share bounds is the element count: at the bar, a 10% slice ofgame_dig's own 16 ms frame (frame_seconds = 0.016000) buys1600 / 25 =64 elements.game_dig's shipped body is 4 spheres —4 × 25 = 100µs, 0.625% of the frame; an 8-bead capsule proxy is 200 µs, 1.25%; a 200-triangle capsule mesh is200 × 25 = 5000µs, 31.25% of the whole frame, which is not a single body's budget at all. Reachable, and loose. - C3's 10× is a ratio between two whole measurements, so its share is 1.0 and the ceiling is
1/(1 − 1/10) = 1.111— no obstruction. Element counts alone give200/8 =25× before any per-element difference, so the clause could only fail if a triangle test were 2.5× cheaper than a sphere test. Reachable. - C1 is a count, not a ratio — and arithmetic reached it before the run.
2R = 4.0cells against a maximum step of 2.4588 cells is not a share argument, it is a decision: C1 was predicted FALSIFIED before the harness was written, at every thickness in the registered sweep, and the run happened to produce the number rather than to discover the verdict. That is✗54's pattern. - What arithmetic could not reach before the run is exactly two things, and they are the two the
machine decides: C2's absolute half (25 µs is a wall clock on a governed CPU —
M-281,✗24— which is why every timed row carriesghzandcycles_per_element), and C3's cost ratio, whose 25× element-count floor is arithmetic but whose per-element factor is not. C3's accuracy half on the registered fixture was shown unfalsifiable by arithmetic in advance (see below), and the rim's failure aspecth = 7ris arithmetic too — so the only genuinely run-dependent numbers in this row are microseconds and the rim's miss counts.
C2: linear, flat, and 16× inside a bar the cited method itself would miss
fw8_gss10 (Algorithm 2 ×8, Algorithm 1 ×10), interval shrink off, triangle arm — the registered
element counts, each exactly realisable as 2 · longitudes · rings:
elements |
elements_tested |
broad_phase_cull |
total_us |
us_per_element |
cycles_per_element |
ghz |
|---|---|---|---|---|---|---|
| 8 | 8 | 0.000000 | 9.110 | 1.138750 | 5,050.75 | 4.435 |
| 16 | 16 | 0.000000 | 19.811 | 1.238187 | 5,333.25 | 4.307 |
| 40 | 27 | 0.325000 | 33.691 | 1.247815 | 5,319.70 | 4.263 |
| 100 | 47 | 0.530000 | 61.290 | 1.304043 | 5,521.28 | 4.234 |
| 200 | 94 | 0.530000 | 128.291 | 1.364798 | 5,754.67 | 4.217 |
| 400 | 144 | 0.640000 | 197.362 | 1.370569 | 5,771.10 | 4.211 |
| 888 | 250 | 0.718468 | 367.813 | 1.471252 | 6,187.78 | 4.206 |
| 1,600 | 452 | 0.717500 | 707.117 | 1.564418 | 6,535.88 | 4.178 |
marginal_us_per_element = 0.424731, linear_fit_r2 = 0.995687 over the eight counts. The sphere arm
is flatter still: marginal_us_per_element = 0.283267, linear_fit_r2 = 1.000000, and
us_per_element sits at 0.288750 at 8 elements and 0.283266 at 1,600 — a swept sphere's inner
minimisation is one field evaluation, so there is nothing for the element count to perturb.
Mechanism. An SDF collider has no pairwise broad phase — there is nothing to test against, only
a function to evaluate — so the element loop is structurally O(n), and the fit confirms rather than
discovers that. The 37% drift in us_per_element from 8 to 1,600 elements is memory and governor, not
algorithm: cycles_per_element rises 5,051 → 6,536 over the same range while ghz falls 4.435 →
4.178. Stated as a weakness: because there is no broad phase to go quadratic, C2's linearity half
is close to structurally implied and r2 is a weak instrument for it. What the fit can rule out is
superlinear cache behaviour at large n, and none appears. The absolute half is the informative one,
and it passes by 16.0×.
The paper's sublinearity does not reproduce here, and the reason is a stated deviation. Their
Table 3 is strongly sublinear because the time interval shrinks whenever an earlier contact is found,
making every later triangle a cheaper problem. Measured as its own arm (interval_shrink): at 1,600
elements fw8_gss10 reads 1.567759 µs/element with the shrink on against 1.564418 off — very
slightly more, not less. This harness gives Algorithm 2 a fixed iteration count so cost is
data-independent and rows are comparable within one build and one run (M-281), and a fixed-count
solver on a shrunken interval does exactly as much work as on a full one. The paper's gain comes from
its adaptive termination, which the fixed count removes. Measured, not a win here, and the reason is a
declared deviation rather than a contradiction of the paper.
The source audit, which corrects the registration's own quoted figures
Pelletier-Guénette, Mercier-Aubin and Andrews, Real-Time Triangle-SDF Continuous Collision
Detection, 10.1145/3747862, PACMCGIT 8(4) Art. 49, SCA 2025.
- The registration's two shuriken figures reconcile only through a fact it omits. It reads "an
888-triangle shuriken at 0.4 ms total, 11.13 microseconds mean per triangle". Table 4 reads
Shuriken / FWGSS: Total 0.4 ms, Tri. Tested 36, Mean 11.13 µs. The mesh has 888 triangles; 36 of them reached the narrow phase, and36 × 11.13 = 400.7µs — 0.40 ms exactly. The naive reading,0.4 ms / 888 = 0.45 µs/tri, is a figure that appears nowhere in the paper. This harness therefore reports cost per element tested — the paper's own unit — withbroad_phase_cullbeside it, and never divides a total by a mesh size. 0.96 µs/tri at 100Kis a per-triangle mean whose total is 86.85 ms — five 16 ms frame budgets. The per-triangle figure is affordable; the scene is not.- C2's 25 µs bar is below the cited method's own worst published scene mean. FWGSS's per-triangle
means are 25.57 µs (Skate), 7.93 (Bunny), 11.13 (Shuriken), against Macklin et al. 2020's DCD
at 30.69–67.97. The method the registration cites would fail C2 on one of its three published
scenes. So C2 passing here at 1.5644 µs/tested is not this harness beating the paper — it is a
far simpler problem: one analytic
maxof exact distance fields, an analytic gradient, no rotation, no discretised SDF, no adaptive subdivision. - Table 4's runtime share for Shuriken/FWGSS is 74.07% — collision detection is three quarters of their frame, and DCD is 97.28%.
C3: the registered fixture is support-exact, so it measures the mesh
The mechanism, and it is why the clause could not fail as registered. The support function of a union of spheres is the max of the spheres' support functions, and the 8 bead centres include both segment endpoints, so
sup_beads(n̂) = |h·(â·n̂)| + r = sup_capsule(n̂) for every n̂,
exactly. The harness asserts it rather than arguing it: support_deficit_spheres_cells is
0.000000 on all 192 wall rows, asserted below 1e-12. Against a plane the proxy is
support-exact, so the measured disagreement on the registered fixture is not the proxy's error at
all — it is the 200-triangle mesh's inscribed-polyhedron deficit, r(1 − cos(π/10)) = 0.0979
cells of faceting for 10 longitudes, growing with the half-height. The two columns track each other to
four decimals at every half-height:
capsule_half_height_cells |
aspect | toi_disagreement_cells (worst) |
support_deficit_mesh_cells |
|---|---|---|---|
4.8 (game_dig's own) |
3.4 | 0.162891 | 0.162629 |
| 9.6 | 5.8 | 0.347904 | 0.347588 |
| 14.4 | 8.2 | 0.585198 | 0.585786 |
| 19.2 | 10.6 | 0.895958 | 0.895906 |
| 24.0 | 13.0 | 0.942291 | 0.941845 |
| 28.8 | 15.4 | 1.218634 | 1.224642 |
C3's scored population is the 32 wall rows at game_dig's own capsule (radius 2 cells, half-height
4.8 cells from BODY_OFFSETS' 1.2-unit span, aspect 3.40): worst toi_disagreement_cells
0.162891, mean 0.077861, min 0.000040, against a 1.0-cell bar — HELD, and held by a
mechanism, not by a margin. cost_ratio_spheres_vs_mesh is 56.051261 worst, 95.432759 median,
144.938750 best against a 10× bar; over all 192 wall rows the worst is 28.052083, still 2.8× the bar.
Solver accuracy on the scored rows: solver_error_cells 0.001878 worst against
solver_accuracy_bar_cells = 0.010000, and 0.009180 worst over all 284 rows carrying the column, with
solver_chosen = fw8_gss10 and solver_cleared_accuracy_bar = true. mesh_false_negative and
mesh_false_positive are 0 and 0 over all 288 C3 rows against an independent exact reference
(toi_capsule_mesh_reference); the paper's own equivalents are 0.94% and 0.98% over 2,048
configurations.
This is P-70's C3 shape, and the predecessor said so out loud and built a second fixture rather
than waiting for the next audit to find it. Asserting "within one cell" on a fixture where the proxy
is exact by identity is asserting a tenth of a cell of someone else's faceting.
Where the clause actually fails — the convex rim, reported and not scored. 8 beads spaced 2h/7
apart stop overlapping at h = 7r: in cells, r = 2, so the union opens at h = 14 cells, which is
aspect (14 + 2)/2 = 8.0, and the sweep crosses it. Above that the union has real gaps and a
2-cell convex nub enters one:
capsule_half_height_cells |
capsule_aspect |
bead_spacing_cells |
beads_disjoint |
proxy_missed_impact |
worst disagreement (rows with both ToIs) | miss floors, cells |
|---|---|---|---|---|---|---|
| 4.8 | 3.4 | 1.371429 | false | 0 of 16 | 0.225229 | — |
| 9.6 | 5.8 | 2.742857 | false | 0 of 16 | 0.287957 | — |
| 14.4 | 8.2 | 4.114286 | true | 1 of 16 | 0.613518 | 1.031761 |
| 19.2 | 10.6 | 5.485714 | true | 4 of 16 | 0.676828 | 0.841832, 0.848926, 0.863238, 0.939196 |
| 24.0 | 13.0 | 6.857143 | true | 6 of 16 | 0.908178 | 0.826662, 0.842625, 0.848432, 0.887874, 0.939367, 1.031884 |
| 28.8 | 15.4 | 8.228571 | true | 6 of 16 | 0.753377 | 0.825655, 0.888037, 0.930081, 0.934070, 0.939168, 1.031840 |
bead_spacing_cells crosses 2r = 4.0 between 9.6 and 14.4, exactly where beads_disjoint flips —
the geometry and the column agree. 17 of 96 rim rows are a proxy miss that the exact reference
confirms is a real contact (mesh_false_negative = 0 throughout, so the reference is not the thing
that is wrong). Against a plane the same beads are exact; the gaps are invisible to a flat surface
and fatal to a curved one, which is the whole reason the registered fixture cannot tell a working
proxy from a holed one.
How strictly C3 is falsified on the rim, stated exactly. The registered bar is "a disagreement
above one cell". On the 17 misses the disagreement is bounded below by
toi_disagreement_floor_cells, and 3 of the 17 exceed one cell outright — 1.031761 at aspect 8.2,
1.031884 at 13.0 and 1.031840 at 15.4. The other 14 floors lie between 0.825655 and 0.939196, so a
purely metric reading of the bar does not condemn them. What condemns them qualitatively is the kind
of failure rather than its size: the proxy reports no impact at all within the step on a
configuration where a contact exists, which in a resolver is a body passing through a rock, not a
sub-cell ToI error. So the honest answer to C3 is: the cheap version exists for game_dig's body
(aspect 3.40, beads overlapping, 0.1629 cells of disagreement that belongs to the mesh anyway, 56×
cheaper) and does not exist above aspect ~8, and the rule for any future implementation is beads
spaced under 2r — ceil(h/r) + 1 of them — never a fixed 8.
Four fixture defects the harness's own controls caught
- Conservative advancement Zeno-stalled on the dug field. The sphere solver began as plain
conservative advancement (Mirtich 1996; the temporal half of Macklin et al.
10.1145/3384538, and what the cited paper's own §4.6 uses). WithL = 1a clearanceclicenses advancing byc/|step|, and the clearance shrinks by1 − cos θper step — at most 0.293 on the slab face, so twenty iterations reachf64. On thedugfield the brush leaves a concave seam where the pocket meets the slab, a sphere crossing that seam moves nearly tangentially to the pocket's own surface,cos θ → 0, the factor → 1, and the march never converges. The 512-iteration assertion fired atτ = 0.1824(bench doc comment; a pre-fix number, not in the committed CSV). There was deliberately no "give up and return no collision" branch, which is why this surfaced as a stall rather than as a fabricated zero in the exact column C1 is scored on. Replaced by a Lipschitz branch and bound over time intervals, which is sound by construction rather than by fixture: for 1-Lipschitzφand a straight segment of lengthL,min_{t∈[a,b]} φ(p(t)) ≥ φ(p(m)) − L(b−a)/2, so an interval whose bound exceeds the radius provably contains no contact and is dropped, and the earlier half is examined first, so the first leaf reached is the earliest contact. Resolves a graze inO(log)instead of never; leaf resolutionL·2⁻⁴⁰ = 2.3e-12world units at the fastest speed swept;sphere_bnb_nodes_high_water= 1,869 of an asserted 4,096 cap in the committed file. - FWGSS returned
t_endinstead of the crossing. Algorithm 2'st_endis Equation 9's constraint used as a culling device — lowered only where a penetrating sample was seen — while the unsigned-distance line search deliberately lands on the isosurface, whereφis±ε. When it landed on the+εside,t_endwas never lowered below the penetrating time and the harness reported a ToI of exactly 1.0 against a closed-form 0.5, a 0.576-cell error, systematic per orientation because the sign of thatεis deterministic (bench doc comment; pre-fix, not in the CSV). Caught bysolver_error_cellsagainst the closed-form support ToI. The paper describes the same behaviour from the other side (§4.3, "may never quite reach its target"). Fixed: the ToI is the earliest crossing found by the line search, with penetrating times kept as valid-if-late upper bounds. Worst error in the committed file:solver_error_cells = 0.009180againstsolver_accuracy_bar_cells = 0.010000. - The rim launch was calibrated by the proxy under test —
M-44in a new place.rim_launchfirst bisected the launch position so the bead proxy's own analytic ToI landed mid-step. Ath = 3.6units the beads are 1.029 apart, so the bead nearest the capsule's mid-point sitsh/7 = 0.514off the axis — further thanr_rim + r_bead = 0.5— which means no bead can ever touch the rim on a broadside strike. The bead ToI was+∞at every launch position, the bisection ran its bracket tox₀ = 0, and the body started centred inside the rim: sixteen rows reportedtoi = 0.00000on both arms, a comparison of two methods that were both already penetrating. Fixed by placing on the true capsule — point-to-segment distance minus radius, finite for every orientation — so the reference is the geometry both proxies approximate rather than either proxy. - The fixture's dynamic range was smaller than the clause's own bar —
✗51's rule in a geometric costume. The launch first placed the true capsule's contact atτ = 0.5, leaving half a step of approach. A representation whose support falls short of the capsule's by more than the remaining travel cannot contact the wall at all inside one step, so the fixture reported "none" rather than a disagreement — and at half a sprint step that ceiling is 0.576 cells, below C3's own one-cell bar. Fixed two ways: the placement moved toτ = 0.1, and a second wall arm (wall_wide, 8 cells per step against a 16-cell wall) gives the one-cell bar 7.2 cells of room. The fix is visible in the committed artefact: ath = 28.8cells the narrowwallarm still clips at a worst disagreement of 0.919980 with one of its 16 rows returning no mesh ToI at all (mesh_missed_impact = true), whilewall_widereports 1.218634 against a true mesh support deficit of 1.224642.
A fifth, recorded because it is the same rule applied to the harness's own instrument rather than to
its headline: ccd_toi_error_cells read 0.000000 on every row and nothing in the artefact proved the
comparison had ever been made. ccd_toi_checks was added and asserted non-zero — 10,000 per slab
row, 2,240,000 in total. M-44 applies to instrument checks, not only to results.
What changed as a result
Do not build this. That is the result, and it is a completed one. At every speed a game_dig body
can reach, over 500,000 randomised shots against a wall swept from 2 cells to a twentieth of a cell,
the shipped discrete resolver missed zero contacts. The CCD arm also missed zero — 0 of 4,480,000
across the entire sweep, at every speed to 160 u/s and every thickness to 0.05 cells — so it bought
nothing measurable. The cost of the wrong decision is now priced: a 200-triangle capsule CCD query is
128.291 µs, which is 128.291 / 16000 = 0.80% of a 16 ms frame, and 56–145× the cost of the
8-bead proxy (spheres_us 0.56–2.70 µs on the scored rows). Nothing in crates/isomesh/src/**
changes; this row does not want a source change.
The number that would make this actionable is 40 u/s. That is the first swept speed at which
game_dig's own 2-cell body tunnels — 2,331 of 160,000 — and it is 40 / 19.209373 = 2.08× the
fastest speed the demo can produce. The window says the crossing is at 2R + t ≈ 4 cells of travel
per frame, i.e. 4 × 0.125 / 0.016 = ~31 u/s. If a projectile, a thrown tool or a vehicle is ever
added above roughly 30 u/s, discrete collision stops working and this row becomes live. Below that it
is premature — which is exactly what the registration said its own falsification would mean.
And if it is ever needed, reach for the bead proxy — not because it is 56× cheaper, but because it
is exact against a plane, which the 200-triangle mesh is not (0.162891 cells of faceting error at
game_dig's own body, 1.224642 at aspect 15.4). It is valid only while the beads overlap: 8 beads
cover a capsule to aspect 8.0, and above that they have holes a 2-cell rock enters.
Would be shown wrong by: a discrete tunnel at a game_dig speed — any non-zero
tunnels_discrete on a row with body_radius_cells = 2.0 and speed_cells_per_step ≤ 2.4588 — which
would mean the 2R + t window is not what decides it; a game_dig body whose effective radius in the
resolver is smaller than BODY_RADIUS (a foot sphere, a probe point, a swept ray), which would move
2R and could put the game inside the tunnelling regime at its own speeds; a rim fixture at aspect
below 8.0 producing a proxy miss, which would mean bead disjointness is not the mechanism; or a
us_per_element above 25 µs on a machine whose ghz column shows it was not simply governed down.
💥 ✗63 / M-395 — C1 FALSIFIED by 44× to 2,275× at 33³ on all eight fields and no integrator could have passed it: a volume integral over the same triangles agrees with the surface integral to 1.7e-13, so the whole gap is Marching Cubes. C2 splits — cross-machine determinism HELD on 48 of 48 hashes across Zen 3 and an Apple M5, the asymmetry half FALSIFIED by an exact 0.000000e0 on box_exact. C3 FALSIFIED at 20 of 24 rows. And the paper's surface form costs 2.14× the classical origin-fan it was registered as cheaper than (P-83, R-083)
M. cargo bench --bench experiment_p83, docs/experiments/p-83.csv, 24 rows (8 reference
fields × 17³/33³/65³), f64, Zen 3 (amd-ryzen-9-5900x-12-core, powersave, clock_mhz 4200 on
every row). Each field is intersected with an axis-aligned clip box and extracted by Marching
Cubes, and its volume, centre of mass and inertia tensor are compared against a dense
tangent-plane voxel integration of the same clipped field at 256³ with boundary voxels refined
4³ — so the comparison is the polyhedron against the field, not the quadrature against a closed
form. The provenance line reads
# commit 9cbe95a on amd-ryzen-9-5900x-12-core at 2026-08-28T00:53:36Z with no
(WORKING TREE DIRTY); 9cbe95a is an ancestor of HEAD, the file itself landed at 6bf877d,
and the cross-machine fixture docs/experiments/p-83-m5-hashes.txt at 22c9fa0. Four # comment
lines plus the column header, then 24 data rows counted from the file, 46 columns.
Every number below is read from the committed clean-tree CSV, not from the run the original report quoted. That run was
# commit 63c7161 (WORKING TREE DIRTY)at2026-08-27T23:08:43Z, taken while ~25 sibling Phase-24 agents were compiling. Nothing that is not a clock moved. All 24 rows ofvolume_rel_error,com_rel_error,inertia_rel_error,convergence_order, the threeorder_*columns,asymmetry_pre,asymmetry_pre_abs,tetra_rel_error, everyreference_*column and all 48 hashes reproduce the quoted digits exactly — which isM-279's rule satisfied in the strongest available form, since the M5 arm agrees with both Ryzen runs on the same 48 hashes. What moved is timing, and one reported conclusion dies with it:
- WITHDRAWN: "18.13–18.35 ns/triangle on 23 of 24 rows (one 35.83 ns outlier under contention)". There is no outlier on the quiet tree.
mass_props_ms / trianglesis 18.14–18.35 ns on all 24 rows — a 1.16% band,(18.35 − 18.14)/18.14, across a 234× range of triangle counts,58,112/248. The run-independent statement that replaces it is that band itself: the mass pass is a fixed instruction count per triangle, andM-281applies to the nanoseconds but not to the flatness.extract_msper sample: sphere13.6 ns→ 12.1–12.9 ns;fbm_terrain237 ns→ 203.2–227.0 ns. Extraction got faster on a quiet machine, as expected.surface_over_tetra_ms: IQR2.1368–2.1417→ 2.1380–2.1412, median 2.1404, full range 2.1290–2.1552.tetra_ms / triangles:8.48 ns→ 8.47–8.59 ns, median 8.49.share: the eleven values the report quoted moved by −0.41% to +1.92% of themselves, four up and four down at 33³. WITHDRAWN: "contention biasessharedownward, conservative against a falsified C3" — the sign is not consistent, and the correct reading is in C3 below.- CORRECTED, not moved: the report gave
asymmetry_pre_absas "1.48e-17 … 2.29e-11", which is the range over the 33³ rows only. Over all 21 non-box_exactrows the committed file reads 1.249114e-17 … 5.200818e-11. The relative columnasymmetry_preis 9.815228e-18 … 2.743539e-15, i.e. at most 12.4 ulp, and that is unchanged.- Also corrected: "the reference is 16–8500× better than the method everywhere" mixed denominators. The
8,533×iscsg_difference'sreference_gap_relagainst its 65³ volume error; the16×isnoise_cavity's against its 65³ inertia error. Held to one field per pairing, the honest span is given in the vacuity section.
| clause | registered | measured |
|---|---|---|
C1 volume, com and inertia within 1e-4 of the dense voxel reference on all eight fields at 33³, error falling at h² |
≤ 1e-4 on all three, and order ≥ 1.5 | FALSIFIED — c1_holds false on all 24 rows. Smallest failing value at 33³ is noise_cavity's inertia, 4.412184e-3 = 44× the bar; the smallest volume miss is sphere's 9.353191e-3 = 94×; the largest is thin_plate's inertia, 2.275269e-1 = 2,275×. The h² half HOLDS on 5 of 8 fields: convergence_order ≥ 1.5 on sphere 1.9771, torus 2.0259, box_exact 1.8388, csg_difference 1.7092, gyroid 1.9784; below on thin_plate 0.8975, fbm_terrain 1.2918, noise_cavity 0.7886 |
| C2a fixed triangle order gives bit-identical tensors across machines | identical | HELD — bit_identical_across_machines = true on 24/24. 24 distinct inertia_hash and 24 distinct mesh_hash, all 48 reproduced on the second machine |
| C2b the pre-symmetrisation asymmetry is non-zero | > 0 | FALSIFIED — asymmetry_pre_abs is exactly 0.000000e0 on box_exact at 17³, 33³ and 65³. The registered falsifier verbatim: "C2 by zero asymmetry, which would mean the crate's triangles are better behaved than the paper's and the symmetrisation step can be dropped" |
| C3 mass properties cost under 2% of extraction | share < 0.02 |
FALSIFIED — 20 of 24 rows. share spans 0.007338–0.154014; the four passes are fbm_terrain at 1.9361 / 1.2301 / 0.7338% and thin_plate at 65³ at 1.9619% |
The source that landed, and its contract
This is one of only two registered source changes in Phase 24 and the only one that landed.
crates/isomesh/src/mass.rs (+ src/mass/tests.rs, 9 tests), one line in lib.rs —
pub mod mass; at line 127 — and one new
Error::MassPropertiesUndefined { volume, largest_moment }. Read from the module:
no_std. Nouse std::, noalloc::;mass.rsimportscrate::vec3::{cross, dot, sub}andcrate::{Error, Real, Result}and nothing else.- Allocation-free. Fourteen scalar accumulators —
volume_sum,centroid_sum[3],trace_sum,outer_sum[3][3]— one pass over the triangle slice, no scratch buffer, no&mutoutput parameter because there is nothing to reuse. - Generic over
Real, arrays in every public signature:mass_properties(&[[R; 3]], &[[u32; 3]]) -> Result<MassProperties<R>>. No math library in the API. - No new dependency.
- No panicking path. Out-of-range indices return
Error::IndexOutOfRange { at, index, vertices }; a surface that does not bound a positive finite volume, or a moment that overflowed, returnsError::MassPropertiesUndefined. An inward-wound mesh is rejected, not flipped — the sign is the caller's contract, and repairing it would make an inside-out mesh indistinguishable from a correct one. - No square root is evaluated anywhere in the module.
N = (X₂ − X₁) × (X₃ − X₁)is left unnormalised because‖N‖cancels between the area elementdAand the unit normalnin every one of the paper's integrals, so the triangle's area is never formed.grep sqrt crates/isomesh/src/mass.rsreturns nothing. The one quadrature kernel is120·∫(x·x)x dξdη = (S·S)S + Q·S + 2Σₐ(S·Xₐ)Xₐ + 2Σₐ(Xₐ·Xₐ)Xₐ, the paper's Eq. (48) with Table 1 folded in; the leading factors1/18,1/96,1/400,1/240are applied once at the end, one correctly rounded division per number rather than a rounding per triangle.
SHARE, recomputed — and C1's arithmetic was decided before the run
C1's 1e-4 could not be reached at 33³ by any integrator, and the committed file proves it two
ways. The registered comparison is against a dense voxel integration of the field, so what is
being measured is the distance between the Marching Cubes polyhedron and the solid. On the
canonical sphere (R = 1, domain [−2, 2], h = 4/32 = 0.125 at 33³) the chord deficit of a
linear-interpolant polyhedron is ≈ (h/R)²/4 = 3.906e-3, already 39× the bar before anything
is measured; 1e-4 needs h/R ≤ 0.02, i.e. 201³. The file's own columns say the same thing
more strongly. Taking each field's 33³ error and its own fitted order from the CSV, the resolution
at which the bar would first be met — 32·(err/1e-4)^(1/p) + 1 — is:
| field | volume_rel_error @33³ |
order_volume |
res for 1e-4 | inertia_rel_error @33³ |
order_inertia |
res for 1e-4 |
|---|---|---|---|---|---|---|
sphere |
9.353191e-3 | 1.9887 | 314³ | 1.557260e-2 | 1.9771 | 412³ |
torus |
3.566312e-2 | 2.0259 | 583³ | 4.088751e-2 | 2.0275 | 622³ |
box_exact |
2.213542e-2 | 1.9354 | 522³ | 4.729309e-2 | 1.8388 | 913³ |
csg_difference |
2.719990e-2 | 1.9141 | 599³ | 5.454607e-2 | 1.8165 | 1,028³ |
thin_plate |
1.223958e-1 | 0.9769 | 46,338³ | 2.275269e-1 | 0.8975 | 176,027³ |
gyroid |
1.941390e-2 | 2.0167 | 437³ | 3.144638e-2 | 1.9784 | 587³ |
fbm_terrain |
1.054115e-2 | 2.5699 | 197³ | 2.230116e-2 | 2.5038 | 278³ |
noise_cavity |
3.055301e-2 | 0.7886 | 45,330³ | 4.412184e-3 | 2.0338 | 207³ |
C3's 2% is resolution-dependent by construction, and that is arithmetic, not a measurement.
With triangles T ∝ h⁻² and samples C ∝ h⁻³, share = (T·c_t)/(C·c_c) ∝ h: it falls with
resolution and rises on cheap fields, so the same code passes or fails the clause depending only
on the grid it is handed. The committed file shows exactly that — sphere's share is 0.154014 →
0.094181 → 0.051850 over two doublings, a ratio of 1.635 then 1.816, converging on 2.
One thing the arithmetic could not reach before the run: whether the reference itself converges. That is the registered vacuity control and it is a property of an integrator nobody had written yet. It is reported below.
C1 — the clause is not about the integrator, and the file settles that
At 33³, against the 1e-4 bar (c1_holds = false on all 24 rows):
| field | volume_rel_error |
com_rel_error |
inertia_rel_error |
convergence_order |
tetra_rel_error |
|---|---|---|---|---|---|
sphere |
9.353191e-3 | 6.218771e-7 | 1.557260e-2 | 1.9771 | 1.803797e-14 |
torus |
3.566312e-2 | 1.265193e-4 | 4.088751e-2 | 2.0259 | 1.953176e-15 |
box_exact |
2.213542e-2 | 1.415529e-55 |
4.729309e-2 | 1.8388 | 3.258468e-14 |
csg_difference |
2.719990e-2 | 1.865803e-3 | 5.454607e-2 | 1.7092 | 2.324769e-14 |
thin_plate |
1.223958e-1 | 3.908137e-15 |
2.275269e-1 | 0.8975 | 3.166401e-14 |
gyroid |
1.941390e-2 | 3.554784e-3 | 3.144638e-2 | 1.9784 | 1.076360e-14 |
fbm_terrain |
1.054115e-2 | 5.100315e-4 | 2.230116e-2 | 1.2918 | 2.793406e-14 |
noise_cavity |
3.055301e-2 | 1.950766e-3 | 4.412184e-3 | 0.7886 | 1.390602e-14 |
Volume and inertia miss on 8 of 8; the centroid passes on three (sphere, box_exact,
thin_plate) and those are the three whose true centroid is the origin. convergence_order is
the minimum of order_volume, order_com and order_inertia over the informative series, and
the minimum comes from a different column on different fields: inertia on sphere, box_exact,
thin_plate and gyroid; the centroid on csg_difference and fbm_terrain (fbm_terrain's
order_volume is 2.5699 and its order_inertia 2.5038 — only the centroid is slow,
because the solid is a large exactly-represented box with a small wrinkled lid and every centroid
error lives in the lid); and volume on torus and noise_cavity, whose series is not even
monotone: 2.979575e-2 → 3.055301e-2 → 9.984830e-3.
tetra_rel_error is what makes this entry worth writing. It is the surface integral against a
classical signed-tetrahedron volume integral — the origin fanned to every triangle,
V = det(a,b,c)/6 and ∫xᵢxⱼ = (V/20)(aᵢaⱼ + bᵢbⱼ + cᵢcⱼ + sᵢsⱼ) — over the same polyhedron,
which is exact for a closed oriented triangle mesh. Over all 24 rows it spans 1.909884e-15 to
1.682692e-13, asserted < 1e-6. So the surface integral is exact on the polyhedron it is
handed, to thirteen digits, and the entire 1e-2 gap against the voxel reference is Marching
Cubes geometry against the field.
C1's registered falsifier says a convergence order below 1.5 "would mean the surface integral
is not seeing the geometry the volume integral sees". A volume integral over the same triangles
agrees to thirteen digits. The surface integral sees exactly that geometry; the geometry is 1e-2
from the field at 33³. C1 as written cannot be passed by any integrator — it is a Marching Cubes
fidelity clause wearing a mass-properties clause's name, and the three orders below 1.5 are the
three fixtures whose feature size is at or under h, not three failures of the method:
thin_plate is 2 × (4/64) × (0.4/2) = 0.025 thick (ThinPlate::THICKNESS_IN_CELLS = 0.4 at its
canonical 4/64 cell) against the cell_size column's 0.25 / 0.125 / 0.0625 (0.2, 0.4, 0.8 of a
cell), noise_cavity's blobs are two to four cells across and change topology between
resolutions, and fbm_terrain's lid is fractal.
inertia_com_rel_error is the centred tensor, which is what a physics engine consumes and which
compounds the centroid error: at 65³ it is 1.549174e-2 against inertia_rel_error's 1.502183e-2
on csg_difference, 1.912352e-1 against 1.863736e-1 at 17³. The compounding is real and small; it
does not change any verdict.
C2 — two clauses in one column
C2a, cross-machine determinism: HELD, 24/24
bit_identical_across_machines is true on every row. The second machine is an Apple M5
(MacBook Air, aarch64-apple-darwin, rustc 1.96.1), reached at ssh mac_air, and it ran the
harness — this half is not BLOCKED. Its four projected columns are committed as
docs/experiments/p-83-m5-hashes.txt, whose own header records that the M5 CSV's provenance line
reads # commit unknown on apple-m5 at 2026-08-27T23:06:02Z, "unknown because the tree was
rsynced without .git". That is the honest anchor: the fixture is 24 rows of
field,resolution,inertia_hash,mesh_hash, and all 48 hashes match the committed Ryzen CSV
exactly, with 24 distinct inertia_hash and 24 distinct mesh_hash so the match is not a
constant. Without the file the column reads no_peer and c2_holds reads blocked, so the
measurement is real rather than assumed.
The mesh_hash half is stronger than the clause asked for: Marching Cubes extraction is itself
bit-identical across ISA and OS, which is the crate's unconditional-libm policy paying off,
and it is why the 48 hashes are also identical between the dirty and the clean Ryzen runs.
C2b, non-zero pre-symmetrisation asymmetry: FALSIFIED
asymmetry_pre_abs is exactly 0.000000e0 on box_exact at all three resolutions. On the
other 21 rows it is 1.249114e-17 to 5.200818e-11 absolute, which relative to the tensor beside
it (asymmetry_pre) is 9.815228e-18 to 2.743539e-15 — at most 12.4 ulp,
2.743539e-15 ÷ 2⁻⁵². Symmetrisation moves the answer by less than the last bits everywhere, and
by nothing at all on an axis-aligned box.
c2_holdsconflates the two halves and readsfalseonbox_exactat 17³, 33³ and 65³ for a reason that is not the cross-machine clause failing. The bench computes it asarm.props.asymmetry > 0.0 && identical == "true"(experiment_p83.rs:894), a conjunction of C2a and C2b. On those three rowsidenticalistrue— the hashes match the M5 — and thefalseis entirely the> 0.0term. Score the halves separately: C2a HELD 24/24, C2b FALSIFIED, andc2_holdsreadingtrueon the other 21 rows is only C2b's absence of an exact zero there, not a stronger result.
asymmetry_postis0.000000e0on all 24 rows and is structurally zero — it is not a result. The symmetrised tensor stores each off-diagonal entry once and mirrors it (mass.rs:305-307), so the column can only ever read zero and proves that the step was applied, not that it was needed. The informative column isasymmetry_pre.
The mechanism, and the paper is right about its own inputs. Each triangle contributes a
rank-one G ⊗ N, whose antisymmetric part cancels only against the rest of a closed surface, so
the asymmetry is a global cancellation residual. The paper's Eq. (22) requires
∮(x·x)x⊗n dA = ∮(x·x)n⊗x dA, "which holds in the exact case but might be violated by
discretization schemes", and its §6.1 measures the violation on a GiD-triangulated cylinder,
Θˣᶻ ≠ Θᶻˣ. It also names the cause in its own sentence: "A further aspect, which has to be kept
in mind, is related to the precision of the coordinates generated by the CAD system. Commonly,
they have a limited precision, which can be seen in the diagrams. Thus, the achievable accuracy is
limited", and its conclusion generalises it — "The more accurate the surface integration is
performed the more symmetric the tensor becomes." This crate hands the kernel f64 coordinates
from an analytic field on a mesh with boundary_edges = 0 and non_manifold_edges = 0 on all 24
rows, so the cancellation reaches the round-off floor. On box_exact it reaches further: every
vertex coordinate, every cross product and every cubic moment is a dyadic rational that is exact
in f64, so the cancellation is exact and the zero is a true zero rather than a small number.
The column is still worth keeping, and the reason is in a test rather than the CSV.
mass::tests::asymmetry_separates_a_closed_mesh_from_a_leaking_one deletes one triangle from a
cube shifted to (7, 5, 3) and asserts the residual jumps from ≤ 1e-13·Θ₀₀ to > 1e-3·Θ₀₀.
That is the M-44 proof that this zero could have been non-zero; it lives in the test because no
reference field produces a leaking mesh. MassProperties::asymmetry is public as a leak
detector, not as a symmetry residual.
C3 — falsified at 20 of 24, and the gate is a clock
| field | share 17³ |
33³ | 65³ | triangles/cells @65³ |
extract_ms/sample @65³ |
|---|---|---|---|---|---|
sphere |
0.154014 | 0.094181 | 0.051850 | 3.63% | 12.1 ns |
torus |
0.135213 | 0.068775 | 0.035214 | 3.21% | 15.8 ns |
box_exact |
0.134830 | 0.089904 | 0.053555 | 4.40% | 14.3 ns |
csg_difference |
0.114116 | 0.077515 | 0.046097 | 4.59% | 17.2 ns |
thin_plate |
0.065408 | 0.036779 | 0.019619 | 1.56% | 13.8 ns |
gyroid |
0.096408 | 0.075699 | 0.050066 | 16.45% | 57.5 ns |
fbm_terrain |
0.019361 | 0.012301 | 0.007338 | 8.59% | 203.2 ns |
noise_cavity |
0.095796 | 0.074924 | 0.051489 | 22.17% | 75.0 ns |
The raw columns every derived per-item figure above is computed from, so the arithmetic is
reproducible from this entry: triangles over cells = (resolution − 1)³, mass_props_ms and
tetra_ms over triangles, extract_ms over resolution³ samples and over triangles.
| field | res | triangles |
mass_props_ms |
extract_ms |
tetra_ms |
|---|---|---|---|---|---|
sphere |
17³ | 536 | 0.009760 | 0.063371 | 0.004560 |
sphere |
33³ | 2,312 | 0.041990 | 0.445844 | 0.019640 |
sphere |
65³ | 9,512 | 0.172622 | 3.329231 | 0.080661 |
torus |
17³ | 656 | 0.011930 | 0.088231 | 0.005570 |
torus |
33³ | 2,256 | 0.040951 | 0.595436 | 0.019130 |
torus |
65³ | 8,416 | 0.152872 | 4.341280 | 0.071361 |
box_exact |
17³ | 584 | 0.010630 | 0.078840 | 0.004970 |
box_exact |
33³ | 2,696 | 0.048911 | 0.544035 | 0.022850 |
box_exact |
65³ | 11,528 | 0.210182 | 3.924577 | 0.098191 |
csg_difference |
17³ | 584 | 0.010630 | 0.093151 | 0.004960 |
csg_difference |
33³ | 2,768 | 0.050210 | 0.647746 | 0.023450 |
csg_difference |
65³ | 12,020 | 0.218242 | 4.734394 | 0.101921 |
thin_plate |
17³ | 248 | 0.004540 | 0.069411 | 0.002130 |
thin_plate |
33³ | 1,016 | 0.018480 | 0.502464 | 0.008680 |
thin_plate |
65³ | 4,088 | 0.074201 | 3.782115 | 0.034690 |
gyroid |
17³ | 2,536 | 0.046010 | 0.477245 | 0.021490 |
gyroid |
33³ | 10,632 | 0.193362 | 2.554364 | 0.090791 |
gyroid |
65³ | 43,116 | 0.791237 | 15.803898 | 0.367123 |
fbm_terrain |
17³ | 1,188 | 0.021590 | 1.115150 | 0.010090 |
fbm_terrain |
33³ | 5,208 | 0.094500 | 7.682171 | 0.044210 |
fbm_terrain |
65³ | 22,508 | 0.409493 | 55.805111 | 0.191782 |
noise_cavity |
17³ | 2,560 | 0.046491 | 0.485314 | 0.021720 |
noise_cavity |
33³ | 13,236 | 0.240042 | 3.203810 | 0.112131 |
noise_cavity |
65³ | 58,112 | 1.060090 | 20.588742 | 0.495274 |
The run-independent statement, which is ✗24's rule applied to this clause.
mass_props_ms / triangles is 18.14–18.35 ns on all 24 rows and tetra_ms / triangles is
8.47–8.59 ns, each a ~1.2% band over a 234× range of triangle counts — those are instruction
counts, stable, and they make share an identity: share < 0.02 ⟺
extract_ms/triangle > 50 × 18.2 ns = 0.91 µs. Every passing row clears it and every failing row
does not: fbm_terrain extracts at 0.939 / 1.475 / 2.479 µs per triangle, thin_plate at 65³ at
0.925, and the next highest is torus at 65³ at 0.516. So C3 is not a property of isomesh::mass
at all — it is a statement about how expensive the field sample is and how many triangles per
cell the grid produces, and the method passes exactly where FbmTerrain's per-sample cost buries
it.
Two of the four passes are inside the run-to-run spread of their own gate. thin_plate at 65³
clears 2% by 1.905% of the bar and fbm_terrain at 17³ by 3.195%, while the same eleven
share values moved by up to 1.92% between the dirty and the clean run of the identical
binary. A verdict decided by that margin is a coin the governor tosses; the same clause read
against the integer triangles/cells column — 1.56% on the one passing non-fbm row against
3.21%–22.17% everywhere else — is decided by the grid and reproduces exactly.
The result that refutes a sentence in the registered hypothesis
surface_over_tetra_ms = mass_props_ms / tetra_ms, both medians of 25 passes over the identical
triangle list in the identical run and the identical build: 2.1290 to 2.1552 across 24 rows,
median 2.1404, IQR 2.1380–2.1412. Per triangle that is 18.14–18.35 ns for the paper's form
against 8.47–8.59 ns for the classical origin-fan signed-tetrahedron decomposition — at
identical accuracy on identical input, since tetra_rel_error is ≤ 1.682692e-13.
The registration says "the operation count is below tetrahedral volume discretisation at equal resolution." The paper's own sentence behind that is §6.1's: "For the same surface discretization using the surface and the volume discretization approach, the number of multiplications to generate the MMI tensor is larger for the volume discretization" — and the volume discretisation it is comparing against is spelled out one paragraph earlier as "a discretization with tetrahedral elements having the same surface discretization", i.e. a filled tetrahedral mesh with interior elements. That claim is not in dispute and this experiment does not test it. The origin fan is a different object: it needs no interior mesh either, it consumes the same triangle list, and against it the paper's form does 2.14× the work. The sentence as written into the registration is refuted for the comparison this crate would actually make.
The decision is surfaced and stops there: no swap is recommended. Swapping mass.rs's kernel
for the fan is a one-function change that buys 18.17 − 8.49 = 9.7 ns per triangle — on the
largest fixture here, 58,112 triangles, that is 0.56 ms once — and loses asymmetry, which is the
only leak detector the module has. The measurement is the deliverable; the trade is a caller's to
make.
The vacuity control — which is about the reference, not the method
The registration's own words: "the reference must be a dense voxel integration at a resolution
that itself converges, reported with its own h² fit, or C1 is measuring the reference." The
column is reference_order, from a three-grid Richardson fit over 64³/128³/256³ of the whole
ten-moment vector, normalised so each component is order one, with reference_gap_rel (the raw
last-doubling movement, which assumes nothing) and reference_residual_rel (the extrapolation)
beside it.
| field | reference_order |
reference_gap_rel |
reference_residual_rel |
reference_order_naive |
reference_gap_rel_naive |
reference_vs_analytic_rel |
|---|---|---|---|---|---|---|
sphere |
2.0003 | 1.376154e-5 | 4.585949e-6 | 5.4249 | 1.176248e-4 | 3.816395e-6 |
torus |
2.0033 | 5.375834e-5 | 1.786528e-5 | 2.9629 | 2.185529e-3 | 1.411006e-5 |
box_exact |
exact |
0.000000e0 | 0.000000e0 | exact |
0.000000e0 | 0.000000e0 |
csg_difference |
2.4559 | 8.411885e-7 | 1.874879e-7 | 2.1659 | 8.788166e-5 | na |
thin_plate |
0.4150 | 5.311877e-5 | 1.593563e-4 | exact |
0.000000e0 | na |
gyroid |
2.0529 | 2.820704e-5 | 8.956313e-6 | 2.6857 | 5.983313e-4 | na |
fbm_terrain |
−0.0013 | 1.414626e-5 | 1.597787e-2 | 10.3456 | 5.443452e-5 | na |
noise_cavity |
1.5706 | 1.498060e-4 | 7.603527e-5 | 1.0514 | 5.166988e-4 | na |
Leg 1 — it reproduces closed forms. reference_vs_analytic_rel is the reference volume
against 4π/3, 2π²Rr² (Rr² = 0.09) and 8: 3.816395e-6, 1.411006e-5, and exactly zero.
Its own self-estimate reference_residual_rel reads 4.585949e-6 and 1.786528e-5 on those two —
1.20× and 1.27× the true error, bracketing it from above — which is what makes the estimate
believable on the five fields with no closed form.
Leg 2 — the naive arm fails on the same samples, and it is the proof the control could have
failed. reference_order_naive and reference_gap_rel_naive are the identical integration with
boundary voxels classified by their centre's sign instead of by the tangent-plane volume fraction.
On the four fields where both arms are informative the naive gap is 8.5×, 40.7×, 104.5× and
21.2× worse (sphere, torus, csg_difference, gyroid), and the order column reads
5.4249, 2.9629, 2.1659, 2.6857 and 10.3456 — noise, beside the tangent-plane arm's 2.0003
/ 2.0033 / 2.4559 / 2.0529 on exactly the same data. An h² fit next to a column that does not fit
h² on the same data is evidence; an h² fit on its own is a hope. One caveat stated rather than
buried: thin_plate's naive arm reads exact because it finds no plate at all. The slab is
0.025 thick over a [−2, 2] domain, so at 64³ and 128³ (h = 0.0625, 0.03125) no voxel centre
lands inside it, both grids return exactly zero, the first gap is zero and the fit is skipped.
That exact is a degenerate agreement, not an accurate reference.
Leg 3 — the reference is far better than the method on every field, held to one denominator.
Comparing reference_gap_rel against the same row's 65³ inertia_rel_error — 3.892281e-3,
1.024324e-2, 1.272173e-2, 1.502183e-2, 1.192619e-1, 7.818202e-3, 3.199166e-3 and 2.430607e-3 in
the table's field order: 283× (sphere), 191× (torus), ∞ (box_exact, gap exactly zero),
17,858× (csg_difference), 2,245× (thin_plate), 277× (gyroid), 226× (fbm_terrain), 16×
(noise_cavity). The narrowest margin is 16×, while C1's inertia miss at 33³ spans 44× to
2,275× the bar, so no verdict here is reference-limited.
Two reference orders are honest failures, and both have a cause. thin_plate's 0.4150:
the plate is 0.025 thick against the finest reference voxel's 0.015625, so a single voxel is cut
by both faces and the one-tangent-plane cell model is simply the wrong model — the boundary
layer is the entire body. fbm_terrain's −0.0013: the sequence has stalled, not diverged.
Its last-doubling movement is 1.414626e-5, which is small; the Richardson column reads 1.597787e-2
only because it divides by 2^p − 1 with p ≈ 0. That is why reference_gap_rel is emitted
beside it, and it is why the leg-3 comparison above uses the gap rather than the residual.
Three further controls, all asserted per row rather than printed.
boundary_edges= 0 andnon_manifold_edges= 0 on all 24 rows. The divergence theorem does not apply to a surface with a hole, and a leaking mesh would make every number here a different question's answer.clip_inert, and it is the column that could have failed and did. Every field is intersected with an axis-aligned box — one code path, withclip_half_extentas data: 1.5 on five fields, 1.75 onnoise_cavity, 5.875 onfbm_terrain, 6.5 ongyroid. For the seven closed fields the box sits outside the surface, and the harness proves the intersection is inert by extracting with and without it and comparing the mesh hash, then assertsclip_inert == ReferenceField::closed_in_domain(). It istrueon 21 rows andfalseonfbm_terrain's three, where the clip is what closes the solid.- Every relative error asserted strictly positive. A zero would mean the method and the reference are one computation wearing two names.
Four fixture defects, each caught by this harness's own controls
- A degenerate centroid series reported "the method does not converge" for a quantity the
method computes exactly. Five of the eight fields are centred on the origin, so
com_rel_erroris1.415529e-55onbox_exactand3.9e-15onthin_plateat every resolution. A least-squares slope through three round-off values is ~0, and folding that through theminreportedconvergence_order0.0000 onbox_exact— turning the method is exact here into the method does not converge — and drove everyreference_ordernegative (−1.90 onsphere, −4.32 onbox_exact) with residuals of 100%. Fixed with anINFORMATIVE = 1e-10floor on the series and its differences, and — chore C5's rule,docs/research/2026-08-27-phase-24-agent-prompt.md— an excluded series emits the stringexact, never0.0000, because a reader who grabs the obvious column must not be handed the opposite of the truth.order_comreadsexactonbox_exactandthin_plate;reference_orderreadsexactonbox_exact. - The reference's order was a minimum over ten scalar moment series, and read −3.91 on
fbm_terrainand −5.75 onnoise_cavity. One near-zero off-diagonal moment changes sign between two grids and its two successive differences land in the wrong ratio. Replaced by the Euclidean norm over the whole normalised ten-vector, which cannot do that and is the residual of the whole integration — which is what the vacuity control is asking about. - Richardson's
gap/(2^p − 1)divides by something that vanishes as the observed order does. Onfbm_terrainit reported 1.597787e-2 for a last-doubling movement of 1.414626e-5 — an error larger than the quantity. Both columns now go out, the extrapolation where the order supports it andreference_gap_rel, which assumes nothing. - Both sides of the speed ratio were measuring redundant arithmetic, and the control was
flattering the method.
mass.rsrecomputed the three per-corner contractions once per axis — eighteen dot products where six suffice, on the innermost loop — and the tetrahedral control did nine divisions per triangle. Hoisting the module's was necessary before reporting a cost clause falsified; hoisting the control's movedsurface_over_tetra_msfrom 1.68 to 2.14, i.e. the instrument had been reporting a 1.68× penalty where the real one is 2.14×.
What changed as a result
isomesh::masslanded. It is exact on the polyhedron to 1.7e-13 against an independent volume integral,no_std, allocation-free, generic overReal, arrays in the signature, no new dependency, no panicking path, and no square root. C1 being falsified is a statement about Marching Cubes, not about the module.- Do not treat the symmetrisation as a numerical step on this crate's meshes. It corrects at
most 12.4 ulp and exactly nothing on an axis-aligned box. It stays in
mass.rs— two adds and a halve, and fidelity to the paper's Eq. (66) — but the number to look at isasymmetry_pre, and its value is as a leak detector. asymmetryis public for that reason and no other, with the leaking-cube test as its could-have-been-non-zero proof.- Do not adopt the paper's inertia kernel over the origin fan on a cost argument. 2.14× on identical input at identical accuracy; the registered claim holds only against a filled volume mesh.
- Do not expect mass properties at 2% of extraction. It is 3.5%–15.4% on the 20 rows that
fail, covering seven of the eight fields, and under 2% only where the field sample is expensive.
It is still far cheaper than the
parry3dhandoff it replaces — the registered bar is a claim about the wrong denominator. - A future re-registration of C1 should name Marching Cubes, not the integrator, and should
gate on
tetra_rel_error— which is a property of the arithmetic, reproduces across machines, and would catch a real integrator defect that the 1e-4 bar cannot distinguish from grid coarseness.
Would be shown wrong by: a tetra_rel_error that rises above the 1e-13 floor on any fixture,
which would move C1's gap back onto the integrator and make the clause meaningful as written; a
watertight f64 fixture on which asymmetry_pre rises above ~1e-14 relative without a boundary
edge, which would restore C2b; a mesh whose inertia_hash differs between the Ryzen and the M5,
which would break C2a and with it the fixed-iteration-order argument; or an origin-fan
implementation that is slower than the surface form on the same triangle list, which would
restore the registration's operation-count sentence for the comparison that matters.
💥 ✗64 / M-396 — C1 HELD by three to four orders, C2 FALSIFIED as registered and HELD under one named repair, C3 FALSIFIED and resolution-dependent: the fracture costs 10,464–12,726 cycles per fragment against M-116's 240.7–271.8 ms, and the convex-cell partition is a pure function of the edit log only if a crossing vertex is solved from its stable-id plane triple and coincident planes are collapsed — 6 / 6 / 2 / 1 distinct partitions over all 40,320 orderings (P-84, R-084)
M. cargo bench --bench experiment_p84, docs/experiments/p-84.csv, 12 rows, f64, Zen 3. Two
arms: c1c3, eight rows — fbm_terrain and gyroid at 16³ and 32³ cells a chunk, dug by 60 brushes from
M-50's largest bucket and fractured by a 3-cell impact k-DOP, median of 9 timed reps plus one separate
counted rep for cycles; and c2, four rows — M-36's own eight Subtract brushes on an 8³ box_exact
chunk, every one of the 40,320 orderings run on each of four arms crossing two vertex arithmetics with two
plane orders. Committed at 6bf877d.
Every number below is read from the committed
docs/experiments/p-84.csv, whose# commitheader reads6bf877d on amd-ryzen-9-5900x-12-core at 2026-08-28T00:54:39Zwith no(WORKING TREE DIRTY)marker, and6bf877dis an ancestor ofHEAD(b2b481e). The file has four#comment lines, one column header and 12 data rows over 71 columns. The reporting run was a dirty pre-run taken while roughly twenty-five sibling benches were compiling, and every clock in it moved (M-281). Withdrawn and replaced, old → new:fracture_ms_per_fragment0.002508–0.005124 → 0.002544–0.003047, so the reported "1952× to 3987× under the 10 ms bar" and "4879× under the 25 ms falsifier" are withdrawn for 3,282–3,931× and 8,205–9,827×;fracture_ms_worst0.019191–0.059309 → 0.014230–0.037386;cycles_per_fragment10,717–21,233 → 10,464.1–12,726.2, a 1.67× collapse at the top end on the identical binary, which is why the 21,233 is withdrawn outright;ghz3.877–4.189 → 3.9429–4.1858;m116_speedup_mean_low46,975–95,973 → 79,008.6–94,099.2;m116_speedup_mean_high53,044–108,373 → 89,217.0–106,819.7;m116_speedup_worst6,222–19,228 → 9,869.9–25,931.1, which moved up at the top as well as up at the bottom. The reported "three to five orders of magnitude of headroom" is withdrawn as a single band and replaced with the two it conflates: three to four orders against the registered bar and its falsifier, four to five againstM-116's own stage. Every integer, every hash and every exact ratio reproduced bit-identically —fragments4941 / 1733 / 2245 / 1065,fracture_cells149 / 166 / 170 / 225,cell_growth_ratioto all six decimals,orderings40320,distinct_partitions6 / 6 / 2 / 1,distinct_partitions_raw18720,partition_hashe6be63994b22e771on the arm that holds — which isM-279's rule satisfied: the quiet run agrees with the noisy one on everything that is not a clock. Thep-85.csvshares the bench header quotes also belong to a superseded run and are re-read below.
| clause | registered | measured |
|---|---|---|
C1 a brush intersected against a convex-cell partition produces convex fragments in under 10 ms per fragment, against M-116's 241–272 ms |
< 10 ms, falsified above 25 |
HELD — 0.002544–0.003047 ms per fragment, 3,282–3,931× under the bar and 8,205–9,827× under the falsifier; 10,464.1–12,726.2 cycles per fragment at 3.9429–4.1858 GHz |
| C2 the convex-cell partition is a pure function of the edit log, bit for bit, over all 40,320 orderings of eight same-kind brushes | distinct_partitions == 1 |
FALSIFIED as registered — 6 on lerp+as_logged, 6 on lerp+canonical, 2 on solve+as_logged. HELD at 1 on solve+canonical alone |
| C3 a chunk that has taken 60 brushes has under 4× the convex cells of an unedited one | < 4× |
FALSIFIED — 6.412534 and 6.019270 at 16 cells a chunk; 1.360286 and 1.381061 at 32, on the same fields and the same 60 brushes |
| vacuity control: the 40,320-ordering arm must reach every ordering, asserted by count | orderings == 40320 |
SATISFIED — 40320 on all four c2 rows, permutations_distinct 40320, both asserted before any arm runs |
No clause is VACUOUS and none is BLOCKED: all three got an instrument, and no clause names a second
machine or a real GPU wall clock, so nothing was owed to mac_air or to a frame timer.
Three
*_holdsvalues readfalsefor something narrower than "the clause failed", and eight readNAfor something that is not a failure at all.c2_holdsisNAon the eightc1c3rows andc1_holds/c3_holdsareNAon the fourc2rows — the two arms measure different clauses on different fixtures, so thoseNAs are arm scope and not verdicts. Within thec2arm the threefalses are three different failures. Onlerp+canonical,distinct_topology = 1anddistinct_solid_flags = 1: the arrangement and the union are order-free and onlydistinct_positions = 6is not, so thatfalseis arithmetic alone. Onsolve+as_logged,distinct_positions = 2equalsdistinct_topology = 2: there is no arithmetic divergence at all, so thatfalseis labelling alone. Onlylerp+as_loggedcarries both, and itsdistinct_partitions = 6equals itsdistinct_positionsbecause the positions hash refines the topology hash — the full hash tracksdistinct_positionsexactly in all four arms (6 = 6, 6 = 6, 2 = 2, 1 = 1), so the four numbers are one instrument read at four depths and not four independent counts.
The SHARE line, recomputed against the committed p-85.csv first, because R-085 removed this row's
cost case and the entry has to say so precisely. The registration reads "SHARE: C1 moves the whole
destruction-collider stage." R-085 has since attributed the collider's 45%, and from
docs/experiments/p-85.csv at 5c55f12 (also an ancestor of HEAD), over its six rows:
| stage | share of the chunk collider build, p-85.csv |
|---|---|
handoff_share — the crate's own weld plus collider::readiness |
0.799083–0.818325 |
bvh_share — parry3d's QbvhBuilder |
0.178850–0.198394 |
construct_share |
−0.000133–0.004602 |
copy_share — the triangle copy |
0.000350–0.000500, i.e. 0.035–0.050% |
residual_share |
0.000003–0.000031 |
(The bench header quotes handoff 0.795854–0.815711, bvh 0.179151–0.199501 and copy 0.000354–0.000565
from the superseded p-85 run; the committed file's figures are the ones above.)
There is no convex-decomposition term anywhere in that 45%, because the crate does not do convex
decomposition — README.md:182 lists it under "Not yet" and README.md:69 says "not here — export
the mesh and decompose downstream". Four stages plus the residual sum to 0.999969–0.999997, so the
decomposition is complete and the missing term is missing because the work does not happen, not because
the instrument lost it. So, clause by clause:
- C1 moves none of
R-085's 45%. It movesM-116's own stage:avian3d0.7'sconvex_decomposition_from_meshat 240.7 / 271.8 / 249.0 ms mean per fragment, worst 323.7 / 369.0 / 362.6, over 23–24 fragments per target. 100% of that stage, because there is no second path — the crate has one way to get a fragment collider and it is the oneM-116measured. - C2 has no share and no cost content. It is the determinism clause, unaffected by
R-085, and it is the clause that survives. - C3 has no share either. It is a memory bound guarding C1's mechanism.
So R-085's conclusion "do not build R-084 for cost" is correct about the chunk collider and silent
about the stage C1 is denominated in. The 45% is handoff and BVH; C1's 241–272 ms is a stage that is not
in the pipeline at all yet. Both statements are true at once and neither refutes the other.
Arithmetic reached both bars before the run and one thing it could have reached and did not. C1 was
falsifiable in either direction a priori — 240.7 / 10 = 24.07× and 240.7 / 25 = 9.63× are both inside
a plausible range for a plane-clip arrangement. C2 was falsifiable a priori because Sutherland–Hodgman's
t = d_a/(d_a − d_b) on endpoints earlier clips produced is order-dependent by inspection. C3 was
falsifiable only on a fixture where convex_cells_before is not 1, which is a recorded fixture decision
(see the instrument, step 2). What arithmetic could have reached and nobody computed is that C3's bar is
not resolution-free: convex_cells_before grows with the cube of the cell count while the cut region is
fixed in cells, so the ratio is dominated by its denominator. Measured on fbm_terrain, the denominator
grows 7.6529× from 16³ to 32³ against a cell-count ratio of 8, the numerator grows 1.6234×, and
7.6529 / 1.6234 = 4.7141 — exactly the 6.412534 / 1.360286 the two rows report. On gyroid: 7.3563 /
1.6878 = 4.3584, exactly 6.019270 / 1.381061. That is one input→output pass over the fixture, it was
available before the harness existed, and it is Part 5's enumerate the rows before writing the harness
rule in a new costume — the population was not empty, but the bar's dependence on the fixture's own
resolution was derivable from the fixture and was not derived.
C1, and the number that is not a clock. Müller's "typically negligible, i.e. below 10 ms" was measured on a Core i7 at 3.07 GHz with a GTX 680; this is the same runtime step on a 5900X thirteen years later.
| field | cells | planes | fragments | cells | total ms | ms/fragment | worst ms | cycles | cycles/frag | GHz |
|---|---|---|---|---|---|---|---|---|---|---|
fbm_terrain |
16 | as_logged |
4941 | 149 | 13.843179 | 0.002802 | 0.037386 | 55,300,811 | 11,192.2 | 3.9429 |
fbm_terrain |
16 | canonical |
4941 | 149 | 13.169523 | 0.002665 | 0.034094 | 55,442,868 | 11,221.0 | 4.0100 |
fbm_terrain |
32 | as_logged |
1733 | 166 | 4.454512 | 0.002570 | 0.014230 | 18,580,650 | 10,721.7 | 4.1821 |
fbm_terrain |
32 | canonical |
1733 | 166 | 4.432910 | 0.002558 | 0.014570 | 18,559,017 | 10,709.2 | 4.1844 |
gyroid |
16 | as_logged |
2245 | 170 | 6.822454 | 0.003039 | 0.033564 | 28,520,915 | 12,704.2 | 4.1836 |
gyroid |
16 | canonical |
2245 | 170 | 6.839404 | 0.003047 | 0.035505 | 28,570,399 | 12,726.2 | 4.1661 |
gyroid |
32 | as_logged |
1065 | 225 | 2.716876 | 0.002551 | 0.022180 | 11,144,217 | 10,464.1 | 4.1858 |
gyroid |
32 | canonical |
1065 | 225 | 2.709866 | 0.002544 | 0.024765 | 11,309,281 | 10,619.0 | 4.1797 |
cycles and fragments are both integers on the row and cycles_per_fragment is their exact quotient, so
10,464.1–12,726.2 cycles per fragment is the form of C1 that does not depend on this machine's
governor (M-280, M-281, ✗24). Stated as a clock-free bound: at the paper's own 3.07 GHz the worst
arm is 4.145 µs per fragment, which is 2,412× under the paper's own 10 ms figure, and even at a
hypothetical 1 GHz it is 12.726 µs, still 786× under. That is the sentence a wall-clock ratio cannot
carry.
Against M-116, both registered bars reported as the falsifier demands:
| field | cells | planes | vs 240.7 ms mean | vs 271.8 ms mean | vs 369.0 ms worst |
|---|---|---|---|---|---|
fbm_terrain |
16 | as_logged |
85,912.3× | 97,012.7× | 9,869.9× |
fbm_terrain |
16 | canonical |
90,306.9× | 101,975.1× | 10,823.0× |
fbm_terrain |
32 | as_logged |
93,642.8× | 105,742.1× | 25,931.1× |
fbm_terrain |
32 | canonical |
94,099.2× | 106,257.4× | 25,326.0× |
gyroid |
16 | as_logged |
79,204.9× | 89,438.6× | 10,994.0× |
gyroid |
16 | canonical |
79,008.6× | 89,217.0× | 10,392.8× |
gyroid |
32 | as_logged |
94,353.0× | 106,544.1× | 16,636.2× |
gyroid |
32 | canonical |
94,597.1× | 106,819.7× | 14,899.8× |
fracture_ms_worst is the one column here that should be read as an order of magnitude and nothing
finer. It is a single-piece maximum accumulated over 9 reps, not a median, and it moved 0.019191–0.059309
→ 0.014230–0.037386 between the reporting run and this one on the identical binary. What survives quoting
is the within-row ratio, which is taken inside one run and one build: the worst fragment costs 5.5× to
13.3× the median fragment across the eight rows, and even the worst of the worst, 0.037386 ms, is
267.5× under the 10 ms bar and 668.7× under the 25 ms falsifier.
The mechanism is that nothing is decomposed. Clipping a convex shape against a convex cell yields
convex pieces, so a fragment arrives with a collider already attached. avian3d's 240.7 ms is not made
faster; it is not spent. The impact k-DOP is the fracture pattern, every solid piece of every overlapped
cell is split by the pattern's planes, a leaf inside all of them is a fragment, and no field is sampled
inside the timed region at all — a leaf inherits its parent's solid classification, which is precisely
what the paper's invariant buys. 1,065–4,941 fragments come out of 149–225 overlapped cells, with
392–2,339 remainder pieces beside them.
C2, and the repair is the row. Four arms, all 40,320 orderings each, crossing the two forks the construction actually has. The registration anticipated only the first.
as_logged |
canonical |
|
|---|---|---|
lerp — v = a + t(b−a), t = d_a/(d_a − d_b), the arithmetic A-027 describes |
topology 2, positions 6, solid flags 2 → distinct_partitions 6 |
topology 1, positions 6, solid flags 1 → 6 |
solve — Cramer's rule on the three plane equations, triple in ascending stable edit id order |
topology 2, positions 2, solid flags 2 → 2 | topology 1, positions 1, solid flags 1 → 1, c2_holds = true, partition_hash e6be63994b22e771 |
The two repairs are independent and each removes exactly one column of divergence. solve removes the
arithmetic: Cramer's rule on a triple named by the edits' own identities — not by their positions in the
log, which is the premise M-36 is about — is order-free by construction, and solve+as_logged's
distinct_positions = 2 = distinct_topology says 100% of its residue is combinatorial and none of it
arithmetic. canonical removes the labelling: a cut plane is dropped when a smaller stable id in the
same cell bounds the same plane in either orientation, which takes distinct_topology and
distinct_solid_flags to 1 in both vertex modes. Neither alone is enough. lerp+canonical still reports
6 positions with 1 topology — 100% arithmetic — and solve+as_logged still reports 2 with 2.
The topological half is the fixture, not a clipper bug, and simplicity_scan measures it instead of
assuming it. On M-36's own eight-brush fixture, coincident_plane_pairs = 3 in nonsimple_cells = 3
of the 182 cut cells, with nonsimple_points = 36 and max_planes_at_a_point = 4. Two brushes contribute
the same half-space three times over; a half-space appearing twice cannot move an intersection of
half-spaces, but it leaves a vertex on that plane with two ids it could equally be tagged with, and
which one it gets is decided by the traversal. Those 36 points are exactly the slivers_dropped = 36
zero-width leaves the as_logged rows report, and collapsing the coincident planes takes
coincident_plane_pairs, nonsimple_cells, nonsimple_points, max_planes_at_a_point and
slivers_dropped all to 0. Axis-aligned is not generic: dop_dirs = 6 on every row, and two
hand-authored brushes agreeing on one tangent plane is not a coincidence worth calling unlikely. Note that
degenerate_vertices = 0 and singular_triples = 0 both read clean on the as_logged rows — neither
counter can see two distinct ids naming the same plane, which is why simplicity_scan had to exist.
It is a labelling failure and not a geometry failure, and the columns say which.
topo_class_lo_pieces = topo_class_hi_pieces = 1709 and topo_class_lo_solid = topo_class_hi_solid =
1026 in all four arms: the two topology classes hold the same leaves and the same solid leaves and differ
only in what those leaves are called. convex_cells_after = 1026 and total_pieces_after = 1709 are
identical across all four arms, and partition_volume_error_rel = 3.331e-16 throughout. So the compound
is order-free — its geometry, its leaf count and its solid classification — in every arm including the
naive one. What is not order-free is the id triple a vertex carries, which is exactly what a replication
hash would sign.
c2_holds = trueonsolve+canonicalsits on the same row asdistinct_partitions_raw = 18720, and the registration's words are "bit for bit".partition_hashis taken over each cell's sorted piece multiset, which isolates arithmetic order-dependence from emission order — the question C2 asks.partition_hash_rawis taken over the breadth-first split's emission order, and it splits 18,720 ways in every one of the four arms. So the thing that is one is the partition as a set of convex pieces with named vertices, not the byte stream that serialises it. A protocol that signs a canonicalised representation gets 1; a protocol that signs the emission order gets 18,720, on the arm where C2 holds. The 18,720 is also the strongest vacuity control on the row, and it is free: the traversal demonstrably took 18,720 distinct shapes over the same 40,320 orderings, and the canonical hash still came out once.
The consequence, stated the way a networked editor needs it: a networked editor cannot assume two clients
that applied the same eight edits in different orders hold the same compound — even though M-36
guarantees they hold the same field — unless it computes each crossing vertex by solving its three
plane equations on the ascending stable-id triple and collapses coincident planes to the smallest stable id
in the cell before arranging. Those are two one-line requirements and together they are the difference
between 6 and 1. Neither is a tolerance and neither costs more than a divide.
C3, and the bar is not resolution-free.
| field | cells | cell size | before | after | ratio | c3_holds |
all leaves before | all leaves after | all-leaf ratio |
|---|---|---|---|---|---|---|---|---|---|
fbm_terrain |
16 | 0.250 | 2,904 | 18,622 | 6.412534 | false |
3,357 | 82,259 | 24.5037 |
fbm_terrain |
32 | 0.125 | 22,224 | 30,231 | 1.360286 | true |
24,198 | 58,249 | 2.4072 |
gyroid |
16 | 0.250 | 2,439 | 14,681 | 6.019270 | false |
3,222 | 61,278 | 19.0186 |
gyroid |
32 | 0.125 | 17,942 | 24,779 | 1.381061 | true |
21,065 | 49,804 | 2.3643 |
Identical in both plane modes, so this is not the coincident-plane defect. The wider all-leaves reading is worse, not better: at 16 cells a chunk it is 6.13× and 4.75× the 4× bar against 1.60× and 1.50× on the solid-only reading, so the 16-cell failure is not an artefact of counting only solid pieces. At 32 cells both readings hold.
The clause names no resolution, so a resolution at which it fails falsifies it — and the reason is the
denominator arithmetic above. One fixture caveat belongs beside the ratio and is in the file:
brush_radius_cells = 1.50 and impact_radius_cells = 3.00 are in cells, so the 32-cell arms dig
brushes of half the world radius the 16-cell arms dig. That is the natural scaling for a voxel editor — a
brush is so many cells wide — but it means C3's two resolutions are not the same hole, which is why
cell_size_world is on the row.
The reporting run's proposed repair does not survive this file, and it is withdrawn. It suggested that "a bound on
max_pieces_in_a_cellor on pieces per cut cell would be the resolution-free version." Neither is resolution-free on this data:max_pieces_in_a_cellis 4,290 → 855 onfbm_terrainand 2,979 → 485 ongyroidacross the same two resolutions, and new pieces per cut cell is 33.37 → 9.12 and 22.75 → 7.07.max_cuts_in_a_cellmoves too, 47 → 26 and 41 → 20. What a resolution-free version of C3 should be denominated in is an open question this row does not answer. What the row does answer is that the registered 4× bar is a statement about chunk resolution wearing the clothes of a statement about brush count, and it should not be reused as written.
What the instrument is, in full, because no convex decomposition exists in the crate. A-026 and
A-027 are both open and A-026 is blocked on a scope decision, so this bench builds the substrate it
measures — and it is not a convex decomposition of a mesh, it is the construction A-027 proposes, which
is why it is cheap. The chunk grid supplies the outer convex cells for free: a chunk is a grid of
chunk_cells³ cubes and a cube is convex, so Müller's offline ACD pass is simply not needed — he pays for
it offline with approximate convex decomposition, and a voxel field already has it. The unedited surface
contributes one tangent plane per boundary cell: for a cell whose eight corners straddle zero, the plane
through the local zero crossing with normal ∇f/|∇f|, and cube ∩ half-space is one convex piece — so an
unedited chunk's compound is its full cells plus its boundary cells, cells_full_before 2,419 / 20,227 /
1,657 / 14,820 plus cells_boundary_before 483 / 2,029 / 783 / 3,129 against convex_cells_before 2,904 /
22,224 / 2,439 / 17,942, agreeing to within 0.15%. That is what a marching-cubes-derived convex
decomposition looks like, and it is why convex_cells_before is a real number rather than 1; had the
partition come from brush planes alone, an unedited chunk would be one cell and C3's ratio would have been
unbounded by fixture rather than by measurement, so this is a recorded fixture decision and not an
accident. Each brush contributes its k-DOP supporting planes from the shape's exact support function
h(d) = max_{x∈S} d·x — sphere c·d + r|d|, box c·d + Σ b_i|d_i|, capsule max(a·d, b·d) + r|d|
(Klosowski, Held, Mitchell, Sowizral & Zikan, IEEE TVCG 4(1), 1998) — so these are tangent planes and the
enclosure is exact for a box brush and conservative for a sphere or a capsule. The partition of one cell
is the arrangement of its cube by the planes that cross it, built breadth-first: split every current
piece by the next plane and drop the empty ones, so every leaf is an intersection of half-spaces and hence
convex. A piece is carried as its vertex set with each vertex tagged by the sorted ids of its three
defining planes, which makes the 1-skeleton recoverable — two vertices are adjacent exactly when they share
two planes — so clipping needs no face-cap reconstruction. C1's fracture is Müller's runtime step
verbatim, and the compound is collected outside the timed region because "precomputed" is the paper's
premise.
Both halves of the paper's invariant are checked rather than assumed, and that is what makes the C1
number mean anything. convexity_violations = 0 on all 12 rows — every vertex of every piece is on the
piece's own side of every plane incident to it, to 1e-9 of the cell size — which is the convex half:
"clipping a convex shape against a convex cell yields convex pieces" held on this data rather than in
the abstract. partition_volume_error_rel is the non-overlapping half: every cell's leaf volumes must
sum to its cube's, and overlapping pieces would sum high while a gap would sum low. It reads
3.331e-16 on the four c2 rows and 1.776e-15 to 3.442e-15 on the eight c1c3 rows, against an
asserted bound of 1e-9. So the pieces are convex and they tile, and both are measurements.
The fidelity price of the M-116 comparison is on the row and it is not free. avian3d decomposes an
arbitrary fragment mesh; this substrate approximates the solid to the fidelity of a 6-DOP-cut grid.
volume_error_rel, the compound's volume against the folded field's volume sampled on a 96³ lattice
(compound_volume_after against field_volume_sampled): 0.000685 / 0.000096 / 0.000428 / 0.000236,
i.e. 0.0685% / 0.0096% / 0.0428% / 0.0236%. That is the column, and it is what the 79,008.6–106,819.7×
is bought with.
The vacuity control, its column and its value. The registered control is a count: orderings = 40320
on all four c2 rows, asserted, with permutations_distinct = 40320 asserted pairwise distinct before any
arm runs — M-36's own fixture reached in full rather than sampled. That count alone proves the arm ran
everywhere; it does not prove a 1 would have been a measurement, so three live controls sit beside it.
perturbed_hash_differs = true on all four rows: displacing brush 0's centre by 1e-9 — far below a
cell, so no plane moves across a cell boundary and the displacement can only show up in the coordinates —
changes partition_hash, asserted. That is the value that proves the fixture could have failed: the
instrument demonstrably says different when the input differs by one part in a billion, so
distinct_partitions = 1 on solve+canonical is a zero the instrument was able to break.
perturbed_topology_differs = true licenses the second zero separately: a 1e-9 nudge cannot move a
plane across a cell boundary, so it cannot license distinct_topology = 1, and a coarse nudge of a quarter
cell is applied and the leaf plane-triple sets must change. Without it, distinct_topology == 1 would be
P-70's C3 — a held clause with no instrument. And distinct_partitions_raw = 18720 in every arm, as
above. On the c1c3 side the population controls are fragments > 0 (1,065–4,941), convex_cells_before >
0 (2,439–22,224) and cells_cut_by_brushes > 0 (471–967) — C1 and C3 each had a non-empty population to
fail on, and the hash covers cells_hashed = 182 of the 8³ chunk's 512 cells, the ones a brush plane
actually crosses, because the other 330 receive no brush plane and would pad the measurement with a
constant.
Six fixture defects, every one caught by a control in this harness rather than by review, and the fourth cost an arm. (The brief for this entry said four; the harness documents six, and the last two are the ones that changed what C2 measures.)
cube_vertsaliased its cube-face plane ids. Corners were taggedi*2, 2+j*2, 4+k*2, which puts the x-max face on the same idset_cubewrites y-min to, y-max on z-min's id, and z-max onSURFACE_ID. Every corner on a far face then carried a repeated plane id,shared_tworeported false edges between unrelated vertices, and the false vertices bred: one piece reached 8.4 million vertices in a single 268 MB allocation and the process was OOM-killed. Caught bydegenerate_vertices == 0.- A split half was pruned with the wrong orientation. The first repair for (1) tested each candidate
against every plane the piece's tags mention as
n·x + d <= 0; the outside half of a split is bounded by the cut plane the other way round, so that test deleted it whole. One 16³fbm_terraincell reported its single surviving leaf at8.6e-5against a cube of1.5625e-2. Caught by the per-cell volume closure, at a relative error of exactly 1.0. - The compound did not carry each cell's surface plane. Ids
0..=6are rewritten per cell;fracturerestored the cube but notSURFACE_ID, so every piece bounded by the surface was measured against another cell's surface plane and pruned to nothing. Caught byfragments > 0. - The 14-DOP arm is cut, and the volume control is why — this is the instructive one. With the eight
cube-diagonal directions added to make a 14-DOP, one 16³
fbm_terraincell closed at 1.3495e-2 against a cube of 1.5625e-2 — 13.6% of the cube missing — and another emitted duplicated leaves. The vertex-tag clipper's rule that two vertices are adjacent exactly when they share two planes is sound for a simple polytope, one whose every vertex lies on exactly three facets, and an oblique 14-plane set makes non-simple ones: four planes through a point put three tagged vertices on one plane pair, two of them at the same position, and both chords to the third produce the same crossing vertex. Rather than report a piece count from an arrangement that does not tile its own cube, the arm was removed. Every row inp-84.csvisdop_dirs = 6— the axis-aligned DOP, exact for a box brush and a conservative enclosure for a sphere or a capsule. Fixing it needs a clipper that derives vertices from plane triples rather than from edges. That is a design change, not a tolerance, and it is the one piece of work this row files against the construction itself. - The canonical sort ran after the sums it was supposed to canonicalise. The inherited version sorted
each leaf's vertices by plane triple for the hash only, leaving
centroidandvolumesumming in the breadth-first split's emission order. Both are naive float sums, so both were ULP-order-dependent, and both feed a decision: the centroid picks the leaf's solid flag throughfold, the volume picks whether the leaf is a sliver at all. Two order dependencies manufactured by the instrument, standing in front of the exact question C2 asks. The sort now runs first, which makes every derived quantity a function of the leaf's vertex set. Caught by splitting the single hash into the three projections and findingdistinct_positionsanddistinct_solid_flagsdisagreeing for reasons one number could not distinguish. - The 6-DOP arm is not immune to defect 4 either, and
M-36's own fixture proves it. Axis-aligned was being treated as generic.simplicity_scanfindscoincident_plane_pairs = 3in 3 of the 182 cut cells,nonsimple_points = 36,max_planes_at_a_point = 4— and those 36 points are precisely the 36 zero-width leaves the sliver filter was silently absorbing. Before this scan existed,degenerate_vertices = 0andsingular_triples = 0both read clean, because neither counter can see two distinct ids naming the same plane.
What changed as a result.
- Do not build
A-027for cost — confirmed and sharpened rather than overturned.R-085's 45% has no convex-decomposition term in it, so C1's 79,008.6–106,819.7× is against a stage that does not exist in this crate yet. C1's real content is that Müller's 2013 result reproduces with three to four orders of headroom against its own bar on 2026 hardware, and four to five againstM-116's measured alternative — which is a reason the design is not the risk, not a reason to spend a phase on it. - If
A-027is ever built, two things are mandatory and both are one line. Solve each crossing vertex from its three plane equations on the ascending stable-id triple rather than lerping along the clipped edge — that is the whole difference between 6 and 2 distinct partitions and it costs a divide. And collapse coincident planes to the smallest stable id in the cell before arranging — that is the difference between 2 and 1. Together they are the difference betweenM-36's coordination-free story surviving at cell level and not. - The order-dependence is in the vertex names, not in the volume. 1,709 leaves, 1,026 solid, closure
3.331e-16, in all four arms: anyone shipping this can rely on the compound's geometry, its leaf count and its solid classification being order-free even in the naive version. What is not order-free is the plane triple a vertex carries, which is exactly what a replication hash signs. That distinction is worth carrying into any design that hashes geometry across peers. - C3's registered 4× bar should not be reused as written, and no replacement is proposed here because none of the three candidates in the file is resolution-free either.
- Stop tracking the convex-decomposition literature.
M-297holds: VisACD (arXiv:2604.04244) is a GPU method averaging 16.97 s per model against CoACD's 36.31 s — four orders of magnitude off a frame budget. Thirteen years after Müller, nobody has improved on preserving convexity instead of recovering it, andA-027proposes his construction without citing him. This row is the last time that literature needs a look. - One superseded mechanism is withdrawn. An earlier, smaller run of the same harness (6 rows, before
the
planes_modeaxis existed) attributed thesolvearm's residual 2 classes to "which near-degenerate leaves survive the sliver filter and the eps snap". That is wrong: the residue is coincident planes making the vertex tag ambiguous, andcanonicaltakes it to 1 without touching the sliver filter. That run's hashes —03131b1fc0cf55be,1edacb8eda3a17aa— appear in no committed file and are not quoted.
Would be shown wrong by: a coincident-plane group whose smallest stable id is not itself order-free —
which would mean canonical is only relabelling the ambiguity rather than removing it, and would take
solve+canonical off 1; a cell whose 6-DOP arrangement is non-simple for a reason simplicity_scan
does not read, since it scans the cube's six faces and the cell's cut set and nothing else; a
distinct_partitions of 1 arriving on a run where perturbed_hash_differs reads false, which would make
the 1 an instrument that cannot say different; a fracture whose cycles_per_fragment rises with cell
count in a way these two resolutions did not show, which would mean the plane-clip arrangement has a term
this fixture's 149–225 overlapped cells never reached; or a chunk resolution at which cell_growth_ratio
exceeds 4× and the denominator argument above does not account for it, which would mean C3 is measuring
something other than its own denominator.
💥 ✗65 / M-397 — C1 HELD at 80.3–81.8% and C2 FALSIFIED twice over: the copy is 0.035–0.050% and the BVH does not dominate either, so the collider's 45% is this crate's own weld and readiness gate at 80% of the build while all of parry3d is 18.2–19.7%; and C3 FALSIFIED at 1.017–1.047× against a 1.5× bar, at matched triangle and vertex count (P-85, R-085)
M. cargo bench --bench experiment_p85, docs/experiments/p-85.csv, 6 rows (7 lines with the
header), f32, amd-ryzen-9-5900x-12-core, ghz 4.1862–4.1890 on every row. Four registered arms
(arm = c1c2: fbm_terrain and gyroid at 33³ and 65³ samples per axis) plus two c3_match arms —
sphere at a searched 68³ and 137³, because C3's "at fixed triangle count" cannot be met on a shared
grid when one field is a surface everywhere and the other is one shell. Nine timed repeats after three
warmups, the repeat as the outer loop and the arm as the inner one, and the reported row is the repeat
whose total is the median, reported whole. Committed at 5c55f12, whose header carries no
(WORKING TREE DIRTY) and which is an ancestor of HEAD.
Every number below is read from the committed
p-85.csvat5c55f12. The measurements were first taken on a dirty tree at63c7161, with five sibling agents building on the host, and this entry does not quote that run (✗35,✗52). Every integer reproduced exactly —triangles,vertices,seam_boundary_edges92 / 324 / 200 / 684,degenerate_triangles2 / 12 / 6 / 6,unwelded_duplicate_vertices1 / 2 / 1 / 2,triangle_mismatch72 and 96,reps_agreeing_on_largest9/9. Every share and every ratio moved in the third decimal or less. The four figures worth naming because a reader may have seen the older ones:copy_share's top end 0.00056 → 0.00050, C3's 65³ ratio 1.024 → 1.017 (and its cycles counterpart 1.015 → 0.9975, i.e. now marginally below parity),collider_over_contouronsphere137³ 2.90 → 2.05, andresidual_share_worst_rep's worst cell ≤0.005% → 0.0372% — all four inside the same verdict by margins of one to three orders.
| clause | registered | measured |
|---|---|---|
C1 one of copy / construct / bvh / handoff is over 50% of the collider cost, at 33³ and 65³ on fbm_terrain and gyroid |
> 0.50 | HELD — largest_stage is handoff on 4 of 4 registered arms (6 of 6 rows), largest_share 0.803226–0.818325, reps_agreeing_on_largest 9 of 9 on every row. Carried by the registration's own bundling — see below |
| C2 the dominant stage is the triangle copy, not the BVH the docs blame | copy largest |
FALSIFIED, and the registered falsifier did not fire either — copy_share 0.000350–0.000500, bvh_dominates false on 4 of 4 |
C3 at fixed triangle count gyroid's collider costs ≥ 1.5× sphere's |
≥ 1.5× | FALSIFIED — c3_ratio 1.047287 at the 33³ pair, 1.017153 at the 65³ pair; c3_ratio_cycles 1.040373 and 0.997500 |
This was the phase's pivotal row, and it was scheduled first for exactly that reason. The registration says so itself — "THIS IS THE CHEAPEST ROW IN THE PHASE AND IT DECIDES WHICH OF P-81 AND P-84 IS WORTH DOING" — and both of those have since run on its answer. What it decided is recorded at the end of this entry.
The attribution, which is the point of the experiment:
| field | cells | triangles | copy |
construct |
bvh |
handoff |
(weld | readiness) | total |
largest |
|---|---|---|---|---|---|---|---|---|---|---|
fbm_terrain |
33³ | 3,944 | 0.0024 | 0.0221 | 0.8586 | 3.9173 | 1.5021 | 2.4152 | 4.8005 | handoff 0.8160 |
gyroid |
33³ | 10,628 | 0.0050 | 0.0262 | 2.5499 | 10.5610 | 4.0076 | 6.5534 | 13.1423 | handoff 0.8036 |
fbm_terrain |
65³ | 16,882 | 0.0083 | 0.0290 | 4.0934 | 18.6070 | 7.3476 | 11.2595 | 22.7379 | handoff 0.8183 |
gyroid |
65³ | 43,112 | 0.0203 | 0.0505 | 11.3394 | 46.5769 | 18.2347 | 28.3422 | 57.9873 | handoff 0.8032 |
sphere |
68³ | 10,556 | 0.0050 | 0.0263 | 2.4728 | 9.9597 | 3.7746 | 6.1851 | 12.4639 | handoff 0.7991 |
sphere |
137³ | 43,016 | 0.0204 | −0.0076 | 11.2770 | 45.5925 | 18.0430 | 27.5494 | 56.8825 | handoff 0.8015 |
Milliseconds. handoff is exactly weld_ms + readiness_ms on every row, to the bit. The shape is
field- and resolution-independent to about a percentage point across a 10.9× triangle range
(3,944 → 43,112) and two fields of opposite topology: readiness_share 0.484322–0.503105, weld_share
0.302843–0.323148, bvh_share 0.178850–0.198394, construct_share −0.000133 to +0.004602, copy_share
0.000350–0.000500. That constancy is itself C3's mechanism, and it is why the verdicts are read from
shares and ratios rather than from milliseconds (M-280, M-281).
construct_ms should be read as zero, not as a small stage. It is TriMesh::new's wall time minus an
out-of-band probe of rebuild_bvh's own body, and it is not clamped — sphere 137³ reads
−0.007550 ms, a negative in the committed file, which is the honest report that parry's non-BVH work is
below the noise floor rather than ✗52's clamped submit at 0.0000. bvh_share_of_construct says the
same from the other side: 0.974916–1.000670. trimesh_new_ms is recorded, so the subtraction is
reversible from the CSV: construct_ms + bvh_ms == trimesh_new_ms on all six rows.
C1 held on the registered list and is marginal on any finer one, and this must be said plainly
C1's HELD is carried by the registration's own decision to make handoff "anything between". Split it
into the weld and the readiness gate — the finest split the harness can produce — and the largest stage
becomes readiness on all six rows:
| arm | finest_largest_stage |
finest_largest_share |
|---|---|---|
fbm_terrain 33³ |
readiness |
0.503105 |
gyroid 33³ |
readiness |
0.498651 |
fbm_terrain 65³ |
readiness |
0.495185 |
gyroid 65³ |
readiness |
0.488765 |
sphere 68³ |
readiness |
0.496240 |
sphere 137³ |
readiness |
0.484322 |
C1's registered falsifier is "four stages each under 50%". Under the finest split that falsifier is
met on three of the four registered arms and missed on the fourth by 0.31 percentage points. So the
clause is robust on the four-stage list it was written against — 80.3–81.8%, never within 30 points of the
bar — and straddles the bar on any decomposition that separates the weld from the gate. Both
finest_largest_stage and finest_largest_share are columns, so this is in the artefact and not only in
prose. (Out of file, and stated as such: six runs of the same binary during development put that same
share between 0.437 and 0.536 — a spread this single-run file cannot show, and the reason the sensitivity
is reported rather than filed as a curiosity.) Any future prose quoting a share from this row must say
which decomposition it belongs to.
C2 is falsified by the prediction and by the folklore, and the answer is a third thing
The registered prediction was the copy, by analogy with ✗52. copy_share is 0.000350–0.000500 —
0.035% to 0.050% of the build, and against ✗52's geometry copy at 59% of a GPU extraction that is
three orders of magnitude down. The registered falsifier was BVH construction dominating, which would
have vindicated Godot's documentation; bvh_dominates is false on 4 of 4 registered arms and on all
six rows, with bvh_share 0.178850–0.198394. Neither the hypothesis nor the folklore it was contrasted
against survives.
Why the copy cannot dominate here, and why the registration's structural analogy is exactly backwards.
✗52's copy dominated because it crossed a bus. This one crosses nothing: copy_bytes is
72,144 to 775,728 bytes moved at copy_gb_per_s 30.06–38.18, which is memory bandwidth. On the CPU
side the bytes do not have to go anywhere, so the copy is a memcpy and a memcpy of 776 KB is free next to
a 46 ms walk.
Why parry's constructor is the BVH and nothing else is read from the source rather than inferred:
TriMesh::new is with_flags(v, i, TriMeshFlags::empty()), which moves the two buffers in, calls
set_flags(empty()) — which builds nothing — and then, because result.bvh.is_empty(), calls
rebuild_bvh() (parry3d-0.30.2/src/shape/trimesh.rs:724-751). There is no TriMesh without a BVH,
which is why bvh_ms is a transcribed probe run outside the total window and construct_ms is a
difference.
So the answer is the crate's own work, and it is arithmetic from the row. copy_ms + trimesh_new_ms is
everything parry3d does: 0.883057 / 2.581101 / 4.130744 / 11.410274 ms on the four registered arms,
which is 18.17% / 19.64% / 18.17% / 19.68% of the build (20.09% and 19.85% on the two sphere arms).
The other four fifths are weld::Welder's O(V) spatial hash and collider::readiness' T-001 validity walk
— an edge hash for the manifold counts, a link walk for bowtie vertices, a per-face area test. Both are
multi-pass walks driven by counts, not by geometry, which is the mechanism behind both the
field-independence of the shares and C3's falsification.
C3 is falsified at matched triangle and vertex count, which is what makes it airtight
| pair | triangles |
vertices |
cost_per_triangle (µs) |
cycles_per_triangle |
ratio | ratio, cycles |
|---|---|---|---|---|---|---|
gyroid 33³ vs sphere 68³ |
10,628 / 10,556 | 5,290 / 5,280 | 1.236571 / 1.180737 | 5101.14 / 4903.18 | 1.047287 | 1.040373 |
gyroid 65³ vs sphere 137³ |
43,112 / 43,016 | 21,532 / 21,510 | 1.345040 / 1.322357 | 5593.07 / 5607.09 | 1.017153 | 0.997500 |
triangle_mismatch is 72 and 96, i.e. triangle_mismatch_share 0.677% and 0.223%, both
asserted under 3%. Unplanned but recorded, the pairs also match in vertices to 10/5,290 = 0.189%
and 22/21,532 = 0.102% — so both drivers of the two dominant stages are held fixed, not just the one
the clause names. The governor-independent instrument agrees and at the 65³ pair crosses parity:
c3_ratio_cycles 0.997500 says gyroid is fractionally cheaper per triangle than sphere in
cycles. The cost is proportional to triangle count to within 5%, which the registration named as "the
best possible outcome for the scheduler".
The per-field structure C3 named is real, measured, and does not cost. gyroid carries
324 and 684 seam_boundary_edges against sphere's 272 and 536 (19.1% and 27.6% more) and
12 and 6 degenerate_triangles against sphere's 0 and 0. The mechanism exists; it moves
the cost by 2–5%, not by 50%. A degenerate sliver costs the same to hash and to walk as a healthy triangle.
M-279's rule: the new instrument agrees with the old one where they overlap
M-135 measured the 45% as collider::readiness at f64, mean share 45.0% against contour 29.0%, weld
25.5%, normals 0.4%. readiness_ms here is that same stage, at f32, in a different binary:
| arm | readiness_ms (p-85) |
collider_ms (stage_breakdown.csv) |
deviation |
|---|---|---|---|
fbm_terrain 33³ |
2.415150 | 2.504471 | −3.57% |
gyroid 33³ |
6.553404 | 6.774106 | −3.26% |
fbm_terrain 65³ |
11.259483 | 11.318704 | −0.52% |
gyroid 65³ |
28.342203 | 28.345036 | −0.01% |
Within 3.6% on all four arms, across a scalar change and two binaries. That is what says the two
harnesses are measuring the same stage, and it is the only reason this row is allowed to speak about
M-135's number at all. Note the denominators differ and must not be conflated: M-135's 45% is of a
four-stage pipeline that counts the weld separately, while readiness_share here is 48.4–50.3% of a
total_ms that includes the weld.
And M-135's 45% is a validity-check cost, not a collider build. Nothing in the shipped tree pays it:
parry3d is a dev-dependency by design and game_dig resolves its body against the field, not against
triangles. Any future prose treating that 45% as "the collider" should say "the collider check".
The vacuity control, and exactly how far its teeth reach
Registered: "the four stages must sum to the measured total within 5%, reported as a residual column, or
the decomposition is missing a stage." residual_ms is that column and it is asserted, on the row and
on the worst of the nine repeats. Measured: residual_share 0.000031 / 0.000011 / 0.000007 / 0.000003
on the registered arms and 0.000010 / 0.000003 on the sphere arms; residual_share_worst_rep at most
0.000372. copy + construct + bvh + handoff + residual == total on all six rows to the bit.
A zero has to prove it could have been non-zero (M-44), and here the proof is a named plausible
omission rather than an identity. The weld is precisely the stage a four-item list called
copy / construct / bvh / gate does not contain, and the registration's own hypothesis puts it in
contention ("or the weld that M-69 and ✗18 argue about"). So the harness also computes
residual_share_without_weld and asserts it exceeds the bar: it reads 0.302853–0.323148, six
times the 5% bar. The instrument is shown firing on the exact omission it exists to catch.
And the control's limit is stated rather than hidden. stages_above_bar is 2 on every row and
min_stage_share is −0.000133 to 0.000500: only bvh and handoff are individually above 5% of the
total, so the residual is blind to dropping copy or construct altogether. The CSV names which
stages those are instead of implying the control is total.
Seven fixture defects, each caught by one of this harness's own controls rather than by review
- C3 matched the sphere's resolution to
gyroid's pre-weld triangle count while the row records the post-weld count parry is actually handed. Caught byassert_eq!between the fixture phase and the timed arm:left: 10628, right: 10632. Welding collapses duplicate vertices and a triangle whose corners collapse stops being a triangle — and 10,632 is exactly whatstage_breakdown.csvrecords forgyroid33³, so the two counts are both real and the wrong one was being matched. "Fixed triangle count" has to mean the count the collider receives. - The C1 sensitivity line aggregated the finest split with
maxover arms instead ofmin. Caught by reading the harness's own printed output, which announced "C1 would be HELD" from the best arm. C1 is a conjunction over four arms, so its weakest arm decides it, and here the two answers genuinely differ: on the committed run the registered arms'finest_largest_shareruns 0.488765 to 0.503105, somaxclears the bar andmindoes not. Fixed to the minimum, with both ends printed. c3_ratiomeantgyroid ÷ sphereon one row of a pair andsphere ÷ gyroidon the other. Caught by reading the emitted CSV back. A column whose meaning depends on which row you are reading is a corrupt-but-plausible artefact — correct header, garbage data. C3's claim has a direction, so the column has one; verified in the committed file, where both rows of each pair now read 1.047287 and 1.017153.- Five independent per-stage medians made
residual_msread +4.33% ongyroid65³ — inside the registered bar and pointing at a missing stage — while the worst single repeat's residual read 0.000%. Caught byresidual_share_worst_repdisagreeing withresidual_shareby three orders of magnitude. Every repeat's stages summed to its own total exactly; the 4.33% was five medians disagreeing about which repeat they came from, and it would have made the registered columns fail to add up in the CSV. Fixed by reporting the repeat whose total is the median, whole; per-stage medians are kept as*_median_msandmedian_mixing_share(−0.001821 to +0.004430) states how far apart the two views are. - Sequential arm ordering let a machine excursion land on one arm of a ratio. Caught by the
spherearm's wall time moving 58% between two runs of the same binary while its cycle count moved 1.5% —M-280arriving uninvited. Fixed by making the repeat the outer loop and the arm the inner one, so all six arms are built inside each of the nine repeats and an excursion lands across every arm. The price is that each build starts on a cache the other five just evicted, which raises absolutes uniformly and leaves the shares where they were — and it is what a chunked pipeline building chunk after chunk actually does. - The counted (hardware-counter) build ran outside the interleaved regime, which is a control firing
on its own scheduling. Caught by
counted_over_medianreading 1.355–1.372 on a run whose residuals were 0.00002%. Fixed by giving the counted build its own interleaved wave; on the committed runcounted_over_medianis 0.985141–1.012489. duplicate_verticeson the row is measured after the weld and is therefore zero by construction —M-44's zero exactly, a number that could not have been non-zero, and it is 0 on all six rows. Caught while trying to price the weld. Fixed by reading the unwelded single-chunk mesh once, untimed, inprepare:unwelded_duplicate_vertices= 1 / 2 / 1 / 2 on the registered arms. That one pair of columns turned "the weld is 30% of the build" into "the weld is 30% of the build and removes one or two vertices per chunk", which is the finding that prices the shipped examples.
What changed as a result
The redirection this row was scheduled to make: R-081, not R-084.
R-084(convex decomposition) is the wrong half, for cost. It acts strictly downstream of the copy — it replaces or augments theTriMeshconstructor — so its entire reachable share iscopy_ms + trimesh_new_ms, 18.17–19.68% of the build on the registered arms, and a convex decomposition costs far more than a binned SAH BVH build. A construction-side attack has a ~20% ceiling on a number it would raise.R-084has since run and found no convex-decomposition term anywhere in the 45% — so "do not buildR-084for cost" is correct about the chunk collider and silent about the stageR-084's own C1 is denominated in. If it is built, build it against a contact-quality bar, not a time one.R-081(the field query) is the right half, because it removes the artefact rather than a stage of it: no weld, no gate, no copy, noTriMesh, no BVH. It removes 100% of 4.800489–57.987347 ms per chunk — one 65³gyroidchunk is 3.62 frames at 16 ms — and 11.410274 ms of that survives even if the weld and the gate are both skipped.R-081recomputed its share against this file and found there is no query half at all: all four registered stages are construction, and the residual bounds any query component ats ≤3.12e-5 (0.000150 ms of 4.800489, the largest of the six). SoR-081's C1 SHARE premise was falsified as a premise, by this file, before that harness existed.- The cheapest win is neither ticket, and it is not a ticket.
collider::readinessis 48.4–50.3% of the build and it is a diagnostic, not a requirement — parry refuses only an empty index buffer. Running the gate in debug and never in release halves the cost with no algorithm at all. - The shipped examples are already priced correctly.
bevy_isomesh/examples/game_walk.rs::to_trimeshandgame_capsule_walkbuild one collider per chunk and neither welds nor runs the gate. Givenunwelded_duplicate_verticesof 1 or 2 per chunk, that is the correct choice rather than an omission: they pay 18.17–19.68% and forgo two coincident vertices and a diagnostic. The weld remains load-bearing for a collider assembled from more than one chunk — the two-chunk probe measures 92 / 324 / 200 / 684seam_boundary_edgesclosed by it,M-69's mechanism reproduced per field.
Godot's folklore, measured inside one binary, is testimony about one game's fields. The registration
cites Godot Voxel Tools — "creating a collider from a mesh is actually much more expensive than meshing
itself (about 3 to 5 times)", no timings, no hardware. Comparing against M-135's committed contour_ms
would be a cross-build ratio, which M-281 forbids, so the contour is re-timed in this binary:
collider_over_contour reads 9.365259 and 5.942653 on gyroid, 5.305239 and 2.045088 on
sphere, and 0.642880 and 0.411314 on fbm_terrain — inverted on the field this game actually
meshes, where the contour is 1.56× and 2.43× the collider build. The two costs are denominated in
different things: the contour is per-sample and dominated by field evaluation (fbm_terrain's 65³
contour is 55.281225 ms for 16,882 triangles while gyroid's is 9.757821 ms for 43,112), and the collider
is per-triangle. Godot's 3–5× is the ratio of triangles-per-sample to field-cost-per-sample, and says
nothing about collider generation being intrinsically expensive.
Would be shown wrong by: copy_share rising toward ✗52's regime on any path where the vertices must
be converted rather than memcpy'd — an f64 mesh narrowing into glam::Vec3, or a device-side buffer, is
the obvious candidate and no row here has one; a bvh_dominates true on any field, which would vindicate
the Godot documentation after all; a field whose c3_ratio reaches 1.5× at matched triangle and vertex
count, which would restore C3 and mean the per-field structure does cost after all; a readiness_ms that
stops agreeing with M-135's collider_ms within a few percent, which would mean the two harnesses are
not measuring the same stage and this row cannot speak about the 45%; or a decomposition that splits
handoff and reports the largest stage above 50% on all four registered arms — the committed
finest_largest_share runs 0.488765 to 0.503105, so that observation would settle C1 on the finer list
rather than leave it straddling.
💥 ✗66 / M-398 — C1 FALSIFIED at 3.01% against a 20% bar, and the bar was 15.29× chance rather than 2×: a capsule hits a sliver at 2.30× its area share, which is real enrichment and still six times too little, so the recorded degenerate_triangles metric has no gameplay consequence. C2 FALSIFIED by the letter of its column at 1.134 and 1.055 ± 0.101 over episodes, which does not reopen M-133. C3 HELD weakly — 0 of 89 against a null expectation of 1.052 (P-86, R-086)
M. cargo bench --bench experiment_p86, docs/experiments/p-86.csv, 3 rows, f32, Zen 3
(amd-ryzen-9-5900x-12-core). Two independent fixtures on fbm_terrain — a game_capsule_walk
path driven until the body itself makes 495 chunk-column crossings (28,723 steps, 2,899.77 m)
and a 10⁴-step randomised walk over an eight-chunk square — plus their pooled combined row;
the controller is collide-and-slide over parry3d swept-capsule casts at a fixed dt of 0.016667
s, with no Bevy under crates/, and the field arm is game_dig::resolve_body transcribed with the
✗45/M-363 chord ground probe. Committed at 28194ca, whose provenance line carries no
(WORKING TREE DIRTY) and which is an ancestor of HEAD.
This entry quotes the clean-tree re-run and not the run the harness was built on. The original pre-run stamped
# commit 63c7161 (WORKING TREE DIRTY)while ~25 sibling agents were compiling, and that file was never committed —docs/experiments/p-86.csvhas exactly one commit,383f77f"p-86.csv - re-run on a clean tree". One number moved and it is the wall clock:wall_seconds22.0 → 16.4, a 1.34× speed-up from the quiet machine. Every other value on all three rows is identical — all 2,961 stops, all 594 episodes, all 753,052 triangles,worst_decile_area_share0.01307925,seam_excess_episodes_sigma0.100977,chord_inset_measured0.114346. No clause here is denominated in time. Every verdict is an integer count, a ratio of two integer counts, or an area share of a fixed mesh, which is✗24's rule (gate the count the ratio samples) andM-281's (a millisecond is a property of the binary) applied before the fact rather than after — and it is why a 34% clock move left all three verdicts untouched.wall_secondsis printed and carries nothing. No clause names a second machine, so nothing here is BLOCKED.
| clause | registered | measured |
|---|---|---|
| C1 at least 20% of controller stops land on a triangle in the bottom decile of the aspect-ratio distribution | ≥ 0.20 | FALSIFIED — 0.030057, i.e. 89 of 2,961; 0.0287–0.0392 on every reading of the clause |
| C2 seam-adjacent triangles carry no more stops per triangle than interior ones | ≤ 1.0 | FALSIFIED by the column — seam_excess_ratio 1.134027; but 1.055 ± 0.101 over episodes and the two arms straddle unity |
| C3 the field-query path removes all of C1's stops | stops_field_path = 0 |
HELD, and weak — 0 of 89, against a null expectation of 1.052 |
This is one of the six rows Phase 24 registered as an expected null, and it came back a null. The registration's own falsifier says so: "C1 by under 20%, which would mean slivers are not what stops a character and the recorded metric has no gameplay consequence — a genuine null and worth the afternoon."
The SHARE recomputation is what makes this a strong null rather than a shrug, and it has to
lead. The registration reads "SHARE: this is a rate, not a ratio of a total." That is true and
incomplete. It is true in ✗51's sense: worst_decile_fraction is
stops_on_worst_decile / stops_total, both produced by this harness, so the statistic spans 0 to 1
and C1 is not arithmetically unreachable. What the registration never does is name the null
rate, and the null rate is the whole result.
| quantity | column | value |
|---|---|---|
| the decile's share of triangles, by count | decile_triangles / triangles |
75,306 / 753,052 = 0.100001 |
| the decile's share of triangles, by area | worst_decile_area_share |
0.01307925 |
| C1's bar under a uniform-over-triangles null | — | 0.20 / 0.100001 = 2.00× chance |
| C1's bar under an area-weighted null | c1_bar_over_chance |
0.20 / 0.01307925 = 15.29× chance |
| the enrichment actually measured | 0.030057 / 0.01307925 | 2.298× chance |
| what C1 needed on top of what happened | 15.29 / 2.298 | 6.65× |
A decile is 10% of the triangles by construction, so reading the clause against a count share makes the 20% bar a mere 2× chance and the clause looks like a coin-flip proposition. A swept capsule does not sample triangles by count. It hits a triangle roughly in proportion to the area that triangle presents to the sweep, and a bottom-decile triangle is near-zero-area by definition — that is what puts it in the bottom decile. So the honest null is the decile's area share, 1.308% of the mesh, and C1's bar is 15.29× chance. Stated the other way: reaching 20% of 2,961 stops needs 592 stops on the decile, and 89 arrived.
A clause needing 15× area-weighted enrichment on a mesh whose slivers are coplanar with their
neighbours was expected to fail, and this is the arithmetic the registration could not reach before
the run. The count share 0.100001 is a property of the definition of a decile and was known a
priori; the area share 0.01307925 is a property of fbm_terrain meshed by Marching Cubes at
0.5-unit cells and could only be measured. Both are in the file, which is why the null is
quantitative rather than a shrug: the enrichment is not 1.0. Slivers are hit above their area
share, by 2.30×. They are simply nowhere near 15×.
C1, on every reading of the clause:
| reading | numerator | denominator | fraction | bar |
|---|---|---|---|---|
registered — the blocking triangle is in the bottom decile of q over all meshed triangles |
89 | 2,961 | 0.030057 | 0.20 |
generous — any triangle blocking that step is bottom-decile (stops_any_blocker_worst_decile) |
116 | 2,961 | 0.039176 | 0.20 |
decile over the tested population instead of the whole mesh (aspect_ratio_p10_tested 0.235517) |
96 | 2,961 | 0.032421 | 0.20 |
path arm alone (aspect_ratio_p10 0.223288) |
70 | 2,298 | 0.030461 | 0.20 |
randomised arm alone (aspect_ratio_p10 0.222721) |
19 | 663 | 0.028658 | 0.20 |
The two independent fixtures agree to 0.18 of a percentage point — 3.046% over 495 seam
crossings against 2.866% over a 10⁴-step randomised walk — and the widest reading of the clause is
3.92%. There is no reading between 2.9% and 3.9% that comes within 5× of the bar. q is the crate's
own mean-ratio quality, 2√3·|cross| / Σlᵢ², transcribed from validate_indexed: 1 for
equilateral, 0 for degenerate, so "the bottom decile of the aspect-ratio distribution" is the
bottom decile of the number the crate already records.
The crate's own degenerate_triangles metric, which is the thing this experiment exists to
connect to a gameplay symptom, is stricter than a decile and scores exactly zero. It counts
area ≤ AREA_EPSILON_REL · cell_size² with AREA_EPSILON_REL = 1e-6 — numerically zero area, not
merely thin:
| column | value |
|---|---|
degenerate_triangles |
225 of 753,052 = 0.0299% of the mesh |
degenerate_triangles_tested |
8 — the ones the broadphase ever handed to the controller |
stops_on_degenerate |
0 of 2,961 |
| expected stops on 8 tested triangles at the measured 0.029827 stops per tested triangle | 0.24 |
stops_on_degenerate = 0is honest and low-powered, and the entry says which. Only 8 of the 225 degenerate triangles were ever within reach, so the expected count under the null is 0.24 and a zero against 0.24 proves little on its own. The load-bearing C1 answer is the bottom-decile one — 89 stops attributed across 9,928 tested decile triangles — which has real power. The vacuity assert (degenerate_triangles == 0 || degenerate_triangles_tested > 0) is what makes the zero a measurement rather thanM-44, and it is the weaker of the two instruments by design.
C2 is FALSIFIED by the letter of its registered column, and it must not be read as reopening
M-133.
| definition | seam tris | interior tris | seam stops | interior stops | excess |
|---|---|---|---|---|---|
registered — x/z band, tested denominator |
23,109 | 76,164 | 758 | 2,203 | 1.134027 |
x/z band, all meshed |
— | — | 758 | 2,203 | 1.122359 |
| all axes, tested | — | — | 2,164 | 797 | 1.190351 |
| all axes, all meshed | 508,011 | 245,041 | 2,164 | 797 | 1.309678 |
c2_holdsreadsfalseonpath_495_crossingsandcombinedandtrueonrandom_10k_steps, and that disagreement is the finding rather than the column. The clause says "no more", so 1.134027 > 1.0 is a genuine failure of the registered inequality and the verdict stands as FALSIFIED. But the sign is not reproducible between the two fixtures: 1.204331 on the seam-crossing path and 0.907098 on the randomised walk, two walks on the same field and the same mesh. A lip mechanism at a chunk join does not flip sign between two walks over it. Reading thefalseas "seams stop characters" is a misparse of a column whose companion row readstrue.
Three measurements say the excess does not survive its own error bar, and all three are in the file:
(a) The two arms straddle unity. 1.204331 and 0.907098.
(b) Over episodes — the effective sample size — the excess is inside one sigma of 1.0. A body
climbing one 55° face stalls on every frame of the climb, so the raw stop count is autocorrelated
and a Poisson bar over it is far too tight. stop_episodes counts maximal runs of consecutive
stalling steps: 2,961 stops are 594 episodes.
| arm | seam_excess_ratio |
seam_excess_episodes |
seam_excess_episodes_sigma |
σ from 1.0 |
|---|---|---|---|---|
path_495_crossings |
1.204331 | 1.025551 | 0.122464 | 0.21 |
random_10k_steps |
0.907098 | 1.116542 | 0.178934 | 0.65 |
combined |
1.134027 | 1.054675 | 0.100977 | 0.54 |
The episode sigma is excess · √(1/seam_stops + 1/interior_stops) over episode_seam_stops 144 and
episode_interior_stops 450. The same expression over the raw counts (758 and 2,203) gives
0.0478, against which 1.134027 sits 2.81σ high — so the raw bar is 2.11× too tight, and
reporting the raw 1.13 as a finding is exactly the error the episode counter exists to prevent.
(c) The slope confound is measured and absent for the registered bucket. Stops happen where the terrain is steep, so any bucket steeper than its complement carries more stops for a reason that has nothing to do with what the bucket is named after.
| bucket | mean \|∇h\| inside |
mean \|∇h\| outside |
|---|---|---|
x/z seam band (registered) |
mean_slope_xz_band 0.9480 |
mean_slope_off_xz_band 0.9488 |
y band |
mean_slope_y_band 0.9608 |
mean_slope_off_y_band 0.9307 |
| at stops | mean_slope_at_stops 1.4497 |
population 0.9488 |
The registered bucket is slope-neutral to 0.08%, so its 1.13 is not a slope artefact — it is noise.
The y band is measurably steeper, which is why the all-axis 1.310 is a slope excess and not a seam
excess (defect 1 below).
The honest summary, which is not the column: the registered inequality fails at 1.134 on 2,961
autocorrelated stops; over the 594 independent episodes the excess is 1.055 ± 0.101, 0.54σ from
unity, with the sign not reproducible between two fixtures and the slope confound measured at zero.
M-133 stays a topology claim. C2's registered falsifier — "a seam excess, which reopens M-133's
'not reliably seam-closing' as a gameplay defect rather than a topology one" — describes an
observation this run did not make.
C3 is HELD and weak, and the entry says so out loud. stops_field_path = 0 on all three rows.
The number that makes it weak is in the file beside it:
| column | path | random | combined |
|---|---|---|---|
stops_field_replay_all — field replays that stalled, over all stops |
34 | 1 | 35 |
stops_total |
2,298 | 663 | 2,961 |
stops_on_worst_decile |
70 | 19 | 89 |
stops_field_path_expected = stops_on_worst_decile · stops_field_replay_all / stops_total |
1.036 | 0.029 | 1.052 |
stops_field_path |
0 | 0 | 0 |
The same replay fires on 35 of 2,961 stops — 1.18% — so under the null that a bottom-decile stop is
an ordinary stop, the expected count inside C1's 89-stop set is 1.052. A zero against an
expectation of roughly one is not significant (p ≈ 0.35 under Poisson). C3 is scored HELD because
its registered falsifier is "any surviving stop" and none survived; it is scored weak because
the instrument had about one expected event to remove. field_control_stalls = 569 proves the
instrument can fire at all, and the 35 live replays prove it fires on real data — so this is not
M-44. It is a real zero with almost no power, which is a different and smaller thing.
The mechanism by which the field path removes those stops is measured, not argued, and it is not
flattering. The field controller does not clear a sliver by being smarter; it clears it by
standing inside the rock. Replaying each mesh-controller stop through the transcribed
resolve_body and then asking parry3d how deep the resulting capsule sits in the crate's own
triangles:
| column | value | as a fraction of the 0.4 capsule radius |
|---|---|---|
field_penetration_mean |
0.0864 | 21.6% |
field_penetration_max |
0.1413 | 35.3% |
mesh_penetration_max |
0.0013 | 0.3% |
And on its own trajectory the field controller stalls more, not less: stops_field_walk
3,346 against the mesh arm's 2,961. game_dig's own comment prices this error at "18% of a
radius into the steepest slope, which is 7 cm and invisible"; on fbm_terrain it is 8.6 cm mean
and 14.1 cm max, which understates by 2.02× on a field that comment is not written about.
Mechanism: what stops a capsule on fbm_terrain is a hillside, not a triangle.
mean_slope_at_stops is 1.4497 against a population mean of 0.9488 — stops happen where
|∇h| is 52.8% above average, i.e. on 55.4° faces against a 43.5° mean, with
steepest_gradient 2.5453 (68.6°) available. Collide-and-slide loses horizontal progress as sin²θ
when it climbs, so M-115's STALL_SHORTFALL of 0.50 is precisely a 45° gate: every stop
this harness records is a 45°-or-steeper face, which is correct geometry doing its job.
The reason the sliver enrichment stops at 2.30× is geometric and it is the run-independent statement of this result: a Marching Cubes sliver is a thin triangle lying in the same plane as its neighbours. It presents almost no area to the sweep and it does not stick out, so a capsule that reaches its cell is nearly always stopped by the fat triangle beside it. Removing every bottom-decile triangle removes at most 3.0% of stops, and those stops are on 55° faces the fat triangles in the same cells would have stopped anyway. The enrichment is real (2.30×, not 1.0) and the payoff is not (3.0%, not 20%).
The registered vacuity control, its columns and its values. The registration asks for "a
non-zero stop count on both arms, and the bottom aspect-ratio decile must be non-empty, both
reported as counts". Both are assert!ed in row(), and two more were added because the
registered pair does not cover C3:
| control | column | value |
|---|---|---|
| registered 1 — non-empty bottom decile | decile_triangles |
75,306 (9,928 of them decile_triangles_tested) |
| registered 2 — non-zero stops, path arm | stops_total |
2,298 |
| registered 2 — non-zero stops, randomised arm | stops_total |
663 |
| added 3 — attribution complete | unattributed stops | 0, assert_eq! |
| added 4 — C3's instrument can fire | field_control_stalls |
569 against a vertical wall |
| added 5 — both C2 buckets populated | seam_triangles_tested_xz / interior_triangles_tested_xz |
23,109 / 76,164 |
| added 6 — the degenerate bucket was reachable | degenerate_triangles_tested |
8 |
Why decile_triangles = 75,306 proves the fixture could have failed. The decile is not an empty
tail invented by a percentile on a short list: it is 10.0001% of a 753,052-triangle distribution,
its threshold aspect_ratio_p10 = 0.223245 sits deep inside q's range (1.0 is equilateral),
9,928 of its members were actually handed to the controller, and the fixture did land 89 stops
on them. Reaching C1's 592 stops therefore required no triangle the fixture did not have and no stop
the fixture did not produce — only 6.65× more enrichment than the 2.30× observed. The 20% bar was
reachable in fact and not only in arithmetic, and it was missed by a factor of 6.65. Under the
count-share reading it would have needed only 2.00× chance and was still missed. The vacuity pair
is also why the second arm matters: two fixtures with independent stop populations (2,298 and 663)
landing on 3.046% and 2.866% is a null with a reproducibility claim attached, not a single walk's
number.
Five fixture defects, all caught by this harness's own controls rather than by review.
- The all-axis seam band is not a seam test. A band one cell either side of
y = 0— a real chunk plane — selects the terrain whose height is near zero, and on an fbm heightfield that is the zero-crossing band, which is the steepest part of the surface. It bucketed 465,178 of 688,728 triangles (67.5%) as "seam" on the path arm. Caught by the raw counts and then quantified:mean_slope_y_band0.9608 againstmean_slope_off_y_band0.9307, so theyband is measurably steeper and steepness is what causes stops. The all-axis excess 1.309678 is therefore a slope excess. The registered columns usegame_capsule_walk::measure's ownx/ztest, which is the definition that answers "confirmM-115from the controller's side", and that bucket is slope-neutral (0.9480 against 0.9488). ensureinflates the interior denominator. It meshes a whole chunk when the body comes withinREACHof it, so a chunk the walk merely clipped contributes ~500 triangles of which only the ones by its own boundary were ever reachable — a seam excess manufactured by the meshing policy. Caught bytriangles753,052 againsttriangles_tested99,273: 86.8% of the meshed denominator was never handed to the controller. A per-triangletestedflag set in the broadphase is now C2's denominator. It moves the combined excess from 1.122359 to 1.134027 — so the defect was not the cause of the excess, and the number is now over a denominator that cannot manufacture one.- Stops are autocorrelated and the raw error bar is 2.11× too tight. 2,961 stops are 594
episodes. Caught by the two arms disagreeing in sign on C2 (1.204331 against 0.907098), which
is impossible at the raw-count bar of ±0.0478.
seam_excess_episodes1.054675 ± 0.100977 is the number that says C2's 1.13 is not evidence of a seam defect; without it this entry would have reported a 13% seam excess as a finding. - The ground-probe lift check measured the spawn height, twice. Version 1 bucketed hover by the
spawn column's gradient, but
resolve_fieldpushes along the gradient, which is mostly horizontal on a slope, so a body dropped on a gentle column slides into a steep one; it read 0.2342 against a 0.63 gradient. Version 2 spawned 0.25 above the terrain, at which height the probe already answers, so gravity was cut on step one and every column reported 0.245 = spawn minus one step — chord and flat cross then returned identical maxima and the discriminating assertion fired on a correct lift. Caught by the assertions themselves, twice. The check is now a quasi-static trigger measurement plus an exact bound derived from the probe's own five sample points with the terrain rise read from the field, plus a built-in mutation test:chord_inset_measured0.114346 againstchord_inset_expected0.114343,chord_excess_over_bound−0.000023, and✗45's flat cross atflat_excess_over_bound+0.114154 withflat_cross_hover_max0.735 againstchord_hover_max0.645. The transcription is pinned to three decimals rather than to an inequality, and the bound check is demonstrably able to fire. - C3's zero has almost no power and nothing in the registration says so. Caught by emitting
stops_field_replay_all(35 of 2,961) and derivingstops_field_path_expected= 1.052. C3 is scored HELD with the expectation printed beside it; a real test of "the field path removes sliver stops" needs roughly 10× the stops or a fixture that manufactures slivers deliberately.
Not a defect, and recorded because it sets the direction of every deviation: this controller stops
on 8.00% of steps (2,298 of 28,723) where M-115's Avian body stalled on roughly 2% of frames.
Expected, and in the honest direction — no friction where Avian has 0.4, no step offset either way,
and a commanded rather than integrated horizontal velocity. It gives C1 four times the stop sample
M-115 had, and C1 still came back at 3%.
What changed as a result. This is a "do not build this" row, and that is a conclusion.
- Do not promote
degenerate_trianglesfrom a metric to a gate, and do not add sliver collapsing or quality-driven remeshing for the controller's sake. The measured ceiling on removing every bottom-decile triangle is 3.0% of stops; the crate's own degenerate count is 0.0299% of the mesh and took 0 stops.M-115's open question — how many of those stops are real — is answered: at least 96% of them, and by the geometry rather than by the extractor. M-133is not reopened. It stays a topology claim, on 1.055 ± 0.101 over independent episodes, a sign that flips between two fixtures, and a slope confound measured at zero.- A decision is surfaced and not taken. The field-query path does remove the bottom-decile
stops, by penetrating the surface 8.6 cm on average and 14.1 cm at worst — 21.6% and 35.3% of a
capsule radius — while stalling more on its own trajectory (3,346 against 2,961). That trade
belongs to the owner.
game_dig's "at worst 7 cm and invisible" comment is measured wrong forfbm_terrainby 2.02×; that is a comment fix in a file this ticket may not touch, left as a note rather than an edit. - Nothing landed in the crate.
crates/isomesh/src/**untouched; the change is the new bench and its[[bench]]block.
The one sentence the crate needs: the recorded degenerate_triangles metric has no gameplay
consequence — 3.01% of controller stops fall on the bottom aspect-ratio decile against a
registered 20% bar and against an area-weighted chance of 1.31%, and not one of the 2,961 stops fell
on a triangle the crate actually counts as degenerate.
Would be shown wrong by: a fixture whose slivers are not coplanar with their neighbours — a step, a lip, or a transition seam that leaves a thin triangle standing proud of the surface — putting ≥ 20% of stops on the bottom decile, which would mean the 2.30× enrichment measured here is a property of a smooth heightfield rather than of thin triangles; or a controller with a step offset, which climbs over the fat triangle and leaves the sliver as the only blocker; or any stop landing on a triangle the crate counts as degenerate once more than 8 of the 225 are within the controller's reach.
💥 ✗67 / M-399 — C1 and C2 HELD, C3 FALSIFIED: an octree navigation graph built on the sign bitmap and never on a triangle repairs P-72's eleven-edit dig in 0.1433–0.4366 ms for the worst single edit and 0.8793–2.5396 ms for all eleven, over a repair set 1.50–1.83× the crate's own dirty-cell count that grows 1.6355× while the world grows 512× — but the convexity-preserving merge gives 2.5492–3.8597×, not the registered 5×, because the order of magnitude is in the octree, not in the merge (P-87, R-087)
M. cargo bench --bench experiment_p87, docs/experiments/p-87.csv, 16 rows, scalar f64,
amd-ryzen-9-5900x-12-core with clock_mhz 4202 on every row. Two fields (fbm_terrain, gyroid)
× four world sizes (32³–256³, 512× in cells) × two eleven-edit traces at 4³ chunk granularity,
radius-6-cell spherical brushes, the height probed per edit at that edit's own x — P-72's trace
inherited literally, plus an added breakthrough arm. Median of three traces per arm; every integer
asserted equal across reps. Committed at 383f77f, whose provenance line carries no
(WORKING TREE DIRTY) and which is an ancestor of HEAD (782188c).
Every number below is read from the committed
docs/experiments/p-87.csvat383f77f. The harness's first artefact was63c7161 (WORKING TREE DIRTY), taken while ~25 sibling agents were compiling, and this entry does not quote it (✗35,✗52). Every integer and every integer-derived ratio reproduced to the last digit —repair_factor1.5025–1.8257,repair_growth1.6355 / 1.6750 / 1.0366 / 0.9717 at 256³,reduction3.8597 / 3.6759 / 3.6048 / 3.5660 and 2.5492 / 2.5524 / 2.5575 / 2.5653,merge_drift1.0011–1.2369,nav_dirty_chunks / mesh_dirty_chunks0.7567–0.9326,topology_changes0 and 2 — which isM-279's rule satisfied: the quiet run agrees with the dirty one on everything that is not a clock. Every clock moved, and one of them moved enough to change what may be said. Worst single edit 0.1730–0.5117 → 0.1433–0.4366 ms; whole-trace 4.2487 → 2.5396 ms worst, a 1.67× move on the identical binary and fixture;build_msat 256³ 212.4876 / 179.5515 / 220.5410 / 281.2375 → 121.4720 / 120.4441 / 164.9126 / 167.1912 (1.34–1.75× faster);rebuild_over_repairat 256³ 495.44 / 357.90 / 545.94 / 549.64 → 468.66 / 361.05 / 645.90 / 382.96, one element moving 30%. The consequence is spelled out under C1: the eleven-edit reading of the 2 ms bar is not a gate, and the entry states it as an integer instead (✗24,M-281).
| clause | registered | measured |
|---|---|---|
| C1 local repair after P-72's eleven-edit dig costs under 2 ms at 4³ granularity | octree_update_ms + graph_update_ms < 2.0 |
HELD — 0.1433–0.4366 ms, 4.6–14.0× under the bar, on all 16 rows (c1_holds true ×16). Under the eleven-edits-in-one-frame reading it fails on 4 of the 8 p72_dig rows (2.3611–2.5396 ms) and holds on all 8 breakthrough rows (0.8793–1.1847 ms) — see below; the clause as registered is the single-edit one. |
| C2 the repair set is edit-proportional, factor < 3 against the dirty set, and does not grow with world size at fixed edit size | repair_factor < 3 and repair_growth < 2 |
HELD — repair_factor 1.5025–1.8257 on all 16 rows; repair_growth 1.6355 / 1.6750 (p72_dig) and 1.0366 / 0.9717 (breakthrough) at 256³ while world_total_cells grew 512× |
C3 the convexity-preserving merge gives ≥ 5× cell reduction on both fields, and gyroid is worst |
reduction ≥ 5 on both, gyroid < fbm_terrain |
FALSIFIED on the bar — 3.5660–3.8597 on fbm_terrain, 2.5492–2.5653 on gyroid, 1.30–1.96× short of 5×. The ordering half HELD: gyroid is worst at all four world sizes. |
SHARE, and it is the reason none of the three clauses needed an Amdahl ceiling. The registration's
SHARE line is "C1 moves the whole navigation-rebuild stage, currently unbuilt" — share 1.0. ✗51's
1/(1 − s + s/factor) does not bind, and for a plainer reason than share 1.0: none of the three clauses
is a speedup against a baseline. C1 is an absolute latency bar on a stage that does not exist yet, C2 is
a ratio of two directly counted sets, C3 is a ratio of two directly counted sets. All three were
arithmetically reachable before the run and the harness prints that before its first row rather than
discovering it afterwards. What arithmetic could not reach before the run is C1's second reading and C2's
shape. The registration says "the local repair after P-72's eleven-edit dig trace costs under 2 ms" and
does not say whether the subject is one edit or the trace; the two readings differ by 8.19–9.82× on the
p72_dig arm and 2.71–3.06× on the breakthrough arm, and which one a frame budget cares about is the
trace. And C2's falsifier is world-proportional growth, whose negation is not derivable from the
mechanism alone — a local repair whose leaf surgery happened to dissolve
a world-sized region would still be "local" by construction and world-proportional by measurement. The
only thing arithmetic settled in advance is the falsifier's own magnitude: 32³ → 256³ is 512× in cells,
so anything short of that is a measurement and not a tautology.
The comparison the registration invites and this entry refuses. Massonnat & Verbrugge measure octree
update 0.22–1.36 ms, local graph update 0.03 ms, ~1 ms total on an Intel Core i7-12700H. This is a Zen
3 at 4202 MHz. M-281 forbids that as a gate, so the paper's figures are the reason the direction was
worth building and are not a bar anything here passes or fails. For the record and not as a verdict:
octree_update_ms 0.0623–0.2452, graph_update_ms 0.0810–0.1914, total_ms 0.1433–0.4366.
The two readings of C1, both from the file:
| field | world | trace | dirty_cells |
repair_cells |
factor | octree ms | graph ms | worst edit ms | median edit ms | 11 edits ms | topology_changes |
|---|---|---|---|---|---|---|---|---|---|---|---|
fbm_terrain |
32³ | p72_dig |
4,058 | 7,245 | 1.7854 | 0.0695 | 0.0997 | 0.1693 | 0.1169 | 1.3863 | 0 |
fbm_terrain |
32³ | breakthrough |
3,027 | 4,703 | 1.5537 | 0.1935 | 0.1201 | 0.3137 | 0.0605 | 0.9284 | 2 |
fbm_terrain |
64³ | p72_dig |
6,036 | 9,875 | 1.6360 | 0.1068 | 0.0938 | 0.2006 | 0.1688 | 1.8240 | 0 |
fbm_terrain |
64³ | breakthrough |
2,809 | 4,263 | 1.5176 | 0.1967 | 0.1151 | 0.3118 | 0.0781 | 0.8793 | 2 |
fbm_terrain |
128³ | p72_dig |
7,545 | 11,747 | 1.5569 | 0.1417 | 0.1446 | 0.2863 | 0.2359 | 2.5396 | 0 |
fbm_terrain |
128³ | breakthrough |
2,979 | 4,643 | 1.5586 | 0.1983 | 0.1155 | 0.3138 | 0.0669 | 0.9609 | 2 |
fbm_terrain |
256³ | p72_dig |
7,608 | 11,849 | 1.5574 | 0.1443 | 0.1149 | 0.2592 | 0.2215 | 2.4886 | 0 |
fbm_terrain |
256³ | breakthrough |
3,110 | 4,875 | 1.5675 | 0.2139 | 0.1197 | 0.3336 | 0.0615 | 0.9544 | 2 |
gyroid |
32³ | p72_dig |
3,999 | 7,301 | 1.8257 | 0.0623 | 0.0810 | 0.1433 | 0.1091 | 1.2390 | 0 |
gyroid |
32³ | breakthrough |
3,013 | 4,632 | 1.5373 | 0.1955 | 0.1143 | 0.3097 | 0.0738 | 0.9187 | 2 |
gyroid |
64³ | p72_dig |
6,152 | 10,323 | 1.6780 | 0.0966 | 0.1204 | 0.2169 | 0.1774 | 1.8846 | 0 |
gyroid |
64³ | breakthrough |
2,826 | 4,246 | 1.5025 | 0.1919 | 0.1154 | 0.3073 | 0.0703 | 0.9032 | 2 |
gyroid |
128³ | p72_dig |
7,886 | 12,322 | 1.5625 | 0.1199 | 0.1292 | 0.2490 | 0.2136 | 2.3611 | 0 |
gyroid |
128³ | breakthrough |
2,858 | 4,425 | 1.5483 | 0.1987 | 0.1194 | 0.3181 | 0.0736 | 0.8948 | 2 |
gyroid |
256³ | p72_dig |
7,845 | 12,229 | 1.5588 | 0.1303 | 0.1250 | 0.2553 | 0.2308 | 2.5062 | 0 |
gyroid |
256³ | breakthrough |
2,895 | 4,501 | 1.5547 | 0.2452 | 0.1914 | 0.4366 | 0.0731 | 1.1847 | 2 |
total_ms is the worst single edit of the median rep, and octree_update_ms + graph_update_ms =
total_ms exactly on all 16 rows — both components come from that one edit, because amortised is not the
statistic for the frame a breakthrough lands on. c1_holds is that column against 2.0 and reads true
sixteen times.
c1_holds=trueis a verdict about one edit and says nothing about the four bolded whole-trace cells. A reader who takes the column as "the eleven-edit dig fits in 2 ms" is reading a claim the column does not make.
The whole-trace reading, and why it is reported rather than gated. trace_total_ms exceeds 2 ms on
exactly four rows — fbm_terrain and gyroid at 128³ and 256³ on p72_dig — at 2.3611–2.5396 ms,
i.e. 1.18–1.27× the bar. On the superseded dirty run the same four rows read 2.88–4.25 ms, 1.44–2.12×
the bar. The verdict did not flip and the margin did, and the margin is now smaller than the 1.67×
spread the identical binary showed on this very column between two runs. So "the eleven-edit dig does not
fit a 2 ms frame budget" is withdrawn as a conclusion: it is a wall clock on a governed CPU, and ✗24's
rule applies — a wall-clock ratio is not a gate, gate the count the ratio samples. The run-independent
replacement, from integers only:
- The trace reclassifies 12,288–23,040 cells, being
nav_dirty_chunks × 64exactly on all 16 rows, over 192–386 dirty 4³ chunks for eleven edits. - That chunk set is 0.7567–0.9326 of
mesh_dirty_chunks— the setisomesh::chunk::dirty::mark_edithands the mesher for the same eleven edits — on all 16 rows, never above 1. Whatever a frame costs, the navigation repair's footprint is a strict fraction of a stage this crate already pays for. That is the sentence a frame budget should be given, and it is an integer ratio, so it is the only form of the claim that survives a re-run.
The tempting cross-bench version of that sentence is not available.
M-377measures the mesher on the same field, the same 128³ world, the same 4³ granularity and the same eleven-edit dig at 29.69 ms per trace, against 2.5396 ms here — 8.6%. Different bench, different binary, different run, soM-281forbids it as a gate and it is recorded as an indication of scale only. The chunk-count ratio above is the same statement without the clock.
The mechanism, and it is one paragraph. A MIXED unit cell — the surface passes through it — is an
obstacle, which is the paper's "cells containing obstacles are split" taken to the leaf: at maximum depth
there is nothing left to split. An edit therefore does four bounded things. It flips sign bits inside the
brush box (dirty_cells, taken from EditReport::sign_changed_cells and independently recomputed by the
harness as pattern_changed_cells — equal on all 16 rows). It re-derives the AIR/SOLID/MIXED
state of every cell of every 4³ chunk containing a flipped bit. It walks the pyramid bottom-up over the
edit's own ancestors only — the candidate set at level l is the deduplicated parents of the level l−1
nodes whose state actually moved, so nodes_reevaluated is 714–1,767 for eleven edits and the world
contributes only octree_depth, which is 5, 6, 7, 8. And it rebuilds leaves under the topmost changed
nodes — those with no changed parent — plus the free-leaf pool of every region that lost a member. Nothing
in that chain is indexed by world size, which is why repair_growth is 1.6355 rather than 512.
C2's saturation is the half that decides the direction, and it is visible as a plateau. repair_growth
against the same field-and-trace at 32³ reads 1.0000 → 1.3630 → 1.6214 → 1.6355 on fbm_terrain/p72_dig
and 1.0000 → 1.4139 → 1.6877 → 1.6750 on gyroid/p72_dig. From 128³ to 256³ the world grows 8×
in cells and the repair set moves by +0.87% and −0.75% — it shrinks on gyroid. The rise from 32³
to 128³ is not world-proportionality either: at 32³ a radius-6 brush spans 12 of 32 cells on an axis, so
consecutive brushes overlap and the union of eleven of them is smaller than eleven disjoint brushes; by 128³
they are disjoint and the set saturates. dirty_per_edit says the same thing from the crate's side — 368.9
→ 548.7 → 685.9 → 691.6 on fbm_terrain. Against M-311's 925 dirty cells for one radius-6 brush in a
solid lattice, repair_per_m311 is 0.4173–1.2110, also under 3.
C3 is falsified by the bar and its ordering half is intact, and the two must not be read from one column.
| field | world | free cells | all leaves | free leaves (cells_before_merge) |
regions (cells_after_merge) |
reduction |
free cells per free leaf | free cells per region |
|---|---|---|---|---|---|---|---|---|
fbm_terrain |
32³ | 10,512 | 4,579 | 1,293 | 335 | 3.8597 | 8.13 | 31.38 |
fbm_terrain |
64³ | 88,162 | 18,852 | 5,422 | 1,475 | 3.6759 | 16.26 | 59.77 |
fbm_terrain |
128³ | 721,331 | 75,811 | 21,492 | 5,962 | 3.6048 | 33.56 | 120.99 |
fbm_terrain |
256³ | 5,835,575 | 304,291 | 86,475 | 24,250 | 3.5660 | 67.48 | 240.64 |
gyroid |
32³ | 14,820 | 7,141 | 1,996 | 783 | 2.5492 | 7.42 | 18.93 |
gyroid |
64³ | 124,765 | 29,044 | 8,201 | 3,213 | 2.5524 | 15.21 | 38.83 |
gyroid |
128³ | 1,023,258 | 117,349 | 33,339 | 13,036 | 2.5575 | 30.69 | 78.49 |
gyroid |
256³ | 8,287,363 | 471,808 | 134,638 | 52,485 | 2.5653 | 61.55 | 157.90 |
c3_holdsreadsfalseon all 16 rows and it is a conjunction of three tests, two of which passed. The harness computesreduction >= 5 && peer_reduction >= 5 && gyroid_worst.gyroid_worstis true on every row — 2.5492 < 3.8597, 2.5524 < 3.6759, 2.5575 < 3.6048, 2.5653 < 3.5660 — so the registered falsifier "or bygyroidnot being the worst, which would mean the reduction tracks something other than topological complexity" did not fire. The reduction does track topological complexity; it simply does not reach 5×. Readingfalseas "the ordering was wrong" inverts the finding.
Where the paper's order of magnitude actually is, and it is not in the merge. 28,190 → 303 is 93.0×,
and the greedy convexity-preserving merge here delivers 2.55–3.86× — 24–36× short. But the merge is the
second stage. Free cells per free leaf, which is the octree's own aggregation before a single merge
runs, goes 8.13 → 67.48 on fbm_terrain and 7.42 → 61.55 on gyroid across the sweep: an 8.3×
improvement in compression from the tree alone, still climbing at 256³, against a merge factor that is
flat to four significant figures on gyroid (2.5492 / 2.5524 / 2.5575 / 2.5653) and mildly falling
on fbm_terrain (3.8597 → 3.5660). End to end the structure gives 240.64 and 157.90 free cells per
navigation region at 256³, which is the paper's order of magnitude and then some — but the tree earned it.
The reason the merge cannot: two boxes merge only when they are face-contiguous on one axis and their
extents agree exactly on the other two, and a dense field riddles free space with unit-cell MIXED
obstacles, so one obstacle cell blocks a whole slab. gyroid has 2 air components to fbm_terrain's 1 and
tunnels on all three axes, which is exactly why it merges worst — the falsified bar and the held ordering
have the same cause.
The registered vacuity control, its column, and the value that proves the fixture could have failed.
The control is topology_changes: the dig must change the free-space topology at least once, read from
isomesh::connectivity::Air — crate source, maintained independently of everything in the harness — and
never from the brush. It is asserted >= 2 on the breakthrough arm and it reads exactly 2 on all eight
of those rows: air_components_before 1 (fbm_terrain) / 2 (gyroid), air_components_max 2 / 3,
air_components_after back to 1 / 2, with edits_pocketing = 1 and edits_joining = 1. One brush entirely
inside solid seals a pocket (+1 component); the shaft descending from open air breaks into it (−1). The
proof that a 2 could have been a 0 is in the same file, in the same column, from the same instrument: the
p72_dig arm scores 0 on all eight of its rows, with edits_joining = 0 and edits_pocketing = 0.
The identical union-find, reader and world, one arm 2 and one arm 0 — which is M-44's reachability check
satisfied by demonstration in both directions rather than by argument. The near-miss is recorded too
(M-44's second rule, record the margin): air_merges on the p72_dig rows is 11–27, non-zero on
every row, and scoring that as a topology change would have made the control pass on an arm that never
changed the topology at all — Air::dig reports a merge when the blob's own fresh label is absorbed within
one call, which is not two pre-existing components becoming one. That is P-70's C3, and the harness names
it in the code rather than in review.
The registered vacuity control fired against the registration's own fixture, and that is the most
valuable thing in this row. C1 names "P-72's eleven-edit dig trace", so the trace was inherited
literally — and P-72's trace scores topology_changes = 0 on all eight of its rows. The failure is
structural, not accidental: every brush in that trace straddles the surface, because the height is probed
per edit at that edit's own x precisely so it would hit the surface (which is P-72's own fix for two
void runs). So every newly-air sample is adjacent to open air that is already there, and the dig widens
one component eleven times — 1,999 to 4,882 newly-air samples per trace and not one component created or
destroyed. Read strictly, as a change in the number of air components, which is the only topological
quantity Air maintains, the registered control cannot fire on the registered fixture. The two
available responses were to weaken the control to air_merges > 0, which is the easier question and would
have passed vacuously, or to add an arm on which it can fire. The harness took P-62's precedent — that row
added a 400,000-cell random arm because eight reference fields gave only seven tunnel cells, "a hair from
M-44's vacuous zero" — and added breakthrough, which carries the live assertion while p72_dig keeps
the registered trace and reports its 0. Both arms are in the file, so C1 and C2 are still measured on
the fixture the registration names, and the control is still real. A registered vacuity control that
cannot fire on the registered fixture is a defect in the registration, and it is only findable by writing
the control as an assertion instead of a printed column.
Fixture defects the harness's own controls caught, in the order they fired:
- Leaf-id recycling inside one repair, caught by the region/free tiling equality on the first run:
after edit: regions cover 10854 of 10831 free cells,fbm_terrainat 32³.Nav::kill_leafreturned ids to the free list immediately, so a dissolved region's member list — read later in the same repair, to recover its surviving free leaves for the merge pool — named a different node: the fresh leaf that had taken the id. When that fresh leaf wasSOLID, a non-free leaf was handed to the free-space merge, and the region volumes then over-covered the free volume by 23 cells. Fixed with aleaf_retirelist drained intoleaf_freeonly at repair end. The 23-cell excess is the whole signal: a timing-only harness would have reported a slightly faster repair. - The registered vacuity control could not fire on the registered fixture —
topology_changes= 0 on all eightp72_digrows, as above. Caught by asserting the control rather than printing it. gyroid's solid branch was expected to refuse a radius-6 sealed chamber at 32³ (its labyrinth branch is ≈0.65 world units half-thick and 6 cells is 0.75 at 32³), sobreakthrough_pathsearches radii 6, 4, 3, 2 against the bitmap and panics if none fits, rather than defaulting. The ladder never fired:brush_cellsreads 6 on all 16 rows, because the search asks the sampled sign field and not the analytic field. Reported because the expectation was wrong in the harness's own doc comment and the file is what settles it — and because it means both arms use the same brush size, so the two traces are comparable at equal brush.- A local merge that silently shreds the structure would still be fast, so the incremental merge is
scored against a global re-merge of the same final field.
merge_drift=post_regions_incremental / post_regions_globalreads 1.2369 at 32³ and falls monotonically to 1.0050 / 1.0011 at 256³: the local strategy leaves at most 23.7% more regions than a from-scratch merge on the smallest world and 0.11–0.50% more on the largest. The degradation shrinks as the world grows, which is the direction that matters.
The build-versus-repair number, and it has a crossover the direction has to respect. build_ms is the
from-scratch cost of the whole structure — pyramid, leaves, global merge, graph — measured in the same run
and the same binary as the repair (M-281), so rebuild_over_repair = build_ms / total_ms and
rebuild_over_trace = build_ms / trace_total_ms are within-run ratios.
| field | world | build_ms |
rebuild_over_repair |
rebuild_over_trace |
world cells ÷ reclassified_cells |
|---|---|---|---|---|---|
fbm_terrain |
32³ | 0.7431 | 4.39 | 0.54 | 2.2× |
fbm_terrain |
64³ | 3.7338 | 18.61 | 2.05 | 13.7× |
fbm_terrain |
128³ | 19.9076 | 69.54 | 7.84 | 95.3× |
fbm_terrain |
256³ | 121.4720 | 468.66 | 48.81 | 764.3× |
gyroid |
32³ | 1.2512 | 8.73 | 1.01 | 2.2× |
gyroid |
64³ | 5.7288 | 26.41 | 3.04 | 13.1× |
gyroid |
128³ | 28.2459 | 113.42 | 11.96 | 91.0× |
gyroid |
256³ | 164.9126 | 645.90 | 65.80 | 757.6× |
p72_dig rows. At 32³ incremental repair is a loss: rebuilding the whole structure costs 0.54× the
eleven-edit trace on fbm_terrain and 1.01× on gyroid. The integer says why, and says it without a clock
— the repair reclassifies 15,040 of 32,768 cells, 45.9% of the world, so there is nothing local about a
local repair when the brush is 12 cells across a 32-cell world. By 256³ it reclassifies 21,952 of
16,777,216, 0.131% — a footprint 764× smaller than the world it sits in, against 2.2× at 32³ — and
the measured stage ratio is 469–646× on the worst edit and 49–141× on the trace. Because one element of
that band moved 30% between two runs of the
same binary, the load-bearing form of this row is "two to three orders of magnitude from 128³ up, and
under 1× at 32³", with the crossover between 32³ and 64³.
The repair set, precisely, because R-088 rides it. repair_cells = leaves_removed + leaves_added +
regions_removed + regions_added, summed over the eleven edits of one rep, and that identity holds on all
16 rows. One edit performs, in order:
- Bits. Flip sign bits inside the brush's sample box;
flippedis the changed samples only. - Locate. Every cell incident to a flipped sample (up to 8 per sample, indices
s−1andsper axis) → deduplicatedpattern_changed_cells, which equals the crate'ssign_changed_cellson all 16 rows; the 4³ chunk of each such cell → deduplicatednav_dirty_chunks. - Reclassify. Re-derive
AIR/SOLID/MIXEDfrom the eight corner bits for every cell of every dirty chunk —reclassified_cells=nav_dirty_chunks × 64, exactly, on all 16 rows — because whole chunks are the granularity a chunked world hands its consumers. Cells whose state actually moved arestate_changed_cells(2,038–7,236 per trace). - Pyramid. Bottom-up, level by level: candidates at level l are the deduplicated parents of level
l−1 nodes whose state moved;
nodes_reevaluatedcounts candidates (714–1,767 per trace). Only nodes whose combined state moves propagate upward. - Tops. The changed nodes with no changed parent. Everything below a top is rederived; nothing above it needs to be.
- Leaf surgery.
collect_under(tops)→leaves_removed(1,196–4,135 per trace); each killed id goes toleaf_retire, not toleaf_free.derive_under(tops)→leaves_added(2,419–7,304). Steps 1–6 areoctree_update_ms. - Graph. The merge pool is the newly added
AIRleaves plus the still-live free leaves of every region that lost a member (regions_removed, 214–401 per trace);merge_poolre-merges it intoregions_added(327–648 per trace), andmax_pool_leaves— the largest single-edit pool — is 145–263. This isgraph_update_ms. - Retire. Only now is
leaf_retiredrained intoleaf_free. Defect 1 is why.
Invariants asserted after every edit, not printed: the leaves partition the world (Σ (2^level)³ =
world_cells³); the regions tile the free leaves and each region's box volume equals its own members'
volumes, which is how convexity is checked rather than argued; every integer identical across three reps;
and both arms agree on the pre-edit Static snapshot, so the build is a pure function of the bitmap.
What changed as a result. The direction is not dead and not cheap in the way the paper suggested.
C1 and C2 clear the two questions that could have killed it — the repair is local in the only sense that
matters (its chunk set is a strict subset-sized fraction of the mesher's own, on every row) and it does not
grow with the world (1.6355× against 512×). C3 says the reason to prefer it has moved: the coarse graph's
compression comes from the octree, so a build that keeps the tree and drops the Hertel–Mehlhorn merge
entirely keeps 8.13–67.48 free cells per navigation cell and loses only the 2.5–3.9× on top. Whether the
merge is worth its code is now a measured question rather than an assumed benefit. Three things this row
does not license: quoting a whole-trace millisecond as a budget claim (✗24 — quote
nav_dirty_chunks / mesh_dirty_chunks ≤ 1 instead); comparing anything here to the paper's ~1 ms
(M-281 — different machine); and building the repair at world sizes at or below 32³, where a full rebuild
is cheaper than the eleven-edit trace.
Would be shown wrong by: a repair_growth that resumes climbing above 256³, which would mean the
128³–256³ plateau was the brush saturating rather than the repair being local, and would restore C2's
falsifier; a field on which gyroid is not the worst merge, which would break C3's surviving half and
mean reduction tracks something other than topological complexity; a merge with a non-box convexity
predicate reaching 5× on either field, which would show the bar was reachable and the greedy axis merge
was the wrong instrument rather than the claim being wrong; a nav_dirty_chunks / mesh_dirty_chunks above
1 on any fixture, which would make the navigation repair a new stage rather than a rider on an existing
one; or a graph query — A* with visibility pruning and a 3-D funnel, which this harness does not build —
whose cost on 24,250 or 52,485 regions is itself over frame budget, which would make every number above
irrelevant.
💥 ✗68 / M-400 — C1 FALSIFIED on both readings (0.688892 and 0.831008 against a 0.90 bar), C2 HELD for the cheap reading and FALSIFIED for the tight one, C3 HELD on the analytic fixtures and FALSIFIED on the reference fields at 62 / 649 overstatements: the octree does give a clearance number without a medial axis, and there is no version of it that is both accurate enough and local (P-88, R-088)
M. cargo bench --bench experiment_p88, docs/experiments/p-88.csv, 14 rows (7 fixtures ×
2 estimators), scalar f64, Zen 3. M-346's fixture inherited literally — a BoxExact swallowing
[−2, 2]³ at 64³ with a Capsule of radius 2, 4 or 8 cells subtracted along x, so the field
value is the exact clearance — plus fbm_terrain and gyroid at 64³/128³ under an eleven-edit
trace (8 sphere brushes at 6 cells on P-72's probed path, then 3 narrow capsule cuts), truth from
the same query on a 4× refined sign grid. 160,000 samples per row, 1,120,000 per estimator.
Committed at 0a7594c, clean tree, an ancestor of HEAD.
The registration's own sentence contains two estimators and they give different verdicts, so both are run over the same samples, the same trace and the same truth, and both get a row.
regionis the literal reading — "P-87's merged convex regions give a larger bound directly" —d(p, ∂B)for the merged convex regionBholdingp, oneO(depth)leaf walk.ballis the reading CALIBRE's own definition invites, since λ-membership is a thresholded ball query:d(p, ⋃ non-free cells)by branch-and-bound descent of the same pyramid, withball ≥ regionasserted per sample. Scoring only the literal one would answer the question with a straw estimator; scoring only the tight one would beP-70's C3.
| clause | registered | measured |
|---|---|---|
C1 bound within 1 voxel on ≥ 90% of samples, across M-346's fixtures |
≥ 0.90 | FALSIFIED on both — region 330,668/480,000 = 0.688892, ball 398,884/480,000 = 0.831008 |
| C2a λ-membership flips ≤ 4× changed samples | ≤ 4.0 | HELD on both, with room — worst over every λ and fixture 0.8482; worst single edit 1.1176 |
C2b the flip set is computable from P-87's repair set with no extra traversal |
0 flips outside | HELD for region (0 at every λ, and 0 outside the leaf subset) — FALSIFIED for ball (149–682 outside at every λ ≥ 1.0) |
| C3 the bound never overstates, over 10⁶ samples | 0 overstatements | FALSIFIED — 62 (region) and 649 (ball) over 1,120,000 samples each; 0 on the 480,000 analytic ones |
SHARE, recomputed. The registration says "this is an accuracy and a rate, not a ratio of a
total", and that is correct as written. ✗51's ceiling 1/(1 − s + s/factor) binds a speedup
denominated in a share of a larger total; none of these three clauses is a speedup, so no share can
throttle them. C1's denominator is the sample set — share 1.0 by construction — and it is
reachable in both directions: an exact bound scores 1.0, and a one-cell-thick region inside an
eight-cell channel is 7.5 cells short. C2 is a ratio of two directly counted sets plus a subset
test, both reachable either way. C3 is a one-sided count and a count has no denominator to dilute.
M-281 does not bind — no clause compares against another machine — and clock_mhz (4200) is on
every row anyway because bound_ns_per_query is.
The one thing arithmetic could not reach before the run is C2b, and it is the clause that split. C1's failure mode was derivable in kind (a merged region is a box inside the free set, so it can only understate) but not in magnitude; C3's analytic zero is provable; C2a's bar of 4 was never in danger, since the flip set measured 0.25–0.85 of the changed set rather than a multiple of it. Whether the dependency radius of a bound exceeds the repair set is a property of the merge geometry rather than of a formula, and no amount of pre-run arithmetic settles it.
Accuracy, per fixture. within_fraction is within_one_voxel / samples; errors are in cells.
| fixture | truth | region fraction |
ball fraction |
region max understatement |
ball max understatement |
region p90 err |
ball p90 err |
|---|---|---|---|---|---|---|---|
slab_r2 |
analytic | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 0.962671 | 0.962671 |
slab_r4 |
analytic | 0.701425 | 0.835625 | 2.000000 | 1.171573 | 1.774336 | 1.103077 |
slab_r8 |
analytic | 0.365250 | 0.657400 | 4.000000 | 1.291796 | 3.500651 | 1.268201 |
fbm_terrain_64 |
refined 4× | 0.463406 | 0.929638 | 12.552669 | 1.299013 | 6.236757 | 0.948900 |
gyroid_64 |
refined 4× | 0.350888 | 0.864406 | 16.316283 | 1.299033 | 8.418815 | 1.051693 |
fbm_terrain_128 |
refined 4× | 0.394875 | 0.871400 | 24.922016 | 1.299031 | 12.542291 | 1.035101 |
gyroid_128 |
refined 4× | 0.275438 | 0.784444 | 32.956128 | 1.299037 | 17.150570 | 1.136304 |
C1 is registered "across M-346's fixtures", so its verdict is the pooled analytic figure:
0.688892 and 0.831008, both under 0.90. Pooled over all seven fixtures it is 0.507326 and 0.848988;
the widest single ball row that clears the bar is fbm_terrain_64 at 0.929638, and that is a
refined row, not one C1 is registered on.
c1_holdsreadstrueon theslab_r2rows and onfbm_terrain_64 / ball, andfalseon the other eleven. That column is per row; C1's verdict is the pooled analytic one and it is FALSIFIED on both estimators. Twotrues out of fourteen do not make a 90% bar.
And the easiest fixture passes by equality, which is worth saying rather than banking. slab_r2
scores 1.000000 with max_understatement_cells = exactly 1.000000 on both estimators. The bar
is within one voxel; the worst sample sits on it. One more cell of channel radius and it stops
passing — which is precisely what slab_r4 does.
The mechanism, and it is different for the two readings. On the region reading
max_understatement_cells is 1.000000 / 2.000000 / 4.000000 at r = 2 / 4 / 8 cells: exactly
r/2, three fixtures in a row, an integer relation and not a fit. P-87's convexity-preserving
greedy merge grows runs along x and then along y, and the z rows of a digitised disc rarely
share a y-extent, so a cylinder is merged into thin z-slabs and the inradius at the axis is
half a slab thickness rather than r. The bound is correct — a slab really does admit that sphere —
and it is a bound on the wrong object. On the ball reading the slab geometry is irrelevant and the
limit is digitisation: 1.000000 / 1.171573 / 1.291796, the free-cell union being the analytic
channel eroded by up to a cross-section diagonal. Those two columns are the whole accuracy story,
and they say the loose reading fails for a reason a better merge could fix while the tight reading
fails for a reason only a finer grid can.
Locality, per fixture, over the registered λ sweep {0.5, 1.0, 1.5, 2.0, 3.0} cells.
| fixture | changed samples | region flip factor by λ |
region outside repair set |
ball flip factor by λ |
ball outside repair set by λ ≥ 1.0 |
|---|---|---|---|---|---|
slab_r2/r4/r8 |
228 | 0.2456 / 0 / 0 / 0 / 0 | 0 at every λ | 0.2456 / 0 / 0 / 0 / 0 | 0 at every λ |
fbm_terrain_64 |
3,387 | 0.8482 / 0.1913 / 0.1913 / 0.0567 / 0.0118 | 0 at every λ | 0.8482 / 0.6430 / 0.6430 / 0.5244 / 0.3927 | 283 / 283 / 474 / 682 |
gyroid_64 |
3,476 | 0.8331 / 0.1899 / 0.1899 / 0.0184 / 0.0023 | 0 at every λ | 0.8331 / 0.6064 / 0.6064 / 0.4822 / 0.3179 | 260 / 260 / 332 / 451 |
fbm_terrain_128 |
3,845 | 0.7865 / 0.3017 / 0.3017 / 0.1165 / 0.0312 | 0 at every λ | 0.7865 / 0.5506 / 0.5506 / 0.4455 / 0.3334 | 191 / 191 / 240 / 474 |
gyroid_128 |
4,032 | 0.7654 / 0.2262 / 0.2262 / 0.0635 / 0.0099 | 0 at every λ | 0.7654 / 0.4965 / 0.4965 / 0.3869 / 0.2453 | 149 / 149 / 215 / 328 |
C2a holds everywhere with room. The largest flip factor anywhere in the file, over every λ, both
estimators and all seven fixtures, is 0.8482 against a bar of 4 — a factor of 4.7 of
headroom — and the strictest per-edit reading, worst_edit_flip_factor, tops out at 1.1176
(edit 3 of fbm_terrain_64 / ball). λ = 0.5 is always the largest, because there membership
degenerates toward "the cell is air" and the flip set approaches the sign-change set itself.
C2b is the row. flips_outside_repair_set is 0 on all seven region rows at every λ, and
flips_outside_leaf_subset is 0 as well — the region-bound flip set lies inside the leaf half
of P-87's repair set alone, which is tighter than the clause asked for. On the ball rows it is
non-zero at every λ ≥ 1.0, up to 682. The mechanism is the obvious one once stated: removing
material raises the clearance of every cell within λ of the removal, and a cell λ away has neither a
changed leaf nor a changed region. So the tight estimator needs a blast radius of λ around every
edit, which is exactly the extra traversal the clause forbids. λ = 1.0 and λ = 1.5 give identical
numbers on every row because a cell-centre ball bound's value set jumps 0.866 → 1.5: bound ≥ 1.0
iff all 26 neighbours are free.
c2_holdsreadsfalseon fourballrows, and not because the factor failed. C2 is a conjunction: the factor half passed on those rows (0.3927 / 0.3179 / 0.3334 / 0.2453, against 4), and the subset half failed. A reader who takesc2_holds = falseas a flip-count blow-up has it backwards.
Cost, as a within-row ratio, because an absolute nanosecond is a property of the binary (M-281,
✗24).
| fixture | region ns/query |
ball ns/query |
ball / region |
|---|---|---|---|
slab_r2 |
20.9 | 660.1 | 31.6× |
slab_r4 |
26.6 | 791.3 | 29.8× |
slab_r8 |
30.7 | 1043.4 | 34.0× |
fbm_terrain_64 |
31.5 | 623.2 | 19.8× |
gyroid_64 |
37.0 | 849.2 | 23.0× |
fbm_terrain_128 |
53.5 | 958.4 | 17.9× |
gyroid_128 |
56.3 | 1393.8 | 24.8× |
The gate-relevant statement is the ratio band, 17.9–34.0×, taken inside one row of one file: the reading that nearly clears C1 costs one to two orders more per query than the reading that rides the repair set exactly. The absolute columns are printed, not asserted.
C3, and why the analytic zero is provable rather than lucky. overstatements is 0 and
max_overstatement_cells is 0.000000000 on all six slab rows — 480,000 analytic samples per
estimator — and it could not have been otherwise: a cell all eight of whose corners lie inside a
convex cylinder lies inside it, so a bound read off the free-cell union of a digitised convex
channel cannot exceed the exact distance to that channel's wall. On the reference fields, against a
4× refined truth:
| fixture | region overstatements |
region worst (cells) |
ball overstatements |
ball worst (cells) |
|---|---|---|---|---|
fbm_terrain_64 |
38 | 0.250000 | 463 | 0.500000 |
gyroid_64 |
17 | 0.246773 | 101 | 0.289306 |
fbm_terrain_128 |
5 | 0.250000 | 81 | 0.250000 |
gyroid_128 |
2 | 0.179235 | 4 | 0.179235 |
| total | 62 | 649 |
One violation kills a one-sided clause and there are 649. No tolerance was applied; the strict
comparison bound > truth produced these, and 0.25 and 0.50 cells are half a voxel, not float slop.
The mechanism is M-347 made operational: a coarse cell whose eight corners are all outside can
still have the surface passing through it, the 4× grid finds a solid sample there, and the coarse
bound has claimed clearance through material.
The caveat, stated in the direction that matters. Refinement is one-sided evidence in
M-347's own sense — it can catch a lie, it cannot prove there are none, so 62 and 649 are floors. And against the coarse trilinear surface, which is what this crate's mesher and collider actually produce, the bound cannot overstate: trilinear interpolation of eight positive corners is positive throughout the cell. So the falsification is about the voxelisation, not about the octree — and that is exactly the direction a gameplay gate cannot tolerate. A creature is told it fits where it does not, and the lie is in the sign field.
The registered vacuity control, both halves.
| fixture | known_clearance_samples |
narrow_passage_samples |
narrow_within_one_voxel |
|---|---|---|---|
slab_r2 |
160,000 | 23,878 | 23,878 |
slab_r4 |
160,000 | 6,895 | 6,895 |
slab_r8 |
160,000 | 1,716 | 1,716 |
fbm_terrain_64 |
0 | 10,618 | 10,618 |
gyroid_64 |
0 | 9,957 | 9,957 |
fbm_terrain_128 |
0 | 8,427 | 8,427 |
gyroid_128 |
0 | 8,313 | 8,313 |
| total per estimator | 480,000 | 69,804 | 69,804 |
The first half is asserted non-zero in the total and wherever truth_source == analytic. The
second half is the one that matters: a narrow-passage sample is air now, solid in the pristine
field (so the passage was dug), and of true clearance under one cell (so it is narrower than two
cells). The fixture is built so the column can fire: every trace closes with capsule cuts of radius
0.9 cells whose axis runs down a line of cell centres, so exactly the four sample lines at
√2/2 = 0.707 cells go to air and the next ring at 1.58 does not — a passage one cell across. And
the line is searched, not assumed: narrow_line picks the cell-centre line through the most
solid material after the wide dig and asserts it solid at more than half of 64 probes, because a
cut down a line that is already air removes nothing and the column would be M-44's vacuous zero.
What those samples then prove, and it is the most useful number here. narrow_within_one_voxel
equals narrow_passage_samples on every one of the fourteen rows — the bound is within one
voxel on 100% of the dug one-cell passages, on both estimators, including the region rows that
pool to 0.688892 overall. So C1's failure is entirely in the open channels and not in the
interesting ones. The bound is loose exactly where a creature has room to spare, and tight exactly
where the gate would be consulted.
C3's zero is a measurement (M-44). probe_overstatements re-runs the identical comparison
against bound + 0.5 cells — the classic error of measuring to an obstacle cell's centre instead
of its box — and reads 29,008 to 110,111 per row, asserted > 0 everywhere. Half a voxel of
optimism would have been caught 84,382 times on slab_r2 / region alone; the strict comparison
caught it 0 times. Likewise for C2b's zero: lambda_flips > 0 per row, repair_set_cells a strict
subset of the world (repair_set_fraction 0.047761–0.249142 of world_total_cells), and a global
assertion that the identical containment predicate returns non-zero somewhere in this run — it does,
1,935 times across the ball rows, and that is the result rather than the control.
Fixture defects this harness's own controls caught.
- A refinement factor whose arithmetic cap sat under the bar it was gating. A coarse non-free
cell at distance
Dis guaranteed to contain a non-free fine cell only in the corner holding its solid corner sample, so the refined truth can exceed the coarse bound by at most√3·(1 − 1/f)— 0.866 cells atf = 2. That is under the one-voxel bar, so no reference row could ever miss C1, and the first run duly scoredwithin_fraction = 1.000000withmax_understatement_cells = 0.866025on the nose on every reference row. That is the cap, not a measurement of the surface —M-283's tell, exactness as the symptom.REFINE = 4puts the cap at 1.299 so the bar is reachable in both directions, and the referenceballrows then read 0.784444–0.929638. - A "worst λ" selection that always picked the degenerate λ. Ordering the sweep by flip count
alone selects λ = 0.5 on every row — the file still shows why, since
flip_factor_l05is the largest entry on all fourteen rows — and at λ = 0.5 membership degenerates to "the cell is air", where both estimators trivially ride the repair set:flips_outside_repair_set_l05is 0 on every row,ballincluded. The entireballlocality result was invisible and the globalM-44assertion fired. Selection is now ordered by(flips_outside_repair_set, flips), which is whylambda_cellsreads 3.0 on the four referenceballrows and 0.5 elsewhere, and every λ's numbers are on the row regardless.
Corrections to the pre-registration run. The numbers first reported for this row came from a
dirty tree (63c7161 (WORKING TREE DIRTY)) while roughly twenty-five sibling harnesses were
compiling. Every integer and every ratio taken within a row reproduced exactly on the quiet tree at
0a7594c — all fourteen within_fraction values, all max_understatement_cells, overstatements
38/17/5/2 and 463/101/81/4, the flip factors, the 682/451/474/328 outside-counts,
worst_edit_flip_factor 1.1176, both vacuity columns. Only the clock moved, and it moved a long
way: bound_ns_per_query fell from 29.6–116.4 to 20.9–56.3 on region and from 782.6–1682.6
to 623.2–1393.8 on ball, the worst single row 116.4 → 56.3, a 2.07× move on the identical
binary — the same effect P-87 saw at 1.67× and M-281 explains. The briefed statement "14–31×
dearer" is withdrawn as a property of that run; the run-independent replacement is the within-row
ratio band 17.9–34.0×, and the conclusions rest on integers and on ratios taken inside one row.
Consequence. Neither reading reaches CALIBRE's bar on M-346's fixtures, and the two failures
are not the same failure. The reading that rides P-87's repair set exactly — 0 flips outside it,
in fact inside the leaf subset — is the one that fails C1 worst (0.688892), because a
convexity-preserving merge answers with the inradius of a slab. The reading that nearly passes C1
(0.831008 analytic, 0.929638 on the widest reference row) cannot ride the repair set at all, needs a
λ-radius blast around every edit, and costs 17.9–34.0× per query. So the answer to the ticket is a
null, and the null is the result: do not build this as CALIBRE's clearance oracle. CALIBRE still
needs ρ, or it needs a finer sign field and a real distance transform rather than a region box.
Two things are worth keeping: the bound is within one voxel on 100% of dug one-cell passages, which
is where a gate is actually consulted, and P-87's repair set is demonstrably sufficient for any
bound that is a function of a cell's own leaf.
Would be shown wrong by: a merge that preserves convexity without slabbing a cylinder — the
r/2 relation is a property of the greedy x-then-y run order, not of octrees, and a merge whose
regions were maximal inscribed boxes would move region's 0.688892 upward without touching its
perfect locality; a ball estimator whose λ-neighbourhood is provably inside P-87's repair set
plus a bounded halo that can be computed during the repair walk rather than after it, which would
make C2b hold at the tight reading; any overstatement found on the analytic fixtures, which would
falsify the convexity argument above rather than the voxelisation; or a refinement beyond 4× that
leaves overstatements at 62 and 649, which would suggest those counts have converged rather than
being floors.
💥 ✗69 / M-401 — C1 HELD at 4.36× and 1.76×, C2 FALSIFIED at 267% and 46%: 1³ is worse than 2³ on both fields, so M-377's 4³ optimum is now interior with measured neighbours on both sides and nothing left untested below it — and M-377's two-term model does not extrapolate to c = 1, because at one cell a chunk the cost stops being field evaluations (P-89, R-089)
M. cargo bench --bench experiment_p89, docs/experiments/p-89.csv, 6 rows, f64, Zen 3,
at 22c9fa0 — a clean tree, no (WORKING TREE DIRTY) on the header, an ancestor of HEAD.
p-72's fixture verbatim — same 128³ world cell count, same EXTENT, same ORIGIN, same six-cell
brush, same eleven-edit probed-per-edit dig path, same three-trace median, same three controls —
with the granularity list changed to [1, 2, 4] and the model machinery C2 needs added.
Every number below is read from the committed
docs/experiments/p-89.csvat22c9fa0. The pre-registration run at63c7161was dirty, is superseded, and its numbers are not reproduced here — quoting a run absent from the file cited is✗35's and✗52's defect. The correction is not cosmetic. On the M-279 side the two runs agree completely: every integer and every prediction reproduced exactly —dirty_chunks_total5,976 / 1,501 / 396 and 5,811 / 1,456 / 376,min_dirty_chunks_per_edit493 / 121 / 30 and 440 / 109 / 31,region_chunks_total,mark_field_calls90,112 on all six arms,model_work_calls, both stencils, all four vertex columns,k_ns_per_call41.985658 / 152.875911,k_residual, and thereforepredicted_ms11.5093 / 37.4387 bit-identical, because the predictions are committedp-72values times this run's deterministic call counts. What moved is the clocks, and only on the 1³ arms:
63c7161(dirty, superseded)22c9fa0(committed)gyroid1³mark_ms/remesh_ms/measured_ms16.2242 / 6.7022 / 22.9264 29.3633 / 12.9144 / 42.2777 gyroid1³model_error0.991994 2.673356 gyroid1³mark_model_error/remesh_model_error2.238104 / 0.031288 4.860460 / 0.987177 fbm_terrain1³mark_ms/remesh_ms/measured_ms25.4096 / 22.4127 / 47.8223 27.4164 / 27.3053 / 54.7217 fbm_terrain1³model_error0.277351 0.461635 fbm_terrain1³mark_model_error/remesh_model_error0.711359 / 0.007894 0.846518 / 0.208677 2³ and 4³ measured_ms, all four9.7229 / 8.8756 / 31.0102 / 30.3875 9.6883 / 8.5748 / 31.0779 / 29.8045 The four coarse arms moved by −0.36% / −3.39% / +0.22% / −1.92%; the 1³ arms moved by +84.4% and +14.4%,
remesh_msatgyroid1³ by 1.93×. Both verdicts are unchanged on either run — C1's smallest margin is 1.54× on the old run and 1.76× here against a bar of 1.0, C2's smallest error is 27.7% there and 46.2% here against 10% — but one claim does not survive: the superseded run readremesh_model_errorat 1³ as 3.1% and 0.79% and supported "the model extrapolates, only the flat-mark premise fails". Here both halves are outside the 10% bar. That claim is withdrawn.M-280andM-281apply: a millisecond on a governed CPU is a property of the run, and the 1³ arm — 2,097,152 chunks against 32,768 at 4³ — is the arm with the least cache-resident state and therefore the most to lose to machine conditions. The run-independent half of the finding is the counted amortisation collapse below, which is integer arithmetic.
| clause | registered | measured |
|---|---|---|
| C1 1³ is worse than 2³ on both fields | 1³ slower on both | HELD — 42.2777 against 9.6883 ms on gyroid (4.3638×) and 54.7217 against 31.0779 on fbm_terrain (1.7608×) |
C2 the cost at 1³ matches M-377's two-term model to within 10% |
model_error < 0.10 |
FALSIFIED on both — 2.673356 (267.3%) on gyroid, 0.461635 (46.2%) on fbm_terrain |
Neither clause is VACUOUS. Both are instrumented by columns, and C2 is deliberately not implied
by its own construction: k_field is a least-squares-through-origin fit at two anchors, c = 2
and c = 4, so the fit has a residual and model_error is not identically zero at the anchor.
k_residual reads 0.001826 / 0.001843 on gyroid and 0.003132 / 0.003248 on fbm_terrain
— non-zero, which is the whole point. A single anchor would have been P-70's C3, a clause whose
predicate is implied by how it was built. c1_holds and c2_holds are global verdicts over
both fields, evaluated at c = 1 and stamped on all six rows, so the 0.107169 in the gyroid 4³
row's model_error is an in-sample diagnostic and not a C2 verdict.
SHARE, recomputed before the run, said out loud, and half wrong in the informative direction.
The registration's own SHARE is "this experiment measures a curve and moves nothing", so no clause
is denominated in a share of a runtime and there is no 1/(1 − share/factor) ceiling to check. C2's
10% bar does have a reachability question, it is arithmetic on docs/experiments/p-72.csv alone,
and the harness prints it from the file before measuring anything (P-70's discipline: a number in
a comment drifts). gyroid's committed mark_ms is 3.6734 / 3.6840 / 3.7205 / 3.8009 / 4.0234 /
5.0104 at c = 64 → 2 — flat to 3.47% over 64³–8³, then rising 1.245315× from 4³ to 2³, where
mark is 52.06% of total_ms:
| field | committed mark_ms 4³ → 2³ |
mark share of total_ms at 2³ |
cost of a flat mark term at 1³ if that step repeats once | C2's 10% bar |
|---|---|---|---|---|
gyroid |
1.245315× | 52.06% | 12.77% | arithmetically UNREACHABLE from the constant half of the model |
fbm_terrain |
1.071874× | 47.85% | 3.44% | reachable |
So it was stated, from the committed file, before the run, that C2 was already out of reach on
gyroid for a reason that has nothing to do with c = 1's remesh cost — and it was run anyway,
per ✗51. It should be: the pre-run figure is a floor, not an estimate, and it under-states
both failures because it assumes the 4³→2³ step repeats once. It does not repeat; it explodes.
Measured mark_ms from 2³ to 1³ is 5.8294× on gyroid and 1.8353× on fbm_terrain,
against the 1.2453× and 1.0719× the estimate extrapolated. That is why fbm_terrain, computed
reachable at 3.44%, still failed — at 46.2%, 13× the predicted cost. The reachability
arithmetic named the ordering of the two failures correctly and their magnitude not at all.
C1, and the value of this row is that it closes M-377's own open question by confirming a
boundary. M-377's "would be shown wrong by" reads, in as many words: "an optimum below 2³ — the
curve is rising at 2³ on both fields, so 1³ should be worse still, but it is untested."
| field | 1³ | 2³ | 4³ | 1³ / 2³ | 1³ / 4³ |
|---|---|---|---|---|---|
gyroid measured_ms |
42.2777 | 9.6883 | 8.5748 | 4.3638× | 4.9305× |
fbm_terrain measured_ms |
54.7217 | 31.0779 | 29.8045 | 1.7608× | 1.8360× |
sample_duplication reads exactly 8.000000 at 1³ against 3.375000 and 1.953125, asserted
against ((c+1)/c)³ to 1e-4. There is no granularity below 1, so M-377's 4³ now has a
measured neighbour on each side and no untested region under it. The phase registered this as an
expected null and it is one: the result is that the answer did not move. A null that closes a named
open question is a completed result, and this one converts a conjecture about the shape of the
curve into a bracketed minimum.
C2 is falsified in both halves, and the half that was supposed to be safe is the correction.
M-377's model is a field-evaluation count, units × (c+1)³ + stencil × vertices, and this
harness asserts that identity against a counted field rather than assuming it — on the build and
on the remesh, with the stencil derived from the remainder. It comes back 6 on all twelve
populations, exactly:
| field | c | build calls | − grid | = | stencil × build_vertices |
remesh calls | − grid | = | stencil × remesh_vertices |
|---|---|---|---|---|---|---|---|---|---|
gyroid |
1 | 17,992,540 | 16,777,216 | 1,215,324 | 6 × 202,554 | 154,788 | 47,808 | 106,980 | 6 × 17,830 |
gyroid |
2 | 7,760,844 | 7,077,888 | 682,956 | 6 × 113,826 | 109,713 | 40,527 | 69,186 | 6 × 11,531 |
gyroid |
4 | 4,570,084 | 4,096,000 | 474,084 | 6 × 79,014 | 109,410 | 49,500 | 59,910 | 6 × 9,985 |
fbm_terrain |
1 | 17,560,264 | 16,777,216 | 783,048 | 6 × 130,508 | 147,774 | 46,488 | 101,286 | 6 × 16,881 |
fbm_terrain |
2 | 7,518,156 | 7,077,888 | 440,268 | 6 × 73,378 | 105,504 | 39,312 | 66,192 | 6 × 11,032 |
fbm_terrain |
4 | 4,401,778 | 4,096,000 | 305,778 | 6 × 50,963 | 103,946 | 47,000 | 56,946 | 6 × 9,491 |
So W(c) = dirty_chunks × (c+1)³ + 6 × remesh_vertices is measured exactly rather than
modelled, and M-377's stencil of 6 is confirmed on a seventh and eighth population including a
granularity where a chunk holds a single cell. What C2 tests is the bridge from that count to a
millisecond — flat mark_ms from the committed CSV plus k_field × W(c) — and the bridge is where
it breaks:
| field | c | mark_ms |
predicted_mark_ms |
mark_model_error |
remesh_ms |
predicted_remesh_ms |
remesh_model_error |
model_error |
|---|---|---|---|---|---|---|---|---|
gyroid |
1 | 29.3633 | 5.0104 | 4.860460 | 12.9144 | 6.4989 | 0.987177 | 2.673356 |
gyroid |
2 | 5.0371 | 5.0104 | 0.005321 | 4.6512 | 4.6064 | 0.009738 | 0.007437 |
gyroid |
4 | 4.0393 | 5.0104 | 0.193820 | 4.5355 | 4.5937 | 0.012657 | 0.107169 |
fbm_terrain |
1 | 27.4164 | 14.8476 | 0.846518 | 27.3053 | 22.5911 | 0.208677 | 0.461635 |
fbm_terrain |
2 | 14.9387 | 14.8476 | 0.006133 | 16.1392 | 16.1290 | 0.000633 | 0.003269 |
fbm_terrain |
4 | 13.9623 | 14.8476 | 0.059628 | 15.8422 | 15.8908 | 0.003058 | 0.030383 |
Both terms are outside the bar at 1³ on both fields, and mark is the worse of the two on both — 486% against 99%, and 85% against 21%. Mark is also the term the pre-run arithmetic condemned. The flat-mark premise is the larger failure and the field-call term is no longer exonerated.
The mechanism, and it is one sentence backed by integers rather than by a clock: k_field is not
a constant, because the model counts field evaluations and 1³ is the granularity at which field
evaluations stop being the cost. Divide the measured remesh_ms by the exactly-counted W:
| field | c | W = model_work_calls |
measured ns / call | fitted k_ns_per_call |
ratio | remeshed_cells_total / dirty_chunks_total |
region_chunks_total |
|---|---|---|---|---|---|---|---|
gyroid |
1 | 154,788 | 83.433 | 41.985658 | 1.9872× | 1.0000 | 37,125 |
gyroid |
2 | 109,713 | 42.394 | 41.985658 | 1.0097× | 8.0000 | 5,632 |
gyroid |
4 | 109,410 | 41.454 | 41.985658 | 0.9873× | 64.0000 | 868 |
fbm_terrain |
1 | 147,774 | 184.777 | 152.875911 | 1.2087× | 1.0000 | 37,125 |
fbm_terrain |
2 | 105,504 | 152.972 | 152.875911 | 1.0006× | 8.0000 | 5,632 |
fbm_terrain |
4 | 103,946 | 152.408 | 152.875911 | 0.9969× | 64.0000 | 856 |
The per-call cost is constant to 1.0% and 0.3% across 2³ and 4³ and inflates by 1.99× and 1.21×
at 1³. The right-hand columns say why, and they are pure integer arithmetic from the file: cells
re-meshed per dirty chunk is exactly 64, 8 and 1, so every per-chunk cost that is not a field
evaluation — the buffer, the layout setup, the dirty-set entry, the eight-corner gather bookkeeping
— gets 64× less amortisation at 1³ than at 4³ and 8× less than at 2³. The model has no term for
it, so k absorbs it and stops being a coefficient. Note the direction the naive duplication story
points: W at 1³ is only 1.4108× and 1.4006× W at 2³ — because a 1³ dirty set is the
tightest possible wrap around an edit and re-meshes half the cells 2³ does (5,976 against
12,008; 5,811 against 11,648) — while remesh_ms rises 2.7766× and 1.6919×. The 8×
duplication lands on the untimed build, not on the trace.
mark_edit shows the same collapse with the field work held provably fixed, which is what makes
the mechanism a mechanism and not an interpretation of a clock. mark_field_calls is exactly
90,112 on every one of the six arms, both fields — 11 edits × 2 × 16³ corner samples — because the
edit box is a world-cell box, and region_cells_total is likewise exactly 37,125 = 11 × 15³ on
every arm. Against zero change in field evaluation, region_chunks_total rises 868 → 5,632 →
37,125 on gyroid (42.77×) and 856 → 5,632 → 37,125 on fbm_terrain (43.37×), and at
1³ every region cell is a chunk, so region_chunks_total == region_cells_total exactly. mark_ms
tracks the chunk count, not the sample count: the excess over the flat term is 24.3529 ms over
37,125 region chunks = 0.656 µs/chunk on gyroid and 12.5688 ms = 0.339 µs/chunk on
fbm_terrain. The two are within 1.94× of each other while the fields' per-sample costs differ by
3.64× (k_ns_per_call 41.99 against 152.88), which is the signature of a term that is closer to
field-independent than to field-proportional — bookkeeping, as bookkeeping should be, though not the
near-identity the superseded run read. Consequence: mark's share of the trace goes 47.11% → 51.99%
→ 69.45% on gyroid and 46.85% → 48.07% → 50.10% on fbm_terrain. M-377's "everything is
remesh_ms" is a statement about 8³–64³ and inverts below 2³. The same premise is visibly wrong
in sample in the other direction too: 94.3% and 94.8% of the 4³ rows' model_error
(1.0293 and 0.9339 ms of over-prediction) is the flat mark term carrying c = 2's 5.0104 and 14.8476
against 4³'s actual 4.0393 and 13.9623.
The vacuity control, its column and its value. M-377's assertion inherited verbatim —
VOID: chunk {c} marked no dirty chunk in {EDITS} edits on {field} — instrumented by column
dirty_chunks_total; plus the registration's own stronger wording, which p-72 never
instrumented — "the 1³ arm must mark dirty chunks on every edit or the row is void" —
instrumented by column min_dirty_chunks_per_edit, asserted > 0:
| field | dirty_chunks_total 1³ / 2³ / 4³ |
min_dirty_chunks_per_edit 1³ / 2³ / 4³ |
|---|---|---|
gyroid |
5,976 / 1,501 / 396 | 493 / 121 / 30 |
fbm_terrain |
5,811 / 1,456 / 376 | 440 / 109 / 31 |
Why those values prove the fixture could have failed: that exact string is the one that returned
zero and caught four distinct fixture defects in p-72 — a dig path that missed fbm_terrain's
sheet, a dig path that missed gyroid's undulation at a fixed height, an edit box computed against
an origin of zero, and a world in the positive octant. The fixture here is p-72's unchanged, so
the zero remains reachable by every one of those four routes. The per-edit form is strictly stronger
than the total, and that is not decoration: p-72's third defect produced a non-zero total from
productive edits beside edits that dug air, which a > 0 total accepts. Here the weakest single
edit at 1³ still marked 493 and 440 chunks, so no row is carried by one lucky edit. Two further
non-vacuity guards sit on the other side: stencil_of refuses a zero-vertex population ("the
{what} emitted no vertices, so its stencil is a division by zero"), and the untimed accounting
pass's dirty-chunk count is asserted equal to the timed rep's, without which W would not be the
work that was timed.
Fixture defects, and the result is a null with a reason: no new one, on a fixture whose controls
caught four. All three inherited controls passed on the first run at 1³. That is a claim about
instruments that were exercised, not about instruments that were absent, and here is what each one
established at a granularity p-72 never reached:
- The surface-identity control passed at the granularity where a seam defect is loudest.
distinct_surface_pointsis 53,110 on all threegyroidpartitions and 34,360 on all threefbm_terrainpartitions — quantised tocell_size × 1e-6, four orders finer than any real surface movement and four orders coarser than an ulp near 4.0 (M-32) — against rawverticesof 209,030 / 117,490 / 81,548 and 135,812 / 76,344 / 53,023. At 1³ every internal face is a chunk face, so a partition-dependent vertex would have had 2,097,152 chunks' worth of opportunity. Three partitions, three raw counts, one distinct-point count —M-377's corroboration shape, extended. - The anchor control is what makes C2's parameters legitimate rather than convenient.
k_fieldis fitted against committedp-72remesh_ms, which is only legal if this run's 2³ and 4³ arms are those arms, sodirty_chunks_totalis asserted equal to the committed integers — 1,501 / 396 and 1,456 / 376, and it passed.M-279: the new run must agree with the old one on everything that is not a clock. k_residualisNaNon both 1³ rows by construction, and that is the column saying "out of sample". There is no committedp-72arm at c = 1 to residual against. It is what makes the 1³ prediction an extrapolation rather than a fit.- The fixture did not survive 1³ unmodified, and the change was forced by the arm rather than
chosen.
p-72stores every chunk's initialMeshBufferin aBTreeMapand uses it only to sumbuild_verticesbefore dropping it. At 1³ that is 2,097,152 liveMeshBuffers for a running total, so the sum is accumulated directly. No measured quantity changes:build_vertices,distinct_surface_points,verticesandtrianglesat 2³ and 4³ all reproducep-72's committed integers exactly. - The trace's field-call accounting runs as a fourth, untimed pass, because a
Cellincrement inside the timed region perturbs the thing being timed;p-72counts only the untimed build. The pass is deterministic and its dirty-chunk count is asserted equal to the timed rep's.
Budget, since the registration flagged 1³ as a risk (2,097,152 chunks, 8× duplication): it is
not one. arm_wall_s is 2.114 / 0.851 / 0.520 on gyroid and 6.355 / 2.666 / 1.536 on
fbm_terrain, 14.042 s over all six arms, and a full three-repeat median was taken at every
granularity (reps = 3 on all six rows). No substitution was needed, because the expensive parts
at 1³ — the 2,097,152-chunk build and the identity pass — are outside the repeated trace, which
touches ~6,000 chunks.
What changed as a result. Nothing in crates/isomesh/src/**, and that is the answer: do not build
a 1³ active-cell structure. It is 4.36× and 1.76× worse than 2³ and 4.93× and 1.84× worse than the
4³ optimum on edit-plus-remesh; it costs 3.94× the field evaluations of 4³ on every full build
(17,992,540 against 4,570,084); and it carries 3.935794× and 3.952619× vertex duplication
against 1.535455× and 1.543161× at 4³ — 2.56× the raw vertex bytes for the same surface (209,030
against 81,548). Three things for the ledger that are not "nothing":
M-377's 4³ optimum is now bracketed. Measured neighbours on both sides, and nothing untested below, because there is no granularity under 1. The open question is closed rather than deferred.M-377's two-term expression is confirmed as a call model and refuted as a time model outside 2³–64³. The count identity holds exactly at 1³ with a stencil of 6; the constant that converts calls to milliseconds does not, and misses by 99% and 21% one step below the range it was fitted in. Anything sizing chunks byM-377's model needsremeshed_cells_total / dirty_chunks_totalbeside it — the amortisation factor, exactly 64 / 8 / 1 here — because that is the quantity the missing term is divided by.M-377's "mark_msis flat" should be read as scoped to 8³–64³. It is a statement about a range in whichregion_chunksis small, and it is wrong by 486% one step outside it whilemark_field_callsdoes not move by a single call. Any later work budgetingmark_editas constant needsregion_chunks_total, which is now a column.
Would be shown wrong by: a 1³ arm measuring faster than 2³ on either field, which would break
the duplication argument and force M-377's whole granularity result to be re-derived; a
remesh_ms at 1³ within 10% of k_field × W(1) on a quiet machine, which would restore the
field-call bridge and put the entire model error back on the flat-mark premise where the superseded
run had it; a mark_ms that tracks mark_field_calls rather than region_chunks_total — i.e. flat
at 1³ — which would mean the 42.8× rise in per-chunk classification is not what mark is paying for;
or an implementation in which remeshed_cells_total / dirty_chunks_total falls to 1 without the
per-call cost inflating, which would mean the missing term is not per-chunk at all.
💥 ✗70 / M-402 — C1 HELD at 6.3916× and 10.4802× on the registered 46–60 bucket, but only at the brick: P-39's chunk-level cull alone reads 1.5799× and 1.8825×, under its own 2× bar and under its own clock-free evaluation ratios of 1.5956 and 1.8993; C2 FALSIFIED at 9.398804 and 10.996338 bytes per brick, lost to the index and not the payload; C3 the registered null — additional_removed 0 on 8 of 8, because the brick enclosure is nested inside the chunk's and the two culls are one test at two scales (P-90, R-090)
M. cargo bench --bench experiment_p90, docs/experiments/p-90.csv, 8 rows, f64, Zen 3
(amd-ryzen-9-5900x-12-core). A 128³-cell world over [-2, 2]³ partitioned twice — 32,768 bricks of
4³ (M-377's optimum) and 64 chunks of 32³ (P-39's granularity, eight bricks to a chunk edge) —
re-meshed under P-72's inherited eleven-edit dig trace on top of M-50's four log buckets (15/30/45/60
surface-following sphere and capsule brushes, Add or Subtract, nested prefixes of one LCG log), on
gyroid (base_lipschitz 3.464102) and ground_slab (BoxExact, 1.000000). Four arms interleaved
inside each of 21 repetitions (M-281): the full tape, chunk-pruned, chunk-then-brick-pruned, and an
empty-tape floor. speedup_* are ratios of medians; speedup_both_min/_max are per-repetition
ratios. clock is std_time_Instant_monotonic. Committed at 96d15be — the provenance line carries
no (WORKING TREE DIRTY), and 96d15be is an ancestor of HEAD.
Every number below is read from the committed file at
96d15be, and the harness's own first run is superseded. That run stamped# commit 63c7161 (WORKING TREE DIRTY), and its own note records roughly eighteen sibling harnesses compiling throughout. Every integer reproduced exactly — all three survivor totals, all three removal totals,bricks_differing_from_parent,world_brick_entries,world_bricks_occupied, the necessity counts, every byte column (they are functions of integer entry counts) and botheval_ratio_*— which isM-279's rule satisfied. What moved is every clock column, and the per-repetition band moved most. Ongyroid46–60speedup_both6.1285 → 6.3916, and its band[3.8996, 10.5988]→[6.3743, 6.4626]— a 2.718× spread collapsing to 1.0139×;ceiling_speedup10.8324 → 11.9405,share_prunable0.907684 → 0.916251,speedup_chunk_only1.5241 → 1.5799. Onground_slab46–60speedup_both11.9383 → 10.4802, band[8.3818, 17.5399]→[10.1347, 10.6243],ceiling_speedup40.6865 → 35.6532,share_prunable0.975422 → 0.971952,speedup_chunk_only1.9223 → 1.8825. No verdict flipped:c1_holds,c2_holdsandc3_holdsare identical row for row across the two runs. The first run's own conclusion that "21 repetitions andspeedup_bothstill spans a 2.7× range" is withdrawn — that spread was the load and not the measurement; on a quiet tree the band is 1.4% wide ongyroid46–60 and 4.8% onground_slab46–60. What survives run-independently is the pair of integer ratios, 15.6941 and 18.3847, which are the same in both files.
| clause | registered | measured |
|---|---|---|
C1 pruning still gives ≥ 2× at 4³ on M-50's 46–60 bucket |
≥ 2× | HELD — 6.3916× on gyroid, 10.4802× on ground_slab, and at every one of 21 repetitions (speedup_both_min 6.3743 and 10.1347). Clock-free companions: eval_ratio_both 15.6941 and 18.3847 |
| C2 a per-brick surviving-brush list costs < 8 bytes/brick amortised over the trace | < 8 | FALSIFIED — 9.398804 and 10.996338 (peak); 8.922674 and 10.386746 (bytes_per_brick_mean_trace, the literal reading). Holds at 1–15 and 16–30, fails from 31–45 up |
| C3 chunk-then-brick removes strictly more than either alone | > 0 | FALSIFIED — additional_removed 0 on all 8 rows; additional_over_brick_only is exactly 0 while additional_over_chunk_only is 1,620–12,366 |
And the sharp second number, which is what makes C1 readable: speedup_chunk_only is 1.5799 and
1.8825 at 46–60 — below the registered 2× on both fields. P-39's chunk-level cull, transplanted
unchanged to a world of 4³ bricks, does not clear the bar C1 sets. So the honest headline is not
"pruning still pays at 4³"; it is pruning still pays at 4³ only if the prune is done at 4³ too.
The SHARE recomputation leads, because it is what decides whether the clause was ever reachable. The
registration denominates C1 in "the field-evaluation share of remesh, which M-377 measured as
essentially all of remesh_ms". That is the wrong denominator by construction: pruning removes brush
evaluations and nothing else — the base field and the marching-cubes cell work are untouchable — so the
share C1 can actually move is
share_prunable = (remesh_full_ms − remesh_floor_ms) / remesh_full_ms
where the floor is the same dirty bricks re-meshed from the base field with an empty tape. That floor
is a measured fourth arm (remesh_floor_ms), interleaved with the other three, not an assumption, and
ceiling_speedup = remesh_full_ms / remesh_floor_ms sits beside it in the file.
| field | bucket | remesh_full_ms |
remesh_floor_ms |
share_prunable |
ceiling_speedup |
needs, for 2× | eval_ratio_both |
|---|---|---|---|---|---|---|---|
gyroid |
1–15 | 6.7869 | 2.5434 | 0.625253 | 2.6685 | 4.9921× | 4.5581× |
gyroid |
16–30 | 13.7725 | 2.5522 | 0.814687 | 5.3963 | 2.5889× | 8.9391× |
gyroid |
31–45 | 21.7538 | 2.5574 | 0.882440 | 8.5063 | 2.3074× | 11.9832× |
gyroid |
46–60 | 30.3804 | 2.5443 | 0.916251 | 11.9405 | 2.2012× | 15.6941× |
ground_slab |
1–15 | 4.4215 | 0.6873 | 0.844548 | 6.4329 | 2.4511× | 4.9724× |
ground_slab |
16–30 | 10.8162 | 0.6963 | 0.935628 | 15.5347 | 2.1478× | 11.4335× |
ground_slab |
31–45 | 18.4123 | 0.6957 | 0.962218 | 26.4676 | 2.0817× | 15.1878× |
ground_slab |
46–60 | 24.7246 | 0.6935 | 0.971952 | 35.6532 | 2.0594× | 18.3847× |
"Needs, for 2×" is the arithmetic the ✗51 rule asks for, stated as a factor rather than a share:
(full − floor) / (full/2 − floor) is the reduction in brush work a 2× total speedup requires, given
that the floor cannot be touched. At the registered bucket that is 2.2012× and 2.0594× against
measured evaluation reductions of 15.6941× and 18.3847× — 7.13× and 8.93× of headroom. The harness's
pre-run estimate, written into its header before the first run, was share ≈ 0.906 and a ceiling of
≈10.6× on the harder base; measured, 0.916251 and 11.9405. C1 was reachable with a factor of five to
spare and the arithmetic said so in advance.
And the registration chose the one bucket where the ratio is comfortably reachable. At 1–15 on
gyroid the ceiling is 2.6685 — the bar is 74.9% of the maximum available — and the required brush-work
reduction, 4.9921×, is larger than the reduction the mechanism actually delivers there, 4.5581×
in exact evaluation counts. So the clause fails at 1–15 for a reason that is arithmetic on integers and
does not need the clock at all; the clock agrees, at speedup_both 1.7684 against a 2× bar. Had C1
named the 1–15 bucket it would have been a ✗51-shaped clause — a ratio of a total registered without
checking the share of that total it could move. This is a comment on the registration, and it is fair
because the arithmetic is entirely inside the committed file.
c1_holdsreadsfalseon thegyroid1–15 row, and that is not C1 being falsified. C1 is registered on the 46–60 bucket only; the column is computed per row, so the seventrues and onefalsedescribe eight rows of which one is the clause's population. On that population C1 HELD on both fields. The 1–15 row is quoted above as the share observation, not as a verdict.
C1's clock-free half, and it is the load-bearing half (✗24, M-280). shape_evals_* are exact
counts of brush enclosure-and-distance evaluations, and they include every evaluation the pruning itself
made — one per brush per chunk pass, plus one per surviving-chunk-brush per brick pass. At gyroid
46–60 the trace evaluates 6,080,091 brushes unpruned, 3,810,543 with the chunk cull and
387,413 with both, i.e. 1.5956× and 15.6941×; at ground_slab 46–60, 5,211,855 → 2,744,135 →
283,489, i.e. 1.8993× and 18.3847×. Both eval_ratio_* columns are identical in the superseded run and
in this one — the counts are deterministic functions of a seeded log and a fixed partition.
They also bound the clock, which is how "chunk-only misses the bar" becomes machine-independent. The
three arms mesh the identical cells — asserted, not assumed: the pruned and unpruned arms must make
identical Sdf::sample counts (samples_total 89,130–111,158) — so an arm's time is the shared floor
plus work proportional to its own brush-evaluation count. With a positive floor, full/chunk is then
strictly less than eval_ratio_chunk. Both those ratios are below 2 (1.5956 and 1.8993), so
P-39's chunk-level cull cannot reach C1's bar at 4³ granularity on any machine, not merely on this
one. Measured, the clock sits 0.98% and 0.88% under its own bound — 1.5799 against 1.5956, 1.8825 against
1.8993 — which is the consistency check that the model is the right one.
Where the win comes from, in one line of arithmetic. A brush is prunable over a box of circumradius
r only when it clears the running field by (1 + l)·r, and r is 0.10825 at 4³ against 0.86603
at 32³ — a factor of eight. So the threshold is 0.4833 world units at the brick and 3.8660 at the
chunk on gyroid, and 0.2165 against 1.7321 on ground_slab. 3.8660 is larger than gyroid's value
can ever be — it is a sum of three sine–cosine products, so bounded by ±3 term by term — which is why
the chunk pass is weak on that field: it leaves a mean of 34.3920 brushes per re-mesh of a tape
growing 50 → 60, and the brick pass cuts that to 3.3216 — a further 10.35×, 90.34% of the
chunk-level survivors removed at the brick. On ground_slab, 29.0450 → 2.9129, 9.97×. 4³ is not where
pruning survives; 4³ is what makes it pay.
The per-brick bookkeeping does not eat the win, and the file says how much it does cost. A prune costs
one shape evaluation per brush per box while a mesh costs 125 samples per box (samples_per_brick,
derived from the layout and checked against (cells + 1)³). Fitting one per-evaluation cost from the full
and floor arms gives 3.894–4.726 ns across all eight rows — the marginal brush evaluation is a
property of the brush, not of the base, exactly as the pre-run ≈4 ns estimate assumed. That single
constant predicts the chunk arm to within −3.8% to +4.7% (seven of eight rows inside 2%), and the
measured both arm comes out 10.1–27.7% slower than the same model says it should — 4.7532 against
a predicted 4.3180 ms at gyroid 46–60, 2.3592 against 2.0006 at ground_slab 46–60. At 3.3 surviving
brushes per brick the fixed per-brick cost is no longer negligible against the brush work. That is the
bookkeeping, priced — it is visible, and it is an order of magnitude smaller than the win.
How much of the ceiling is left on the table, and it is an identity rather than a mystery.
speedup_both / ceiling_speedup = remesh_floor_ms / remesh_both_ms, so the attained fraction of the
ceiling is the floor's share of the pruned arm: 53.5% at gyroid 46–60 (2.5443 of 4.7532 ms) and
29.4% at ground_slab 46–60 (0.6935 of 2.3592). The residue is brush work that survived the bound,
not overhead.
C2 is FALSIFIED on both readings of "amortised", and the representation is named because an assumed representation is an assumed answer. The costed structure is a CSR arena over the whole world's bricks:
offsets: [u32; bricks + 1]— 4.000122 B/brick, dense and unavoidable if a brick is to be looked up in O(1) during re-mesh, and paid whether or not the brick has a survivor.indices: [u16; entries]— 2 B per surviving brush, an index into the world edit log. Theu16caps the log at 65,535 edits against Dreams' 100,000;bytes_per_brick_u32idxis the cost of not capping — 14.797485 and 17.992554 B/brick, 473.5 and 575.8 KiB for a 128³ world.
That reduces C2 to an integer bar arithmetic could reach before the run, and did not. With
bricks = 32,768, 4·(bricks + 1) + 2·entries < 8·bricks is exactly entries ≤ 65,534, i.e. fewer
than 1.99994 surviving brushes per world brick on average. Measured world_brick_entries and its margin
to that bar: gyroid 36,283 (+29,251), 59,767 (+5,767), 74,825 (−9,291), 88,452 (−22,918);
ground_slab 36,284 (+29,250), 65,208 (+326), 90,609 (−25,075), 114,626 (−49,092). So C2
holds at the two shortest buckets and fails from the middle bucket up, and ground_slab 16–30 clears by
326 entries of a 65,534 bar — bytes_per_brick 7.980103 against 8, 0.25% under. The arithmetic could
name the bar in advance; only the run could supply entries.
The clause is lost to the index, not to the payload, and every alternative is in the file (46–60, both fields):
| encoding | gyroid |
ground_slab |
verdict |
|---|---|---|---|
payload alone, index charged at zero (bytes_per_brick_payload) |
5.398682 | 6.996216 | under 8 on both — the floor is affordable |
chunk-relative u16 offsets into a per-chunk arena (_chunkarena) |
7.410400 | 9.007935 | the tightest O(1)-indexable form; under on one field only |
per-brick u64 bitmask over the parent chunk's survivors (_bitmask64) |
8.000000 | 8.000000 | exactly 8 — legal (max_chunk_survivors 50 and 44 ≤ 64) and still not under 8 |
registered CSR u16 (bytes_per_brick) |
9.398804 | 10.996338 | FALSIFIED |
two-level sparse, 512-bit occupancy per chunk (_sparse) |
9.068604 | 10.842651 | worse — occupancy is 88.62% and 93.04%, and sparse loses when nearly every brick has a list |
global CSR with u32 indices, no 65,535 cap (_u32idx) |
14.797485 | 17.992554 | the price of Dreams' 100,000-edit log |
No representation that indexes a brick in O(1) gets under 8 bytes on both fields at 46–60. Exactly one
gets under on one field. The mean-over-the-trace reading is no kinder: bytes_per_brick_mean_trace
8.922674 and 10.386746.
C2's cited premise is measured rather than inherited, and ✗41's Part-5 chaining rule is obeyed. The
clause invokes "✗41's finding that 1,507 survivors cut to 73 necessary". Necessity here is
leave-one-out over the same 32,768 bricks at the same final tape, so bytes_per_brick and
bytes_per_brick_necessary are two statistics over one population with nothing multiplied:
survivors_to_necessary_world 66.2066× and 101.6188×, bytes_per_brick_necessary 4.081665
and 4.068970 — comfortably under 8. It is not a route to passing C2, for two reasons. The
necessary set is not constructible by any conservative bound — deciding it cost 32,768 × (|S| + 1)
re-meshes per row here — and the 66–102× is inflated against ✗41's own 20.64× by the confound ✗41
named: only 3,391 of 32,768 gyroid bricks and 1,462 of 32,768 ground_slab bricks carry any
triangle, so most of the reduction is bricks whose necessary count is zero because nothing there meshes.
The dirty-brick statistics (survivors_brick_level 1,322 over 398 re-meshes) are a different population
and are never combined with the world-wide one.
necessary_only_identicalreadsfalseon two rows and it is not a clause verdict. It is✗41's joint-droppability upgrade, which held on 64 of 64 chunks there and fails here: re-meshing from the leave-one-out-necessary brushes alone changed the mesh on 1 brick atgyroid31–45 and 3 atgyroid46–60, of 26,124 and 28,774 bricks where leave-one-out removed anything, and on 0 of the fourground_slabrows. The failure mode✗41named but never observed — two brushes each individually redundant and jointly decisive — is real at brick granularity with a surface-following log.
C3 is the registered null and it is a completed result: additional_removed = 0 on 8 of 8. "Do not
build this" is the conclusion, and the reason is structural rather than a property of this fixture.
| field | bucket | removed_chunk_only |
removed_brick_only |
removed_both |
additional_over_chunk_only |
additional_over_brick_only |
additional_removed |
|---|---|---|---|---|---|---|---|
gyroid |
1–15 | 280 | 3,094 | 3,094 | 2,814 | 0 | 0 |
gyroid |
16–30 | 1,680 | 8,875 | 8,875 | 7,195 | 0 | 0 |
gyroid |
31–45 | 4,592 | 14,698 | 14,698 | 10,106 | 0 | 0 |
gyroid |
46–60 | 8,173 | 20,539 | 20,539 | 12,366 | 0 | 0 |
ground_slab |
1–15 | 900 | 2,520 | 2,520 | 1,620 | 0 | 0 |
ground_slab |
16–30 | 3,525 | 7,424 | 7,424 | 3,899 | 0 | 0 |
ground_slab |
31–45 | 6,198 | 12,312 | 12,312 | 6,114 | 0 | 0 |
ground_slab |
46–60 | 8,667 | 17,369 | 17,369 | 8,702 | 0 | 0 |
additional_removedis 0 whileadditional_over_chunk_onlyis 12,366 on the same row, and both are correct. The clause says "strictly more than either alone", so the registered column isremoved_both − max(removed_chunk_only, removed_brick_only), which is the minimum of the two one-sided differences. The large positive number is the comparison against the chunk level; the zero is the comparison against the brick level. Neither is an empty share and neither is a void gate — the populations are 2,520 to 20,539 removals per row.
The mechanism, and it is why the zero is exact rather than approximate. A brick's enclosure ball is
contained in its parent chunk's: the furthest brick centre sits √3 · 0.4375 from the chunk centre, and
0.4375 + 0.0625 = 0.5, so d + r_brick ≤ r_chunk with equality at the chunk corner (the pad() slack
is 16 ULP and moves nothing at this scale). The base field is l-Lipschitz, so
|f(c_brick) − f(c_chunk)| ≤ l·d, and therefore the brick's interval is a sub-interval of the chunk's for
every shape. Any brush the chunk test rejects, the brick test rejects too. The two culls are the
same test at two scales — nested, not composed — and the chunk level is a strictly weaker instance
that can find nothing the brick level misses. The file corroborates it as an exact integer identity rather
than an argument: survivors_brick_level equals survivors_brick_direct on every row (847/847,
1,068/1,068, 1,273/1,273, 1,322/1,322 and 632/632, 698/698, 843/843, 970/970), over 1,594 and 1,297
brick prunes.
The fourth arm is why this is a measurement and not a tautology. removed_brick_only is the full tape
pruned directly over the brick box with no chunk pass in front of it. Had additional_removed been
defined against chunk-only instead, the vacuity control would have implied C3 HELD — a brick whose
survivor set differs from its parent's is an additional removal over chunk-only — which is P-70's C3,
a HELD with no instrument behind it. The harness names this in its own header as the reason the fourth arm
exists.
The registered vacuity control: bricks_differing_from_parent, asserted non-zero in main. Values
397 / 399 / 400 / 398 on gyroid and 305 / 324 / 328 / 333 on ground_slab, against
remeshes of 397/399/400/398 and 312/324/328/333.
Why that value proves the fixture could have failed the control. The counter is not saturated: on
ground_slab 1–15 it reads 305 of 312 re-meshes, and distinct_bricks_differing 249 of 256
distinct dirty bricks — seven re-meshes whose brick survivor set was identical to the parent chunk's. A
counter that could only ever return all-of-them would not have produced 305/312. And the magnitude says
what the zero in additional_removed is not: it is not that the brick level does nothing, because the
brick level cuts the mean survivor count from 34.3920 to 3.3216 per re-mesh at 46–60 — 90.34%. It is
that the chunk level adds nothing to the brick level.
Two more controls held and are worth naming. Soundness: every dirty brick re-meshed from the full
tape, from its chunk's survivors and from its brick's survivors is bit-identical in positions and
normals plus mesh_hash — meshes_bit_identical and hashes_identical true on 8 of 8, both asserted,
so no speedup here belongs to a wrong mesh. And M-44: every one of the eleven edits marked at least one
dirty brick, asserted per step. The re-mesh counts also satisfy M-279 where they overlap with a prior
measurement: M-377 recorded 396 dirty 4³ chunks for the same eleven-edit gyroid trace, and this
harness reads 397–400 with a longer tape in front of the dig.
Five fixture defects and instrument corrections — four caught by an instrument firing, one by re-reading the clause before the run.
- The mechanism does not exist on one of
M-377's two fields, and the harness asserts it rather than saying it.FbmTerrain::value_bound()isFieldBound::Unbounded, solipschitz()isNone, so there is no base enclosure to test a brush against and no brush can ever be pruned at any granularity. A timed arm there would have priced bookkeeping against a structurally zero benefit.ground_slab(BoxExact, one sheet aty = 0) replaces it and brackets the quantity that decides the answer —l= 1.000000 against 3.464102 — and the unavailability is an assertion onlipschitz().is_none(), so the row breaks if the crate ever givesfbm_terraina constant. - The first fixture panicked, and the panic was right.
P-72's per-columnyprobe cannot place a log brush ongyroid: its period is 2π against a 4-unit world, so whole columns of[-2, 2]³never cross zero, and it died at(-0.940, -1.633). Placement is now by enumeration — the centres of the cells of a 64³ scan whose corners disagree in sign — which has no failure case to paper over. The dig path keepsP-72's per-edit probe unchanged, which is the construction that stopped two of that harness's runs being void. additional_removedwas nearly defined so that the vacuity control implied it. Caught from the clause's own wording before the run; the fix is the brick-direct fourth arm and the min-of-two-sided definition above, both documented in the harness header.- An assertion the author wrote from
✗41fired, and was correct to.necessary_only_hash_unchangedwas written as anassert!, expecting✗41's joint-droppability result to transfer. It does not — 4 bricks across the 8 rows change their mesh when every individually-unnecessary survivor is dropped at once. Converted to the counted columnnecessary_only_bricks_differing. Written as a comment instead,✗41's 20.64× would have been quoted here as though it applied. - The repetition count was raised 9 → 21 by its own spread columns, and that was still not enough.
speedup_both_min/_maxput the per-repetition band on the row rather than in a footnote, and on the dirty tree it read[3.8996, 10.5988]at 21 repetitions. Only the clean-tree re-run at96d15beclosed it to[6.3743, 6.4626]. The columns that decide the entry are the integers —✗24's rule, and this is the run that proves the point rather than asserting it.
What changed. Nothing in crates/isomesh/src/**: R-090 is a measurement ticket and P-70/P-71's
precedent applies — measure it, surface the decision, stop. What the result licenses:
- If per-brick pruning is ever built, build it at the brick. The chunk pass stays worth keeping as a pre-filter — it cuts the brick pass's input from the full tape to a mean of 34.39 brushes, an exact 1.5956× evaluation saving on its own — but it must not be sold as a cull: 1.5799× and 1.8825× on the clock, 1.5956 and 1.8993 in exact counts, under the registered 2× bar on both fields and provably so on any machine.
- Do not carry a per-brick surviving-brush list on a 128³ world at 46–60 log length. 9.398804 to 10.996338 B/brick is 300.8 to 351.9 KiB, and no O(1)-indexable representation gets under 8 on both fields. Materialise the list lazily for the dirty bricks and discard it: a survivor set costs one shape evaluation per brush to recompute against 2–4 bytes per brick per world to store.
- Do not store only the necessary brushes. 4.068970–4.081665 B/brick would pass C2, but the set is not computable by any bound and on this fixture it is not even valid — 4 bricks change their mesh when all individually-unnecessary survivors are dropped at once.
- Do not apply Lipschitz brush pruning to an
Unboundedbase. There is nothing to prune against, at any granularity.
Would be shown wrong by: a single brick where the two brick-level arms disagree in either direction,
which would mean the running fold's prefix rather than the box containment decides the survivor set and
would put C3 back in play — the file's exact equality on all eight rows currently rules it out; an
O(1)-indexable per-brick encoding under 8 bytes on both fields at 46–60, which would restore C2 — the
payload alone is 5.398682 and 6.996216, so the room exists if a structure can index a brick without a
dense offset per brick; a speedup_chunk_only at or above 2× on a field whose base Lipschitz constant is
low enough that the 32³ threshold still bites, which would make P-39's granularity sufficient after all
and is the one direction the two fields here cannot rule out; or a remesh_floor_ms that is not the
floor — a base field or cell loop that pruning can cheapen — which would raise every ceiling_speedup
and change what the SHARE line is denominated in.
💥 ✗71 / M-403 — item 3.6's prediction is exactly inverted: geomorph FAILS on fbm_terrain at 25.0771 px and the gyroid half it was predicted to lose is the one that HELD at 4.1900 px, because Lengyel's containing-cell rule is missing a morph target on 39.69% of terrain fine vertices against the < 1% the clause needs; and dither, registered as the expensive option, costs 3.49× less temporal history (P-91, R-091)
M. cargo bench --bench experiment_p91, docs/experiments/p-91.csv, 30 rows (35 lines: four #
comment lines, one column header, 30 data rows), 81 columns, f32 fields with f64 statistics,
amd-ryzen-9-5900x-12-core, 24 threads. Fixture is game_lod_flyover's own block geometry —
FbmTerrain::<f32>::canonical() and Gyroid::<f32>::canonical(), BASE_H = 0.25 doubling per level,
meshed with MarchingCubes at level L and L+1, five transition methods per (field, level pair) at the
repo's own switch distances LEVEL_RANGE·(L+1) = 7.0 / 14.0 / 21.0. Committed at 874a68b, header
# commit 874a68b on amd-ryzen-9-5900x-12-core at 2026-08-28T00:56:51Z with no (WORKING TREE DIRTY)
marker, and git merge-base --is-ancestor 874a68b HEAD passes.
✗24andM-281are discharged by construction, not by argument: there is no clock in this row. No column is denominated in time. Every registered number is an integer count, a ratio of two integers taken inside one row, or an exact projection of geometry through a fixed camera.cpu_mhzis on the row and nothing is computed from it. The independent reproduction below therefore differs in exactly one cell, and that cell iscpu_mhz.
| clause | registered | measured |
|---|---|---|
C1 geomorph p99 pixels-of-pop < 1.0 on fbm_terrain at the current switch distance and ≥ 1.0 on gyroid |
terrain < 1 px, gyroid ≥ 1 px | FALSIFIED by the terrain half — 25.0771 px against a bar of 1.0, a 25.1× miss. The gyroid half HELD at 4.1900 px |
C2 dither gets a lower p99 pop than geomorph on gyroid and a higher cost in P-77's history rejection |
lower pop, higher cost | FALSIFIED on the cost half — 123,769 against geomorph's best case 431,578, i.e. 3.49× cheaper. The pop half HELD — 0.9683 px against 4.1900 px |
| C3 rejection under dithered LOD plus active digging exceeds the sum of each alone | superadditivity > 1.0 | HELD by sign only — 1.002476 against a fixture ceiling of 1.075770, which is 241 interaction samples of 97,321 (0.25%), i.e. additivity to engineering precision |
c1_holdsis a single global verdict replicated on all 30 rows, and the half that killed it is the terrain half. C1 is a conjunction over two fields with opposite required directions, so the bench computes one boolean from the two level-0 geomorph rows and stamps it everywhere. A reader who grabsc1_holds = falseoff thegyroidgeomorph row will attribute the failure togyroid— which is the exact opposite of what happened, sincegyroid's half is the one that passed. The disambiguating column isc1_half_this_row_holds:falseon the threefbm_terraingeomorph rows,trueon the threegyroidgeomorph rows, andNAon the other 24 rows, because a clause about the morph has no half on a row that does not morph.
c2_holds = falseis a conjunction of which one part passed.c2_pop_half_holds = trueandc2_cost_half_holds = falseon all 30 rows. The pop half — the half the registration argued for from topology, that a triply-periodic field denies a morph its target alongp + t·n— is the half that held. The cost half fell in the direction opposite to the prediction.
C1, at the two rows the clause is actually about, plus the arm it is scored against:
| field, L0→1, d = 7.0 | none (hard switch) |
geomorph |
dither (S = 8) |
needs |
|---|---|---|---|---|
fbm_terrain p99_pixels_of_pop |
29.7375 | 25.0771 | 3.7172 | < 1.0 |
gyroid p99_pixels_of_pop |
7.7467 | 4.1900 | 0.9683 | ≥ 1.0 for C1 |
fbm_terrain max_pixels_of_pop |
41.6578 | 41.6578 | 5.2072 | — |
gyroid max_pixels_of_pop |
8.7655 | 6.2964 | 1.0957 | — |
The mechanism number, and it is where the two orders of magnitude live. The geomorph residual is exactly zero where the morph target exists and the full displacement where it does not, so the clause is a statement about a failure count and nothing else:
rule, fbm_terrain L0→1 (1,159 fine vertices) |
fail fraction | integers |
|---|---|---|
| containing coarse cell (item 3.6, registered) | 0.396894 | 460 no-hit + 0 flipped + 0 no-normal, 699 success; 460/1159 = 0.396894 |
| 3×3×3 dilation | 0.053494 | 62/1159 |
| no cell restriction, ±3 coarse cells | 0.053494 | 62 no-hit + 0 flipped, 1,097 success; 62/1159 = 0.053494 |
rule, gyroid L0→1 (3,309 fine vertices) |
fail fraction | integers |
|---|---|---|
| containing coarse cell (registered) | 0.484436 | 1,603 no-hit, 1,706 success; 1603/3309 = 0.484436 |
| 3×3×3 dilation | 0.083409 | 276/3309 |
| no cell restriction, ±3 coarse cells | 0.083409 | 276 no-hit + 0 flipped, 3,033 success; 276/3309 = 0.083409 |
Both accounting identities close exactly — success + no_hit + flipped + no_normal == fine_vertices on
every arm of every row, asserted — and the three fractions are monotone by nesting, also asserted.
So item 3.6 is right in sign and wrong by two orders of magnitude in size. On the unrestricted ray, which is the arm that tests 3.6's stated mechanism (a heightfield is star-shaped along the up axis and a triply-periodic minimal surface is not), terrain does beat gyroid: 0.053494 against 0.083409, a factor of 1.5592. Directionally correct, and both are five to eight times too many for a sub-pixel p99. The containing-cell restriction contributes 7.42× more failures on terrain than non-star-shapedness does (0.396894 / 0.053494) and 5.81× more on gyroid. Lengyel's own withheld guarantee — "(It is unclear whether this point always exists.)" — is now a measured number on both fields.
SHARE recomputation, in full, including the part arithmetic could not reach before the run.
The registration's SHARE is "C1 and C2 move the LOD transition only; C3 moves the TAA resolve." Those are
two disjoint budgets, so there is no double count to price and no ✗51-style share ceiling: the pop
clauses move geometry the transition emits, C3 moves history the resolve reuses, and neither clause is
stated as a fraction of a total.
C1's terrain half is reachable only if geomorph_fail_fraction_cell is under about 1%. The residual
distribution is two-valued — 0 on morph success, the full surface displacement on failure — so a 99th
percentile lands inside the failure population as soon as that population exceeds 1%, and the p99 is then
approximately the hard switch's own. The alternative route, failures whose own displacement happens to be
sub-pixel, is arithmetically dead: at d = 7.0, H = 1080, θ = 45° one pixel is
1 / 186.2393 = 0.005369 world units = 0.021478 fine cells at fine_h = 0.25, against M-121's already
measured pop of 0.6–1.6 cells typical and 3.136 worst. C1's terrain half is therefore precisely the test
"does Lengyel's containing-cell rule succeed on more than 99% of fine vertices", which is what item 3.6's
implied near-zero failure rate claims. It is a real test rather than a dead end, and the column it turns on
is geomorph_fail_fraction_cell. Measured: 0.396894, which is 39.7× the 1% the clause needed — the
clause fell for a reason that was reachable in either direction and was decided by an integer.
C3's ceiling is 1.075770, from the fixture rather than from the clause. The combined arm's rejections
lie inside the union of the two causes, so superadditivity ≤ 1 + excess_dig / (excess_lod + excess_dig):
the dither's flip set is the whole frame while the dig's changed set is only the brush silhouette
(taa_brushes_placed = 2; the bench names the geometry as a 0.25-radius brush at about 3 units), so
excess_dig is small and 1.0 is clearable only just.
1 + 7,374 / 97,321 = 1.075770, and the measured 1.002476 sits 3.27% of the way from 1.0 to that
ceiling. superadditivity_ceiling is on the row so the verdict reads against what the fixture allowed
rather than against 1.0 alone.
A looser bound is also on the row and worth stating because it is the one that proves 1.0 was nowhere near
a wall: no arm can reject more than the whole population, so superadditivity ≤ (taa_population_static −
static) / (excess_lod + excess_dig) = (1,030,808 − 33,822) / 97,321 = 10.244. The union bound is the
tight one and it is what the column carries.
One thing the registration's own reachability note got wrong, and the file shows it. The bench header
says "C2 has no arithmetic bound and needed none." C2's pop half does have one, and it is the same bound
as C1's. The dither arm is an analytic alpha-to-coverage model — the resolved residual is δ / min(S, F)
with S = 8 slots and F = 12 fade frames — so the dither column is exactly the none column divided
by 8: pop_world_p99 0.041595 / 8 = 0.005199 on gyroid at d = 7.0, to the last committed digit. C2's pop
half therefore reduces to "is geomorph's p99 above one eighth of the hard switch's", and since geomorph's
p99 is approximately the hard switch's whenever the failure fraction exceeds 1%, the pop half was decided
by geomorph_fail_fraction_cell too. Measured margin: 4.1900 / 0.9683 = 4.327×. The half held for a
real reason, and that reason is not independent of C1's.
C3's arithmetic, reproducible from the row's own history_rejected_* columns. All six counts are
global to the run and identical on all 30 rows; taa_population_static = 1,030,808 samples (480 × 270
resolve over an 8-frame window after 16 warm-up frames):
| arm | column | rejected |
|---|---|---|
| static, jitter on | history_rejected_static |
33,822 |
| dithered LOD | history_rejected_lod |
123,769 |
| active digging | history_rejected_digging |
41,196 |
| dithered LOD and digging | history_rejected_lod_and_digging |
131,384 |
| geomorph LOD, triplanar | history_rejected_lod_geomorph |
432,188 |
| geomorph LOD, UV-locked | history_rejected_lod_geomorph_uv_locked |
431,578 |
excess_rejected_lod= 123,769 − 33,822 = 89,947excess_rejected_digging= 41,196 − 33,822 = 7,374sum_of_parts= 33,822 + 89,947 + 7,374 = 131,143.0superadditivity= (131,384 − 33,822) / (89,947 + 7,374) = 97,562 / 97,321 = 1.002476superadditivity_excess_samples= 131,384 − 131,143 = 241superadditivity_ceiling= 1 + 7,374 / 97,321 = 1.075770
c3_holds = true is a sign test on 1.002476 > 1.0. 241 samples of interaction out of 97,321 is 0.25%,
and 0.25% is additivity — which is C3's own registered falsifier, "additivity would mean the two effects
are independent and dither is affordable after all." Reporting HELD without that sentence inverts what the
row means. The geometric reason is on the row: excess_dig is 8.20% of excess_lod, so there is almost
nothing for the two causes to overlap over.
Mechanism: a morph and a dither fail in orthogonal dimensions, and each failure is structural.
Geometry. The morph needs a coarse-surface intersection along p + t·n inside the containing coarse
cell. It is missing on 460 of 1,159 terrain vertices and 1,603 of 3,309 gyroid vertices, and the failures
are not degenerate normals — geomorph_no_normal_cell is 0 on every row — nor, under the registered rule,
flipped hits: geomorph_flipped_cell is 0 on four of six rows and 1 on the other two. Under the
unrestricted rule the flip class does appear, and only on the cave: geomorph_flipped_reach is 0 / 1 / 1
on the three terrain rows and 0 / 38 / 32 on the three gyroid rows, which is the one place in the file
where non-star-shapedness shows up as its own signature rather than as a missing hit.
A dither needs no target at all,
so its residual is δ / S unconditionally, and it wins the pop comparison on the field item 3.6 predicted
would defeat a morph.
Time, and here the causality inverts. A morph moves the surface at every pixel on every frame of
the fade, so normal, depth and fog all change every frame and the 3×3 YCoCg neighbourhood clamp rejects
history across the whole transition. A dither moves nothing: a renderer writes zero motion and a flipped
pixel's history is a content mismatch confined to 1/S of the coverage, which the clamp mostly contains.
Measured 432,188 against 123,769 — a 3.4919× inversion of the registered clause, scored against
geomorph's best case 431,578 so dither had to beat the arm that favours geomorph and still won by
3.4870×. The owner's own explanation for that number was falsified by the control built for it: the
UV-locked arm exists to test whether game_dig's world-space triplanar material sliding under the morphing
surface is the confound, and 431,578 against 432,188 is a 0.14% difference against a 3.49× effect. The
cost is the surface motion itself, not the material.
What that does to the one measured argument in the literature. Haydel, Yuksel and Seiler
(10.1145/3618359) chose morphing over stochastic LOD because stochastic causes "significantly increased
data movement" spikes at transitions. Their budget is data movement at the transition; this row's budget
is temporal reuse across it. Two budgets, opposite verdicts, and neither invalidates the other — which is
exactly why only the structural half of their argument was ever portable off a cycle-accurate TRaX
simulation.
Instrument agreement, M-279's rule, checked three ways and asserted.
- The pixel conversion is item 3.8's verbatim and is on the row rather than in a comment:
pixels_per_world_unit_at_distance= 186.2393 at d = 7.0, and1080 / (2 × 7 × tan(22.5°)) = 186.2393— exact for the stated camera (view_height_px= 1080,fov_y_deg= 45.0, Bevy'sPerspectiveProjection::default). It reads 93.1197 at d = 14.0 and 62.0798 at d = 21.0, both exactlyH / (2 d tan(θ/2)). pop_world_max× that factor ismax_pixels_of_pop: 0.223679 × 186.2393 = 41.6578 on thefbm_terrainnonerow, to the last committed digit.distance_for_p99_under_one_pxis the same identity read the other way — 7.0 × 29.7375 = 208.16 — because the projection is exactly proportional to1/d.pop_cells_vertex_metric_max= 1.541236 on the terrain L0→1 block sits underm121_reproduced_adjacent_only= 1.6177, the maximum of the same statistic over all twelve blocks, so the new pixel instrument agrees withM-121where the two overlap.reproduce_m121runsM-121's ownworst_gapover all twelve blocks and every ordered level pair and is asserted against the committed 3.136 with a one-sided 1% tolerance: measuredm121_reproduced_worst_pop_cells= 3.1412, +0.16%, withm121_reproduced_median= 1.4574 insideM-121's own "typically 0.6–1.6".
Independent reproduction, which is what makes this row integer-reproducible. R091Final re-ran the
bench and diffed all 30 rows × 81 columns cell by cell against the owner's run: one differing cell,
cpu_mhz (4201 against 4200). Every registered column, every rejection count, every pixel figure, the
3.1412 and the 241 interaction samples reproduce exactly.
The registered vacuity control, its column, its value, and why that value proves the fixture could have failed. Registered: "the no-transition arm must show a measurable pop, reported in pixels, or both methods are being compared against an invisible baseline."
Columns: vacuity_none_p99_pixels and vacuity_none_max_pixels, stamped on every row, plus an
assertion loop that re-reads p99_pixels_of_pop, max_pixels_of_pop and pop_cells back off every
emitted method = none row and asserts each strictly positive, with assert_eq!(none_rows, pops.len()) so
no geometry escapes the control. Values at the current switch distance: fbm_terrain 29.7375 px p99 /
41.6578 px max / 0.894715 pop_cells; gyroid 7.7467 px / 8.7655 px / 0.188263.
That value proves the fixture could have failed for a reason stronger than its size. The same instrument
demonstrably emits exact zeros: the geomorph residual is 0.0 on geomorph_success_cell = 699 of 1,159
terrain vertices (60.31%) and 1,706 of 3,309 gyroid vertices (51.56%), so a zero is inside this
instrument's range and the 29.7375 is not an artefact of an instrument that cannot report nothing. Had the
two levels extracted the same surface at the switch, every residual would be identically zero and the
assertion would have fired — and in that world "geomorph achieves sub-pixel pop" would be a true
statement about nothing. The baseline is also 29.74× and 7.75× the one-pixel bar both methods are scored
against, and it is corroborated as the same pop M-121 measured, not a new one (item 3 above).
Second half of the same control: a one-slot dither is a hard switch scattered across pixels, so
dither_s1 must read exactly none — asserted to f64::EPSILON, and it does, on all six level pairs
(29.7375 / 41.6578 and 7.7467 / 8.7655 at d = 7.0). Had a geometric benefit leaked into the dither model,
every dither number in the file would be an artefact of the harness rather than of alpha-to-coverage.
Fixture defects the harness's own controls caught.
- The
M-121reproduction failed first, and the fix is a finding aboutM-121. Restricted to adjacent level pairs it reads 1.6177 cells against the committed 3.136 — a 1.94× disagreement.game_lod_flyover::level_foris recomputed every frame under a user-controlled fly speed, so a block can cross twoLEVEL_RANGEboundaries between frames and switch 0 → 2 in one step, whileh = spacing(min(was, now))divides a two-level displacement by the level-0 cell. Enumerating all six ordered pairs on all twelve blocks reproduces 3.1412.M-121's 3.136 is a two-level switch.m121_reproduced_adjacent_onlykeeps the trap visible on every row. - A 40–60% geomorph failure rate on both fields is either a finding or a fixture defect, and the only
way to tell is to ask whether the ray misses the coarse surface or merely meets it next door. The
first run read exactly that, so two extra nested restriction arms were built — 3×3×3 dilation, and no
restriction within ±3 coarse cells — with
cell ⊆ cell27 ⊆ reachasserted monotone andsuccess + no_hit + flipped + no_normal == fine_verticesasserted on each. Verdict: finding, not defect — the unrestricted arm still fails 5.35% and 8.34%. - The owner's own explanation for the 3.49× cost was falsified by the control built for it. The UV-locked geomorph arm tests the triplanar-material hypothesis and reads 431,578 against 432,188 — 0.14% against a 3.49× effect.
P-77's smooth-shade defect, inherited rather than rediscovered.P-77's first run read a 95.5% steady-state rejection rate off a smooth shade; the world-space albedo detail that fixes it is transcribed here rather than re-derived.P-77's camera defect binds this fixture. The rejection rate is a function of reprojection displacement and a walking camera saturates it at 86.6%, so the camera is pinned toP-77's staticHEADLINE_ARMregime — the only regime where C2's and C3's ratios have headroom.M-121's statistic overstates the visible displacement, and the registered column had to change to say so. A vertex-to-nearest-vertex distance contains the coarse mesh's own vertex spacing:p99_pixels_vertex_metric= 67.1820 px against the registered vertex-to-nearest-trianglep99_pixels_of_pop= 29.7375 px, a 2.2592× correction. Both are on every row.- The gyroid coarse mesh yields four zero-area triangles at every level, counted as
degenerate_coarse_triangles = 4rather than silently skipped, because the closest-point routine divides by a zero barycentric sum on one. - Stated, not fixed: the cost half has no zero-proof arm of its own. Its vacuity control is
assert!(static_rej > 0)with 33,822 of 1,030,808, inherited fromP-77'szero_proof_no_jitter_staticarm reading exactly 0. That is weaker thanP-77's control and the row says so. - Stated, not fixed: the denominators are not shared with
P-77. This static arm's rate is 33,822 / 1,030,808 = 3.28%, 6.7×P-77's 0.49% headline, because the scene differs (480 × 270, LOD-block geometry, a trilinear-reconstruction cast rather than analytic sphere tracing). No number may be cross-quoted betweenP-77andP-91. 3.28% still leaves about 30× of headroom, so C2's and C3's ratios are measurements and not quotients of saturated rates. - Stated, not fixed: the pop metric is plausible, not perceptual. StopThePop (
arXiv:2402.00525) and FLIP (10.1145/3406183) are the only published popping metrics and both need a trained perceptual model. This is a projected geometric displacement and must not be quoted as a visibility threshold. No frame time is claimed anywhere in the file.
Every number in the two reports was re-checked against the committed clean re-run, and two do not
survive it. The reports were written off a run stamped 63c7161 (WORKING TREE DIRTY) while roughly
twenty-five sibling agents were compiling; the committed file is the quiet-tree re-run at 874a68b.
Everything else in both reports reproduces to the last committed digit — the pixel figures, all six
rejection counts, 1.002476, 241, 3.1412, 1.6177, 1.541236, 186.2393, 4 / 6 / 12 bytes, the four degenerate
triangles.
geomorph_fail_fraction_cell27— the owner's report tabulates the 3×3×3 dilation at 0.1044 on terrain and 0.1614 on gyroid. The committed file reads 0.053494 and 0.083409, which are62/1159and276/3309, identical to the unrestrictedreacharm on five of the six rows (the sixth,gyroidL2→3, is 67/273 against 66/273 — one vertex). Neither reported figure appears in any column ofdocs/experiments/p-91.csv, and the independent reproduction diffed against the owner's own saved run found onlycpu_mhzdiffering, so the reported pair belongs to a draft run earlier than either. The conclusion those figures supported — that the dilation is an intermediate step between the containing cell and an unrestricted ray — is withdrawn. What the committed integers say instead is stronger and run-independent: one cell of dilation already recovers every target a ±3-coarse-cell search finds, so the whole 0.396894 → 0.053494 collapse is the containing-cell wall and nothing beyond it, and the residual 5.35% / 8.34% is star-shapedness with no restriction left to blame.cpu_mhz— 4201 in the independent reproduction, 4200 in the committed file. It is the only cell that moved in 2,430, and nothing is computed from it.
A briefed conclusion withdrawn on the committed file's evidence. C2 is one of the six clauses this
phase registered as an expected null, and the null's stated content is "dither also failing on gyroid,
which would mean neither transition works on cave topology and the honest answer is a hard switch at a
distance where nobody looks." That null did not fire and must not be reported as the result. At the
repo's own switch distance the 8-slot dither reads 0.9683 px on gyroid — the only one of all 30 rows
whose p99 falls under one pixel — and distance_for_p99_under_one_px for that row is 6.78 units,
below the 7.0 the demo already switches at. Dither works on cave topology. The completed result is a
different and larger null, and it is two prohibitions rather than one: do not build item 3.6's geomorph,
and do not build item 3.8's switch rule. C2 fell on its cost half, in the direction opposite to the
prediction.
What changed as a result.
- Do not build item 3.6's one-scalar geomorph as specified. The containing-cell rule fails on 39.69% of terrain and 48.44% of gyroid fine vertices, so the field it was predicted to succeed on is the one that kills it. If a morph is built at all the restriction must be relaxed to at least the 3×3×3 neighbourhood, and even 5.35% is five times too many for a sub-pixel p99.
- Do not derive switch distances from item 3.8's rule under a hard switch.
distance_for_p99_under_one_pxonfbm_terrainL0→1 is 208.16 units against the demo's 7.0 —7.0 × 29.7375, an exact within-row identity — a 29.74× switch distance. Ongyroidit is 54.23, still 7.75×. The rule is not a tunable, it is a prohibition. - If a cross-fade is built, build the dither, and this reverses the one measured argument in the literature. Dither wins the pop on gyroid (0.9683 px against 4.1900 px) and costs 3.49× less temporal history. The shippable form of item 3.8 is 8× alpha-to-coverage, which needs 26.02 units on terrain instead of 208.16 and is already sub-pixel on gyroid at 7.0.
- The bytes argument is stronger than the docs claim and it does not save the method.
bytes_per_vertex= 4 againstbytes_second_position= 12 is a 3× saving, not the 2× implied by the gameplay doc's "6 bytes/vertex instead of 12";bytes_per_vertex_doc_claim= 6 is on the row so a reader can redo the arithmetic.morph_t_max_coarse_cells_cellis 0.584485 on terrain and 0.097031 on gyroid, so a quantisation would need under one coarse cell of range. A 3× memory win on a transition that is visible at 25 px is not a trade worth making. - C3 closes as independence, and that is a budgeting decision. A 0.25% interaction means a cross-fade's TAA cost does not hide inside digging's, so the two must be added rather than shared. Dither is affordable on its own terms — 123,769 against geomorph's 432,188 — not because destruction already paid for it.
Would be shown wrong by: a containing-cell geomorph failure fraction under 0.01 on fbm_terrain at
BASE_H = 0.25, which would restore C1's terrain half and with it item 3.6; a morph implementation whose
temporal-history rejection is below a dither's on the same resolve, which would restore C2's cost half and
Haydel/Yuksel/Seiler's ordering; a superadditivity above about 1.02 on a fixture whose dig silhouette is
a larger share of the frame, which would make C3's mechanism claim readable as a mechanism rather than a
sign; a perceptual validation against FLIP_t or a forced-choice study showing that a 25-pixel geometric
displacement is not visible, which would void the whole pixel instrument rather than any one clause; or a
geomorph_fail_fraction_cell27 that separates from geomorph_fail_fraction_reach on a field where the
coarse surface is more than one cell away along the normal, which would make the dilation an intermediate
step after all.
💥 ✗72 / M-404 — C1 FALSIFIED on both of its readings, by 3.00× at the cheapest field
and 58.4× at a dug chunk, while C2 HELD at 77.6–246.2× and C3 HELD at 0 differing bytes over 10,000 edits — so the title inverts: you do not choose between extracting and decoding, you already extracted because the chunk was dug, and the answer is send the log, keep the mesh local, regenerate because the extraction was going to happen anyway (P-92, R-092)
Numbering. ✗72 is the next falsified id and M-404 the next measured id. Against the highest committed pair (
✗55,M-384) those are✗56andM-385, dual-numbered on the✗52 / M-376precedent because one clause falsified and two carry substantial measured material.
M. cargo bench --bench experiment_p92, docs/experiments/p-92.csv, 86 rows (91 lines: four #
comments, one column header, 86 data rows — counted, not briefed), scalar f32 and f64,
AMD Ryzen 9 5900X (amd-ryzen-9-5900x-12-core, ghz 4.1336–4.1934 on 84 rows, worst_ratio 1.0000
so nothing was multiplexed). Four arms: c1_marginal (80 rows — five field families × two precisions ×
eight knob points, each family a least-squares t = a + b·T at a fixed 33³ grid), c2_size (4 rows,
M-50's four log buckets), c3_replay (1 row), c3_control (1 row). Fixture: 33³ chunks —
35,937 samples, 32,768 cells — marching_cubes, with gyroid_dug30 and the C2/C3 chunks carrying
real subtract-sphere brush logs. Committed at ad0a5a3, no (WORKING TREE DIRTY) on the header, and
git merge-base --is-ancestor ad0a5a3 HEAD passes.
| clause | registered | measured |
|---|---|---|
| C1 marginal extraction cost per triangle < 7.3 ns at 33³ | < 7.3 ns | FALSIFIED — 21.9212 ns at the cheapest field, 3.00× the bar; 426.1258 ns at 58.4× worst. c1_holds = false on all 80 C1 rows |
| C1's own gloss, "cheaper than decoding an encoded mesh of the same output" (a total) | < 7.3 ns | FALSIFIED — ns_per_triangle_total 49.4097–2930.7178 ns, i.e. 6.77× to 401.5× the bar. Arithmetically unreachable before the run |
| C1 against the decode measured on this machine | < meshopt_ns_per_triangle |
FALSIFIED — c1_holds_vs_measured = false on all 86 rows; local decode is 4.2589–6.4373 ns, so the best marginal misses by 3.41× even against the slowest local decode |
C2 field + log ≥ 20× smaller than meshopt's encoding, across M-50's four buckets |
≥ 20× | HELD — 246.1824 / 141.0236 / 99.6973 / 77.6249. c2_holds = true on 4 of 4 |
| C3 byte-identical extraction over a 10⁴-edit trace, M5 against Zen 3 | 0 differing bytes | HELD — bytes_differing = 0, replay_edits = 10,000, peer = experiment_p92_replay-apple-m5.bin |
The SHARE recomputation, said out loud, and the clause arithmetic could not reach
✗51's rule: a clause stated against a cost names the share of that cost it can move, before the run.
C1 is not a speedup ratio, so the arithmetic is a reachability check — and the registration's own text
carries two incompatible readings that the check separates.
- The literal wording — "Marginal extraction cost per triangle" — puts the 35,937-sample grid pass
and the 32,768-cell classification walk in the fitted fixed term
aand leaves only the emit stage inb. Reachable, genuinely unknown, and what the harness fits. - The gloss — "re-extracting is cheaper than decoding an encoded mesh of the same output" — is a
total, because a receiving endpoint that decodes does not sample the field at all. Two committed
per-sample marginals for
marching_cubeson this Zen 3 bracket that total: 10.68 ns/sample (✗51) and 13.1892 ns/sample (docs/measurements/resolution_sweep-ryzen9-5900x.csv). So one 33³ extraction costs10.68 × 35,937 = 383,807 nsto13.1892 × 35,937 = 473,980 ns, andtotal/T ≤ 7.3 nsneeds T ≥ 52,576 to 64,929 triangles out of 32,768 cells — 1.60 to 1.98 triangles per cell averaged over the whole volume. A marching-cubes surface isO(n²). Even at the ceiling of 5 triangles per active cell that demands 10,515 to 12,986 active cells, 32.1%–39.6% of the grid; the widest fixture here reached 26,384 triangles, short of the bar by 1.99×–2.46× on triangle count alone. The total reading was unreachable by arithmetic before any code ran, and it is written here because that is the rule. The run confirms it rather than discovering it.
triangle_term_share = b·T/(a + b·T) reports how much of an extraction the marginal clause is even
about: 0.0115 to 0.8072 across the C1 rows. So C1-as-registered talks about between 1% and 81% of a
chunk extraction and never all of it. C2 is a ratio of two independent byte counts with no Amdahl
ceiling — reachable. C3 is a byte count — reachable.
C1 — the fitted marginal, and how the fit separates the grid-sampling term
Not by dividing a total by a count. Within one family the grid is fixed at 33³ and the knob is an
area knob, chosen so the sample loop's instruction sequence does not change: box_exact half-extent
(min/max/abs, no libm call at all — the crate's cheapest field and therefore the lower bound),
sphere radius (one sqrt whatever the radius), gyroid scale (the six libm calls run at every
scale), fbm_terrain amplitude (a trailing multiply over the same four octaves and the same lattice),
gyroid_dug30 scale (the thirty subtract-spheres are walked at every sample regardless). Only the
triangle count moves, so t = a + b·T puts the sampling and classification cost in a and the emit cost
in b. Eight knob points a family, timed round-robin, fit_points = 8.
| family | prec | ns_per_triangle (fitted b) |
cycles_per_triangle |
fit_a_ms |
fit_r2 |
fit_sound |
× 7.3 |
|---|---|---|---|---|---|---|---|
box_exact |
f32 | 21.9212 | 93.0802 | 0.277785 | 0.999982 | true | 3.00 |
box_exact |
f64 | 22.9063 | 95.7758 | 0.276431 | 0.999961 | true | 3.14 |
sphere |
f32 | 27.8346 | 117.4800 | 0.228030 | 0.999919 | true | 3.81 |
sphere |
f64 | 29.8024 | 126.4834 | 0.265546 | 0.999912 | true | 4.08 |
gyroid |
f32 | 58.6082 | 245.0759 | 0.590806 | 0.993040 | true | 8.03 |
gyroid |
f64 | 90.7579 | 379.5804 | 0.840029 | 0.991489 | true | 12.43 |
fbm_terrain |
f32 | 130.8575 | 543.0724 | 6.649519 | 0.999792 | true | 17.93 |
fbm_terrain |
f64 | 129.9082 | 536.9738 | 6.381141 | 0.999781 | true | 17.80 |
gyroid_dug30 |
f32 | 309.5667 | 1298.4850 | 2.096217 | 0.998105 | true | 42.41 |
gyroid_dug30 |
f64 | 426.1258 | 1782.5839 | 2.630045 | 0.998302 | true | 58.37 |
The tightest lower bound is box_exact/f32 at 21.9212 ns/triangle = 93.0802 cycles/triangle. No field
in the crate can undercut it — ✗51 classified its body as min/max/abs with no calls — and it misses the
bar by 3.00×.
M-19's check on fit_a_ms, against the family's own range. box_exact/f32's a = 0.277785 ms sits
against measured extract_ms of 0.283863 ms (296 triangles) to 0.498445 ms (10,088 triangles):
a is 97.9% of the smallest run and 55.7% of the largest. Negligible at the top of the range,
dominant at the bottom — do not extrapolate this marginal below roughly 300 triangles. No fit_a_ms
in the committed run is negative, which is M-21's signature checked and clear.
The total basis, ns_per_triangle_total = extract_ms·1e6/triangles:
| family | prec | triangles | ns_per_triangle_total |
triangle_term_share |
|---|---|---|---|---|
box_exact |
f32 | 296 – 10,088 | 958.9966 → 49.4097 | 0.0229 – 0.4437 |
box_exact |
f64 | 296 – 10,088 | 954.1318 → 50.2701 | 0.0240 – 0.4557 |
sphere |
f32 | 104 – 7,976 | 2228.4808 → 56.4110 | 0.0125 – 0.4934 |
sphere |
f64 | 104 – 7,976 | 2592.6250 → 63.1274 | 0.0115 – 0.4721 |
gyroid |
f32 | 4,564 – 25,436 | 182.8501 → 83.1473 | 0.3205 – 0.7049 |
gyroid |
f64 | 4,564 – 25,436 | 249.3166 → 124.7822 | 0.3640 – 0.7273 |
fbm_terrain |
f32 | 2,374 – 5,172 | 2930.7178 → 1416.9058 | 0.0447 – 0.0924 |
fbm_terrain |
f64 | 2,374 – 5,172 | 2818.0455 → 1363.9064 | 0.0461 – 0.0952 |
gyroid_dug30 |
f32 | 7,840 – 26,384 | 564.4389 → 393.4284 | 0.5485 – 0.7868 |
gyroid_dug30 |
f64 | 7,840 – 26,384 | 734.5309 → 527.9047 | 0.5801 – 0.8072 |
49.4097 ns is the best total anywhere — 6.77× the bar — and 2930.7178 is 401.5×.
fit_sound is a required caveat, and the caveat is now about the column, not about one arm
fit_sound is a > 0 && r² ≥ 0.95 (FIT_R2_FLOOR = 0.95), and it exists so a reader who grabs the
obvious ns_per_triangle is not misled — chore C5's lesson. In the committed clean run every one of
the 80 C1 rows reads fit_sound = true, with fit_r2 spanning 0.991489 (gyroid/f64, the lowest)
to 0.999982 (box_exact/f32). So no committed marginal in this table is unquotable.
Six rows read
fit_sound = n/a, and that is not a failed fit. The fourc2_sizerows and the twoc3_replay/c3_controlrows are single-mesh arms, not knob sweeps: they carryfit_points= 1,fit_a_ms= 0.000000 andfit_r2= 0.000000 because there is no line to fit. Theirns_per_triangleis therefore a total, not a marginal — 308.3787 / 441.7750 / 572.4733 / 701.6788 on the C2 buckets (identical to their ownns_per_triangle_total) and 672.1540 on the C3 row. Reading those four zeroes as a collapsed fit is the misparse the column was added to prevent.
c1_holdsreadsn/aon the 6 non-C1 rows andfalseon all 80 C1 rows;c2_holdsreadsn/aon the 82 non-C2 rows andtrueon 4 of 4;c3_holdsreadsn/aon 84,trueon the replay row, andcontrolon the control row.c3_holds = controlis a label, not a verdict: that row'sbytes_differing= 1 is the desired outcome. Everyn/ahere is "this arm does not score this clause", never "this clause failed".
regen_control_differing= 0 on the two C3 rows, and that is a control that does not run in that arm, not a control that fired empty. The regeneration control belongs to the C1 and C2 arms, where it reads 2,435 to 2,459,570 (C1) and 1,235,003 to 1,235,873 (C2).
The vacuity control the registration names, shown as the pair it is
the encoded-size arm must use a real encoder on the real triangles, not an estimate, and its decode time must be measured on this machine rather than quoted from the blog post.
meshopt 0.6.2 — the Rust FFI binding to zeux's own meshoptimizer C library — is a dev-dependency,
and every row runs the real codec over that row's real triangles.
| column | value | why it proves the fixture could have failed |
|---|---|---|
meshopt_roundtrip_differing |
0 on all 86 rows | encode → decode loses no vertex and no triangle (compared up to rotation, because the index codec normalises each triangle's rotation) |
meshopt_control_differing |
1 on all 86 rows | one quantised position component moved by one ULP, through the real encoder and the real decoder, compared by the same comparator, and exactly one vertex differs. A blind comparator says 0; a useless one says thousands |
regen_differing |
0 on all 86 rows | the field-plus-log byte string is decoded back, the chunk is re-extracted from the decoded description, and not one mesh byte moves |
regen_control_differing |
2,435 – 2,459,570 | flip one bit of the encoded cell_size exponent and thousands to millions of mesh bytes move |
meshopt_bytes_per_triangle |
2.5531 – 5.3462 | an estimate cannot vary row to row; the spread is asserted non-zero |
meshopt_decode_ms / meshopt_ns_per_triangle |
4.2589 – 6.4373 ns | measured here, so c1_holds_vs_measured scores C1 against this machine rather than against the blog post. A 4.19 GHz Zen 3 lands at or slightly under the published 2 GHz i7-8650U figure, so 7.3 is a fair bar and not a handicap |
brushes_biting |
= brushes: 15/15, 30/30, 45/45, 60/60, with brushes_drawn = 64 |
a log padded with no-ops would compare a fat description against geometry it did not produce |
replay_min_triangles |
12,394 > 0 | a digest stream of 10,000 hashes of the empty mesh would agree perfectly across two machines and mean nothing |
meshopt_roundtrip_differing = 0 beside meshopt_control_differing = 1, and regen_differing = 0
beside regen_control_differing in the thousands-to-millions, are the whole thesis of this experiment
instrumented rather than argued — the bytes are sufficient to regenerate the chunk — on every row.
C2 — HELD in all four of M-50's buckets, by 3.88×–12.31× more than required
log_bucket |
brushes |
triangles |
vertices |
meshopt_bytes (vtx + idx) |
field_plus_log_bytes |
size_ratio |
size_ratio_f32 |
× 20 |
|---|---|---|---|---|---|---|---|---|
| 1–15 | 15 | 15,460 | 8,143 | 72,870 (54,308 + 18,562) | 296 | 246.1824 | 577.5203 | 12.31 |
| 16–30 | 30 | 16,460 | 8,629 | 77,704 (57,836 + 19,868) | 551 | 141.0236 | 329.1252 | 7.05 |
| 31–45 | 45 | 16,960 | 8,877 | 80,356 (59,795 + 20,561) | 806 | 99.6973 | 232.3015 | 4.98 |
| 46–60 | 60 | 17,340 | 9,077 | 82,360 (61,322 + 21,038) | 1,061 | 77.6249 | 180.4675 | 3.88 |
meshopt was given its strongest line — 16-bit quantised positions over the chunk's own box, octahedral
normals in two bytes, vertex-cache then vertex-fetch optimisation — and size_ratio_f32 (180.5–577.5) is
the same ratio against an unquantised f32 position+normal encoding. The C3 replay's final chunk, with
f64 wire scalars and 50 brushes, still gives size_ratio 43.3201.
The description grows exactly linearly and the geometry does not. field_plus_log_bytes steps
296 → 551 → 806 → 1,061: +255 bytes per 15 brushes = 17.0 bytes a brush (op + centre + radius) over a
41-byte base field description, arithmetic from those four integers. The triangles it produces grow
sub-linearly — 15,460 → 17,340 as the log goes 15 → 60 — so the ratio decays as 1/N: 246 → 141 → 100 →
78. [INFERENCE] extrapolating that decay puts the 20× crossover near 250 brushes on a chunk this
size, far outside M-50's buckets and the number R-095's log trimming should respect.
C3 — HELD, zero differing bytes over 10,000 edits, Zen 3 against Apple M5
bytes_differing = 0, bytes_differing_scope = cross-machine-digest-stream, peer =
experiment_p92_replay-apple-m5.bin, replay_edits = 10,000, replay_min_triangles = 12,394,
replay_total_triangles = 148,093,810, replay_ms = 99,541.849, extract_ms = 9.954185 ms
mean per edit, final chunk 15,785 triangles / 8,251 vertices.
The trace is 200 chunks × 50 subtract-spheres, each brush placed strictly inside its own chunk so a
chunk's log is exactly its own brushes and the window needs no approximation. After every edit the chunk
is re-extracted in f64 and hashed with isomesh::validate::mesh_hash — M-31's own instrument, the
one the 216 golden hashes are taken with — and the 8 bytes are appended to a digest stream written to
target/experiment_p92_replay-<machine-slug>.bin. There is one code path: compare the local stream
against every other stream in that directory. Zero peers would be a comparison over an empty set, not a
branch — and the set is never empty, because the harness also writes
experiment_p92_replay-control-onebyteflipped.bin.
The c3_control row is the comparator's liveness proof: same 10,000-edit stream with one byte
deliberately flipped, bytes_differing = 1, bytes_differing_scope = control-onebyteflipped,
asserted non-zero. So the 0 reported against the M5 is a measurement and not a comparator that never
looks. The digest artefact md5'd identically on both machines (92719079f6d47afb4a62e9ff9ae03fa5,
reported from the two runs' stdout — the md5 itself is not a CSV column), and every integer on the CSV
reproduced on the M5: replay_total_triangles, replay_min_triangles, every C1 triangle count, every
meshopt_bytes, every field_plus_log_bytes, and brushes_drawn = 64.
meshopt as a dev-dependency, justified. It is required rather than convenient: the registration
makes "a real encoder on the real triangles, not an estimate" the vacuity control, and the 1.92 ms sponza
figure C1 is scored against was measured with this codec — meshopt-rs, the pure-Rust
reimplementation, would give a different density and answer a different question. Budget check reported by
the original run: cargo tree -p isomesh -e normal is isomesh + libm, unchanged, with and without
--features experimental. New lock entries are dev/build only (meshopt 0.6.2, cc, jobserver,
shlex, find-msvc-tools, float-cmp), all declared MSRVs ≤ 1.85 against the workspace's 1.89.
Mechanism
Per triangle marching cubes does roughly 0.9 new vertices' worth of work, and each new vertex costs one
edge lerp, one Sdf::gradient, one normalise and a push, plus a table lookup and three index pushes.
The gradient is the swing factor, and the family ordering is exactly the ordering of gradient cost:
box_exact's is min/max/abs (21.9 ns/tri) → Sphere's is a sqrt and three multiplies (27.8) →
Gyroid's is six libm transcendentals (58.6–90.8) → FbmTerrain's is four differentiated noise
octaves (129.9–130.9) → a 30-brush BrushStack has no analytic gradient at all, so Sdf's
default central difference charges six full stack evaluations per vertex (309.6–426.1).
meshopt's decoder touches a triangle without evaluating anything: a byte-oriented delta/entropy decode at
meshopt_bytes_per_triangle 2.5531–5.3462 bytes. Decoding reads bytes; extracting evaluates a
field. 93 cycles per triangle is simply more work than an entropy decoder does, and the gap widens to
58× once the field is a brush stack. The total picture is worse in the direction that decides
"transmit or regenerate": triangle_term_share says only 2.3%–44.4% of a box_exact chunk extraction
is per-triangle work at all — the rest is 35,937 grid samples and a 32,768-cell classification walk that a
decoder never performs.
C2 goes the other way for the same reason the crate exists: the description is procedural. A 17,340-triangle chunk is 82,360 encoded bytes; the field plus a 60-brush log is 1,061.
C3 holds because libm is the only float backend (I-001) and the cell size is a power of two (M-32),
so origin + h·local is exact and every sample is the same bit pattern on both machines. The replay
reaches a regime the 216 fixtures do not — 10,000 sequential edits, stacks 1–50 deep folded with max
(exact and associative), gyroid arguments to 80 radians across a 40×40×8-unit world — and nothing drifts.
What the clean-tree re-run moved, and what was withdrawn
The bench was first run on a dirty tree with roughly 25 sibling agents compiling. Every clock moved;
every integer and every byte count did not. ✗24 (a wall-clock ratio is not a gate) and M-281
(a millisecond is a property of the binary) are why the verdicts below rest on integers and on ratios
taken within a single row.
| figure | pre-run (dirty) | committed ad0a5a3 |
move |
|---|---|---|---|
box_exact/f32 ns_per_triangle |
21.8202 | 21.9212 | +0.5% |
box_exact/f64 ns_per_triangle |
30.8145 | 22.9063 | 1.35× down |
box_exact/f64 fit_a_ms |
0.475095 | 0.276431 | 1.72× down |
sphere/f64 ns_per_triangle |
42.8750 | 29.8024 | 1.44× down |
gyroid/f32 ns_per_triangle |
88.6915 | 58.6082 | 1.51× down |
gyroid/f32 fit_r2 / fit_sound |
0.79190 / false | 0.993040 / true | the unsound arm became sound |
fbm_terrain/f32 ns_per_triangle |
135.4014 | 130.8575 | −3.4% |
gyroid_dug30/f64 ns_per_triangle |
423.3456 | 426.1258 | +0.7% |
box_exact/f32 cycles_per_triangle |
91.87 | 93.0802 | +1.3% |
ns_per_triangle_total span |
49.43 → 4269.0 | 49.4097 → 2930.7178 | the top end fell 1.46× |
C3 replay_ms |
143,182.691 | 99,541.849 | 1.44× down |
C3 mean per-edit extract_ms |
14.318 | 9.954185 | 1.44× down |
ghz range |
4.1613 – 4.1952 | 4.1336 – 4.1934 | |
every triangle count, meshopt_bytes, field_plus_log_bytes, size_ratio, brushes_drawn = 64, replay_min_triangles = 12,394, replay_total_triangles = 148,093,810, bytes_differing, regen_differing, meshopt_control_differing |
— | identical | 0 |
Three conclusions withdrawn, and what replaced each.
- Withdrawn: "
gyroid/f32isfit_sound = falsein the committed run (r² = 0.79190) and its 88.6915 ns/tri must not be quoted." On the quiet tree that arm is sound at r² = 0.993040 and its marginal is 58.6082 — a 1.51× move on the identical binary, which is exactly why it was unquotable. Replaced by: all 80 C1 rows readfit_sound = true,fit_r2≥ 0.991489, and no verdict rests on any single arm because the cheapest field carries the lower bound andbox_exact/f32moved 0.5%. Thefit_soundcaveat now attaches to the column — sixn/arows that are single-mesh arms, blockquoted above — not to one family. - Withdrawn: the Apple M5 per-triangle table (
box_exact12.0593/13.7526,sphere12.8799/15.0818,gyroid35.5467/55.2021,dug30183.7123/231.5293 ns/tri, "still fails by 1.65× at its best"). No committed file contains an M5 timing —docs/experiments/p-92.csvcarries the Zen 3's clocks only, and the M5's contribution is a digest stream, not a duration. Quoting them would be✗35's defect. Replaced by: C1 is falsified on the committed machine by 3.00× at the cheapest field the crate has, on the marginal basis, and by 6.77× at the best total; what is established cross-machine is C3's byte agreement, which is an integer and machine-independent by construction. - Withdrawn: "6.8–132× on the total basis" and "regen_control_differing ∈ [2,435, 2,459,570]" read
as a whole-file range. The committed total span is 6.77× to 401.5× the bar; and
regen_control_differingis [2,435, 2,459,570] on the C1 rows, 1,235,003–1,235,873 on the C2 rows, and 0 on the two C3 rows where that control does not run. Replaced by the per-arm figures above.
Fixture defects the harness's own controls caught
- The first knob choice was wrong and
M-21caught it. The original sweep used gyroid'sisoand fbm'sfrequency, both of which change the surface's topology rather than only its area — so triangles-per-active-cell moves with the knob and time is not linear in triangles.r²came back 0.19262 and 0.36605, andgyroid_dug30/f64fitted a fixed cost of −9.32 ms: a negative cost for sampling 35,937 grid points. Replaced with area knobs, which is why the committedfit_r2floor is 0.991489. - Median-of-N was the wrong estimator, and the harness proved it against itself.
sphere/f32returnedr² = 0.658where the identicalf64fixture returned 0.99963 in the same run. Switched to the minimum; then, when per-point batching let a sibling'scargoland entirely on one knob point (box_exact/f64: r² 0.99994, then 0.32081 next run) — a slope error, not a level error — to the minimum over 15 round-robin passes of 5 reps. - The
brushes_bitingcontrol fired at 44 of 45. Drawing each bucket independently produced a log containing a brush that changed nothing, which isP-94's C2 collapse arriving uninvited. Rebuilt as one 60-brush log drawn by rejection with the buckets as prefixes:brushes_drawn= 64 for 60 kept, so 4 of 64 randomly placed brushes were already swallowed by their predecessors on a 33³ chunk — an incidental measurement of the collapseR-094/R-096are about. - A column carrying another arm's number —
M-377's defect, caught by reading the harness's own CSV. The first C3 row put the replay's 148,093,810-triangle total intrianglesbeside the final chunk's 74,294-byte encoding, givingmeshopt_bytes_per_triangle= 0.0005. Fixed: a C3 row's geometry columns all describe the final chunk (15,785 triangles,meshopt_bytes_per_triangle= 4.7066) and the aggregates moved toreplay_total_triangles/replay_ms. - The index round-trip is not a
Vec<u32>equality, and asserting that it was would have produced a false failure. meshoptimizer's index codec normalises each triangle's rotation. Measured on a 3,200-triangle probe: 7,500 of 9,600 indices differ literally, 0 of 3,200 triangles differ up to rotation.differing_trianglescompares up to rotation and documents why. cycles_per_triangleis less robust thanns_per_triangle, and one row shows it. Cycles come from the counter window of each point's fastest pass rather than a min over passes, sofbm_terrain/f32reads 543.0724 againstf64's 536.9738 while their ns marginals are 130.8575 and 129.9082. On the cheap arms both are stable and mutually consistent —box_exact/f32: 21.9212 ns and 93.0802 cycles at 4.1901 GHz agree to 1.34% (93.0802/4.1901 = 22.2143ns against the fitted 21.9212). Quote the cheap arms' cycles; treat the expensive arms' as indicative.
What changed as a result
- Do not build "regenerate instead of transmit" as a CPU-versus-bandwidth trade against an encoder. The argument as registered is dead. Re-extraction costs 3.00× more per triangle than decoding at the crate's cheapest field on the marginal basis, 58.4× at a dug chunk, and 6.77×–401.5× on the total basis that actually applies to a receiver. Transmitting wins on CPU and it is not close.
- The direction that survives is not a CPU argument — it is a wire-format and save-file argument, and
C2/C3 establish it. 77.6–246.2× smaller at
M-50's log lengths, and bit-identical on a Zen 3 and an Apple M5 over 10⁴ edits. The honest framing: you are not choosing between extracting and decoding — you already extracted, because the chunk was dug. The 21.9 ns/triangle is a sunk cost of editing, not an alternative to a 7.3 ns/triangle decode. So: send the log, keep the mesh local, and regenerate because the extraction was going to happen anyway. That is Teardown's conclusion reached from this crate's own numbers, and it needs no new machinery. - One source change this found and did not land.
BrushStackhas no analyticgradient, so dug chunks pay six full stack evaluations per vertex for their normals — 309.6–426.1 ns/triangle against gyroid's own 58.6–90.8, a penalty carried entirely by normals and the largest single per-triangle cost in this experiment.∂ₓ max(f, −s)is∂ₓfor−∂ₓsdepending on which branch won: one comparison per axis, zero extra field evaluations. It is a source change, therefore a separate ticket and a separate conversation (P-70/P-71's rule). Surfaced, not merged. - Nothing here reopens meshlet or cluster compression. The encoder came out faster than extraction, which argues for keeping geometry local — not for compressing it.
- Null reported as a completed result. "Do not build regeneration as a decode substitute" is the conclusion, not an absence of one. C1 was registered as genuinely uncertain; it is now settled with a number, and the number closes the argument in the direction the falsifier named.
Would be shown wrong by: a field whose analytic gradient is cheap enough that the fitted marginal
lands under 7.3 ns — box_exact/f32's 21.9212 is the crate's floor, so this needs a new field cheaper
than min/max/abs, which is why the falsification is structural rather than a threshold; or, for C2, a log
past roughly 250 brushes on a 33³ chunk, where the 17-bytes-a-brush growth crosses the 20× bar and
size_ratio falls below it; or, for C3, one differing byte between two machines' digest streams —
which would end the direction outright, and is exactly why c3_control proves the comparator is live on
every invocation.
💥 ✗73 / M-405 — C1 FALSIFIED on the quantity it is denominated in, C3 FALSIFIED at every rate on every variant, C2 HELD by 509×: the registration's 87.50% is the sample-grid upload on a path GPU-011a deleted, the vertex upload C1 is actually about is 1.71% of a 12.5 edits/s frame at the 4³ optimum, and reaching the window floor of 0.1 edits/s would need a bus 20.7× slower than this rig's — so 4³ wins unconditionally and granularity is settled rather than a trade (P-93, R-093)
M. cargo bench --bench experiment_p93, docs/experiments/p-93.csv, 132 rows (2 fields × 6
granularities × 11 edit rates), f64, NVIDIA GeForce RTX 3090 / Vulkan on a Ryzen 9 5900X at
4,200,056 kHz. M-377's fixture carried forward — chunk granularity 2³–64³ at a fixed 128³ world, an
eleven-edit dig trace on gyroid and fbm_terrain — with a camera arm added: a ±1.4 rad sinusoidal yaw
at 60 Hz for 2 s, uploading each chunk that enters the frustum, timed on the device through one persistent
VERTEX | INDEX | COPY_DST | COPY_SRC buffer. Median of three traces per arm. Committed at 487bdf3,
clean header, an ancestor of HEAD.
Every number in this entry is the committed clean-tree run's, and that matters more here than usual. The reported figures came from a dirty pre-run at
63c7161taken while ~25 sibling agents were compiling, and three of C1's six sub-verdicts flipped. The contention estimate is the harness's own reproduction ofM-377:mark + remeshper edit at 64³ reads 40.6043 ms againstM-377's published 39.673 ongyroid(+2.35%) and 127.4117 against 127.423 onfbm_terrain(−0.01%), where the dirty run read up to +44%. Every integer reproducesp-72.csvexactly — all twelveraw_vertices(117,490 / 81,548 / 66,066 / 58,884 / 55,596 / 53,788 and 76,344 / 53,023 / 42,894 / 38,292 / 36,264 / 35,012), bothdistinct_surface_points(53,110 and 34,360), all twelvevertex_duplication, all sixchunks,normal_stencil6 on all twelve arms.M-279's rule is satisfied: the new run agrees with the old on everything that is not a clock.The clocks, meanwhile, moved by up to 5.6× on the same binary, which is why no verdict below rests on one (
✗24— a wall-clock ratio is not a gate;M-281— a millisecond is a property of the binary).calibration_upload_gb_per_swent 8.0675 → 5.099342 (1.58× on the identical payload through the identical path). The per-chunk crossover read 0.2200 / 0.1347 / 0.1488 / 0.1018 across four dirty runs and 0.572216 here — a 5.62× swing, with one reading 1.8% from falsifying and another clearing the floor 5.7×. The verdicts therefore rest on the byte columns, which are exact integers over one shared calibrated rate, and on ratios taken within a single row.
| clause | registered | measured |
|---|---|---|
| C1 a crossover exists in 0.1–100 edits/s, predicted 1–20, because 4³ carries 51.6% more vertex data | crossover ∈ [0.1, 100] | FALSIFIED — on bytes, the registered quantity, it is 0.004834 edits/s on gyroid and 0.001015 on fbm_terrain: 20.7× and 98.5× below the sweep floor, 207× and 985× below the predicted window. c1_holds_bytes = false on all 132 rows |
| C2 at 4³ the weld costs MORE than the upload it saves | weld_ms > saving | HELD — 68.3161 ms against 0.134126 ms on gyroid (509.3×) and 42.6815 against 0.087844 on fbm_terrain (485.9×); worst at 64³ at 13,005.7× |
| C3 a per-chunk granularity beats both fixed choices by ≥ 1.5× at 12.5 edits/s | ≥ 1.5× | FALSIFIED — 0.2376× on gyroid and 0.1171× on fbm_terrain. The registered 64³/4³ pair never beats the better fixed choice at any of the eleven rates on either field, even with the subdivision transition amortised to zero (max 0.9936×); the tuned 16³/4³ pair peaks at 1.3760× and never reaches 1.5× |
No clause is VACUOUS and none is BLOCKED: each has a column that could have said no, and P-93 names no second machine.
Three
falsecolumns will be misread unless they are spelled out.c1_holds_bytes=falsedoes not mean "no crossover exists" — the byte crossover is finite and positive at 0.004834 and 0.001015 edits/s. It is outside the registered band, and the falsifier's own words ("no crossover in 0.1-100 edits per second") make that a falsification: at any rate a game can produce, 4³ wins.weld_pays=falseon all 132 rows and thatfalseis C2 HELD, not C2 failing — it is the column saying the weld does not pay for itself. Andc1_holds=trueandc1_holds_arena=trueon both fields are not the clause holding on its own terms; see below.
The first result is that the registration's denominator is the wrong set of bytes. The bench reads it
from the artefact rather than quoting it (P-70's precedent), and it reproduces:
docs/measurements/gpu_vs_cpu.csv, samples = 129 |
value | column |
|---|---|---|
upload_ms |
7.323576 | committed_upload_ms |
gpu_total_ms |
8.369384 | — |
| share | 87.5046% | — |
| payload, 129³ × 4 B | 8,586,756 | committed_upload_bytes |
| effective rate | 1.172481 GB/s | committed_upload_gb_per_s |
That 87.50% is the sample-grid upload with host-side field evaluation inside it, and the file's own
source says so verbatim — bevy_isomesh/examples/gpu_vs_cpu.rs:31-37: "FieldBuffer::sampled evaluates
the SDF on the CPU and uploads the samples. So this path does not remove field evaluation from the
CPU's budget — it adds an upload to it. […] Evaluating the field in the shader is what would change that,
and it is not this ticket." GPU-011a then did exactly that, and M-155 measured the whole 129³ path
falling from 8.37 ms to 0.54 ms. So the registration's share is a different quantity, on a path the
crate no longer takes. M-377's bill is a vertex upload.
(The report attributed that quotation to mesh_render.rs. It is not there; it is in the example that
produces the CSV. Corrected.)
And M-377's own headline overstates the vertex upload by 1.97×, from integers already in the file.
The payload is raw_vertices × 24 + 3 × triangles × 4, and triangles is granularity-invariant —
104,518 on gyroid and 67,910 on fbm_terrain at every one of the six partitions. So the index buffer is
a constant 1,254,216 / 814,920 bytes that dilutes the vertex duplication:
| vertices 4³ / 64³ | ratio | payload 4³ / 64³ | ratio | |
|---|---|---|---|---|
gyroid |
81,548 / 53,788 | 1.5161× (+51.61%) | 3,211,368 / 2,545,128 | 1.2618× (+26.18%) |
fbm_terrain |
53,023 / 35,012 | 1.5144× (+51.44%) | 2,087,472 / 1,655,208 | 1.2612× (+26.12%) |
Both payload figures check exactly: 81,548 × 24 + 1,254,216 = 3,211,368; 35,012 × 24 + 814,920 =
1,655,208. The excess a consumer actually pays is 666,240 bytes on gyroid and 432,264 on
fbm_terrain (excess_vertex_bytes_vs_64), not 51.6% of the trace.
The cost model, exactly. Every rate-dependent column is milliseconds per second of gameplay:
total_ms(c, r) = r · edit_ms(c) + stream_ms_per_second(c)
edit_ms(c) = (mark_ms + remesh_ms + upload of the re-meshed chunks) / 11
stream_ms_per_second is real device upload for the chunks that entered view, over the 2 s camera
sweep. Weld is deliberately excluded from total_ms — it is never applied on any arm, because C2
prices it separately and folding it in would charge C1 for C2's answer.
The share recomputation, said out loud (✗51 — a clause stated as a ratio of a total must name the
share of that total it can move). At the 4³ optimum at game_dig's own 12.5 edits/s:
| total ms/s | upload share by the clock | upload share by bytes | Amdahl ceiling | |
|---|---|---|---|---|
gyroid |
60.5357 | 83.8374% (upload_share_of_total) |
1.7057% | 1.0174× |
fbm_terrain |
82.3913 | 58.7953% | 0.8468% | 1.0085× |
Byte share is
(12.5 × upload_dirty_bytes_per_edit / calibration_upload_gb_per_s + stream_bytes_ms_per_second) / total_ms
= (12.5 × 35,865 / 5.099342e6 + 0.944642) / 60.5357. So C1 is denominated in a term worth 1.71% and
0.85% of the frame, against the registration's 87.50% — the clause could move the total by at most
1.74% even if the bus were free. Of the 83.84% clock figure, 97.97% is not bytes at all: the
byte-attributable 1.032558 ms/s sits inside a measured 50.7517 ms/s of write_buffer and submit cost.
The one piece arithmetic could not reach before the run, and the run supplies it as an integer. The
registration could compute d_edit from p-72.csv, and it could compute the excess payload from
raw_vertices. What it could not compute is how many times a moving camera re-crosses the bus with the
same chunk. The camera arm answers it exactly: visible_chunk_enters = 3 × stream_units and
visible_chunk_exits = 2 × stream_units on all twelve arms, so
2 × stream_upload_bytes_per_second = 3 × full_world_upload_bytes exactly on all twelve — the camera
streams precisely 1.5 full-world payloads per second (stream_full_world_uploads_per_second =
1.500000 on both fields). With that integer in hand the whole clause closes as arithmetic:
| d_edit (ms) | excess bytes | excess ms @ 5.0993 GB/s | re-uploads/s needed for a 0.1/s crossover | supplied | shortfall | |
|---|---|---|---|---|---|---|
gyroid |
40.543485 | 666,240 | 0.130652 | 31.0316 | 1.500000 | 20.6877× |
fbm_terrain |
125.260589 | 432,264 | 0.084769 | 147.7677 | 1.500000 | 98.5118× |
31.0316 = 0.1 × 40.543485 / 0.130652, and 20.6877 = 31.0316 / 1.5. crossover_streaming_shortfall
is identically 0.1 / crossover_bytes_edits_per_second — the two columns are one fact stated twice
(0.1/0.004834 = 20.69, 0.1/0.001015 = 98.52). At the registration's own predicted 12.5 edits/s multiply by
125: 3,878.95 and 18,470.96 full-world excess re-uploads per second, against 1.5.
Restated clock-free, which is the form that survives a re-run. Requiring the byte crossover to reach
0.1 edits/s requires 1.5 · Δbytes / (B · Δedit) ≥ 0.1, i.e. a bus no faster than
15 · Δbytes / Δedit:
gyroid:15 × 666,240 / 40.543485= 0.2465 GB/s — 20.69× slower than this rig's measured 5.0993, and 127.8× under PCIe 4.0 ×16's 31.5 GB/s ceiling.fbm_terrain: 0.0518 GB/s — 98.51× slower than measured, 608.5× under the bus ceiling.
C1 was declared arithmetically unreachable before the run under any streaming model in which vertex data
is uploaded on change, and run anyway per ✗51 — the magnitude of the miss is the deliverable, and it
is two orders of magnitude.
Three crossovers, measured, with their status. They answer the clause at three levels of realism.
| instrument | column | gyroid |
fbm_terrain |
verdict |
|---|---|---|---|---|
| exact bytes over one calibrated rate — the clause as registered, and the only one not a clock in its numerator | crossover_bytes_edits_per_second |
0.004834 | 0.001015 | c1_holds_bytes false — FALSIFIED on both |
arena, one write_buffer per frame |
crossover_arena_edits_per_second |
0.410188 | 0.152020 | c1_holds_arena true — HELD on both, not load-bearing |
per-chunk write_buffer, the shape bevy_isomesh ships |
crossover_edits_per_second |
0.572216 | 0.177604 | c1_holds true — HELD on both, not load-bearing |
Both HELDs clear the 0.1 floor and neither is load-bearing. Per-chunk sits 1.75× (gyroid) and
5.63× (fbm_terrain) below the registered 1–20 window's lower bound, and arena 2.44× and
6.58× below it — so the registered prediction is missed in every case, and the sweep floor is the only
thing either clears. Their spread across runs of the same binary settles it: per-chunk read 0.1018 /
0.1347 / 0.1488 / 0.2200 on the dirty pre-runs and 0.572216 here (5.62×), and the arena
instrument changed sign — d_stream_arena was −4.2994 ms/s on gyroid (no crossover at all,
c1_holds_arena false) and is +16.391553 here. A verdict that flips on the same binary is ✗24's
defect exactly. The byte crossover moved too — 0.002150 → 0.004834 and 0.000394 → 0.001015 — but
only because the calibrated rate moved, and it did not come near changing its verdict: it would have to
move 20.7× to.
Everything the clean re-run moved, old → new. Every integer is unchanged; every clock moved.
| quantity | dirty pre-run 63c7161 |
committed 487bdf3 |
|---|---|---|
calibration_upload_gb_per_s |
8.0675 | 5.099342 |
crossover_bytes_edits_per_second gy / fbm |
0.002150 / 0.000394 | 0.004834 / 0.001015 |
crossover_arena_edits_per_second gy / fbm |
none, d_stream −4.2994 / 0.017503 |
0.410188 / 0.152020 |
c1_holds_arena gy / fbm |
false / false | true / true — both flipped |
crossover_edits_per_second gy / fbm |
0.101756 / 0.036741 | 0.572216 / 0.177604 |
c1_holds gy / fbm |
true / false | true / true — fbm_terrain flipped |
c1_holds_bytes gy / fbm |
false / false | false / false — the verdict that did not move |
excess_vertex_bytes_ms gy / fbm |
0.0826 / — | 0.130652 / 0.084769 |
excess_reuploads_per_second_for_crossover gy / fbm |
69.76 / 380.75 | 31.0316 / 147.7677 |
crossover_streaming_shortfall gy / fbm |
46.5× / 253.8× | 20.6877× / 98.5118× |
weld_ms at 4³ gy / fbm |
108.7440 / 68.8827 | 68.316064 / 42.681522 |
weld_saves_upload_ms at 4³ gy / fbm |
0.0848 / 0.0555 | 0.134126 / 0.087844 |
| C2 ratio at 4³ gy / fbm | 1,283× / 1,241× | 509.3× / 485.9× |
mixed_speedup at 12.5/s gy / fbm |
0.0518 / 0.0684 | 0.2376 / 0.1171 |
mixed_steady_speedup at 12.5/s gy / fbm |
0.2904 / 1.0354 | 0.9857 / 0.6435 |
best mixed16 speedup anywhere in the file |
1.90× (steady 1.72× at 1/s) | 1.2882× (steady 1.3760×) |
mixed_subdivide_ms_total gy / fbm |
309.65 / 654.46 | 162.435338 / 497.115556 |
| ms per coarse activation | 44–109 | 24.3 / 84.5 |
64³ mark + remesh per edit vs M-377 |
up to +44% | +2.35% / −0.01% |
total_ms at 4³, 12.5/s, gy |
21.96 | 60.5357 |
upload_share_of_total, same cell |
55.5% | 83.8374% |
| byte-attributable share, same cell | 2.7% | 1.7057% |
arena lever at gyroid 2³ |
41.53 → 6.07 ms/s (6.8×) | 44.8756 → 27.8349 (1.61×) |
Unchanged — every integer column, of which these were quoted in the superseded report and re-read here:
all twelve raw_vertices, both distinct_surface_points, all twelve vertex_duplication, chunks,
normal_stencil, stream_writes, visible_chunk_enters / exits / changes, stream_units,
stream_upload_bytes_per_second, welded_vertices (53,098 / 34,359), mixed_coarse_activations
(7 / 6 of 8), mixed16_coarse_activations (26 / 32 of 512), excess_vertex_bytes_vs_64,
stream_full_world_uploads_per_second, upload_roundtrip_verified, calibration_upload_bytes,
committed_upload_ms / _bytes / _gb_per_s. The first four were additionally cross-checked against
docs/experiments/p-72.csv and agree exactly, which is M-279's overlap test.
WITHDRAWN: "the arena reading came out with a negative delta, i.e. coarse chunks stream more expensively
than fine ones." That was true only of the superseded run. On the committed run both arena deltas are
positive (+16.391553 and +18.993325). The run-independent replacement, grounded on integers and on
ratios within one row: streamed bytes are exactly 1.5× resident bytes on every arm, so
stream_bytes_ms_per_second is strictly monotone decreasing in chunk size on both fields — while
gyroid's two clocks are not. Its 8³ arm costs more than its 4³ arm on both, 39.4124 vs 28.4166
ms/s per-chunk and 38.2552 vs 22.3303 arena, while carrying 11.57% fewer bytes (2,839,800 against
3,211,368). Coarse-chunk over-fetch on entry is real; it lives in the clocks, not in the bytes, and the
byte column is what separates them.
The streaming decomposition, which is where the two HELDs come from:
| chunk | stream_writes |
frames | per-chunk ms/s | arena ms/s | bytes ms/s | overhead ms/s | ms per uploading frame, arena |
|---|---|---|---|---|---|---|---|
gyroid |
|||||||
| 2³ | 38,994 | 32 | 44.8756 | 27.8349 | 1.198383 | 43.6772 | 1.740 |
| 4³ | 9,642 | 32 | 28.4166 | 22.3303 | 0.944642 | 27.4720 | 1.396 |
| 8³ | 2,364 | 32 | 39.4124 | 38.2552 | 0.835343 | 38.5770 | 2.391 |
| 16³ | 534 | 31 | 28.7316 | 29.2142 | 0.784640 | 27.9470 | 1.885 |
| 32³ | 153 | 25 | 13.5161 | 15.7187 | 0.761428 | 12.7546 | 1.257 |
| 64³ | 24 | 7 | 5.2170 | 5.9387 | 0.748664 | 4.4683 | 1.697 |
fbm_terrain |
|||||||
| 2³ | 25,311 | 33 | 42.1289 | 28.3827 | 0.778682 | 41.3503 | 1.720 |
| 4³ | 6,270 | 32 | 26.8839 | 23.2278 | 0.614042 | 26.2698 | 1.452 |
| 8³ | 1,509 | 31 | 20.5741 | 22.4804 | 0.542534 | 20.0316 | 1.450 |
| 16³ | 369 | 29 | 20.4099 | 19.2892 | 0.510045 | 19.8999 | 1.330 |
| 32³ | 93 | 22 | 12.5505 | 13.1320 | 0.495728 | 12.0547 | 1.194 |
| 64³ | 18 | 7 | 4.6371 | 4.2344 | 0.486889 | 4.1502 | 1.210 |
Last column is 2 × stream_arena_ms_per_second / stream_frames_uploading, the bench's CAMERA_SECONDS
being 2.0. The arena path issues one write per frame, so that column is essentially a lone
submit + poll(Wait) — and it spans 1.194 to 2.391 ms, a 2.0× spread on the same operation.
That spread is the whole arena crossover, and it is why d_stream_arena can change sign between runs.
On the per-chunk path 96.68% of gyroid 4³'s streaming cost is overhead (27.4720 of 28.4166) against
0.944642 ms/s of bytes.
Mechanism.
- The two terms were never within two orders of magnitude and cannot be made so.
remeshisdirty_chunks × chunk_cells³; at 64³ the same eleven edits re-mesh 262,144 cells per dirty chunk against 4³'s 64. That lands as 40.2833 ms/edit of remesh at 64³ against 0.4261 at 4³ ongyroid, ad_editof 40.5435 ms per edit. The entire surplus geometry 4³ carries is 666,240 bytes = 0.1307 ms on the wire. One edit's remesh penalty buys 310 crossings of that surplus. M-377's 51.6% is a VRAM-residency number, and this is the first measurement that separates residency from bandwidth-per-second. They differ by a constant here — exactly 1.5× — because the camera's yaw gives every visible unit exactly 3 enters and 2 exits. On a camera that revisits chunks more often the constant rises, but it multiplies a 0.13 ms quantity: at the 0.1/s floor it would have to reach 31.03 to matter, and 1.5 is what a 2,000 px/s flick supplies.- The weld loses by a structural margin, not a constant factor. It is O(vertices) with a lattice probe each; the saving is (vertices removed) × 24 bytes at 5.0993 GB/s, i.e. 4.7 ns per vertex removed. The ratio is set by probe cost over bytes-at-bandwidth and cannot be tuned into range.
- A mixed granularity is pinned to the better fixed choice's dominant term. Its cost is
(fine edit) + (coarse-ish stream), and at every rate in the window those differ by more than an order
of magnitude, so the mixed total tracks whichever dominates and adds a transition on top:
24.3 ms per activation on
gyroid((162.4353 + 7.7686)/7) and 84.5 ms onfbm_terrain((497.1156 + 9.6173)/6) — a guaranteed multi-frame hitch neither fixed choice pays.
C2, at every granularity: weld_ms against weld_saves_upload_ms, the saving derived from exact byte
counts at the calibrated rate.
| chunk | gyroid weld / saves / ratio |
fbm_terrain weld / saves / ratio |
welded away |
|---|---|---|---|
| 2³ | 96.5906 / 0.303286 / 318.5× | 63.9469 / 0.197604 / 323.6× | 64,392 / 41,985 |
| 4³ | 68.3161 / 0.134126 / 509.3× | 42.6815 / 0.087844 / 485.9× | 28,450 / 18,664 |
| 8³ | 57.8209 / 0.061260 / 943.9× | 34.2898 / 0.040172 / 853.6× | 12,968 / 8,535 |
| 16³ | 46.6952 / 0.027458 / 1,700.6× | 30.8279 / 0.018513 / 1,665.2× | 5,786 / 3,933 |
| 32³ | 45.4495 / 0.011983 / 3,792.8× | 30.2075 / 0.008968 / 3,368.4× | 2,498 / 1,905 |
| 64³ | 45.1687 / 0.003473 / 13,005.7× | 30.4795 / 0.003076 / 9,908.8× | 690 / 653 |
The registration expected the weld's cost to be granularity-dependent; what is granularity-dependent
is the saving. weld_ms is nearly flat (45.17–96.59 on gyroid across a 2.18× range of raw vertices)
while the saving falls 87× from 2³ to 64³, so the ratio worsens monotonically as chunks coarsen.
welded_vertices lands at 53,098 against distinct_surface_points 53,110 on gyroid and
34,359 against 34,360 on fbm_terrain, identically at all six granularities — the weld reaches
within 12 and 1 vertices of the exact distinct-point count from six different raw counts, which
independently confirms M-377's duplication is real seam duplication and not a counting artefact.
C3, on the registered pair and on a fairer one:
| rate | mixed_speedup gy/fbm |
mixed_steady_speedup gy/fbm |
mixed16_speedup gy/fbm |
mixed16_steady_speedup gy/fbm |
|---|---|---|---|---|
| 0.1 | 0.3138 / 0.2380 | 0.3306 / 0.2539 | 0.3998 / 0.8733 | 0.4029 / 0.9042 |
| 0.2 | 0.4301 / 0.3513 | 0.4758 / 0.3977 | 0.5699 / 1.2882 | 0.5786 / 1.3760 |
| 0.5 | 0.7119 / 0.3087 | 0.8963 / 0.4085 | 1.0442 / 1.1301 | 1.0827 / 1.3042 |
| 1.0 | 0.6641 / 0.2617 | 0.9936 / 0.4255 | 1.1107 / 0.9567 | 1.1884 / 1.2109 |
| 12.5 | 0.2376 / 0.1171 | 0.9857 / 0.6435 | 0.7584 / 0.4257 | 1.0614 / 0.7659 |
| 100.0 | 0.1552 / 0.0915 | 0.9793 / 0.8688 | 0.6009 / 0.3324 | 0.9753 / 0.6458 |
Six of the eleven swept rates; the maximum of each of the four columns on each field appears in one of these rows.
The maximum anywhere in the file, over both fields, all eleven rates and all four variants, is
1.3760×. Nothing reaches 1.5. On the registered 64³/4³ pair the mixed scheme never beats the better
fixed choice at all — max 0.9936× even with the transition amortised to zero. The 16³/4³ pair exists
because a 128³ world holds only eight 64³ chunks and the trace activated 7 of 8 (6 of 8 on
fbm_terrain), leaving almost no static bulk to be coarse about; at 16³ it activated 26 of 512 and
32 of 512, and still does not clear the bar.
WITHDRAWN: "the 16³/4³ variant reaches 1.90× at 0.1 edits/s and 1.72× at 1/s, clearing the bar but only
at rates where nobody has a problem." On the committed run mixed16_speedup peaks at 1.1107×
(gyroid, at 1.0 edits/s) and 1.2882× (fbm_terrain, at 0.2), and mixed16_steady_speedup at
1.1884× and 1.3760× at the same two rates. Nothing clears 1.5, so the caveat is unnecessary:
C3 is falsified outright, at every rate on every variant.
Vacuity control, as registered. "The upload arm must actually upload — asserted against ✗54's own
gpu_vs_cpu.csv row rather than quoted, per P-70's precedent."
| column | value | why this value proves the fixture could have failed |
|---|---|---|
upload_roundtrip_verified |
true | Queue::write_buffer stages host-side, so a harness that never submitted would time a memcpy and call it an upload. The calibration payload goes through the same Uploader every row uses and is then read back with isomesh_gpu::read_bytes and compared byte for byte. Bytes that never reached device memory cannot come back. |
calibration_upload_bytes |
8,586,756 | Exactly the committed row's samples³ × 4, computed from the file at run time, not typed in. |
calibration_upload_ms |
1.683895 | |
calibration_upload_gb_per_s |
5.099342 | Asserted < 31.5 (bus_ceiling_gb_per_s, PCIe 4.0 ×16). This is the assertion a zero cannot pass: a zero-cost upload gives an infinite rate and stops the harness — M-44's rule with an instrument. Also asserted > 1.172481, the committed row's own effective rate read from the artefact, because the committed figure carries host field evaluation and this path does not, so a pure-bus path must beat it. Asserted against the file so it cannot drift from it. |
"…and the camera arm must move enough to change the visible chunk set, reported as a count."
visible_chunk_changes = 16,070 at gyroid 4³ (9,642 enters + 6,428 exits over 3,214 units);
mixed_visible_chunk_changes = 15,305. Both enters and exits are asserted non-zero on all eight arms
per field — a set that only ever grew would be a frustum opening rather than a camera moving. The full
range is 40 to 64,990 changes (gyroid) and 30 to 42,185 (fbm_terrain).
Inherited from M-377: every arm marked dirty chunks and produced geometry and uploaded bytes and welded
something away; all six granularities plus both mixed arms agree on the quantised surface point set with
zero symmetric difference, so no two-level partition dropped a seam; and grid duplication matches
((c+1)/c)³ to 1e-4 with the normal stencil derived from the remainder at 6 on all twelve arms.
Four fixture defects, all caught by this harness's own controls rather than by review.
- The mixed arm subdivided chunks outside the world.
edit_boxpads the brush by one cell, somark_editlegitimately marks fine chunks at coordinate −1 and 32; dividing those down gave coarse coordinates −1 and 2 on a world holding only 0 and 1. The 64³/4³ arm reported eleven activations of eight coarse chunks and paid a full 4,096-chunk subdivision for each phantom, meshing empty space and charging it to the scheduler. Caught only because the harness printedactivations/coarse_chunksrather than activations alone — a count with no denominator cannot be absurd. Filtered to in-world coordinates; now 7 of 8 and 6 of 8. The fixed arms are left unfiltered on purpose, because that isM-377's behaviour and all twelveraw_verticesreproduce it exactly. weld_saves_upload_mscame back negative, which is impossible since welding strictly removes bytes. Two upload medians of three, each ~0.4 ms, cannot resolve a 30 kB delta on a governed machine. The saving is now derived from exact byte counts at the calibrated rate, and the measured difference is kept in the file asweld_saves_upload_ms_measured— where it is still negative on 5 of 12 arms (gyroid4³ −0.166602, 8³ −0.000630, 32³ −1.834237;fbm_terrain4³ −0.230752, 8³ −1.366982). That is the honest statement of the instrument's floor, and it is wider than the entire saving at every granularity. Same substitutionM-337's re-audit forced onP-40: gate on counts.- C1 was first answered by the wrong mechanism and the harness could not say so. The first run
measured streaming with one
write_bufferper visible chunk, got a crossover inside the registered window, and scored C1 HELD. The tell was in the file: the streaming term spread 12.9× across the granularities while the vertex data spread 2.18×. Fixed by measuring all three upload paths on the same frames' bytes and recordingstream_writes/stream_bytes_ms_per_second/stream_overhead_ms_per_second, so the artefact itself shows which mechanism produced the number. - The second instrument had the wrong sign. The arena path's residue is a per-frame
submit+pollthe 64³ arm pays across 7 frames and the 4³ arm across 32 — seven samples of a 1.2–2.4 ms quantity — and it returnedd_stream= −4.2994 ms/s ongyroid, i.e. no crossover at all. On the clean tree the same instrument returns +16.391553 and scores HELD. That flip is the defect's proof, not its repair, and it is why the exact-byte crossover exists as a third instrument and why the verdict rests on that one.
What changed as a result: nothing landed, and that is the answer rather than an omission. M-377's
open question — "the number a consumer paying for GPU upload should weigh against the 51× edit win" — is
now answered, and the weigh-off is not close. The granularity decision is settled, not a trade.
Three things not to build, each with the number that refuses it:
- Do not build a per-chunk or mixed granularity scheduler. It loses to plain 4³ at every one of the eleven rates on the registered 64³/4³ pair (max 0.9936×, i.e. never wins); the tuned 16³/4³ variant peaks at 1.3760× against a bar of 1.5, and does so at 0.2–1.0 edits/s where the mixed frame already costs 21.56–27.90 ms/s; and it adds a 24.3–84.5 ms subdivision hitch per activated coarse chunk that no fixed granularity pays.
- Do not weld chunk seams to save upload. It costs 509× the upload it saves at the optimum granularity and 13,006× at the coarsest. If welding is ever wanted, it must be justified by something other than bandwidth — index-buffer locality, collider quality, file size.
- Do not quote
gpu_vs_cpu.csv's 87.50% as "what upload costs" again. It is the sample-grid upload including host field evaluation, on a pathGPU-011asuperseded atM-155(8.37 → 0.54 ms). The vertex-upload share of a 12.5 edits/s frame at 4³ is 1.71% by bytes ongyroidand 0.85% onfbm_terrain.
The lever the registration did not name, and it is smaller than the dirty run suggested. If vertex
upload is ever a real cost here it will be the per-chunk write_buffer call, not the bytes: at gyroid
2³ the arm issues 38,994 writes and spends 43.6772 of 44.8756 ms/s on overhead. An arena renderer
issuing one write per frame cuts that to 27.8349 ms/s — 1.61×. (WITHDRAWN: the reported "6.07 ms/s,
a 6.8× cut". On the clean tree it is 1.61×, so the lever is 4.2× smaller than briefed.) And the lever
reverses as chunks coarsen: at 4³ the arena is worth 1.27× (gyroid) and 1.16×
(fbm_terrain), and at 16³/32³/64³ on gyroid it is worse than per-chunk (0.983× / 0.860× /
0.878×), because it trades many small writes for one large write plus the same per-frame submit. At the
granularity this crate actually ships the arena is worth 16–27%, and it is a renderer change in
bevy_isomesh rather than an extractor change.
Would be shown wrong by: a streaming model in which the camera re-crosses the bus with the same
geometry 31 times a second on gyroid or 148 on fbm_terrain rather than the measured 1.5 —
a teleporting or cutting camera, or a chunk-eviction policy that re-uploads on every frustum test rather
than on entry, either of which would put the byte crossover inside the registered window without any
number here changing; a renderer whose vertex format is materially larger than 24 B/vertex and whose
index buffer scales with granularity, which would restore M-377's 51.6% to the byte column; a bus under
0.25 GB/s (gyroid) or 0.052 GB/s (fbm_terrain), which is what C1 needs and is 128× and 609×
under PCIe 4.0 ×16; a weld with no per-vertex probe — this one costs 837.8 ns per vertex (68.3161 ms
over 81,548 vertices at gyroid 4³), so a spatial-hash or sort-based pass at 20 ns a vertex would bring
C2's 509× to about 12×, still losing but no longer structurally; or a world large enough that the 4³
arm's mark_ms stops being flat, which would move d_edit and is M-377's own open question rather
than this one's.
Numbering needed: the next ✗ (highest committed ✗55) and the next M- (highest committed
M-384), dual-numbered on the ✗52 / M-376 precedent — C1 and C3 are falsified, and the entry carries
substantial measured material (three crossover instruments, the streaming decomposition, the weld sweep,
and the exact 1.5× streaming identity).
💥 ✗74 / M-406 — C1 HELD on the size half and HELD WITH NO INSTRUMENT on the constancy half, C2 and C3 FALSIFIED: an hour of continuous digging is 415,038 B and a saturated hour is 734,400 B against a 2 MB bar, all 200 of 200 coaxial capsules are individually necessary bit-exactly, and the bespoke coder beats zstd -19 by only 1.42–1.53× — while zstd on the same residuals lands within 1.39–1.43× of it, so the whole win is the model and not the coder (P-94, R-094)
M. cargo bench --bench experiment_p94, docs/experiments/p-94.csv, 10 rows (five world sizes
64/128/256/512/1024 cells at chunk_cells = 16, then the 128-cell world's one hour re-derived at
granularities 2/4/8/32/64), scalar f64, Zen 3. The fixture is a replay of game_dig's dig loop — its
EDIT_PERIOD, both gates, AIM_*, LIPSCHITZ, CELL_SIZE = 0.125 and Ground transcribed by line —
flown for a full simulated hour per world, in which no brush centre is scripted: a centre is where the
sphere trace stops on the field as already edited. Committed at 782188c, header clean (no
(WORKING TREE DIRTY)), and an ancestor of HEAD.
The clean-tree re-run moved nothing, and that is worth stating because the entry was drafted against a dirty pre-run. The superseding figures were taken at
a747921 (WORKING TREE DIRTY)while ~25 sibling harnesses were compiling, and the original report bet on determinism — xorshift64* seeded fromworld_cells, a fixeddt, integer and exact arithmetic in both compressors — predicting "only the header should change." Checked column by column against782188c: every one of the 83 columns reproduces exactly, including all fiveedits, all fivebytes_uncompressed,closed_loop_edits, both compressors' byte counts,dirty_chunks_per_editandtrace_span_cells. No number moved, old → new. This harness contains no clock at all — every column is a count, a byte length, a ratio of two counts, or a distance — so✗24's a wall-clock ratio is not a gate andM-281's a millisecond is a property of the binary are satisfied by construction rather than by care, andM-279's rule (the new run must agree on everything that is not a clock) is satisfied over the whole file.
| clause | registered | measured |
|---|---|---|
| C1 (size) one hour under 2 MB uncompressed | < 2,000,000 B | HELD — 415,038 B largest measured hour (20.8% of the bar); the saturated bound bytes_at_43200_edits = 734,400 B is 36.7%, i.e. 2.72× of headroom |
| C1 (constancy) per-edit cost constant in world size and chunk granularity | no growth | HELD WITH NO INSTRUMENT — bytes_per_edit = 17.000000 on all 10 rows and could not have come out otherwise. Said out loud rather than scored |
| C2 200 coaxial capsules compress to fewer than 40 survivors | < 40, falsifier < 3× | FALSIFIED — surviving_brushes = 200, collapse_ratio = 1.000000. Leave-one-out necessity is 200 of 200 |
| C3 entropy coding beats a general-purpose compressor by ≥ 2× | ≥ 2.0 | FALSIFIED — compression_advantage 1.418111 / 1.430490 / 1.483570 / 1.533404 / 1.534017, and zstd on the same residuals is within 1.386–1.428× |
The hour, five times over. Each world is a separate hour; the row's bytes_uncompressed is
edits × 17 exactly.
world_cells |
sandbox_extent |
strokes |
edits |
of 43,200 | bytes_uncompressed |
closed_loop_edits |
trace_span_cells |
position_bits_needed |
|---|---|---|---|---|---|---|---|---|
| 64 | 8.000 | 211,320 | 1,169 | 2.71% | 19,873 | 1,128 | 92.422 | 15 |
| 128 | 16.000 | 191,168 | 6,207 | 14.37% | 105,519 | 6,068 | 184.477 | 16 |
| 256 | 32.000 | 135,600 | 20,099 | 46.53% | 341,683 | 19,469 | 367.953 | 17 |
| 512 | 64.000 | 120,128 | 23,967 | 55.48% | 407,439 | 23,156 | 735.552 | 18 |
| 1024 | 128.000 | 118,340 | 24,414 | 56.51% | 415,038 | 23,623 | 890.721 | 19 |
The refusal accounting closes exactly on every row, which is what makes the low edit counts readable
rather than suspicious: edits + gate_refusals_distance + gate_refusals_nohit = strokes, i.e.
1,169 + 0 + 210,151 = 211,320; 6,207 + 116 + 184,845 = 191,168; 20,099 + 146 + 115,355 = 135,600;
23,967 + 362 + 95,799 = 120,128; 24,414 + 281 + 93,645 = 118,340. An hour at 60 Hz is 216,000 frames and
216,000 − 4 × edits reproduces strokes to within 4 on all five rows — so a refused attempt retries on
the next frame while an accepted one costs the five-frame throttle. strokes is therefore due frames,
not edits, and the only quantity C1 is denominated in is edits.
C1's size half, against the two public figures, and the 08-11 doc's own width would have lost. The
serialised record is op u8 plus centre 3 × i32 plus radius i32 at a quantum of 1/4096 world units —
17 B, bytes_per_edit = 17.000000 — and quantisation is applied before both compressors so neither
wins on precision the other kept. 43,200 × 17 = 734,400 B against 2,000,000. At the estimate's own
48 B/op it would be 43,200 × 48 = 2,073,600 B, 1.0368× over the bar and a FALSIFIED. So C1 is a claim
about the record's width.
| comparison | column | value |
|---|---|---|
| largest hour ÷ the 08-11 doc's 4.80 MB estimate | hour_bytes_over_estimate |
0.086466 |
| largest hour ÷ Teardown's ~1 Mbit = 125,000 B | hour_bytes_over_teardown |
3.320304 |
| largest entropy-coded hour ÷ the same 125,000 B | entropy_bytes_over_teardown |
0.994144 (world 512) |
The estimate is 11.565× high on the measured hour (1 / 0.086466) and that decomposes into three
factors, not the two the original report named: 48 B against 17 B is 2.8235×, 100,000 operations against an
hour's 43,200 attempts is 2.3148×, and those two alone give 6.536× — which is the overstatement against
the saturated bound, 4,800,000 / 734,400. The remaining 1.7695× is 43,200 / 24,414: the hour did not
saturate. The report's "11.6× from two factors of 2.8 and 2.3" is withdrawn — 2.8235 × 2.3148 = 6.536,
and the third factor has to be named or the arithmetic does not close.
entropy_bytes_over_teardownpeaks at 0.994144 on the 512-cell world, not on the 1024-cell one. The report quoted 1024's 0.989856. The larger world logged more edits (24,414 against 23,967) and coded to fewer bytes (123,732 against 124,268), because its longer, straighter strokes predict better. So the "an hour of digging is 0.99× Teardown's per-client figure" coincidence is real at 0.994144 — and it stays a coincidence of magnitude between testimony and a measurement, because the blog post never states whether ~1 Mbit is per second, per session, or a steady state. Nothing here is denominated in it.
C1's constancy half has no instrument, and the harness's response to that is the part worth keeping.
Brush<S> is a shape plus an op. It holds no chunk reference and no grid index, and its coordinates are
fixed-width, so per-edit cost cannot depend on chunk granularity and cannot depend on world size. A
harness asserting bytes_per_edit constant would be asserting the definition of the type — P-70's C3
shape, a clause whose predicate is unfalsifiable by the fixture. What was done instead: fly the whole hour
separately in five sandboxes, re-derive the granularity rows from the 128-cell hour, and put two
liveness columns on the row proving both knobs moved something else in the same harness while
bytes_per_edit does not.
| knob | liveness column | range | spread |
|---|---|---|---|
| world size 64 → 1024 cells | trace_span_cells |
92.422 → 890.721 | 9.64× |
granularity chunk_cells 2 → 64 |
dirty_chunks_per_edit |
229.308523 → 1.702755 | 134.65× |
And position_bits_needed = 15/16/17/18/19 is the mechanism behind the constant: the information in a
coordinate does grow with world size, one bit per doubling, exactly as log2(extent / quantum) says.
The record spends 32 bits on it at every world. It is over-provisioned by 13 bits at the largest world
measured, so the width is constant because it was never fitted to the world in the first place.
c1_constancy_holdsreadstrueon all 10 rows and thattrueis not evidence. It is computed by comparingbytes_per_editagainstbytes_per_edit_at_other_world_sizeunderf64::EPSILON— one constant against the same constant, an identity that no code change to this crate could make fail. It is on the row for completeness of the registered records, and the verdict above is HELD WITH NO INSTRUMENT on its account.
C2 is FALSIFIED, arithmetically unreachable, and the arithmetic was written into the harness's SHARE
paragraph before the run. A capsule is a segment dilated by radius, and coaxial capsules tile the
axis: capsule i is the only brush reaching full radius over its own axial slab, because a point at axial
offset u past p_i and radial offset ρ is inside the previous capsule only when ρ ≤ √(r² − u²).
Dropping a run of k therefore leaves an uncovered lens of radial thickness
r − √(max(0, r² − (kδ/2)²)), which reaches the full radius as soon as kδ ≥ 2r. At the measured
coaxial_delta = 0.250000 against coaxial_radius = 0.250000 — coaxial_delta_over_radius = 1.000000,
which is the demo's own distance gate satisfied with room —
- one drop leaves
lens_cells_drop_1= 0.267949 cells, over a quarter of a cell of rock, which the 0.125 lattice resolves; - 200 → 40 means keeping every fifth, so
k = 4,kδ/2 = 0.5 > r, andlens_cells_drop_4= 2.000000 cells — a solid disc of rock of radiusrplugging the tunnel.
So no sound drop-based compressor reaches 40 at any grid resolution, and the run existed to produce the
number rather than to discover that. It produced it three ways: surviving_brushes = 200 from a greedy
bit-exact drop, coaxial_necessary_leave_one_out = 200 from ✗41's own leave-one-out instrument
(removing any single capsule moves mesh_hash), and coaxial_hash_verified = true, which re-meshes the
whole tunnel over coaxial_grid_samples = 69,797 samples after the greedy pass rather than trusting the
per-candidate tests — ✗41's necessary_only_hash_unchanged, and the reason 200 is a measurement and not
a heuristic. coaxial_axial_length = 50.000000 units, coaxial_triangles = 18,640.
✗41's 1,507 → 73 is a different redundancy, and that is the substantive content of the
falsification. ✗41 dropped brushes whose Lipschitz enclosure never reaches a given chunk's surface, out
of 64 randomly placed brushes on a base sphere. A stroke has none of those: every brush in it cut wall you
can see. What collapses a stroke is a change of representation, not a removal — and that is a large
collapse, measured on the same arm:
| arm | column | value |
|---|---|---|
| collinear-run merge, brushes after | coaxial_merged_brushes |
1 |
| collapse of that merge | coaxial_merge_ratio |
200.000000 |
| how far the field moved, worst cell corner of the padded box | coaxial_merge_deviation_cells |
5.684e-14 |
The union of collinear, contiguous, equal-radius capsules is the hull capsule —
min_i d(p, seg_i) = d(p, seg_hull) identically — so 200 → 1 is exact in ℝ and fails only
bit-exactness, by 5.7e-14 cells, which is f64 rounding in the fold and not geometry.
coaxial_merge_hash_equalreadsfalseand it is not the merge failing. The merge is exact as a set and the deviation column says so at 5.7e-14 cells — twelve orders below anything a player or an extractor can express atcell_size0.125.falserecords thatmesh_hashis a bit comparison, and the fold's arithmetic reorders. The bit-exact drop is nonetheless whatsurviving_brushesregisters, for a reason internal to the clause: the registration says the arm reproduces✗41's survivor arithmetic, and a survivor is a brush that was in the log and stayed. The hull capsule is not one of the 200. Scoring the merge as a survivor count would clear C2 by redefining its noun, and every other piece of evidence in this crate is bit-exact.
What a merge is worth on a stroke a hand could actually make, since a dead-straight bore is the easy
case: the same closed loop re-flown with wobble_yaw_rate = 0.010000 rad/s bows by wobble_bow_cells =
8.328517 cells (asserted above one cell, or the arm would be the straight arm renamed), and merging
maximal runs of k costs:
k |
brushes | column | deviation, cells |
|---|---|---|---|
| 1 | 200 | wobble_dev_cells_k1 |
0.000000 |
| 2 | 100 | wobble_dev_cells_k2 |
0.000833 |
| 5 | 40 | wobble_dev_cells_k5 |
0.005000 |
| 10 | 20 | wobble_dev_cells_k10 |
0.020833 |
| 20 | 10 | wobble_dev_cells_k20 |
0.083333 |
| 50 | 4 | wobble_dev_cells_k50 |
0.520815 |
| 200 | 1 | wobble_dev_cells_k200 |
8.328517 |
C2's own registered number, 40, is reachable at 0.005000 cells — 1/200 of the bow the stroke already
has — by merging and not by dropping. wobble_dev_cells_k200 equals wobble_bow_cells exactly, which is
the identity that says the whole-stroke merge deviates by precisely the bow.
Nested edits, the other half of C2's wording, measured on the session rather than the fixture:
session_nested_dropped = 68 / 127 / 426 / 530 / 649 brushes provably contained in another
(|c_i − c_j| + r_i ≤ r_j, exactly redundant under max with no mesh test needed), i.e.
session_nested_fraction 0.020461–0.058169. Two to six percent of a real log, not the order of
magnitude the clause's "coaxial and nested edits collapse" implies.
C3 is FALSIFIED, and the column that decides the ticket is bytes_zstd_of_deltas. Both sides see the
same quantised byte stream. bytes_zstd is zstd at level 19 — the strongest setting, chosen
deliberately so the bar is not cleared by handicapping the baseline — and bytes_entropy_coded is an
adaptive binary range coder (LZMA's, 11-bit probabilities, 5-bit adaptation) over a second-order linear
predictor, decoded back and asserted equal to its input.
world_cells |
bytes_zstd (-19) |
bytes_zstd_level3 |
bytes_entropy_coded |
compression_advantage |
bytes_zstd_of_deltas |
zstd_deltas_over_entropy |
bytes_entropy_first_order |
entropy_bytes_per_edit |
|---|---|---|---|---|---|---|---|---|
| 64 | 9,412 | 9,404 | 6,637 | 1.418111 | 9,196 | 1.385566 | 6,382 | 5.677502 |
| 128 | 50,173 | 50,630 | 35,074 | 1.430490 | 48,974 | 1.396305 | 33,723 | 5.650717 |
| 256 | 157,564 | 162,335 | 106,206 | 1.483570 | 151,387 | 1.425409 | 102,924 | 5.284143 |
| 512 | 190,553 | 196,950 | 124,268 | 1.533404 | 177,348 | 1.427141 | 120,916 | 5.184963 |
| 1024 | 189,807 | 207,354 | 123,732 | 1.534017 | 176,682 | 1.427941 | 121,001 | 5.068076 |
zstd applied to the same second-order residuals lands within 1.386–1.428× of a fully adaptive binary
arithmetic coder. The bespoke coder's whole advantage over stock zstd -19 is 1.418–1.534×, and 1.39–1.43
of that survives when zstd is handed the transform. The win is the model, not the coder — so the
actionable recipe is second-difference the quantised record, then zstd: a fifty-line transform, not a
format. At the smallest log bytes_zstd_level3 is 8 B smaller than level 19 (9,404 against 9,412), so
the baseline was never weakened to make the comparison; at the largest it is 9.2% larger.
And the predictor the clause was registered on the strength of is slightly worse on a real session.
bytes_entropy_first_order is 2.21–3.85% smaller than second order on every world (6,382 against
6,637; 121,001 against 123,732). C3's stated mechanism is that brush parameters are strongly correlated
along a stroke, and within one stroke they are — a stroke is a nearly constant velocity along a ray, which
is what a second-order predictor is for. But a session is many strokes, and the direction changes between
them make the second difference noisier than the first. mean_aim_step_over_radius = 5.86–9.50 says how
far consecutive aim points sit apart in radii, which is where that discontinuity lives.
Mechanism, in one line each. C1: the log is (shape, op) at fixed width, so size is edits × 17 B and
nothing else, and the constancy is a property of Brush<S> rather than of the world — with 13 bits of
coordinate slack at 128 units to prove the width was never fitted. C2: coaxial capsules tile the axis, so a
removal always leaves a lens, and only a merge collapses a stroke. C3: zstd already finds the
correlation, because the 17-byte record puts the three i32s at fixed byte offsets and neighbouring edits
share their high bytes, which is exactly what an LZ match window matches — and 5.07–5.68 B/edit is already
near the payload's real information content given distinct_radii = 3 and one op.
Vacuity control — both registered halves, plus three more.
closed_loop_edits(registered half one: a real session capture rather than a synthetic sweep) — 1,128 / 6,068 / 19,469 / 23,156 / 23,623, which is 96.49–97.76% of edits, asserted non-zero. It counts edits whose hit distance along the ray exceeds the hit distance the uneditedGroundwould have returned from the same eye and the same direction. An edit can only be counted there if a previous edit moved the surface, so it is a direct measurement of the feedback loop, and it could have been zero: a scripted sweep scores zero on it by construction.- The sweep control arm —
AutoCarve::centre-shaped, straight line, fixed cadence, no feedback at all — scoressweep_control_closed_loop= 0 atsweep_control_edits= 6,207, the identical edit count, withsweep_control_advantage= 11.947167 (28,040zstdbytes to 2,347 entropy-coded) against the session's 1.430490 at the same count. So "session, not sweep" is a measured 8.35× difference in compressibility, not a claim — and 2,347/6,207 = 0.378 B/edit against the session's 5.650717 says how much information a scripted straight line does not carry. overlapping_pairs(registered half two: the coaxial arm must actually overlap) — 492 of theC(200,2)= 19,900 pairs, by exact segment-to-segment distance underr_i + r_j, asserted non-zero. Zero would mean C2 was compressing disjoint brushes.entropy_roundtrip_ok= true — the range decoder rebuilds every record, including the four-byte count prefix in the length, sobytes_entropy_codedis the length of a real encoding rather than an entropy figure nobody can invert.wobble_bow_cells= 8.328517 > one cell, asserted — otherwise the wobbled arm is the straight arm under another name and its whole tolerance sweep is vacuous.
Two zeros on the row are zeros by construction and must not be read as measurements.
sweep_control_closed_loop= 0 is the point of the control arm — a sweep has no feedback, and the number is there to give the session's 96.5–97.8% a floor to be measured against.wobble_dev_cells_k1= 0.000000 is the identity control of the merge sweep: merging runs of one changes nothing, so a non-zero there would indict the merge machinery. Neither is azero that could not have been non-zeroinM-44's sense being passed off as evidence.
Three fixture defects, all caught by the same two counters — edits against the hour's 43,200 attempts,
and gate_refusals_nohit — and all three are session-policy failures in the same direction. (The
diagnostic figures below are from the harness's development runs recorded in history://R094DigBytes, not
from the committed CSV.) An unsaturated hour clears C1's bar by not digging, which is the cheapest
possible false HELD — every one of these would have been reported as a smaller, safer number.
- The first policy flew the eye along the view direction. 1,067 edits in an hour against 210,661 no-hit refusals: the eye left the rock and the ray ran out of sandbox before reaching the ground. Fixed by making the feet follow the crosshair — a digging player walks into the hole they are making.
- The second policy re-aimed at the last aim point on a no-hit. Worse — 96 edits in a three-minute
session. The eye stops
AIM_NEARshort of that point, so the ray starts inside the cavity that point carved, exits through the hole and finds nothing, and the look is then pinned at the same failing direction for the rest of the hour. Fixed by a monotone downward scan: the world is a heightfield, so there is always rock below. - The third attempt suspended the phase's look script during a recovery so the scan could accumulate.
Worst — 137 edits in an hour, against 1,993 in three minutes without it. A latch refreshed on every
failure never expires, because a lost hand fails on every due frame; the script stayed suspended, the
feet stopped (they follow a crosshair that stopped moving), and the session died. Reverted — the
scan now accumulates only during
BoreandSweep. The generalisable half: prefer a partial instrument that cannot deadlock to a complete one that can.
Two findings from the same counters that are not defects.
- You run out of rock in a small sandbox. Saturation rises monotonically with world size — 2.71% /
14.37% / 46.53% / 55.48% / 56.51% of 43,200 at extents 8/16/32/64/128 units — because a small world gets
excavated into open space where the crosshair finds nothing, which is exactly what
gate_refusals_nohit= 210,151 of 211,320 due frames says at extent 8. The registered "one-hour session" is therefore a bound, not an attainment, and it is on the row asbytes_at_43200_edits= 734,400. Every C1 statement above is made against that bound and not against the measured hour. - 12.5 strokes/s is not what
game_digdelivers.EDIT_PERIOD = 0.08with no catch-up quantises at 60 Hz to five frames = 1/12 s, so an hour offers 43,200 attempts and notstrokes_nominal_12_5= 45,000 — a 4.0% correction to the registration's own throttle figure, on the row so it cannot be lost.
What changed as a result.
- Do not write a bespoke edit-log codec. C3's own falsifier says so and
bytes_zstd_of_deltassays it twice. Ship the transform: second-difference the quantised record, thenzstd. - Do not trim a stroke by dropping brushes. 200 of 200 necessary bit-exactly, and the lens arithmetic
says no grid resolution rescues it.
prune_into's per-chunk Lipschitz pruning (P-39,✗41) is a different and still-good idea; log trimming along a stroke is not. - If a stroke compressor is ever wanted, merge capsule runs with a tolerance — 200 → 40 at 0.005
cells, 200 → 10 at 0.083 cells, on a stroke that already bows 8.33 cells. That is a 5–20× cut in the
log's term count, which matters more than bytes because every field sample walks the log (
M-50's 0.158 → 0.589 ms per-edit curve). A source change beyond this ticket's scope: measured, surfaced, stopped, and filed separately. - Nothing needs doing about save-file size. 0.415 MB measured, 0.734 MB saturated, against a 2 MB bar and an estimate 6.54× high on the bound.
- The 08-11 doc's 48 B/op is corrected to 17 B serialised / 32 B in memory — and the 32 deserves its
own line, because it is a live cost rather than a documentation fix:
bytes_per_edit_in_memory= 32 issize_of::<Brush<Sphere<f32>>>(), andSmoothAdd { k: f64 }forces 8-byte alignment onBrushOp, taking the op tag to 16 B for every brush, smooth or not. A carve-only log pays 15 bytes per edit for a variant it never uses, which is 88% of the serialised record's whole width.
Scope, restated because BACKLOG.md closes networked editing out and this row does not reopen it. This
measures the edit log — the crate's own data structure, what a save file is, and what undo rewinds. No
sockets, no clock, no session model, and none was added. Teardown's ~1 Mbit and the 08-11 doc's 4.80 MB are
quoted as comparisons; neither is an input to any column.
Deviations, declared. The eye is flown rather than walked (game_dig itself flies during a scripted
capture, and the log depends on the eye and the view direction). The aim is traced once per throttle period
rather than once per rendered frame, because only the aim at a stroke instant can enter the log — a
distance-gate refusal then waits a period instead of a frame, which can only lower the edit count, the
conservative direction for a size bound. The brush wheel is [0.25, 0.60] rather than game_dig's
[0.10, 2.00], because R_MAX sets the nearest-brush accelerator's ring bound and a 2.0 brush is a
chamber scoop; it cannot affect bytes_per_edit, which is the record's width. Sandbox walls are a
turn-the-hand-around clamp rather than game_dig's five slab brushes, because those slabs are never in the
log. The session is carve-only, so distinct_radii = 3, there is one op, and the op byte carries ~0 bits —
declared, not exploited. f64 throughout where game_dig is f32; both are four bytes at the 1/4096
quantum, so no size column moves. zstd is a dev-dependency: cargo tree -p isomesh -e normal stays
isomesh + libm.
Would be shown wrong by: a bytes_per_edit that is not 17 — which now means a change to Brush<S>'s
layout or to the record, not a change to the world, and would be a source finding rather than a measurement
one; a saturating session policy that logs meaningfully more than 43,200 edits an hour, which would put the
uncompressed hour over the 2 MB bar and falsify C1's size half on its own bound; any sound drop-based
compressor reaching 40 survivors on a coaxial run, which would mean the tiling argument or
coaxial_hash_verified is wrong; a session whose strokes are long enough and straight enough that the
second-order predictor beats the first, which would restore C3's stated mechanism without restoring its 2×;
or zstd on the second-order residuals falling far behind the range coder on some other trace, which
would mean the coder is worth writing after all and the recommendation in point 1 is premature.
💥 ✗75 / M-407 — C1 and C2 FALSIFIED, C3 HELD: undo is always a re-fold — re-folding from a checkpoint is cheaper at every separation, by 16.3×/15.9×/19.0× at d = 0 and still 1.30×/1.29×/1.55× at d = 127, and the fitted crossover lies 40.95 / 38.50 / 73.86 edits past the bottom of the log; M-50's curve predicts a cadence of 193.8 against a fit-free measured 32, and the disagreement is a shape difference, not a scale factor (P-95, R-095)
M. cargo bench --bench experiment_p95, docs/experiments/p-95.csv, 18 rows (three fields ×
six cadences 4/8/16/32/64/128), f64, Zen 3 (amd-ryzen-9-5900x-12-core, cpu_mhz 4196.969 on every
row). Fixture: a 48³-cell world in 16-cell chunks at cell_size 0.125 — game_dig's geometry, so a
per-chunk millisecond here means what M-50's four buckets mean — carrying a 1,000-edit log of overlapping
spheres cycling Subtract, Subtract, Add, SmoothAdd (log_subtract 500, log_add 250,
log_smooth_add 250) over sphere_r1_2, gyroid and fbm_terrain, three reps, medians. Committed at
664c88e, no (WORKING TREE DIRTY) in the provenance line, and merge-base --is-ancestor 664c88e
HEAD passes. Four # comment lines plus the column header sit above the 18 data rows; the 15 registered
columns are present in registered order followed by 68 extras.
Provenance defect first, because it changes what C2 could be scored against:
M-50has no committed CSV. Its four bucket medians — 0.158 / 0.354 / 0.525 / 0.589 ms per re-meshed chunk for logs of 1–15 / 16–30 / 31–45 / 46–60 — exist only as prose atFINDINGS.md:1098and ingame_dig's docstring table atbevy_isomesh/examples/game_dig.rs:77-79. The two agree exactly, and both trace to E-202: a liveISOMESH_AUTOCARVE=60run under a mouse, printing to stdout, in anf32layout. This is theF-009class of failure — a number that gates later work and lives in a paragraph rather than in an artefact — so the instruction to read C2's denominator out of a committed file could not be honoured, and treating the four medians as this machine's baseline would violateM-281outright (a millisecond is a property of the binary). What the harness did instead: it measures the baseline inside the run. The same four log-length buckets are re-measured here at the same chunk size and cell size,predicted_k_from_m50andmeasured_kare computed by the same formula from the same 16 ms budget and the same measured worst-case dirty-chunk count, andmeasured_k_from_traceanswers the question with no fitting in it at all. Every verdict below rests on an integer, a within-row ratio or a sign.Re-run 2026-08-28 on a clean tree; every number below is
664c88e's. The original run's clocks were taken with ~25 sibling agents compiling, and the report itself recordedworst_undo_msat (sphere_r1_2,k = 32) reading 16.18 / 12.69 / 11.22 / 12.36 ms across four runs of one binary. Moved: thed = 127ratio floor 1.08× → 1.290×; the crossover margins +30.31 / +28.92 / +60.27 → +40.95 / +38.50 / +73.86;measured_k32 / 32 / 16 → 52.4 / 38.6 / 19.0 andk_ratio6.1–12.1× → 3.70 / 5.02 / 10.21×;bucket_ratio_spreadonsphere_r1_23.00 → 2.1083;fit_intercept_mslow end −0.31 → −0.016525 ms; the worst-undo envelope quoted as 4.36 → 49.85 ms → 3.266 → 33.162 ms onsphere_r1_2(33.16 / 39.73 / 35.42 ms atk = 128across the three fields), a top-of-envelope move of about 1.50× on the identical binary. Every integer reproduced exactly:undos_crossing_checkpoint51/26/16/10/6/5,crossings_regular_only47/22/12/6/2/1,checkpoints_built250/125/62/31/15/7,peak_checkpoint_bytes225.30 → 7.18 MiB, all fourcp_vs_logcounts, and the whole normals table. That split — integers fixed, absolute milliseconds ±20%, every ratio taken within one row — is what the verdicts are built on.
| clause | registered | measured |
|---|---|---|
C1a undo beats a re-fold whenever fewer than N edits separate them |
some N > 0 exists |
FALSIFIED — crossover_n = 0 on all 18 rows; undo never wins at any swept d. crossover_direction = none_undo_never_wins |
C1b and N is STABLE ACROSS FIELDS |
same N on all three fields |
VACUOUS — there is no N to be stable. crossover_stable_across_fields = none_on_all_fields |
C2 M-50's curve gives the cadence: k falls out of the four bucket medians, worst undo < 16 ms |
agreement within 2×, and the endorsed cadence's trace under 16 ms | FALSIFIED on the first half — k_ratio 3.7003 / 5.0232 / 10.2079, all > 2. The second half PASSED: 9.799 / 11.671 / 6.678 ms |
| C3 undo is BIT-EXACT over a 10³-edit interleaved-undo trace | one mismatch falsifies | HELD — hash_mismatches 0 over 3,654 undo/redo round trips (203 per row × 18), checkpoint_rebuild_mismatches 0 over 51/26/16/10/6/5 rebuilds |
Two
falsecolumns that a reader must not misparse.crossover_n = 0is the sentinel for "no crossover anywhere in the sweep", not a crossover at separation zero — the harness reports the smallestdwithundo < refold(d)and0for none, and every row is the latter. Andc2_holds = falseis a conjunction of which one part passed:k_ratio <= 2.0 && budget_worst_ms < 16.0. The budget half held on all three fields (c2_budget_worst_undo_ms9.798835 / 11.671141 / 6.678113 ms atc2_budget_cadence32 / 32 / 16). C2 fails on the derivation, not on the frame.
The mechanism was proved before the run, and it is a monotonicity argument rather than a constant.
refold(d) costs one trilinear lattice lookup plus d brush samples per grid sample, so it is monotone
non-decreasing in the separation d. Undoing the last edit through the log walks the base field plus
n − 1 brushes and does not depend on d at all. So { d : undo < refold(d) } is an up-set: if
the inequality ever holds it holds for every larger d. C1's registered wording — "whenever fewer than
N edits separate them" — describes a down-set, and no down-set can exist for any instrument in
which re-folding gets dearer the further back the checkpoint sits. That is stated in the bench's own
header before the harness ran (✗51's rule applied to a direction rather than a magnitude), and the
sweep was run anyway on P-70's precedent: say it first, then produce the number.
The number, at every swept separation, as a within-row ratio (undo_ms / refold_ms_at_dN):
| field | undo_ms |
d=0 |
1 | 2 | 4 | 8 | 16 | 32 | 64 | 127 |
|---|---|---|---|---|---|---|---|---|---|---|
sphere_r1_2 |
37.795 | 16.29× | 15.72 | 15.02 | 12.13 | 9.42 | 6.62 | 4.15 | 2.37 | 1.303× |
gyroid |
41.990 | 15.88× | 15.31 | 14.71 | 11.88 | 9.25 | 6.52 | 4.08 | 2.33 | 1.290× |
fbm_terrain |
29.863 | 19.03× | 18.39 | 17.65 | 14.23 | 11.09 | 7.82 | 4.90 | 2.79 | 1.547× |
And the crossover is answered from the whole sweep rather than its last two points, because the
registered N sits at the boundary of any search that can be run. The offset
(base − lookup)/brush is a constant independent of log length, so a crossover — if one existed — would
always sit a fixed number of edits from the bottom of the log. Two runs of an earlier harness put
sphere_r1_2's at d = 125 of 127 and at none at all: P-72's defect, a boundary hit reported as a
location. So all 128 sweep points are fitted as refold(d) = A + B·d:
| field | refold_fit_intercept_ms A |
refold_fit_slope_ms_per_edit B |
crossover_n_fitted (undo − A)/B |
crossover_margin_edits_past_log |
|---|---|---|---|---|
sphere_r1_2 |
2.191761 | 0.211983 | 167.95 | +40.95 |
gyroid |
2.504465 | 0.238575 | 165.50 | +38.50 |
fbm_terrain |
1.485383 | 0.141279 | 200.86 | +73.86 |
A checkpoint cannot sit below the base field, so d ≤ n − 1 = 127 always. A positive margin therefore
says no crossover can exist at any log length — the fit says undo would need the checkpoint to be
40.95 / 38.50 / 73.86 edits deeper than the deepest place a checkpoint can be. The registered
consequence lands verbatim: "undo is always a re-fold and the checkpoint cadence is the only knob."
SHARE, recomputed — and one clause arithmetic could not reach before the run. C2 is denominated in a
frame, 16 ms, which is the budget undo has to fit in. Least squares through M-50's four medians at their
bucket midpoints (8, 23, 38, 53 edits → 0.158, 0.354, 0.525, 0.589 ms) gives
cost(L) = 0.10882 + 0.0097600·L ms per re-meshed chunk (m50_fit_intercept_ms,
m50_fit_slope_ms_per_edit on every row). With m dirty chunks, k ≤ (16/m − 0.10882)/0.0097600:
1628 at m = 1, 399 at m = 4, 194 at m = 8, 50 at m = 27. The fixed per-chunk term alone only eats the
frame at m ≥ 147 chunks, 5.4× more than this world contains — so C2's clause is an upper bound with
room, reachable, and worth scoring. worst_dirty_chunks_curve = 8 is the measured count, giving
predicted_k_from_m50 = 193.8. C1, by contrast, was arithmetically unreachable before any measurement
— the monotonicity argument above — and the pre-run statement of that is the reason the sweep reports a
fitted margin instead of a "no crossover found" shrug.
C2's verdict criterion was declared before the run (agreement within 2×; 2× rather than tighter
because M-50 is an f32 layout under a mouse on a different base field and this is f64), and the
verdict does not rest on the scale factor, which machine load contaminates. It rests on the shape, all of
it within-run.
| field | predicted_k_from_m50 |
measured_k |
k_ratio |
measured_k_from_trace |
k_ratio_m50_over_trace |
|---|---|---|---|---|---|
sphere_r1_2 |
193.8 | 52.4 | 3.7003× | 32 | 6.0553× |
gyroid |
193.8 | 38.6 | 5.0232× | 32 | 6.0553× |
fbm_terrain |
193.8 | 19.0 | 10.2079× | 32 | 6.0553× |
measured_k_from_trace is the fit-free answer: the coarsest swept cadence whose trace actually kept the
worst single undo inside the frame. It is 32 on all three fields (worst_undo_ms 9.80 / 11.67 / 10.75
at k = 32, against 17.71 / 21.19 / 19.48 at k = 64). M-50's curve says 193.8. A cadence read off
M-50 is 6.06× too generous, on the one machine, in one build, with no fit in the denominator.
Three shape mismatches, each independent of the clock's absolute level:
- The four bucket ratios to M-50 are not constant. A pure scale factor — same function, different constant — would show one ratio repeated four times. It does not:
| field | b1 ms/chunk | ratio | b2 | ratio | b3 | ratio | b4 | ratio | bucket_ratio_spread |
|---|---|---|---|---|---|---|---|---|---|
sphere_r1_2 |
0.257339 | 1.6287 | 0.935731 | 2.6433 | 1.416272 | 2.6977 | 2.022578 | 3.4339 | 2.1083 |
gyroid |
0.600637 | 3.8015 | 1.254039 | 3.5425 | 1.904093 | 3.6268 | 2.727439 | 4.6306 | 1.3072 |
fbm_terrain |
1.474141 | 9.3300 | 2.179956 | 6.1581 | 2.922338 | 5.5664 | 3.732226 | 6.3365 | 1.6761 |
Every median rests on 15 samples (bucket_sample_counts = 15+15+15+15), and the spread is a ratio of
two ratios taken inside one row.
2. fit_intercept_ms varies with the base field where M-50's curve has one constant — −0.016525 /
+0.192025 / +1.048783 ms against M-50's single 0.108820. The intercept is the cost of re-meshing
a chunk with an empty log, i.e. the base field's own sample cost: Sphere is three multiplies,
FbmTerrain is octaves of noise. M-50 measured one base field and its intercept is that field's.
3. fit_slope_ms_per_edit varies per field — 0.03850837 / 0.04686973 / 0.05011090 against M-50's
0.00976000 — and it must, because the marginal cost of one more edit in the log is
(corner samples + 6 × vertices) brush evaluations: eight corners per cell plus the central-difference
stencil at every emitted vertex, and the vertex count is a property of the surface, not of the log.
So evaluation cost is a function of log length and base-field cost and surface complexity, and
M-50's four medians carry only the first. Per the registration this is "a finding about the fold rather
than about undo": fold_cost(L) is not one curve, and a cadence derived from a single field's curve is
far too generous — 193.8 where 32 is what the frame permits.
C3, and the one place a hash can actually move. Through the log alone, undo-then-redo returning the
same hash is an identity — the field at length L is a pure function of log[..L] — so no trace could
refute it, and a HELD on that would be M-44's vacuous zero. So the trace's state is always represented
the way an editor with checkpoints represents it, checkpoint(c) ⊕ log[c..L] for the deepest valid
checkpoint, and an undo below c drops that checkpoint while the redo rebuilds it from the one
beneath. Both halves are asserted: hash_mismatches = 0 (203 hashed round trips per row, 3,654 over the
file, of which 3 per row hash every chunk in the world rather than the edit's own region) and
checkpoint_rebuild_mismatches = 0, comparing the rebuilt snapshot against the dropped one scalar for
scalar over 51 / 26 / 16 / 10 / 6 / 5 rebuilds per cadence.
And the C3 instrument is shown to have teeth by the column beside it. cp_vs_log_hash_mismatches
runs the same hash over the same chunks with the checkpoint path against a full fold from the base
field, and it equals cp_vs_log_checks on every one of the 18 rows — 9, 9, 9, 6, 4, 4 checks and 9,
9, 9, 6, 4, 4 mismatches, 100% disagreement. The zero in hash_mismatches is therefore a zero that
demonstrably could have been non-zero: the very same hash function over the very same chunk set, given a
checkpoint that is one step less faithful, moves every single time.
The finding nobody asked for: a dense-grid checkpoint is bit-exact in the positions and badly lossy in
the normals. cp_vs_log_position_mismatches = 0 on all 18 rows, over the same comparisons that produce
100% hash disagreement — so the whole of that disagreement is normals:
| field | k |
normals compared | mismatched | fraction | p50 dev | p99 dev | max dev |
|---|---|---|---|---|---|---|---|
sphere_r1_2 |
4 | 60,119 | 56,446 | 93.89% | 6.438° | 107.001° | 179.131° |
| 8 | 60,119 | 53,292 | 88.64% | 5.363° | 104.467° | 179.131° | |
| 16 | 39,611 | 32,616 | 82.34% | 5.036° | 105.794° | 179.131° | |
| 32 | 31,691 | 22,578 | 71.24% | 2.838° | 101.696° | 179.034° | |
| 64 | 18,746 | 8,218 | 43.84% | 0.000001° | 88.887° | 179.034° | |
| 128 | 15,719 | 2,441 | 15.53% | 0.000000° | 43.636° | 176.886° | |
gyroid |
4 | 90,302 | 87,459 | 96.85% | 3.281° | 96.425° | 175.838° |
| 8 | 90,302 | 84,502 | 93.58% | 2.701° | 95.293° | 175.838° | |
| 16 | 45,079 | 39,369 | 87.33% | 3.177° | 91.169° | 175.838° | |
| 32 | 41,181 | 31,738 | 77.07% | 1.402° | 89.239° | 174.590° | |
| 64 | 21,993 | 11,862 | 53.94% | 0.075° | 64.723° | 169.462° | |
| 128 | 22,145 | 7,327 | 33.09% | 0.000000° | 36.260° | 154.125° | |
fbm_terrain |
4 | 70,343 | 66,860 | 95.05% | 6.344° | 105.794° | 175.711° |
| 8 | 70,343 | 63,890 | 90.83% | 5.564° | 105.341° | 175.711° | |
| 16 | 45,553 | 37,805 | 82.99% | 5.127° | 105.349° | 177.211° | |
| 32 | 36,931 | 27,002 | 73.11% | 3.566° | 98.642° | 174.295° | |
| 64 | 23,631 | 11,225 | 47.50% | 0.000001° | 80.201° | 175.890° | |
| 128 | 17,141 | 4,425 | 25.82% | 0.000000° | 51.708° | 169.161° |
Mechanism. A checkpoint is exact at a lattice point: it stores the f64 the fold produced there,
brush::apply is a pure function of that value and the brush's own sample, CELL_SIZE is a power of two
and ORIGIN a multiple of it, so (p − origin)/h is exact on the lattice and the interpolation weights
are exactly 0 or 1 there (M-32's spacing rule). Positions are computed from lattice corner values, so
they are bit-exact — 0 mismatches, and that is the column proving it. But marching cubes takes its
normal from Sdf::gradient, a central difference at p ± DIFF_STEP·max(|p|,1), and that lands off the
lattice — where a trilinear snapshot is a different field from the one it was baked from. A trilinear
interpolant is C⁰ and its gradient is piecewise constant per cell with a jump at every cell wall, so a
probe that straddles a wall reads a gradient the true fold never had; 179° means the two normals point
opposite ways.
And the direction is the useful part: fidelity improves as the cadence coarsens — 93.89% → 15.53% on
sphere_r1_2, 96.85% → 33.09% on gyroid, 95.05% → 25.82% on fbm_terrain, with p50 falling to exactly
0.000000° at k = 128 — because a coarser cadence means more brushes are re-evaluated analytically above
the snapshot and fewer samples come from interpolation. That runs opposite to speed (worst_undo_ms
3.266 → 33.162 ms on sphere_r1_2, 3.754 → 39.732 on gyroid, 3.461 → 35.416 on fbm_terrain)
and opposite to memory (peak_checkpoint_bytes 236,239,192 → 7,529,536 B, 225.30 → 7.18 MiB, and
250 → 7 checkpoints_built). So the checkpoint cadence is a three-way trade — latency, memory,
normal fidelity — and it was registered as a two-way one. Nothing in the repo had this. Practical
consequence: a checkpoint is a valid cache for positions and not for shading, so a re-fold that lands
on screen must recompute normals against the analytic fold, or the cadence knob silently sets lighting
quality.
Registered vacuity control, and how close it came to being a decoration. Registered: the
interleaved-undo trace must include undos that cross a checkpoint boundary, reported as a count, or C3
tests only the cheap path. undos_crossing_checkpoint = 51 / 26 / 16 / 10 / 6 / 5 across the six
cadences, asserted non-zero on every row, and each crossing forces a snapshot drop and a rebuild — that
is exactly the population checkpoint_rebuilds counts, so C3's 0 mismatches were earned on the expensive
path 203 times per row. Why that value proves the fixture could have failed: the regular burst
schedule is cadence-independent by design (a burst every 25 edits, depths cycling
1,2,3,5,8,9,4,6,7), so whether a regular burst ever reaches a checkpoint is an accident of arithmetic —
a crossing needs a multiple of k inside [l−u+1, l]. crossings_regular_only is that count and it
falls 47 → 22 → 12 → 6 → 2 → 1: at k = 128 exactly one such coincidence exists in a thousand
edits (the burst at l = 900, depth 7, over the checkpoint at 896). That is P-62's "a hair from
M-44's vacuous zero". The total is non-zero by construction rather than by luck because four
boundary bursts are placed at c + 1 for four checkpoints spread through the trace, each three deep, so
the second undo of each pops the ladder at every cadence — and the difference
undos_crossing_checkpoint − crossings_regular_only is exactly 4 on all six cadences, which is those
four bursts and nothing else. Second M-44 control:
hash_sets_without_geometry = 0 on every row, so no round trip was validated over a set of empty meshes
whose hash is a constant.
Five fixture defects, all found by this harness's own controls rather than by review.
- The first run panicked on the
M-44assertion: 8 of the first 128 edits dirtied no chunk at all. The mechanism ismin— anAddbrush sitting in bulk solid computesmin(field, shape)wherefieldis already the more negative, so it changes nothing. Not a slow edit, a no edit. And the undo of a no-op edit is worse than useless for C3: its hashed region is a set of empty meshes, whose hash is a constant, so the check could not have failed. That isM-44wearing C3's clothing, and it would have passed silently as a HELD with no instrument. Fix: a candidate brush is accepted only if it flips the sign of at least one lattice sample inside its own bounding box, tested against a running exact snapshot of the fold; exhausting 256 candidate positions panics rather than shrugs. The log is therefore per field (P-72's per-field probe is the precedent), with radii and operations from separate generators so only the centres move. - The acceptance test's running snapshot has to be folded over the whole lattice, not the brush's
bounding box. A
Subtractchanges the value wherever−shapeexceeds the field, which reaches beyond the sphere even where the sign cannot move; a bbox-only fold drifts from the true snapshot and the sign-flip test then lies about later edits — silently reintroducing defect 1. crossover_nis not reproducible, and it was reporting a boundary hit as a location. Two runs putsphere_r1_2's crossover atd = 125of 127 and at none at all —P-72's defect exactly. Fix: the answer comes from a least-squares fit over all 128 sweep measurements ascrossover_n_fittedpluscrossover_margin_edits_past_log, both ratios of measured times, which is whatM-280asks for on a governed clock.crossover_nis retained only as the registered column, with0meaning none.- The first draft of the vacuity comment asserted in prose that
crossings_regular_onlywas zero atk = 128, and the run refuted it — it is 1. The claim was wrong and the fix does not depend on it either way: the four constructed boundary bursts make the control non-zero at every cadence regardless, andcrossings_regular_onlyis now reported beside the total so a reader can see how thin the accidental margin is. - A bucket median could have rested on a single reading. Each of M-50's four log-length buckets is
asserted to carry ≥ 10 samples — "under ten is a single reading wearing a median's name" — which is
why the cost curve is measured over
HEAD = 128edits (≥ 60 so all four buckets are covered).bucket_sample_counts = 15+15+15+15on every row. The same rule madequantilereturn a readable 0.0 only alongsidecp_vs_log_checks, so an empty normals sample cannot masquerade as perfect agreement.
What changed as a result. (a) Undo is not a distinct operation to be optimised: it is a re-fold at
d = k − 1, and the only knob is the cadence. Any design that budgets "cheap undo of the last edit"
separately from re-meshing is budgeting a path that does not exist — at d = 0 the log path is still
15.9–19.0× dearer. (b) M-50 must not be used as a cadence oracle, and the reason is its shape, not its
age: intercept is the base field's sample cost and slope carries the surface's vertex count, neither of
which transfers. The empirical cadence on this world is 32, six times finer than M-50 predicts.
(c) M-50 should be re-run into a committed CSV; it currently gates arithmetic in three registrations
(P-95, P-97, P-98) and lives in prose — F-009 again. (d) A checkpoint is a position cache, not a field
snapshot: normals must be recomputed analytically after a checkpointed re-fold. (e) The cadence's memory
axis is not free either — 225.30 MiB of snapshots to buy a 3.27 ms worst undo on a 48³ world is 30× the
cost of the 7.18 MiB that buys 33.16 ms.
Would be shown wrong by: a base field whose sample cost is below a trilinear lattice lookup, which
would make the offset (base − lookup)/brush negative and could put a genuine crossover inside the log —
all three fields here cost more than an array index; a chunk count large enough that
worst_dirty_chunks_curve moves off 8, since both k derivations divide the frame by it; a normal
computed from the lattice corner values rather than from Sdf::gradient, which would move
cp_vs_log_normal_mismatches toward zero and dissolve the third axis of the trade; or one
hash_mismatches on a longer trace, which would mean the ladder is not a function of the log.
💥 ✗76 / M-408 — C1 VACUOUS on M-38's own fixture, then HELD to 0.0375 and FALSIFIED from 0.075 on a fixture that can move; C2 HELD, C3 HELD in a bounded window: M-38's 40,317 distinct results are meshes 2.2e-16 world units apart in a branch where no smoothing happens, so M-38 is retired rather than confirmed and smooth union is gameplay-commutative below half a cell of blend radius (P-96, R-096)
M. cargo bench --bench experiment_p96, docs/experiments/p-96.csv, 16 rows, f64, Zen 3
(amd-ryzen-9-5900x-12-core), 12 threads, CPU only. All 8! = 40,320 orderings of M-38's eight
SmoothAdd brushes folded onto a base box, each ordering meshed by Marching Cubes on a 32³ grid, over
eight blend radii k ∈ {0, 1e-6, 1e-3, 0.01, 0.0375, 0.075, 0.15, 0.3} on two fixtures: m38, which
is M-38's verbatim (BoxExact::canonical() plus brush::tests::eight, cell 0.078125), and
m38_exposed, which keeps all eight brushes, all eight ops and the permutation machinery and shrinks the
base half-extent from 1.0 to 0.35 so brush-brush seams reach the surface (cell 0.0625). Committed at
a02b6b5, header clean — no (WORKING TREE DIRTY). No timing column is reported, so M-280's clock
obligation does not arise; every column is an integer, an exact-arithmetic quantity or a deterministic
reduction over a fixed fold.
| clause | registered | measured |
|---|---|---|
| C1 max symmetric Hausdorff over all 40,320 orderings < 0.1 cells | < 0.1 | VACUOUS on m38 at every k — 0.000000000, with active_samples 0. HELD on m38_exposed for k ≤ 0.0375 (bound 0.078547743), FALSIFIED for k ≥ 0.075 (0.311239209, and 0.656099534 at M-38's own k = 0.15) |
C2 the spread scales with k and vanishes as k → 0, recovering M-36 |
falls with k, 1 result at k = 0 |
HELD on m38_exposed — log-log slope 2.519871 on the mesh spread, 1.287781 on the field spread, monotone in k, and distinct_results = 1 with coincident_orderings = 40319 at k = 0 exactly. VACUOUS on m38 (fewer than three arms above the fit floor) |
| C3 the spread is confined to within 10k of a seam | points_outside_shell = 0 |
HELD on m38_exposed at k = 1e-3, 0.01, 0.0375 — points_outside_shell = 0 with a live outside-shell population and live inside-shell spread. VACUOUS elsewhere, on both sides and for different reasons |
The registered vacuity control passes with flying colours on a fixture that cannot move, and that is the
finding. orderings = 40320 on all sixteen rows, the 40,320 permutations are asserted pairwise distinct,
and on m38 at k = 0.15 the harness reproduces M-38 exactly: distinct_results = 40317,
coincident_orderings = 3, coincident_groups = 3, largest_coincident_group = 2 — three colliding
pairs. A mis-nested or mis-sampled fold does not land on 40,317-with-3. The corroborating controls are all
live too: stack_agreement = 64 on every row (the precomputed nine-operand fold asserted bit-for-bit
equal to BrushStack::sample at all 64 probes), grid_index_roundtrip = 35937 = grid_samples,
boundary_min_world > 0 on every row so no Hausdorff distance is measuring a clipped mesh edge.
And none of it can see whether the smooth branch was reached — it was not. Every brush in
brush::tests::eight lies strictly inside BoxExact::canonical(), so the base is the smallest of the
nine operands everywhere and the runner-up is far away. min_margin_world, the smallest gap anywhere on
the grid between the two smallest operands, is 0.180976 (min_margin_cells 2.316493) against
k = 0.15; smooth_min clamps h = clamp(0.5 + 0.5(b−a)/k, 0, 1) to 0 or 1 whenever |b − a| ≥ k, so
at M-38's own k not one fold step on the whole grid enters the smooth branch: blended_samples
and active_samples are both 0. The 40,317 distinct results are the cancellation residue of
evaluating (b + (a − b)·1) − k·1·0 instead of returning a — algebraically the hard min, numerically a
few ULP:
m38 arm |
blended_samples |
active_samples |
max_spread_world |
max_hausdorff_to_ref_world |
max_hausdorff_cells |
|---|---|---|---|---|---|
k = 0 |
0 | 0 | 0.000000e0 | 0.000000e0 | 0.000000000 |
k = 1e-6 |
0 | 0 | 1.554312e-15 | 2.220446e-16 | 0.000000000 |
k = 1e-3 |
0 | 0 | 1.554312e-15 | 2.220446e-16 | 0.000000000 |
k = 0.01 |
0 | 0 | 1.554312e-15 | 2.220446e-16 | 0.000000000 |
k = 0.0375 |
0 | 0 | 1.554312e-15 | 2.220446e-16 | 0.000000000 |
k = 0.075 |
0 | 0 | 1.554312e-15 | 2.220446e-16 | 0.000000000 |
k = 0.15 |
0 | 0 | 1.554312e-15 | 2.220446e-16 | 0.000000000 |
k = 0.3 |
777 | 0 | 1.554312e-15 | 2.220446e-16 | 0.000000000 |
max_spread_world is identical from k = 1e-6 to k = 0.3 — five and a half decades — because it is
not a function of k at all. No geometric quantity does that. max_hausdorff_to_ref_world is
2.220446e-16 world units, one ULP of a vertex coordinate, which is 2.84e-15 cells: thirteen orders
under the 0.1-cell bar. topology_changes and sign_flips are 0 on every m38 row. So m38's C1 answer
is a zero that could not have been anything else, and it is scored VACUOUS, not HELD — M-44's rule
("a measurement that comes back zero has to prove it could have come back non-zero") applied to the
clause rather than only to the registered control, which is the point the registered control missed.
The SHARE recomputation, said out loud, including the clause that arithmetic could not reach. The
registration says "SHARE: this measures a distance, not a ratio", so there is no share of a total to
name; what has to be checked instead is that the 0.1-cell bar is reachable from both sides.
smooth_min's penalty term is k·h·(1−h), maximal k/4 at h = 1/2, so
min(a,b) − k/4 ≤ smin ≤ min(a,b). The fixture folds n = 9 operands — base box plus eight brushes — in
n − 1 = 8 applications, so every ordering's field lies within (n−1)k/4 = 2k of the
ordering-invariant hard min and two orderings differ by at most 4k. On a near-unit-gradient SDF a
field perturbation δ moves the isosurface by about δ, so the worst-case surface spread is 4k/cell:
k |
worst case, m38 cells (0.078125) |
vs the 0.1-cell bar |
|---|---|---|
| 0.3 | 15.36 | 154× |
| 0.15 | 7.68 | 77× |
| 0.075 | 3.84 | 38× |
| 0.0375 | 1.92 | 19× |
| 0.01 | 0.512 | 5.1× |
| 1e-3 | 0.0512 | 0.51× — bar guaranteed by arithmetic |
So C1 was reachable in both directions at every k ≥ 0.01 and arithmetically unreachable — guaranteed
HELD — for k ≲ 0.002, which is exactly what the 1e-3 and 1e-6 arms are: they confirm the bound
rather than test the clause, and they are labelled that way rather than counted as three-quarters of a
sweep. C2 and C3 name no ratio. Both directions of C1 then actually happened, on different arms.
The pairwise reduction, stated rather than substituted. C1 names max_{i,j} d_H(M_i, M_j) over 40,320
meshes — 812,838,080 pairs. Symmetric Hausdorff is a metric on compact sets, so for any reference R,
max_{i,j} d_H(M_i,M_j) ≤ max_i d_H(M_i,R) + max_j d_H(M_j,R), and since i ≠ j may be assumed the two
largest distances-to-reference bound the diameter. That sum, top1 + top2, is
max_hausdorff_bound_cells, computed from all 40,320 orderings against the identity ordering.
max_hausdorff_cells is a different quantity: the exact all-pairs maximum over a sampled subset of at
most 128 orderings (subset_orderings 127 or 128 per arm, exact_pairs_sampled 8001 or 8128), built from
the 64 largest distances-to-reference plus 64 evenly strided and deduplicated — a lower bound biased
towards the extremes. The scoring uses each for what it can prove: HELD arms are scored on the bound,
because a bound under the bar proves the registered all-pairs quantity is under the bar, and FALSIFIED
arms are scored on the exact column, which is a real measured pair of orderings. Both columns are in the
file, exact_pair_max_cells ≤ bound_cells is asserted on every row so the reduction is checked rather
than assumed, and the nearest-neighbour queries underneath are exact — the bucket search widens until
best ≤ r·cell, which proves no unscanned bucket can hold anything closer, and panics rather than return
an unproven answer. Substituting one of these for the other silently is P-70's C3 and is not done here.
m38_exposed, where the clauses have instruments. Shrinking the base to 0.35 makes the brush union
protrude so brush-brush seams reach the surface; the base is not one of the permuted objects — the fold
seeds with it and permutes the eight brushes — so this is the smallest edit that reaches the blend while
leaving the permuted fixture untouched. It is a deviation from the registration, labelled as one in the
fixture and base_half_extent columns. Without it all three clauses would have been vacuous on all
sixteen rows.
k |
distinct | coincident | active |
blended |
exact max_hausdorff_cells |
bound cells | max_spread_cells |
sign_flips |
topology_changes |
C1 |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 40319 | 0 | 0 | 0.000000000 | 0.000000000 | 0.000000 | 0 | 0 | vacuous |
| 1e-6 | 31798 | 8522 | 0 | 2 | 0.000000000 | 0.000000000 | 0.000000 | 0 | 0 | vacuous |
| 1e-3 | 31798 | 8522 | 4 | 187 | 0.000000000 | 0.000000000 | 0.000335 | 0 | 0 | true |
| 0.01 | 32343 | 7977 | 116 | 1934 | 0.000162343 | 0.000324686 | 0.005355 | 0 | 0 | true |
| 0.0375 | 32109 | 8211 | 1868 | 7286 | 0.044393906 | 0.078547743 | 0.036043 | 0 | 0 | true |
| 0.075 | 37291 | 3029 | 7600 | 14511 | 0.311239209 | 0.597168345 | 0.094980 | 5 | 26,880 | false |
| 0.15 | 40232 | 88 | 23636 | 27123 | 0.656099534 | 1.263269441 | 0.202103 | 43 | 33,152 | false |
| 0.3 | 40319 | 1 | 35593 | 35620 | 0.931143672 | 1.438664553 | 0.467200 | 319 | 37,256 | false |
The crossing lies between k = 0.0375 and k = 0.075 — between 0.6 and 1.2 cells of blend radius at
cell_size_world = 0.0625. At 0.0375 the bound itself, 0.0785, is under the bar, so the registered
all-pairs maximum is proved under 0.1 cells. At 0.075 the falsification is a measured pair at
0.311239209 cells, 3.1× the bar — not a loose bound failing. At M-38's own k = 0.15 it is
0.656099534, 6.6× the bar (mean_hausdorff_cells 0.510335485, p99_hausdorff_cells 0.631634721).
The mechanism has two halves, and the second one is a topology knee the field spread does not have.
The deviation is compactly supported, which the log-semiring bound is not. Once |b − a| ≥ k the
operator returns its argument exactly and the blend is off, so deviation lives in a shell of width ~k
around each seam plus the accumulated ≤ 2k drift of the running fold. Measured against C3's own
columns, the confinement is ~0.09–0.14 of the 10k shell, i.e. about 1.0–1.4k, not 10k:
k |
max_deviation_from_seam_cells |
shell_10k_cells |
ratio | outside_shell_population |
points_outside_shell |
C3 |
|---|---|---|---|---|---|---|
| 1e-3 | 0.014498 | 0.160000 | 0.091 | 33,963 | 0 | true |
| 0.01 | 0.190335 | 1.600000 | 0.119 | 18,081 | 0 | true |
| 0.0375 | 0.790596 | 6.000000 | 0.132 | 295 | 0 | true |
| 0.075 | 1.668724 | 12.000000 | 0.139 | 0 | 0 | vacuous |
| 0.15 | 3.410582 | 24.000000 | 0.142 | 0 | 0 | vacuous |
| 0.3 | 6.359713 | 48.000000 | 0.133 | 0 | 0 | vacuous |
So k really is a length, and a shorter one than the memo's bound implies. C3's window is bounded on
both sides and each side is a different vacuity: below it inside_shell_with_spread = 0 — there is no
spread to confine (k = 0 and 1e-6) — and above it outside_shell_population = 0, the 10k shell has
swallowed the grid so points_outside_shell cannot be non-zero. The ratio is stable at 0.133–0.142
across the three vacuous arms, so the localisation is corroborated where the count cannot fail; it is
reported per row rather than averaged into a verdict. The memo's other quantity is emitted separately
and neither reading is substituted for the other: max_deviation_world = 1.450240e-2 / 3.241517e-2 /
6.860920e-2 / 1.518338e-1 at k = 0.0375 / 0.075 / 0.15 / 0.3, against deviation_bound_poly_world
(2k) = 0.075 / 0.15 / 0.30 / 0.60 and deviation_bound_kln9_world (k·ln 9) = 0.082396 / 0.164792 /
0.329584 / 0.659167 — 19% to 25% of the polynomial bound, so |smin_k − min| ≤ k·ln n holds with
about 4× margin. The 2026-08-23 memo measured 0.135 against 0.208 (65%) on eight spheres with no
dominating base; the lower ratio here is the base box holding the argmin.
The mesh Hausdorff has a knee the field spread does not, and it is topological. At k = 0.0375,
sign_flips = 0 and topology_changes = 0: max_hausdorff_to_ref_cells 0.039274 against
max_spread_cells 0.036043, ratio 1.09 — pure vertex sliding, surface motion equals field
perturbation over unit gradient. At k = 0.075, sign_flips = 5 and topology_changes = 26,880 of
40,320, and the Hausdorff jumps to 0.298584 against a field spread of 0.094980, ratio 3.1. Five grid
samples whose sign depends on the ordering create or destroy whole Marching Cubes vertices, and a
created vertex's nearest counterpart in the other mesh is a third of a cell away. So C1's failure
threshold is not where the field spread reaches 0.1 cells; it is where the field spread first reaches
|field| at a near-surface sample — a sharper criterion than the registration's, and measurable from
the field alone without meshing.
And the ordering spread is capped, not cumulative. Every ordering's field lies within 2k of the same
ordering-invariant hard min, so the spread is capped at 4k independently of fold order. That is why a
small k buys gameplay commutativity and why C2's field slope is 1.287781 rather than something
exponential in the brush count. C2's two slopes are sweep-level scalars, deliberately repeated on every
row of their fixture and documented as such — the opposite of M-377's per-field-column defect.
Three fixture defects, all caught by this harness's own controls rather than by review.
M-38's fixture never enters the smooth branch atM-38'sk.min_margin_world = 0.180976againstk = 0.15,blended_samples = 0,active_samples = 0,max_spread_worldconstant at 1.554312e-15 across five and a half decades ofk. The registered vacuity control — 40,320 orderings, 40,317 distinct, 3 coincident — passes perfectly on a fixture that cannot move.M-38isM-44's own cited precedent for the fixture trap ("third occurrence... M-32, M-38"), and this is the same fixture failing the same way about a different quantity.blended_samplesandactive_samplesare NOT the same control, and gating C1's vacuity on the wrong one printed a HELD with no instrument. Atm38,k = 0.3, the blend is finally reached —blended_samples = 777,max_deviation_world = 1.180559e-2— andactive_samplesis still 0: only ever one operand is withinkof the running minimum, so the blend itself is order-independent and the spread stays at 1.554312e-15. The first scoring pass gated C1's vacuity onblended_samplesand printedc1_holds = trueon that arm. C1 asks how far apart two orderings are, not whether the operator did anything, so its gate isactive_samples. Fixed before the committed run; both columns are in the file so the distinction can be re-checked rather than taken on trust.- The closure control is live rather than decorative.
boundary_min_worldonm38falls from 0.250000 atk ≤ 0.15to 0.238194 atk = 0.3— the fold pulling the surface outward by 0.011806, which is exactlymax_deviation_worldat that arm. Still positive, so nothing was clipped and no Hausdorff distance is measuring a grid wall, but the control moved when the physics said it should.
What changed as a result. In one sentence a protocol decision can be made from: smooth union is
commutative at gameplay tolerance — max symmetric Hausdorff under 0.1 cells across all 40,320 orderings —
for blend radii up to about half a cell, and is not commutative at 1.2 cells or above, where a measured
pair of orderings differs by 0.311 cells and two thirds of orderings disagree about the mesh topology. So
a networked editor may merge a run of smooth unions freely if it caps k at half a cell, and must
impose a total order above that. M-38's headline is retired rather than confirmed: on its own
fixture at its own k the 40,317 distinct results correspond to meshes 2.84e-15 cells apart, the number
counts f64 cancellation patterns in a branch where no smoothing occurs, and it is invariant under k
across five and a half decades, which no geometric quantity is. A count has no units, which is why M-38
could not have known. Do not build a fixed-point Real for this: M-39 priced fixed point as
repairing smooth-min's 1-ULP commutativity gap, and this run shows that gap is the entire measured
effect on M-38's fixture and is 2.2e-16 world units. The effect that crosses 0.1 cells is
non-associativity, which no storage format touches. BrushOp::commutes_with stays exactly as it is —
it answers a bit-exactness question and its answer is still correct. Nothing in crates/isomesh/src
changed and nothing should; this is a null on the source and a conclusion on the protocol.
Would be shown wrong by: a fixture whose brush-brush seams reach the surface and whose C1 falsifies
below k = 0.0375, which would move the half-cell protocol threshold; a field with gradient far from unity
at the seam, where the 4k field bound would no longer translate into 4k/cell of surface motion and the
2.5 log-log slope would not hold; a sign_flips > 0 arm whose Hausdorff/field-spread ratio stays near 1,
which would break the topology-knee mechanism and mean the 0.075 falsification has some other cause; or
any run in which the m38 arm's max_spread_world varies with k, which would mean the smooth branch
was reached there and this entry's retirement of M-38 is wrong.
💥 ✗77 / M-409 — C1 FALSIFIED on 2 of 8 fields by exactly 3 bytes each, C2 FALSIFIED with an empty divergence population, C3 HELD on all eight at 1.0055–1.0173× against 1.2: the f64 fold is bit-identical across x86-64 and AArch64 at every one of 100,000 prefixes on all eight fields, and the only divergence in 2,470,824 compared bytes is the sign bit of a NaN that unit_gradient emits in release from a plateau M-31's zero-edit fixtures cannot have (P-97, R-097)
M. cargo bench --bench experiment_p97, docs/experiments/p-97.csv, 8 rows (four # comment lines plus one column header above them; one row per reference field, edits = 100000 on every row), f64, Zen 3 (local_machine x86_64-linux, cpu_khz 4,190,370–4,200,232 per M-280) against the Apple M5 (peer_machine aarch64-macos). The fixture is one 10⁵-brush tape drawn from a fixed integer SplitMix64 seed, replayed at 33³ samples — the top of golden.rs's RESOLUTIONS, i.e. M-31's own fixture resolution with 100,000 folds in it instead of none — with the dig confined to an off-centre box a quarter of each field's extent per axis (dig_box_fraction_of_extent 0.25), so each mesh carries a pristine surface M-31 already hashes and a region that has taken 10⁵ folds. Committed at b2b481e — the # commit header carries no (WORKING TREE DIRTY) — and git merge-base --is-ancestor b2b481e HEAD passes; the file itself landed at bd8b134, also an ancestor of HEAD.
| clause | registered | measured |
|---|---|---|
| C1 the 10⁵-edit trace replays byte-identically on the M5 and the Zen 3, all eight fields | one differing byte falsifies | FALSIFIED — 3 bytes on box_exact, 3 on csg_difference, 0 on the other six. 6 of 2,470,824 compared bytes, 2.43 × 10⁻⁶ |
| C2 if C1 fails, bisection localises the first differing edit and its brush names the operation | an edit index and an operator | FALSIFIED — first_differing_edit is NONE on all eight and grid_bytes_differing is 0 on all eight over 287,496 bytes of folded grid each. There is no differing edit to find |
| C3 replay cost is linear, constant under 1.2× the sum of per-edit costs | < 1.2× | HELD on all eight — 1.005532 to 1.017252, worst row 15.2% under the bar |
Every number here is read from the committed
docs/experiments/p-97.csvatb2b481e, and this is not the file the original R-097 report quoted. That report's numbers came from a dirty pre-run at63c7161taken while roughly twenty-five sibling agents were compiling. Every integer reproduced exactly; every clock moved, one of them across a qualitative boundary. Old → new:
column dirty 63c7161committed b2b481emove linearity_constantsphere0.978121 1.017252 +4.00%, and it crosses 1.0 — the old row said replay was cheaper than the extrapolated per-edit sum, the committed row says dearer linearity_constantnoise_cavity1.157731 1.009014 −12.85% linearity_constantfbm_terrain1.111644 1.016382 −8.57% linearity_constanttorus/box_exact/csg_difference/thin_plate/gyroid1.017135 / 1.022281 / 1.015727 / 1.015656 / 1.018880 1.005532 / 1.014081 / 1.008346 / 1.013862 / 1.009369 −1.14% / −0.80% / −0.73% / −0.18% / −0.93% span of the eight constants 0.978121–1.157731 (0.17961) 1.005532–1.017252 (0.01172) 15.3× narrower worst row's margin under the 1.2 bar 3.5% 15.2% the clause got more comfortable, not less replay_ms19,308–23,026 19,157.586–19,392.905 slowest row −15.8% fold_ms19,307–23,019 19,156.348–19,391.293 extract_ms1.2–7.3 1.167–1.612 slowest row 4.53× faster sum_of_per_edit_ms18,984–20,141 19,028.720–19,099.021 per_edit_ms0.1898–0.2014 (6.1% spread) 0.190287198–0.190990210 (0.37% spread) interactive_linearity_constant4.662–45.368 7.460408–45.598325 low end +60.0%; still > 1.2 on all eight, which is what the assert needs cpu_khz4,189,216–4,202,679 4,190,370–4,200,232 Unchanged to the last digit, which is
M-279's rule satisfied: all eightbytes_differing(0/0/3/3/0/0/0/0), every byte-decomposition column,first_differing_vertex3353 and 3428,nan_normal_vertices,grid_bytes287,496 andgrid_bytes_differing0,bytes_comparedper row and its 2,470,824 total,bytes_beyond_m31per row, all four mesh hashes, the class counts 37,723 / 37,364 / 24,913,cell_size,vertices,triangles, and everycontrol_*column. No verdict moved.
The eight rows, and the divergence is three bytes in one place:
| field | bytes_differing |
normals | at NaN normals | positions / indices / counts | first_differing_vertex |
nan_normal_vertices |
grid_bytes_differing |
C1 | C2 | linearity_constant |
|---|---|---|---|---|---|---|---|---|---|---|
sphere |
0 | 0 | 0 | 0 / 0 / 0 | NONE | 0 | 0 | HELD | EMPTY | 1.017252 |
torus |
0 | 0 | 0 | 0 / 0 / 0 | NONE | 0 | 0 | HELD | EMPTY | 1.005532 |
box_exact |
3 | 3 | 3 | 0 / 0 / 0 | 3353 | 1 | 0 | FALSIFIED | FALSIFIED | 1.014081 |
csg_difference |
3 | 3 | 3 | 0 / 0 / 0 | 3428 | 1 | 0 | FALSIFIED | FALSIFIED | 1.008346 |
thin_plate |
0 | 0 | 0 | 0 / 0 / 0 | NONE | 0 | 0 | HELD | EMPTY | 1.013862 |
gyroid |
0 | 0 | 0 | 0 / 0 / 0 | NONE | 0 | 0 | HELD | EMPTY | 1.009369 |
fbm_terrain |
0 | 0 | 0 | 0 / 0 / 0 | NONE | 0 | 0 | HELD | EMPTY | 1.016382 |
noise_cavity |
0 | 0 | 0 | 0 / 0 / 0 | NONE | 0 | 0 | HELD | EMPTY | 1.009014 |
mesh_hash_local against mesh_hash_peer: dfdbb0786c10d8aa / a502e1802d09a62a on box_exact, d2863a2854678dba / 315b05f9372d7e3a on csg_difference, identical on the other six. vertices, triangles and bytes_compared agree on all eight — the two machines emit the same mesh, of the same size, in the same order.
C2 is falsified with nothing in its population, and that is the finding rather than a technicality. grid_bytes_differing is 0 on all eight rows over 287,496 bytes of final folded grid each (33³ × 8 = 287,496 exactly; 2,299,968 bytes across the eight), and the 100,000-entry per-prefix digest ladder is identical on all eight, so first_differing_edit reads NONE and bisection_steps reads 1 — the search probes the final prefix, finds it equal, and stops. The replay never diverged. The two machines agree bit-for-bit on the state after every one of the 100,000 edits, so there is no differing edit for a bisection to localise and no brush parameters to name. That reaches C2's registered falsifier — "a divergence that bisection cannot localise" — by a better route than the registered one: not "the fold accumulates" but "the fold never diverged at all", so no per-operation fix exists because no operation is responsible. The registration expected the falsifier to indict the fold; the measurement exonerates it and indicts the extractor's normal rule instead.
Where the divergence is, and it is one line of source. All three differing bytes on each field are in the normals (bytes_differing_normals 3, bytes_differing_positions / _indices / _counts all 0), all three sit on a vertex whose own normal is not finite (bytes_differing_at_nan_normals 3), and each field has exactly one such vertex (nan_normal_vertices 1 on those two, 0 on the other six). Zen 3 writes 0xfff8000000000000 in all three components and the M5 writes 0x7ff8000000000000: same quiet-NaN payload, opposite sign bit. In little-endian f64 that is one differing byte per component — 0xff against 0x7f at byte 7 — so 3 components × 1 byte = 3 bytes, which is the column. x86-64 SSE's default NaN is negative and AArch64's is positive, and IEEE 754 leaves the sign of a NaN produced by an invalid operation unspecified, so neither machine is wrong.
The NaN comes from unit_gradient, crates/isomesh/src/marching_cubes/mod.rs:739:
fn unit_gradient<R: Real, S: Sdf<Scalar = R>>(sdf: &S, position: [R; 3]) -> [R; 3] {
let g = sdf.gradient(position);
let len = vec3::length(g);
debug_assert!(len > R::ZERO, "zero gradient at a surface vertex");
vec3::scale(g, len.recip())
}
The zero-gradient guard is a debug_assert! only, and a bench runs in release: len.recip() is +inf, 0 * inf is NaN, and nothing shouts. Its doc comment is the reason this is invisible to M-31, and it is correct as written — "That means the field is degenerate there; it cannot happen for any exact distance field, where |grad| is 1." True, and exactly the point: an exact reference field has no plateau, but a grid folded through 100,000 min/max brushes does. apply is field.min(shape) for Add and field.max(-shape) for Subtract, and min/max select an argument rather than computing one, so adjacent lattice samples are frequently clamped to bit-identical values and the trilinear interpolant over such a cell has an exactly zero analytic gradient. Only box_exact and csg_difference reach it because only they have flat axis-aligned faces that align with the lattice, which makes the plateau exact rather than merely small. crates/isomesh/src/transvoxel/cell.rs:387 carries the same construction — same debug_assert!, same vec3::scale(g, length.recip()), deliberately duplicated because the marching_cubes copy is module-private — so the defect is in two extractors, not one.
The SHARE recomputation, and it is a provenance finding. C3 is registered against "the sum of per-edit costs M-50 measured", and M-50 has no committed CSV. Its four medians — 0.158 / 0.354 / 0.525 / 0.589 ms per re-meshed chunk for logs of 1–15 / 16–30 / 31–45 / 46–60 — exist only as prose at FINDINGS.md:1098 and as a docstring table at bevy_isomesh/examples/game_dig.rs:79, taken from E-202, a live Bevy example under a mouse on a different build and a different run. docs/measurements/edit_trace.csv is a different measurement (three rows of dirty-cell counts, no timing at all). Two things follow, and neither is a quibble:
- Taken literally the clause is not decidable, because the verdict is chosen by which of four buckets you pick. Against the committed
replay_msof 19,157.586–19,392.905 ms: 10⁵ × 0.158 ms = 15,800 ms gives 1.2125–1.2275×, which is above 1.2 on all eight rows — FALSIFIED. 10⁵ × 0.354 = 35,400 ms gives 0.5412–0.5478×, 10⁵ × 0.525 = 52,500 ms gives 0.3649–0.3694×, and 10⁵ × 0.589 = 58,900 ms gives 0.3253–0.3293× — HELD, on all eight, three times over. One denominator out of four flips the clause on every row. (The bench's own SHARE note understates this: it says the literal ratio is "~0.1–0.3× and no possible outcome reaches 1.2". Against the smallest bucket it reaches 1.23. The clause is bucket-dependent, not merely unfalsifiable.) - And comparing another machine's wall clock against this one violates
M-281outright — a millisecond is a property of the binary, andM-50's came from a different binary, a different build and a different run. This is theF-009class of failure: an entry's numbers denominated in a figure that no committed artefact contains, whichF-009was opened to gate mechanically after Phase 19 shipped it twice.
What the harness measured instead, stated in the bench before the run rather than discovered after it: sum_of_per_edit_ms is the marginal cost of one edit inside this run — the slope between a 1,000-brush tape and a 2,000-brush tape over the same grid, times 10⁵. slope_tape_short_ms 190.220–199.172, slope_tape_long_ms 380.860–389.480, per_edit_ms 0.190287198–0.190990210. The slope and not the ratio to zero, because a short fold also pays the base field's transcendentals once and fbm_terrain's are not a per-edit cost. That baseline is reachable in both directions: the 10⁵ tape is ~5 MB and does not fit the cache a 1,000-brush tape sits in, so a constant above 1.2 is physically available — and the interactive arm demonstrates the instrument getting there, at 7.460408–45.598325×, asserted > 1.2 so that C3's HELD cannot be P-70's C3 again.
| field | replay_ms |
fold_ms |
extract_ms |
sum_of_per_edit_ms |
linearity_constant |
achieved ms/edit at 10⁵ | marginal ms/edit (1k→2k) | interactive_linearity_constant |
|---|---|---|---|---|---|---|---|---|
sphere |
19,392.905 | 19,391.293 | 1.612 | 19,064.021 | 1.017252 | 0.193929 | 0.190640 | 42.556779 |
torus |
19,157.586 | 19,156.348 | 1.237 | 19,052.189 | 1.005532 | 0.191576 | 0.190522 | 42.511634 |
box_exact |
19,305.711 | 19,304.538 | 1.173 | 19,037.634 | 1.014081 | 0.193057 | 0.190376 | 41.251508 |
csg_difference |
19,218.169 | 19,216.993 | 1.176 | 19,059.094 | 1.008346 | 0.192182 | 0.190591 | 39.054959 |
thin_plate |
19,292.492 | 19,291.324 | 1.167 | 19,028.720 | 1.013862 | 0.192925 | 0.190287 | 45.598325 |
gyroid |
19,267.079 | 19,265.623 | 1.456 | 19,088.238 | 1.009369 | 0.192671 | 0.190882 | 18.746598 |
fbm_terrain |
19,342.615 | 19,341.400 | 1.215 | 19,030.861 | 1.016382 | 0.193426 | 0.190309 | 7.460408 |
noise_cavity |
19,271.180 | 19,269.816 | 1.364 | 19,099.021 | 1.009014 | 0.192712 | 0.190990 | 17.199971 |
One conclusion from the original report is withdrawn here rather than repeated. It read "the same fields read 0.96–1.03 at a 3,000-edit calibration, so the constant rises with tape length" — and that calibration is in no committed CSV, so quoting it is the same defect the SHARE line above diagnoses, and comparing it to this run is M-281 besides. The within-file evidence is narrower and points partly the other way: the average per-edit cost of the 1,000-brush tape (0.190220–0.199172 ms) is higher than that of the 2,000-brush tape (0.190430–0.194740) on seven of eight fields, because the short tape amortises the base field's cost over fewer edits — exactly what the bench's SLOPE_TAPES comment says it would. The only rise with length that this file contains is between the 1k→2k marginal cost and the achieved 10⁵ average, and that gap is linearity_constant: +0.55% to +1.73%, above 1.0 on all eight rows. So the honest statement is that C3 held with a 15.2% margin, not a marginal one, and its liveness rests entirely on the interactive arm's assert and not on the 10⁵ rows sitting near the bar.
The regime evidence — this is not M-31 under a longer name. bytes_beyond_m31 is the difference between the replayed mesh's byte stream and the zero-edit mesh of the same field, which is precisely what the golden fixture hashes:
| field | pristine_bytes |
bytes_compared |
bytes_beyond_m31 |
share of the compared stream | of which differ inside the common prefix |
|---|---|---|---|---|---|
sphere |
83,352 | 256,920 | 238,209 | 92.72% | 64,641 / 83,352 = 77.55% |
torus |
81,240 | 267,624 | 249,064 | 93.06% | 62,680 / 81,240 = 77.15% |
box_exact |
97,176 | 264,360 | 219,832 | 83.16% | 52,648 / 97,176 = 54.18% |
csg_difference |
99,768 | 266,232 | 225,375 | 84.65% | 58,911 / 99,768 = 59.05% |
thin_plate |
36,696 | 254,376 | 240,918 | 94.71% | 23,238 / 36,696 = 63.33% |
gyroid |
381,624 | 449,160 | 351,522 | 78.24% | 283,986 / 381,624 = 74.42% |
fbm_terrain |
146,688 | 276,864 | 251,693 | 90.91% | 121,517 / 146,688 = 82.84% |
noise_cavity |
471,912 | 435,288 | 338,766 | 77.83% | 302,142 / 435,288 = 69.41% |
77.83%–94.71% of every compared stream differs from the zero-edit mesh, asserted > 0 in the harness. Two arithmetic caveats, both recomputed from the committed columns rather than quoted: bytes_differing counts a length difference as differing in every byte one stream lacks, and pristine_bytes ≠ bytes_compared on all eight rows because the dig changes the vertex count — on noise_cavity the pristine mesh is the longer of the two (471,912 against 435,288), so the dig removed surface there. Netting the length term out, 54.18%–82.84% of the bytes the two meshes hold in common still differ. Either reading says the same thing: the compared mesh is not M-31's mesh. And the divergence landed in the edited region, not the pristine one — box_exact and csg_difference have the lowest in-common shares of the eight and are the two fields that broke C1.
The original report's "79–86%" for this share is withdrawn. The underlying integers are identical between the dirty and the committed run, so nothing moved; the figure was arithmetic taken across rows — the minimum of
bytes_beyond_m31over the maximum ofbytes_comparedand back — which is not any row's share. The per-row range is 77.83%–94.71%.
The vacuity control has two parts and both matter. The registered one is the trace's composition: same_kind_edits 37,723, mixed_edits 37,364, smooth_union_edits 24,913, identical on all eight rows because the integer draws are shared across fields, asserted each > 0 and asserted to partition edits — 37,723 + 37,364 + 24,913 = 100,000 exactly. The classification is the crate's own BrushOp::commutes_with (Add/Add and Subtract/Subtract and nothing else) rather than a second opinion written in the bench, so an edit is same-kind when it commutes with the previous hard edit and mixed when it does not. That value proves the fixture could have failed: 37,364 edits do not commute with their predecessor, which is M-37's regime (11 distinct results from 40,320 orderings), and 24,913 are smooth unions, which is M-38's (40,317 distinct results from 40,320 orderings). A trace of only same-kind brushes is the case M-36 already knows is order-free — one result from all 40,320 orderings — and a C1 HELD over that trace would have been a determinism claim about a computation already proved order-insensitive. 62,277 of the 100,000 edits are outside it.
The separate and more important control is control_bytes_differing: the same tape is replayed with one ULP added to a single brush's radius and the differing output bytes are asserted > 0. It reads 9 on seven fields and 835 on gyroid. So the zeros on the six HELD fields are measurements and not an artefact of a comparator that cannot see — which is M-44's rule, and it is the only thing that makes bytes_differing = 0 mean anything at all.
| control column | six hard-op fields | gyroid |
|---|---|---|
control_perturbation_depths |
18 | 18 |
control_depths_reaching_output |
7 | 8 |
control_perturbed_edit |
99,936 | 98,976 |
control_deepest_reaching_from_end |
64 | 1,024 |
control_perturbed_operator |
subtract |
smooth_add |
control_bytes_differing |
9 | 835 |
control_first_differing_edit |
99,936 | 98,976 |
control_bisection_edit |
99,936 | 98,976 |
control_bisection_agrees |
true | true |
control_bisection_steps |
16 | 17 |
control_divergence_heals |
false | false |
control_differing_prefixes |
64 | 1,024 |
Three things this table says that the single asserted non-zero does not. The depth is measured, not guessed — 18 candidate positions at edits − 2^j plus edit 0, of which only 7 (8 on gyroid) reach the output at all, and the earliest that does is 64 edits from the end (1,024 on gyroid). The bisection instrument proves itself on a divergence it can localise: control_first_differing_edit == control_bisection_edit on all eight, control_bisection_agrees true, control_divergence_heals false, and control_differing_prefixes equals control_deepest_reaching_from_end exactly on every row — the perturbation appears at edit 99,936 (98,976) and never once heals, so the 16 or 17 probes land on the truth. Set that against the main columns' bisection_steps of 1: the same search takes 16–17 probes when there is something to find and 1 when there is not, which is what makes C2's NONE a measurement rather than a shrug. And the deepest-reaching perturbation on gyroid is a smooth_add, surviving 1,024 edits against the hard ops' 64 — a 16× deeper reach — because smooth_min computes mix(b, a, h) − k·h·(1 − h) rather than selecting an argument, so a one-ULP change stays in the value instead of being discarded by the next min. That is also why its control_bytes_differing is 835 against 9.
Five fixture defects the harness's own controls caught, before any of these numbers were believed.
- The first
M-44control was planted at edit 50,000 and reached zero output bytes, and the control refused the run rather than printing a clean zero. It was right, and the reason is the mechanism the experiment is about:AddisminandSubtractismax, and aminselects an argument rather than computing one, so a perturbed brush only survives at a lattice point where it is still the selected argument after every later edit — with hundreds of later brushes covering each point, it almost never is. A guessed position was replaced by a measured geometric depth ladder, which turned a broken control into the result in the table above. - The trace was first scattered uniformly over the whole domain, and six of the eight fields produced the identical mesh hash —
c5dd8988f595a347at 5,000 edits, on every field whose domain is[-2, 2]³. The base field had been erased: with thousands of sphere centres in a 32-cell domain the nearest centre to any point is a fraction of a cell away, somin(field, shape)is a function of the brushes and nothing else. Eight rows would have been one measurement copied eight times, and C1 would have been a determinism claim aboutsqrt,minandmaxwith no transcendental anywhere in the output — the exact opposite of thelibmpropertyM-31exists to pin. Caught by the pairwise-distinct-hash assert inmain, and fixed by confining the dig to a box. - After re-centring,
box_exactandcsg_differencestill collided, because a dig box at 0.25–0.75 of the extent swallowed exactly the unit-sphere bite that distinguishes the two fields. Fixed by moving the box off centre, to 0.30–0.55. Those two are the fields that ultimately diverged, so the fixture defect and the finding were one lattice apart — the same two rows that were once indistinguishable are the only two that broke C1. - The manual paired fold is asserted bit-for-bit equal to
BrushStack::sampleat all 35,937 lattice points, because the ladder C2 is bisected against comes from a transposed fold andreplay_mstimes the crate's own. Two folds are two answers to one question, and the assert is what stops the ladder describing a different computation from the one the clause is about. first_differing_operatorreadsNONEandbisection_stepsreads1, rather than being filled with the nearest available value. There is no differing edit, so there is no operator; a column that reported the closest brush would have manufactured a localisation the run does not have. The same discipline covers the peer's absence: the missing-comparison case records the literal stringBLOCKED, never a zero.
What changed as a result. No source change — crates/isomesh/** is untouched, and R-097 is not one of the phase's two registered source changes. Three things for the owner:
- A real, release-only defect. The crate emits NaN normals for any field with a plateau, in both
marching_cubes/mod.rs:739andtransvoxel/cell.rs:387, and only shouts about it in debug. That is a lighting bug on one machine before it is a determinism bug on two. The fix is one branch inunit_gradient; whether a zero gradient is an error — as the subgrid extractor already treats it — or a defined value is the owner's call, not this experiment's, and it belongs in both copies or the duplication becomes a divergence of its own. - Committing a golden hash of a mesh containing a NaN commits a platform-specific fixture.
M-31's 216 hashes are safe only because the reference fields never produce a zero gradient at a surface vertex. A golden fixture over edited geometry would not be, and these two rows are the evidence — same vertices, same triangles, same positions, same indices, different hash, on the sign bit of a number IEEE 754 declines to specify. - Do not build the Teardown move. A fixed-point rewrite of the fold would fix nothing measured here: the
f64fold is already bit-identical across x86-64 and AArch64 at 10⁵ edits, at every one of 100,000 prefixes, on all eight fields, over 2,299,968 bytes of grid state, withgrid_bytes_differing0 everywhere.libmplusf64held perfectly. The only divergence in the run is a division by zero, and integer arithmetic does not repair that — it only changes which value the invalid operation returns.
One provenance caveat, recorded plainly. The peer artefact directory docs/experiments/p-97-peer/ (8 × .mesh / .grid / .ladder / .hash, plus machine.txt) is an input, not an output. The M5 runs first with no peer present, which is the registration's own BLOCKED outcome and is recorded as the literal string rather than as a zero; its target/p97-self/ is then copied into docs/experiments/p-97-peer/ on the Zen 3, and the Zen 3 run produces the committed CSV. On a tree without that directory the bench records BLOCKED for C1 and C2 rather than 0 — a missing comparison is never a passing one — which is why it is committed. One number in the original report cannot be checked against the CSV and is not claimed here: the two differing vertices were reported at world (−1.0, −1.0, 0.875), and there is no position column in the file. first_differing_vertex 3353 and 3428 are what the artefact carries.
Would be shown wrong by: a third machine whose default NaN sign matches neither, or an adapter on which box_exact produces no NaN normal at all — either would mean the plateau is not where this entry says it is. A grid_bytes_differing above zero on any field, which would move the divergence into the fold and make C2's falsifier the registered one after all. A fixed unit_gradient under which the two machines still disagree, which would mean the NaN was a symptom of something else. Or a longer tape — 10⁶ edits, or a trace that reaches plateaux on a field with curved faces — diverging in the positions, which is the outcome the registration was actually afraid of and which 10⁵ edits did not produce.
🔬 M-410 — C1, C2 and C3 all HELD: fused into the extraction gather the Plantinga–Vegter certificate costs 0.0553 worst of extraction at 65³ against M-378's derived 0.0658, certifies the same set on 25 of 25 rows with 0 unsound over 2,389 hidden-topology cells, and aggregates per chunk at 0 extra passes — but the aggregable object is the count pair, not the fraction, which is wrong by 12.9 points on noise_cavity; and M-378's prose gloss on its own 0.0658 is not a recipe for it (P-98, R-098)
M. cargo bench --bench experiment_p98, docs/experiments/p-98.csv, 25 rows, f64, Zen 3
(cpu_mhz 4193.3–4202.3 on the row, M-280). A bench-local fused walk reproduces the extractor's own
eight-corner prologue (marching_cubes/mod.rs:259-268) once and derives both the case byte and the
certificate from the same registers, over the eight reference fields at 17³/33³/65³ plus p-62.csv's
400,000-cell random arm inherited verbatim; crates/isomesh/src/** was read-only for the ticket, so
nothing shipped moved. Committed at 0527d48, clean tree (no WORKING TREE DIRTY on the header), an
ancestor of HEAD.
The committed file is a clean-tree re-run, and C1's headline numbers are not the ones the harness's own agent reported. That report was written off a dirty pre-run of the same binary. Every integer reproduced exactly —
certified_cells_fused,active_cells,certified_active_fused,refused_cells,tunnel_cells,twelve_vertex_cells,unsound_certificatesandcellsagree withp-62.csvon all 25 rows with zero mismatches, andunsound_if_certify_all,set_differenceandextra_passesare unchanged. What moved is C1's identity: the worst 65³fused_sharewas 0.053922 onsphereand is 0.055328 onbox_exact, with the range 0.004858–0.053922 now 0.004806–0.055328 andfused_share_upper0.05398 → 0.055610. The verdict is unchanged and the margin is 1.19× rather than 1.22×. And one briefed conclusion does not survive the clean run and is withdrawn below: the claim thatM-378's gather-subtraction over-estimates the fused cost on every field.M-377's rule — re-running means re-quoting — is why the sentence is here rather than the old numbers.
| clause | registered | measured |
|---|---|---|
| C1 fused predicate ≤ 0.0658 of extraction at 65³, all eight fields | ≤ 0.0658 | HELD — 0.055328 worst on box_exact, 8/8, range 0.004806–0.055328 |
C1 read against the conservative fused_share_upper |
≤ 0.0658 | HELD — 0.055610 worst on box_exact, strictly harder, same verdict |
| C2 certified sets identical, no certificate on hidden topology | set_difference 0, unsound 0 |
HELD — 0 and 0 on 25/25, over 2,389 tunnel / twelve-vertex cells |
| C3 certified fraction aggregable per chunk at no extra pass | extra_passes 0 |
HELD — 0 on 25/25 from a counted cells_visited == cells |
C1 at 65³, which is the only resolution the clause is registered over:
| field (65³) | active / 262,144 | fused ms | extract ms | fused_share |
_upper |
standalone_share |
bar budget ms |
|---|---|---|---|---|---|---|---|
box_exact |
5,768 (2.200%) | 0.1373 | 2.4819 | 0.055328 | 0.055610 | 0.293057 | 0.1633 |
sphere |
4,760 (1.816%) | 0.1283 | 2.4485 | 0.052404 | 0.052805 | 0.297711 | 0.1611 |
noise_cavity |
28,375 (10.824%) | 0.8395 | 17.3901 | 0.048276 | 0.048314 | 0.074145 | 1.1443 |
csg_difference |
6,014 (2.294%) | 0.1426 | 3.0098 | 0.047372 | 0.047469 | 0.243884 | 0.1980 |
torus |
4,208 (1.605%) | 0.1362 | 2.9205 | 0.046653 | 0.046820 | 0.251128 | 0.1922 |
thin_plate |
2,048 (0.781%) | 0.1019 | 2.2689 | 0.044898 | 0.045229 | 0.608243 | 0.1493 |
gyroid |
21,432 (8.176%) | 0.4555 | 13.1726 | 0.034577 | 0.034582 | 0.074551 | 0.8668 |
fbm_terrain |
8,413 (3.209%) | 0.2552 | 53.0894 | 0.004806 | 0.004820 | 0.015195 | 3.4933 |
The bar holds at 65³ and does not hold at 17³, and an entry that omits the resolution is wrong. Four
of the eight 17³ rows read 0.0673 (torus), 0.0685 (csg_difference), 0.0708 (sphere), 0.0818
(box_exact) — above the bar. All eight 33³ rows are under it (0.004065–0.062599). This is not a
regression in the predicate; it is arithmetic. Clause one's marginal is a fixed per-cell cost —
clause_one_margin_ms / cells is 0.455–0.595 ns per cell on all twenty-four sampled rows, tightest
cluster 0.479–0.488, i.e. ≈ 2.0 cycles at 4.2 GHz — while extract_ms per cell falls as the grid
shrinks (0.0499 ms over 4,096 cells on box_exact at 17³ is 12.2 ns/cell against 9.5 ns/cell at 65³).
Part 5's rule about a suite sampling one point of a stated range applies to the reader here: the
registration says "at 65³", the harness measures three resolutions, and the honest claim is the
registered one.
SHARE, recomputed from p-62.csv before the harness ran — and the recomputation found a defect in a
published entry. C1 is a share of extraction, which is how M-378 stated it, so the bar had to be
re-derived rather than accepted. (predicate_ms − gather_ms) / extract_ms from p-62.csv at 65³:
field (p-62.csv, 65³) |
predicate ms | gather ms | extract ms | standalone | fused | gather/predicate |
|---|---|---|---|---|---|---|
box_exact |
0.7627 | 0.5116 | 3.8130 | 0.2000 | 0.065854 | 0.671 |
csg_difference |
0.7771 | 0.5117 | 4.2717 | 0.1819 | 0.062130 | 0.658 |
thin_plate |
0.7209 | 0.5101 | 3.4218 | 0.2107 | 0.061605 | 0.708 |
torus |
0.7605 | 0.5120 | 4.0624 | 0.1872 | 0.061171 | 0.673 |
sphere |
0.7474 | 0.5075 | 4.2511 | 0.1758 | 0.056432 | 0.679 |
noise_cavity |
1.3600 | 0.5081 | 19.2885 | 0.0705 | 0.044166 | 0.374 |
gyroid |
1.0266 | 0.5115 | 15.1811 | 0.0676 | 0.033930 | 0.498 |
fbm_terrain |
0.8712 | 0.5133 | 51.0242 | 0.0171 | 0.007014 | 0.589 |
The number is right and the sentence is not a recipe for it. 0.0658 is the maximum of p-62.csv's
own fused_share column at 65³ — box_exact's cell reads 0.065844 and recomputes to 0.065854.
M-378's gloss is "two thirds of the standalone cost is re-reading corners" attached to its worst
standalone share, and that arithmetic gives a different number: 0.2107 − ⅔(0.2107) = 0.0702, while
thin_plate's own fused share is 0.0616. The 21% and the 0.0658 come from different rows — the
worst standalone share is thin_plate, the worst fused share is box_exact — and gather/predicate is
0.374–0.708, never two thirds uniformly. So the published sentence reads as a derivation and is a gloss
over a column maximum. Two consequences: the bar was usable as registered, and Part 5's "an entry that
says an instrument was fixed must show the fixed instrument's values" has a sibling — an entry that
states a derivation must state the arithmetic that produces its own number. (A second, narrower
correction: 0.0658 is the column maximum at 65³; over all 25 rows of p-62.csv the largest
fused_share is torus at 17³, 0.097828. The registration scopes C1 to 65³, so this does not touch
the bar — but "the maximum of the column" is only true of the eight rows the clause is about.)
What arithmetic could reach before the run, and what it could not. The bar is an upper bound on
added cost, so 0.0658 × extract_ms over 262,144 cells at ~4.2 GHz is the budget: tightest is
thin_plate at 0.2252 ms = 0.859 ns/cell ≈ 3.6 cycles/cell, against a fused per-cell cost on an
inactive cell of one branch on a byte the extractor already built — so ~3× headroom on the tightest
field, derivable in advance. Arithmetic could not reach three things, and each needed an instrument.
(a) C2 and C3 are counts, not shares, so no Amdahl-style ceiling applies to them at all and the SHARE
line correctly says nothing about them. (b) Whether a ~0.1 ms marginal is resolvable against a
2.3 ms denominator on a host whose load average ran 3–16 all session: decided only by the rig's own
floor control (below). (c) The 17³ overshoot above, which is a consequence of the same fixed per-cell
clause-one cost the reachability argument used — visible in the arithmetic only once someone computes the
budget at a resolution the clause was not registered over, which nobody did.
Mechanism, stated on integers because the integers are identical on every run (M-337). Fusing
removes the whole re-gather: loads_fused_additional is 0 on all twenty-four sampled rows while
loads_standalone_additional is exactly 8 × cells — 2,097,152 at 65³, a second full pass over the
grid for the same answer — both asserted, not derived. And clause two runs on exactly the active cells:
clause_two_evals == active_cells is asserted per row, so the predicate's variable cost is
0.781%–10.824% of cells at 65³ and nothing else. The reason clause one is free is algebra rather than
tuning: F is a convex combination of the eight corners, so 0 ∉ □F(C) is "all eight corners share
a sign", which is case == 0 || case == 255 — a comparison on a byte the extractor already holds.
That term is the one M-378's subtraction left inside the predicate's account.
Withdrawn: the fused marginal is not uniformly below the gather-subtracted estimate. On the dirty
pre-run every field's measured marginal came in at 0.48–0.98 of
standalone_predicate_ms − bare_gather_ms, and that was reported as "the derivation over-estimates by
1.02×–2.07×, and the error tracks the active-cell fraction". On the committed run the same ratio spans
0.117 (thin_plate) to 1.163 (noise_cavity), with fbm_terrain at 1.062 — two fields where the
measured marginal exceeds the estimate. The ordering was never a property of the predicate: both terms
are differences of separately-estimated wall times, and thin_plate's standalone_predicate_ms alone
moved from p-62.csv's 0.7209 to 1.3800 here. The run-independent statement that replaces it is the
integer pair above — 0 added loads against a second 8 × cells — which needs no clock at all.
Cross-instrument agreement, and where it stops (M-279). Every count column of p-98.csv reproduces
p-62.csv exactly across all 25 rows: cells, certified_cells, surface/active_cells,
certified_active_fused, refused_cells, tunnel_cells, twelve_vertex_cells and
unsound_certificates — zero mismatches, a new harness agreeing with the old one everywhere they
overlap. bare_gather_ms reproduces M-378's "0.51 ms on every single arm" as 0.5051–0.5675 on all
eight 65³ rows. The timings do not all agree, and the entry says so rather than averaging them:
thin_plate's standalone predicate reads 1.3800 ms against 0.7209, and its extract_ms 2.2689 against
3.4218 — extract_ms here is a warmed minimum taken inside the same repetition as the walks, which is
the conservative direction for C1 (smaller denominator, larger share) and is why standalone_share runs
to 0.608243 here against M-378's 0.2107. C1's verdict does not rest on any of those: its numerator
is the fused marginal.
The vacuity control, and it is unusually strong. The registered control is p-62.csv's 400,000-cell
random arm inherited verbatim — same LCG (0x2026 ^ 0x5EED1234, multiplier 6364136223846793005),
same seed, same draw order — and the harness asserts the population rather than noting the intent:
tunnel_cells = 2,202 and twelve_vertex_cells = 180, exactly M-378's. The eight reference
fields alone give seven tunnel cells (3 on noise_cavity at 17³, 4 at 33³, and 0 everywhere else),
which M-378 itself called "a hair from M-44's vacuous zero". Beside it, three columns show the zero
could have been non-zero:
| column | random arm | over the 25 rows | what it proves |
|---|---|---|---|
unsound_if_certify_all |
2,382 | 2,389 | the number unsound_certificates would have read for a certificate replaced by true, counted through the same if hidden { if certified { … } } branch |
mutant_set_difference |
15,578 | 24,252 | a mis-paired-z fused variant certifies a different set, so set_difference is a comparison and not a constant |
resolution_floor_ms |
— | 0.0001–0.0010 at 65³ | two readings of the identical baseline loop in one window; every 65³ marginal is ≥ 127× the floor (thin_plate, the tightest) and floor_share ≤ 0.000401 |
unsound_if_certify_all = 2,382 is the value that makes C2 a result. It is not a straw man and not a
separate loop: the degenerate certificate is evaluated at the same cell, in the same branch, with the same
hidden test, so the two counters differ in exactly one predicate. A gate that reads 0 where the worst
possible predicate reads 2,382 has been shown able to fire. unsound_mutant came back 0 — the
mis-paired-z mutant is wrong without being unsound on this population, which is precisely why the
degenerate certificate and not the mutant is what licenses C2's zero, and why both controls are carried.
The predicate is also extremely discriminating on that arm: 19,571 certified of 396,865 active, a
refusal of 377,294 cells (95.07%), and not one accepted cell contains a tunnel.
C2 is a set comparison, and the distinction is the clause's whole reason for existing.
set_difference is a symmetric difference over a bitset indexed by global cell number, asserted
against certified_cells_fused on every row — not certified_cells_fused == certified_cells_standalone,
which is also 0 on all 25 rows and would pass on two implementations certifying equal-sized different
sets. Both readings are reported; only the first is the gate.
C3's real content is that the aggregable object is the count pair, not the fraction. extra_passes
is 0 from a counted cells_visited == cells — 262,144 visits over 262,144 cells at 65³, asserted, so the
number is a traversal count and not an intention. Per-chunk counts sum exactly:
chunk_active_sum == active_cells and chunk_certified_sum == certified_active_fused on all 25 rows,
512 chunks of 512 cells at 65³ (8³ cells per chunk, M-377's granularity optimum). The trap is one layer
up. IsotopyReport::certified_fraction returns 1.0 for an empty chunk, so a mean of per-chunk
fractions is not the global fraction:
| field (65³) | mean_chunk_fraction |
global_fraction |
gap |
|---|---|---|---|
noise_cavity |
0.929270 | 0.800176 | 12.91 pts |
csg_difference |
0.989396 | 0.927502 | 6.19 pts |
box_exact |
0.994841 | 0.936200 | 5.86 pts |
gyroid |
0.966018 | 0.963606 | 0.24 pts |
sphere / torus / thin_plate / fbm_terrain |
1.000000 | 1.000000 | 0.00 |
A consumer can read "this chunk is 93.6% certified" out of the same traversal — provided the report
carries (certified, active) and the caller divides at the end. Average the fractions and the answer is
wrong by up to 12.9 points, in the optimistic direction, on exactly the fields where certification is
partial. The random arm reads 0.049313 against 0.049314 for the same pair, because all 500 of its chunks
have active cells: the fraction trap only bites where a chunk can be empty, which is every chunk in a
real world.
And the shipped route to the same number is a second traversal. extra_passes_shipped_api is a 1
written on every row — a statement, not a counter — because validate::isotopy_report is a separate call
over the same grid. The timing is what makes it a measurement: 1.0281 ms against a 0.1426 ms fused
marginal on csg_difference, 7.2×, and 1.8×–9.7× across the eight 65³ fields (isotopy_report_ms
0.9906–1.4946 ms). The report's own count is cross-checked against the flat and chunk-major fused walks on
every row, so the three implementations agree on what is certified while disagreeing by 7× on what it
costs to ask.
Three fixture defects, all caught by this harness's own controls rather than by review. The readings below are the defective instruments' own and are recorded in the bench's doc comment; no committed CSV contains them, which is the point of naming them here.
- The first baseline was measuring LLVM, not the predicate.
walk_caseoriginally read the eight corners' sign bits and discarded the values, so LLVM dropped the loads and left a sign scan — subtracting that charges the fused predicate for materialising the corners, which is the one cost fusion removes. It producedfused_predicate_ms0.6920 ms onsphereat 65³ against aforced_margin_msof 0.8328 ms: 83% of the cost of running clause two on every cell, for running it on 1.8% of them. Arithmetically impossible, and invisible without the ordering control (fused ≤ forced). The extractor cannot discard those values —corner_valueis live forjoined_maskand every edge interpolation — so all three walks now hold them live identically. The defective reading is kept as a column:walk_signs_ms0.2860–0.2871 ms andfused_share_vs_signs0.018444–0.364466 at 65³, worst onthin_plate— 6.6× C1's own 0.055328 and 5.5× the bar. Same baseline, opposite verdict. - A share clause needs both halves in the same window. With numerator and denominator timed in
separate loops, four runs of the identical binary put the worst 65³
fused_shareat 0.0457, 0.0471, 0.0527 and 0.0779 — a 1.7× spread straddling the bar, three HELD and one FALSIFIED, with nothing about the predicate changing. Timing extraction inside the same repetition and taking the minimum of both series gave 0.0475, 0.0484, 0.0501, 0.0511, 0.0529 — a 1.1× spread, all HELD.M-281's "one build and one run" has to be read as one window, not one process, whenever the clause is a ratio — and the durable half of the fix isCounted, whose integers do not have this failure mode at all. thin_plate's marginal read −0.0180 ms before the pairing went in. Not a negative cost: drift below the timer's own floor. The rig therefore measures its floor — two timings of the identical baseline inside one repetition — and assertsresolution_floor_ms / extract_ms < 0.0658on every 65³ row, because an upper bound is passed by "unresolvably small" and a one-sided clause has to say which it got. On the committed runthin_platereads 0.1019 ms against a 0.0008 ms floor, 127×, the tightest ratio in the file. No row is unresolvable and no marginal is negative.
A bracket that is reported and does not decide the clause. An additive model
clause_one_margin + (clause two ns/cell) × active_cells, each term measured where it is large, reads
modelled_share 0.078522 worst on box_exact — above the bar. It is carried because it locates the
mechanism, and it is explicitly not a second reading of C1: both its terms are themselves unpaired timing
differences, it runs 1.28–1.47× the measured marginal on the five low-activity fields and 0.65–0.91× on
gyroid, fbm_terrain and noise_cavity, so it brackets rather than measures.
What changed as a result.
- The crate can say where it is correct, by default rather than as a debug gate, and the price is
named. At ≤ 0.055328 of extraction at 65³ on all eight fields — one comparison on a byte the
extractor already holds, plus 11.31–14.60 ns/cell on the 0.78%–10.82% of cells that are active — a
certified-cell count comes out of the extraction traversal itself. That is a capability
M-378falsified in its standalone form and stated as a number it filed nothing about. - Do not ship the standalone pass. It buys the identical set (
set_difference0 on 25/25) for a second8 × cells= 2,097,152 grid loads at 65³, i.e. the 0.0152–0.6082standalone_share. - Do not aggregate
certified_fraction. Any per-chunk pipeline must carry(certified, active)and divide once;IsotopyReport::certified_fraction's 1.0-on-empty is a latent 12.9-point error the moment a caller means it per chunk. - Do not build
validate::isotopy_reportinto a per-chunk pipeline. It is a second traversal at 7.2× the fused marginal for a number the first traversal already has. M-378's "two thirds" sentence is corrected here rather than in place, and its 0.0658 stands as what it actually is: the maximum of its ownfused_sharecolumn at 65³.- Any quotation of "under 0.0658" must carry "at 65³". Four of the eight 17³ rows are above it.
Would be shown wrong by: a field or resolution at 65³ whose fused marginal exceeds
0.0658 × extract_ms, which would mean the fixed per-cell clause-one cost is not fixed or clause two
reaches inactive cells; one certified cell that A-020 calls a tunnel or a twelve-vertex contour, on
any population — the falsifier M-378 registered and this row inherits; a non-zero set_difference,
which would mean fusing changed the arithmetic and PV's soundness argument does not carry across the
fusion; a cells_visited above cells, which puts the certificate back above the ceiling as a second
pass; or an unsound_if_certify_all of 0 on the random arm, which would mean the 0 above was counted
over an empty population and this entry measures nothing.
🔬 M-411 — all three clauses HELD, and the two findings worth more than the HELDs: C1's premise is off by two — rank_all_edges reads 6, not eighth — and the metric C1 endorses needs the oracle too, so the deployable LOD input is rate_sign_change, which reproduces the ranking on all 120 rows (P-99, R-099)
M. cargo bench --bench experiment_p99, docs/experiments/p-99.csv, 120 rows = 8 reference fields
× 3 resolutions {17³, 33³, 65³} × 5 k {2, 3, 5, 9, 17}, f64, scalar,
amd-ryzen-9-5900x-12-core. Fixture, predicate, fields, resolutions, k and oracle are all P-66's,
inherited rather than re-invented: k samples of ∇f · ê along every axis-aligned grid edge, flagged
non-monotonic when two sampled projections disagree in sign, against subgrid::roots::all_roots at 128
intervals per edge. What is new is the denominator. # commit a6a3ed3 on
amd-ryzen-9-5900x-12-core at 2026-08-28T00:28:36Z — no (WORKING TREE DIRTY), and a6a3ed3 is an
ancestor of HEAD.
| clause | registered | measured |
|---|---|---|
C1 the single-root rate ranks thin_plate first of eight at 33³ and 65³ |
rank 1 | HELD — rank_single_root = 1 on all 10 rows at 33³ and 65³, at every k; rates 0.441176 and 0.469697 |
C2 it fails to converge on thin_plate and converges on the other seven |
1-of-8 split | HELD — converges = false for thin_plate and true for the other seven, at all five k; 0.388889 → 0.441176 → 0.469697 |
C3 false negatives fall with k, false positives are monotone non-decreasing |
both, in the permitted direction | HELD — FN 322 / 94 / 8 / 1 / 0 and FP 9,886 / 10,387 / 10,565 / 10,637 / 10,658 over k = {2,3,5,9,17} |
Every number below is read from the committed
docs/experiments/p-99.csvata6a3ed3, which is a clean-tree re-run. The measuring agent's report quoted a run at63c7161 (WORKING TREE DIRTY), and quoting a superseded run is✗35's and✗52's defect. So every figure was re-read from the clean file rather than copied. This file has no timing column — every quantity is an exact integer count or a ratio of two of them — soM-280andM-281do not apply and the re-run reproduces the dirty run bit for bit on every number, which is the outcome a clock-free artefact should have and is worth recording as such. Two things in the prior report are nevertheless corrected here, and both are scope errors rather than moved values: "the two denominators differ by at most 6 edges anywhere in the file" is true only at 65³ — the maximum over the whole file is 20, atnoise_cavity33³ — and the reproduction control compares 840 cells, not 720, becauseoracle_samplesis shared withp-66.csvtoo.
SHARE, recomputed, and one clause that was arithmetically unreachable to check
No clause here is a ratio of a runtime total, so ✗51's arithmetic has nothing to bite on and there is
no 1/(1 − share/factor) to compute. The registration says so itself: "SHARE: this is a rate; it moves
nothing and gates the LOD decision M-121 and M-72 both want an input for." All three clauses are
comparisons of exactly counted integer populations — a rank, a sequence direction, and two monotonicities
— over a sweep with 3 resolutions and 5 k, one more than each clause's structural minimum. All three
were reachable before the run, and the one thing that could have made C1 unreachable by arithmetic is
a tie at the top: rank is defined as 1 + (number of fields with a strictly greater rate), so "ranks
first" is satisfied by a tie and a tie is not a result. That is why rank1_strict_single_root is
asserted at 33³ and 65³ before the CSV is written and recorded on every row. It is true on all 120
rows; at 65³, k = 5 the top two are 0.469697 against 0.136549, a 3.44× separation.
The reachability finding that is not arithmetic, and it contradicts the registration's own framing.
✗53 split its two surviving candidates into a deployable one and an offline one — the single-root rate
as "the FP-rate column", and the false-negative count "which needs the oracle, so it is an offline
diagnostic and not a per-frame number". That split is wrong, and it is wrong about the half P-99
registered. rate_single_root's denominator is "edges the root finder reports with exactly one
root", which cannot be known without all_roots — 129 field evaluations per edge, 811,200 edges at 65³.
So C1 as registered endorses an offline metric, and the per-chunk LOD input M-121's 3.14-cell
surface pop and M-72's aliasing both want is still not in hand from C1 alone. This was caught by
writing the SHARE section before the harness, and it was answered rather than merely noted: the bench
records four extra sign_change columns, and that is where the deployable signal turns out to live.
C1 — the denominator was the defect, and the premise was off by two
| field | rate_single_root |
rank_single_root |
rate_all_edges |
rank_all_edges |
flagged_non_monotonic |
|---|---|---|---|---|---|
thin_plate |
0.469697 | 1 | 0.001185 | 6 | 961 |
noise_cavity |
0.136549 | 2 | 0.062366 | 2 | 50,591 |
fbm_terrain |
0.086720 | 3 | 0.255369 | 1 | 207,155 |
gyroid |
0.026888 | 4 | 0.043225 | 3 | 35,064 |
csg_difference |
0.017465 | 5 | 0.004662 | 5 | 3,782 |
torus |
0.000000 | 6 | 0.009615 | 4 | 7,800 |
box_exact |
0.000000 | 6 | 0.000001 | 7 | 1 |
sphere |
0.000000 | 6 | 0.000000 | 8 | 0 |
65³, k = 5. The reversal the experiment exists to show is total: thin_plate goes from 6th to 1st
and fbm_terrain from 1st to 3rd when the denominator changes from all grid edges to the edges that
carry the surface.
The registration's parenthetical is a premise defect and the entry quotes 6. C1 says "where the
all-edges rate ranked it eighth", inherited verbatim from ✗53's prose — "thin_plate has the
lowest non-monotonic fraction of the eight ... It ranks eighth." rank_all_edges for thin_plate is
6, on all 15 of its rows, at every resolution and every k. Five fields score strictly higher, so
the rank is 6; the two below it are sphere, which flags exactly 0 edges at every resolution, and
box_exact, which flags 1 edge of 811,200 at 65³. So the true statement is "last of the six fields
whose gradient turns anywhere in the volume", and eighth was never available. C1's predicate — the
ranking of rate_single_root — is what falsified_by names, and it held. The premise did not.
torus is the sharpest single illustration of the volume/surface distinction and the registration did
not name it. It ranks 4th of eight on the all-edges rate at every resolution — 408, 1,848 and 7,800
flagged edges at 17³, 33³, 65³ — and exactly 0.000000, tied last, on the single-root rate at 33³ and
65³. All 7,800 of its flagged edges at 65³ are off-surface. A metric that ranks the torus fourth for
under-resolution is measuring the field's interior, not its mesh.
C1's registered scope was exactly right, and the file shows why. At 17³ thin_plate is
rank_single_root = 2, behind noise_cavity at 0.535714, at k ∈ {3, 5, 9, 17}; it is rank 1 at
17³ only at k = 2. thin_plate's flagged count is k-independent (see the mechanism) while
noise_cavity's rises with k, so the coarsest grid is the one resolution where the ranking is decided
by the sample count rather than by the geometry. Registering C1 at 33³ and 65³ was not conservatism; at
17³ the clause would have been FALSIFIED.
C2 — the convergence criterion was declared in the bench before the run
Stated in experiment_p99.rs's doc comment, committed before the first run: a field converges at
fixed k when its rate_single_root sequence over 17³ → 33³ → 65³ is non-increasing; it fails to
converge when the sequence rises at either step. converges_strictly (strictly decreasing at both
steps) and rate_ever_nonzero are separate columns so that a field whose rate is identically zero is
not silently counted as evidence of convergence. An unstated criterion is not a clause, and a flat zero
is not a falling sequence.
| field | 17³ | 33³ | 65³ | converges |
converges_strictly |
rate_ever_nonzero |
|---|---|---|---|---|---|---|
thin_plate |
0.388889 | 0.441176 | 0.469697 | false |
false |
true |
noise_cavity |
0.535714 | 0.345278 | 0.136549 | true |
true |
true |
fbm_terrain |
0.296154 | 0.191768 | 0.086720 | true |
true |
true |
gyroid |
0.116667 | 0.051587 | 0.026888 | true |
true |
true |
csg_difference |
0.071429 | 0.030303 | 0.017465 | true |
true |
true |
torus |
0.048780 | 0.000000 | 0.000000 | true |
false |
true |
sphere |
0.000000 | 0.000000 | 0.000000 | true |
false |
false |
box_exact |
0.000000 | 0.000000 | 0.000000 | true |
false |
false |
k = 5, the k ✗53's quoted sequence comes from. thin_plate rises at both steps and reproduces
✗53's 0.3889 / 0.4412 / 0.4697 to six places, and the same 1-of-8 split holds at every k in the
sweep — converges = false occurs on exactly the five thin_plate rows and nowhere else.
The two columns that keep C2 honest are doing work. Four fields converge strictly. torus
converges non-strictly and rate_ever_nonzero = true, so its 0.048780 → 0 → 0 is a real fall.
sphere and box_exact converge at a flat zero: their denominators are real (single_root_edges
4,758 and 5,766 at 65³) and their numerators are 0, so "converges" is true of them and is not evidence
of anything falling. Without rate_ever_nonzero on the row, C2's "converges on the other seven" would
have been carried in part by two fields that never had a rate to reduce.
C3 — both halves asserted in the direction the predicate's form allows
k |
false negatives | false positives (non_monotonic_single_root) |
flagged, all edges | multi-root edges |
|---|---|---|---|---|
| 2 | 322 | 9,886 | 344,500 | 2,172 |
| 3 | 94 | 10,387 | 375,691 | 2,172 |
| 5 | 8 | 10,565 | 385,038 | 2,172 |
| 9 | 1 | 10,637 | 387,357 | 2,172 |
| 17 | 0 | 10,658 | 388,159 | 2,172 |
Summed over 8 fields × 3 resolutions. 322 / 94 / 8 / 1 / 0 matches ✗53's five numbers exactly.
false_positives and non_monotonic_single_root are identical on all 120 rows — they are the same count
under two registered names, written once from one field rather than measured twice. Per
(field, resolution), fn_non_increasing_with_k and fp_non_decreasing_with_k are true on all 120
rows.
✗53's C2 defect is corrected rather than repeated. It asked for a false-positive rate that falls
with k, which is mechanically impossible: adding a sample point can only add an opportunity for two
projections to disagree. The registered direction here is non-decreasing, and the measured rise is
+7.81% (9,886 → 10,658).
The instrument that could actually have caught a violation is flag_dropped_at_higher_k, and it is
stronger than the registered count check. Two totals can both move in the permitted direction while
individual edges swap in and out of the flagged set. The bench tracks the per-edge flag across all five
k and counts edges flagged at one k and unflagged at the next larger one; the column is 0 on all
120 rows. Set inclusion of the flagged sets implies the false-negative sets shrink edge by edge, which
is strictly stronger than the counts falling.
The honest scope of C3, said out loud: both directions are entailed by the sample grids being nested.
KS = {2, 3, 5, 9, 17} gives t = i/(k−1) with denominators 1, 2, 4, 8, 16, so every coarser sample set
is a bit-exact subset of the k = 17 set. What C3 tests is that the implementation is the predicate,
not a property of any field. To keep the direction falsifiable at all, the bench recomputes each k
independently instead of subsetting the k = 17 projections — 36 gradient evaluations per edge against
17, 2.1× the work, paid deliberately so that C3's second half is true by construction of the
predicate and not by construction of a helper. The content of C3 is its magnitudes: the whole
false-negative population lives on two fields, and it is noise_cavity's sub-cell gradient reversals
that 322 → 0 is measuring.
| field | 17³ | 33³ | 65³ | multi-root at 65³ |
|---|---|---|---|---|
noise_cavity |
160 / 52 / 5 / 1 / 0 | 95 / 28 / 2 / 0 / 0 | 30 / 6 / 1 / 0 / 0 | 698 |
fbm_terrain |
12 / 4 / 0 / 0 / 0 | 18 / 4 / 0 / 0 / 0 | 7 / 0 / 0 / 0 / 0 | 147 |
false_negatives at k = 2 / 3 / 5 / 9 / 17. No other field produces a false negative at any k.
csg_difference and gyroid have multi-root edges (48 and 114 at 65³) and the witness catches every one
of them at k = 2 already; thin_plate, sphere, box_exact and torus have multi_root_edges = 0
everywhere, so thin_plate — the field C1 and C2 are about — structurally cannot produce a false
negative in this file. At k = 2 the witness finds 1,850 of the 2,172 multi-root edges, 85.2%, from
the two grid corners the extractor has already sampled.
Mechanism — thin_plate's rate is a closed form, and the axis breakdown proves it
nm_single_root_axis_y carries 100% of thin_plate's flagged single-root edges at every resolution and
every k — 49 / 225 / 961, with nm_single_root_axis_x = nm_single_root_axis_z = 0. The plate is
a box with half-extents [1, 0.0125, 1] on [-2, 2]³ (ThinPlate::canonical,
THICKNESS_IN_CELLS = 0.4 at CANONICAL_CELL_SIZE = 0.0625); y is its thin axis. With m = interior
footprint columns = (n−3)/2 — 7, 15, 31 at n = 17, 33, 65:
$$\texttt{non_monotonic_single_root} = m^2, \qquad \texttt{single_root_edges} = 2m^2 + 4m, \qquad \texttt{rate_single_root} = \frac{m}{2m+4} = \frac{1}{2} - \frac{1}{m+2}$$
Measured against predicted: 49/126, 225/510, 961/2046 — exact at all three resolutions, to the integer.
Why: ThinPlate overrides gradient with the analytic box_gradient, whose interior branch is
g[j] = d[j].signum() for j = argmax q. The plate's mid-plane y = 0 is its medial axis, where the
distance gradient genuinely does not exist, and every registered resolution is odd so y = 0 is a sample
plane (M-266). There d[1] = +0.0 and f64::signum(+0.0) = 1.0, so the mid-plane is assigned +ŷ;
one cell below, the exterior branch gives −ŷ. The y-edge from y = −h to y = 0 therefore samples
projections (−1, +1) and is flagged at k = 2 already — which is why every thin_plate count in
the file is identical across all five k — while the edge from y = 0 to y = +h samples (+1, +1)
and is not. Exactly one flagged y-edge per interior column: m². The denominator adds the other m²
y-edges plus the 4m rim x/z-edges at y = 0.
That is the mechanism of C2's non-convergence, and it is structural rather than noisy: the numerator
is a two-dimensional sheet on the medial plane growing as m², and the only term diluting it is a
one-dimensional rim growing as m. Refinement dilutes the rim and never the sheet, so the rate rises
monotonically toward 1/2. h = 4/(n−1) = 0.0625 at 65³ against a 0.025-thick plate — the plate is
2.5× thinner than a cell at the finest resolution tested. [INFERENCE] the closed form holds while
y = 0 is the only sample plane touching the plate, i.e. while h > 0.0125, which is every odd
n < 321; at n = 321 the samples at y = ±h land exactly on the plate's faces. That is five
refinement levels above 65³, and it is the quantitative form of M-100. ✗53 listed "a thin_plate FP
rate that starts falling above 65³" among its own falsifiers; the formula says it cannot.
The other seven axis splits confirm the breakdown reads geometry rather than noise. fbm_terrain has
nm_single_root_axis_y = 0 at every resolution (391 x / 0 y / 358 z at 65³): it is a heightfield,
∂f/∂y ≡ 1, and a y-edge can never turn. csg_difference and gyroid are isotropic to the edge
(35/35/35 and 193/193/193 at 65³). noise_cavity is near-isotropic (1312/1340/1291).
Why the all-edges denominator ranked it sixth is the same arithmetic from the other side:
thin_plate's numerator is an m² sheet inside a 3(n−1)n² box, so rate_all_edges falls as
Θ(1/n) — 0.003532 → 0.002152 → 0.001185 — purely because the box grows faster than the plate's
surface. The all-edges rate is a volume statistic; the single-root rate is a surface statistic; the
numerator was never the problem.
The vacuity control, its value, and the caveat that ships with it
Column oracle_samples, value 128 on all 120 rows — ✗53's column, inherited, with
assert_eq!(ORACLE_SAMPLES, 128). Pinning the constant is the cheap half. The half that proves the
fixture could have failed is asserted before the artefact is written, and every one of these is a
VACUOUS: assertion in the bench rather than a sentence in this entry:
multi_root_edgessums to 2,172 atk = 5. At 128 intervals the oracle finds a non-empty population C3 can be wrong about; a zero here would make the false-negative sequence a row of zeros over an empty set.false_negativesat the coarsestk = 2is 322, non-zero. So the 0 atk = 17is a zero that could have been non-zero — and was, fourkearlier, on the same edges.M-44's rule satisfied by demonstration rather than by argument.single_root_edges > 0on every one of the 120 rows (minimum 126,thin_plateat 17³). C1's denominator is never empty, so no rate in the file isNaNand no rank is taken over a hole.flagged_non_monotonicis 385,038 of 7,436,928edgesatk = 5, leaving 7,051,890 unflagged. The witness can report both answers; one that flagged everything would make every rate 1 and every rank a tie, and one that flagged nothing could rank nothing.rank1_strict_single_root=true, asserted at 33³ and 65³ before the CSV exists — C1's "first" is not a tie.fp_moves_with_k=trueon 8 of the 24(field, resolution)pairs (fbm_terrain×3,noise_cavity×3,gyroidat 33³ and 65³) — C3's non-decreasing half is not satisfied by a constant.- At least one field converges with
rate_ever_nonzero=true(five do) — C2's "converges on the other seven" is not a statement about empty numerators.
The caveat, unresolved and unresolvable here. all_roots cannot see two roots closer together than
one interval, i.e. 1/128 of an edge. A root pair inside one interval is invisible to both
instruments: it cannot produce a false negative in this file, and it also cannot be ruled out. Every
false-negative count here, including the 0 at k = 17, is scoped to pairs the oracle can resolve. This
is a bound on the instrument, not a measurement of the world, and it is a recorded column rather than a
footnote for exactly that reason.
The deployable metric, which is the answer C1 could not give
rate_sign_change scores C1's numerator against sign_change_edges — edges whose endpoints straddle
the isosurface, which Marching Cubes already classifies for free — and it gives the identical ranking.
rank_sign_change equals rank_single_root on all 120 rows. The two denominators are equal on 18
of the 24 (field, resolution) pairs and differ only on noise_cavity (+18, +20, +6 at 17³, 33³, 65³)
and fbm_terrain (+5, +4, +1). The largest divergence anywhere in the file is 20 edges of 6,522, at
noise_cavity 33³, falling to 6 of 28,882 at 65³. thin_plate's rate_sign_change is 0.469697 at
65³, bit-identical to rate_single_root because it has no multi-root edge at all.
The difference has a closed reading, and it is oracle_parity_violations = 0 on all 120 rows that
licenses it: an endpoint sign change is equivalent to an odd root count, so
sign_change_edges − single_root_edges is exactly the count of edges with three or more roots. That
is 20 edges at noise_cavity 33³ and zero on six of the eight fields — the oracle-free denominator
over-counts by precisely the population the oracle exists to find, and that population is small enough
not to move a single rank.
What changed as a result
Nothing in crates/isomesh/src/**, and nothing should. This row measures a rate, surfaces the LOD
decision, and stops.
The decision, surfaced with the numbers behind it: the per-chunk signal is
flagged_non_monotonic / sign_change_edges at k = 2, not rate_single_root at k = 5. k = 2 is
the two grid corners the extractor has already sampled, it costs two gradient evaluations per straddling
edge and no oracle, and it gives the identical ranking — rank_sign_change = 1 for thin_plate at
33³ and 65³ at k = 2. What k = 2 buys less of is soundness, and its size is on the row:
false_negatives 322 at k = 2 against 8 at k = 5 and 0 at k = 17, i.e. 85.2% of the 2,172
multi-root edges still caught. For an LOD gate that is the right trade — the gate consumes a ranking,
and a 322-edge miss leaves the ranking intact at every resolution.
Do not build the version that consumes rate_single_root or false_negatives directly. Both need
all_roots — 129 field evaluations per edge, 811,200 edges at 65³ — and they are offline diagnostics,
for the reason ✗53 gave for one of them and missed for the other. Reported as a null in one
direction and a result in the other: C1's registered metric is not shippable, and the column beside it
is.
✗53 had the winning metric in its own artefact under a name that hid it. p-66.csv's
false_positive_rate column is rate_single_root — it reads 0.388889 / 0.441176 / 0.469697 on
thin_plate's k = 5 rows — while its non_monotonic_fraction column is rate_all_edges and its
thin_plate_ranks_first column reads false on all 120 rows. The reversal was in the file for a phase;
what was missing was a name that said which denominator each column used.
Five fixture defects, all caught by this harness's own controls rather than by review
- The registration's C1 premise is wrong by two ranks.
rank_all_edgesforthin_plateis 6 of 8, never 8, on all 15 of its rows. Caught by recording both rankings on every row instead of arguing the contrast in prose — which is what✗53did, and its "the lowest non-monotonic fraction of the eight" is the source of the error. The true statement is "last of the six fields whose gradient turns anywhere"; the two below aresphereat 0 flagged edges andbox_exactat 1 in 811,200. - The inherited claim that the single-root rate is the deployable candidate is wrong — its
denominator is defined by the oracle. Caught by writing the SHARE section before the code, and
answered by adding the four
sign_changecolumns rather than by a note. This is the finding that keepsM-121/M-72's ticket honest: C1 held and did not deliver the input it was registered to gate. - C1 would have been FALSIFIED had it been registered at 17³.
thin_plateisrank_single_root= 2 there atk∈ {3, 5, 9, 17} — rank 1 only atk= 2 — behindnoise_cavity's 0.535714 atk= 5. Caught by computing ranks at every resolution andkand recording them, rather than only at the two the clause names — so the file shows the clause's boundary instead of hiding it. thin_plate's entire flagged population depends on the fixture's grid alignment, and the field's own doc comment says why: the plate is centred aty = 0and every registered resolution is odd, so the medial plane is a sample plane (M-266). [INFERENCE] a half-cell shift removes the surface entirely at every level — the doc comment citeslod::tests::the_aliasing_is_alignment_and_a_half_cell_shift_removes_it— and would therefore remove the metric that ranks it first at the same time. Consistent, and it bounds the claim: the witness reports an under-resolved feature it can see, and cannot warn about one the grid misses outright. A shifted-plate arm is not registered and was not run.- A deliberate deviation from
P-66's code that does not move a number, checked rather than assumed. Every edge is axis-aligned, so∇f · êis the single componentg[axis];P-66normalised(h,0,0)and took a three-term dot product behind alen == 0.0guard for an input that cannot occur. Removing the division and the branch is bit-identical in sign classification, and the guard was a fallback for an impossible case. Verified rather than asserted: all 840 shared cells — 7 columns (edges,single_root_edges,multi_root_edges,flagged_non_monotonic,false_negatives,false_positives,oracle_samples) × 120 rows — are identical to the committedp-66.csvat16efbec, 0 mismatches.M-279's rule satisfied: a new instrument's first job is to agree with the old one where they overlap.
No clause was VACUOUS and none was BLOCKED. No clause names a second machine. oracle_parity_violations
and flag_dropped_at_higher_k are both 0 on all 120 rows, asserted after the CSV is written because
they are predicate results a reader needs the numbers to interpret, not vacuity gates.
Would be shown wrong by: thin_plate ranking below any field on rate_single_root at 33³ or 65³,
which would mean the denominator was not the problem and the whole witness family measures the volume; a
rate_single_root sequence that turns over on thin_plate below n = 321, which would break the m²
closed form and with it C2's mechanism; a second field failing to converge, which would make
non-convergence a property of the metric rather than of a sub-cell feature; a non-monotone
false_positives count or a non-zero flag_dropped_at_higher_k, either of which would mean the
implementation is not the predicate; or a resolution at which rank_sign_change diverges from
rank_single_root, which would withdraw the oracle-free denominator and leave the LOD signal offline
after all.
💥 ✗78 / M-412 — C1 HELD at 48 of 48 with worst_component_ulp 0, C3 HELD at 0 open edges, C2 FALSIFIED on both halves on 16 of 16 rows: M-372's obstruction is real and it is in the decomposition, because a 24-tetrahedron barycentric split reaches full octahedral equivariance bit-exactly where the six-tet split is stuck at 12 — and removing it costs 2.4405× the six-tet split and 7.9353× Marching Cubes against registered bars of 2× and 6× (P-100, R-100)
M. cargo bench --bench experiment_p100, docs/experiments/p-100.csv, 80 rows, f64,
amd-ryzen-9-5900x-12-core. Five decomposition arms × eight reference fields × {33³, 25³}, each
arm driven through one copy of P-61's equivariance instrument — all 48 signed axis permutations
applied to P-61's two unchanged fixtures on the fields' own symmetric domain cube, 3,840
extractions in all. Committed at # commit bd8b134 with no (WORKING TREE DIRTY); bd8b134
is an ancestor of HEAD (e70f2e7).
Re-run on a clean tree, and the original report's provenance note is superseded. That report closed with "the CSV provenance line reads
commit 63c7161 (WORKING TREE DIRTY)" and predicted the integers and exact ratios would reproduce. They did, without exception: everyelements_vertex_exact, everyworst_component_ulp, all sixteen triangle triples, every degenerate and non-degenerate count, every seam column. Three things in that report do not survive contact with the committed file and are withdrawn here. (i)elements_triangle_exactforbarycentric_24was reported as "6 on 13 rows"; the file reads 6 on 14 rows, 12 onthin_plate/33³ and 48 onbox_exact/33³ — 13 + 1 + 1 = 15 and the arm has 16 rows, so this was an arithmetic slip rather than a run move. (ii) The run wall time "~2m01s on the Zen 3 / RTX 3090 rig" is not in any committed column and is withdrawn; the file's ownwall_msruns 11–3,058 ms per row, 32,403 ms summed, covers only the 48-element equivariance measurement, and is read by no clause. (iii) The GPU in that sentence is irrelevant — this experiment is scalarf64on the CPU throughout. No verdict moved. Every number quoted below is either a column ofp-100.csvor arithmetic shown from its columns, and every ratio is taken between integers of a single(field, resolution)row, soM-280andM-281do not reach it.
| clause | registered | measured |
|---|---|---|
C1 barycentric_24 reaches 48 of 48 where the six-tet split reaches 12 |
48 on all 16 rows | HELD — elements_vertex_exact = 48 on 16 of 16, worst_component_ulp = 0 on 16 of 16, vertex_failing_labels empty on 16 of 16, first_failing_element = none on 16 of 16. Side by side in the same instrument and the same run: both six-tet arms 12 on 32 of 32, marching_cubes 48 on 16 of 16 |
| C2 at most 2× the six-tet split, and the combined penalty under 6× | ≤ 2.0 and ≤ 6.0 | FALSIFIED on both halves, 16 of 16 rows each. triangles_vs_six_tet 2.3505–2.7264, mean 2.4405. triangles_vs_marching_cubes 6.1912–10.5579, mean 7.9353. Smallest margin against the looser of the two applicable bars is 1.1801× |
| C3 still tiles across chunk seams with zero open edges | 0 | HELD — open_edges = 0 on 80 of 80, c3_open_edges_total = 0, with the mismatched-diagonal control reading 80–3,765 on the same 80 rows |
c2_holdsreadsfalseon all 80 rows, and 64 of them are not being accused of anything. It is a run aggregate stamped onto every row, computed once fromc2_worst_ratio_six_tet(2.726437) andc2_worst_ratio_marching_cubes(10.557864) — both maxima taken over thebarycentric_24arm alone. Sofalsesits besidemarching_cubesrows whose owntriangles_vs_marching_cubesis1.000000andsix_tet_craterows whose owntriangles_vs_six_tetis1.000000.c1_holdsandc3_holdsreadtrueon all 80 for the same structural reason, not becausemarching_cubeswas scored on C1.
The measurement, and it is sixteen integer triples:
| field | n | marching_cubes |
six-tet | barycentric_24 |
6/MC | b24/6 | b24/MC | haus 6-tet | haus b24 |
|---|---|---|---|---|---|---|---|---|---|
sphere |
33 | 2,312 | 7,032 | 17,040 | 3.0415 | 2.4232 | 7.3702 | 0.005510930 | 0.004105556 |
sphere |
25 | 1,064 | 3,168 | 7,536 | 2.9774 | 2.3788 | 7.0827 | 0.011585054 | 0.008878386 |
torus |
33 | 2,256 | 6,848 | 16,096 | 3.0355 | 2.3505 | 7.1348 | 0.019014098 | 0.008980723 |
torus |
25 | 912 | 2,904 | 7,200 | 3.1842 | 2.4793 | 7.8947 | 0.033755986 | 0.020707873 |
box_exact |
33 | 2,696 | 10,440 | 28,464 | 3.8724 | 2.7264 | 10.5579 | 0.102062073 | 0.000000000 |
box_exact |
25 | 1,448 | 5,544 | 13,488 | 3.8287 | 2.4329 | 9.3149 | 0.044194174 | 0.034429552 |
csg_difference |
33 | 2,768 | 10,572 | 27,924 | 3.8194 | 2.6413 | 10.0882 | 0.102062073 | 0.054373556 |
csg_difference |
25 | 1,496 | 5,604 | 13,344 | 3.7460 | 2.3812 | 8.9198 | 0.083064754 | 0.080049958 |
thin_plate |
33 | 1,016 | 3,832 | 9,488 | 3.7717 | 2.4760 | 9.3386 | 0.089267855 | 0.012490879 |
thin_plate |
25 | 568 | 2,104 | 5,008 | 3.7042 | 2.3802 | 8.8169 | 0.076335391 | 0.074109953 |
gyroid |
33 | 10,632 | 30,492 | 72,648 | 2.8679 | 2.3825 | 6.8330 | 0.361561125 | 0.340314162 |
gyroid |
25 | 4,608 | 12,984 | 31,392 | 2.8177 | 2.4177 | 6.8125 | 0.694706520 | 0.738667548 |
fbm_terrain |
33 | 3,946 | 11,544 | 27,466 | 2.9255 | 2.3792 | 6.9605 | 0.321452719 | 0.267772593 |
fbm_terrain |
25 | 2,122 | 6,324 | 14,926 | 2.9802 | 2.3602 | 7.0339 | 0.484227260 | 0.494777106 |
noise_cavity |
33 | 13,236 | 35,832 | 87,556 | 2.7072 | 2.4435 | 6.6150 | 1.096310418 | 0.709508532 |
noise_cavity |
25 | 5,188 | 13,408 | 32,120 | 2.5844 | 2.3956 | 6.1912 | 1.007580940 | 1.180559480 |
Vertex counts move by the same factor — vertices b24/6-tet is 2.3236–2.7258 against the
triangle range 2.3505–2.7264 — so C2's falsification is a genuinely finer contour and not a
fanning artefact of the triangle count. And the 24-tet split does buy geometry for the price:
symmetric Hausdorff is lower on 13 of 16 rows (−25.5% sphere/33³, −52.8% torus/33³, −86.0%
thin_plate/33³, and exactly 0 on box_exact/33³) and higher on 3 — gyroid/25³ +6.3%,
fbm_terrain/25³ +2.2%, noise_cavity/25³ +17.2%, the coarse-grid noise fields, where
interpolated points inside a cell fabricate detail the samples do not support.
The SHARE recomputation, said out loud, and it found a hidden dependency that tightens the
clause. The registration's SHARE line reads "C2 is a triangle count, compared against M-51's
already-measured baseline", and the recomputation below was done before this harness was
written.
First half — reachable, and bracketed by arithmetic alone. triangles_vs_six_tet is a ratio of
two directly measured integer counts, not a fraction of a whole, so ✗51's unreachable-share
failure mode does not apply. The absolute ceiling is derivable with no run at all: a tetrahedron
with one or two corners inside contributes at most 2 triangles, so 24 tetrahedra cap at 48
triangles per cell against the six-tet split's cap of 12 — a hard 4× bound, with a floor
of 1×. The registered 2.0 sits strictly inside [1, 4] and could have gone either way. Measured
2.3505–2.7264, in the upper middle of that bracket.
Second half — reachable, but not independent, and it silently tightens the first. The two halves are the same measurement:
b24/MC = (b24/6tet) × (6tet/MC) exactly, in integers: 17040/7032 × 7032/2312 = 17040/2312
So C2 has one degree of freedom, not two, and the 6× combined bar is a bar on b24/6tet of
6/(6tet/MC). This run measures 6tet/MC rather than assuming M-51's ~3×: mean 3.2415
over 16 rows, range 2.5844 (noise_cavity/25³) to 3.8724 (box_exact/33³). Substituting
the mean, the combined bar is a bar of 6 / 3.2415 = 1.8510 on b24/6tet — 7.5% tighter than
C2's own stated 2.0, so the clause's binding bar is not the one it states.
And here is the piece arithmetic could not reach before the run. 6/x = 2.0 at exactly
x = 3.0, which is M-51's figure to its own stated precision — so which of the two bars binds was
undecidable in advance. Measured per row:
6tet/MC |
derived bar 6/(6tet/MC) on b24/6tet |
rows | binding bar |
|---|---|---|---|
> 3.0 — sphere/33³, torus both, box_exact both, csg_difference both, thin_plate both |
1.5494–1.9766 | 9 | the combined 6×, tighter than 2.0 |
< 3.0 — sphere/25³, gyroid both, fbm_terrain both, noise_cavity both |
2.0133–2.3216 | 7 | the stated 2.0 |
Every row exceeds whichever bar binds it, and the smallest margin is 1.1801×
(fbm_terrain/25³ against 2.0); the largest is 1.7596× (box_exact/33³ against 1.5494). Not
marginal on any row.
And measuring 6tet/MC reproduces M-51 independently, which is the corroboration that makes
the falsification readable rather than a lone number:
| field | M-51 |
here at 33³ | Δ |
|---|---|---|---|
sphere |
3.04× | 3.0415 | +0.1% |
torus |
3.04× | 3.0355 | −0.1% |
box_exact |
3.91× | 3.8724 | −1.0% |
csg_difference |
3.83× | 3.8194 | −0.3% |
thin_plate |
3.84× | 3.7717 | −1.8% |
gyroid |
2.87× | 2.8679 | −0.1% |
fbm_terrain |
2.87× | 2.9255 | +1.9% |
Seven of seven within 1.9%, from a different marcher in a different bench. noise_cavity is the
eighth field and has no M-51 counterpart; it reads 2.7072 and 2.5844.
A robustness check on C2, because two rows carry a large degenerate-sliver mass that predates
this ticket. box_exact/33³ and csg_difference/33³ are 72.41% (7,560 of 10,440) and
61.24% (6,474 of 10,572) zero-area triangles in the shipped six-tet extractor by
validate::accuracy's area epsilon, and 78.41% (22,320 of 28,464) and 68.84% (19,224 of 27,924)
in the 24-tet arm. Every other row is under 3%. Recomputing the ratio on accuracy_triangles —
non-degenerate triangles only:
| reading | b24/6tet |
above 2.0 | b24/MC |
above 6.0 |
|---|---|---|---|---|
raw triangles |
2.3505–2.7264, mean 2.4405 | 16/16 | 6.1912–10.5579, mean 7.9353 | 16/16 |
non-degenerate accuracy_triangles |
2.1230–2.4860, mean 2.3706 | 16/16 | 2.2789–9.3149, mean 6.9611 | 14/16 |
The falsification does not depend on which count is used — that is worth stating as such,
because it is the one thing that could have made C2 an artefact of a pre-existing crate defect
rather than a property of the decomposition. The first half fails on 16 of 16 rows on both
readings. The combined bar survives on exactly 2 of 16 rows under the non-degenerate reading,
and those two rows are precisely the two whose denominator is mostly slivers: box_exact/33³
(2.2789) and csg_difference/33³ (3.1431). On those rows 6tet/MC collapses from 3.8724 raw to
1.0682 non-degenerate, which is the whole of the effect — the six-tet arm's inflated raw count
is the slivers.
Mechanism — why the six-tet split is stuck at 12, checked element by element rather than
counted. All six Kuhn tetrahedra contain the cell's main diagonal 0–7, which runs along
(1,1,1); a signed axis permutation maps that direction to itself exactly when all three signs
agree, so the stabiliser is (6 permutations) × (+++, −−−) = 12, and with four body diagonals
48/4 = 12. The harness checks that the exactly-reproducing set is that subgroup:
exact_are_diagonal_stabiliser is true on 32 of 32 six-tet rows, first_failing_element is
perm=012;sign=-++ — the bare x-reflection, the cheapest element that moves the diagonal — and
the 36 entries of vertex_failing_labels are exactly the six non-uniform sign patterns
{-++, +-+, --+, ++-, -+-, +--} crossed with the six permutations, read straight off the column.
Their worst_component_ulp is 9.2135e18–9.2425e18: the relabelled vertex set is a different
set, not a near miss.
Mechanism — why the 24-tet split has nothing to move, and the two things that had to be true for
bit-exactness. Each tetrahedron is (cell centre, face centre, two adjacent corners of that
face); an octahedral element sends a face to a face and a face edge to a face edge, and the
stabiliser of one tetrahedron is the order-2 reflection swapping its two cube corners, so
48/2 = 24 is a single orbit and the construction never names an axis order or a diagonal. Two
further conditions are load-bearing and both are in the bench: (i) the face-centre and
cell-centre values are means summed in sorted order (f64::total_cmp), because floating
addition is commutative and not associative — a fixed corner order would have leaked the axis
labelling into the value and falsified C1 by the averaging rather than by the decomposition;
(ii) the crossing is R-059's centred offset ((a+b)/2)/(a−b), which P-61 showed is
invariant under swapping the edge endpoints, so the marcher never has to canonicalise which end of
a tetrahedron edge comes first. The result is worst_component_ulp 0, not "close".
six_tet_bench is what makes this a statement about the decomposition. It runs the identical case
classification, quad ordering, crossing placement and vertex cache as barycentric_24 and differs
only in the tetrahedron list — and it reproduces the shipped crate's triangle count exactly on
all 16 rows (7,032/7,032, 10,440/10,440, 35,832/35,832 …) while reading 12. So the 48 cannot be an
artefact of the new marcher.
Mechanism — C3, and it is stronger than the clause. seam_mesh_identical is true on 80 of
80 rows: the two-chunk mesh is the same triangle-key multiset as the single pass over the union
grid, not merely closed. Kuhn tiles across a seam only because every cell picks the same main
diagonal — a convention two chunks must agree on. The 24-tet split has no convention to agree on:
a shared face is cut into four triangles by its own centre, identically from both sides, and that
centre's averaged value is the mean of the same four corner values whichever cell asks.
seam_coords_exact is true on 80 of 80, so M-32's chunk-origin arithmetic is not silently
supplying the zero, and seam_configurations is 5 (fbm_terrain) to 14 (noise_cavity), so the
shared plane genuinely carried distinct cut sign patterns.
The vacuity control, the registered one, and it reads a file rather than a comment.
| control | column | value | why the value proves the fixture could have failed |
|---|---|---|---|
REGISTERED — the six-tet arm reproduces p-61.csv's flat 12 of 48 before the 24-tet arm is believed |
elements_vertex_exact beside elements_vertex_exact_p61, cut_edges_p61, triangles_p61, p61_columns_match; aggregates vacuity_six_tet_rows_at_12, vacuity_mc_rows_at_48 |
12 on 32 of 32 six-tet rows; 48 on 16 of 16 marching_cubes rows; p61_columns_match true on 80 of 80 |
The 12 is parsed out of the committed docs/experiments/p-61.csv by p61_baseline() — 112 equivariance rows — and asserted per row, not typed into a comment. That is P-70's discipline: the number the vacuity control turns on is a number in a file the harness opens. Four columns are asserted per baseline row, and two of them (cut_edges, order_sensitive_edges) are properties of the grid and the field values that no extractor touches, so a mismatch would mean this is not P-61's instrument at all. The bracket is what makes C1 meaningful: an instrument that always said 48 would make C1 empty and one that could never say 48 would make it unreachable, and here one instrument, one run, one set of 16 fixtures reads 12 for one decomposition and 48 for two others. Both counts are assert_eq!, so the run cannot finish without them. |
| C3's positive arm — the mismatched-diagonal seam | seam_control_open_edges |
80 (torus/25³) to 3,765 (box_exact/33³), ≥ 80 on every one of the 80 rows, asserted > 0 |
Chunk B is re-marched with Kuhn's six anchored on corner 2, which splits every x-face on 2–4 instead of 0–6, so the two chunks disagree about the diagonal of their shared face — P-3's crack. The counter demonstrably reports a crack, which is the only thing that makes open_edges = 0 a measurement rather than an M-44 pass. |
| the open-edge census can be non-zero on real geometry | boundary_open_edges |
0 to 4,410 (box_exact/33³; csg_difference/33³ 3,933, fbm_terrain/33³ 454) |
The single-pass mesh's own unpaired edges — the open surfaces' domain boundary. Non-zero on the open fields proves the census counts edges rather than returning an empty map, and subtracting this set is exactly what stops gyroid's and fbm_terrain's boundary being read as a seam crack. |
| the exact-zero Hausdorff is not a zero over an empty set | hausdorff_mesh_to_field, hausdorff_field_to_mesh, accuracy_forward_samples, accuracy_reverse_samples, accuracy_triangles, accuracy_degenerate_triangles |
box_exact/33³ barycentric_24 reads hausdorff 0.000000000 with 13,448 forward and 4,450 reverse samples and 6,144 + 22,320 = 28,464 triangles accounted for, i.e. the whole mesh |
Both directions of the symmetric distance are asserted non-empty and the accuracy report's triangle accounting is asserted equal to the mesh's, so the zero is a real exactness result on the axis-aligned box — the cell centre and face centres let an axis-aligned face be reproduced exactly, which no other arm here does. M-44 applied to a column the registration names but does not gate. |
| identity element | asserted, not recorded | element 0 must reproduce the reference bit-exactly on all 80 rows | P-61's own control. A non-deterministic arm would make its row measure nothing. |
fixture_can_failreadsfalseon 2 of 16 fixtures —box_exactat both resolutions,order_sensitive_edges= 0 — and that is not C1 scoring itself on a fixture that cannot fail. That column isP-61's question about the crossing formula: whether any cut edge has endpoints a relabelling would swap. It is silent about the decomposition, and the six-tet arm reads 12 on both of those rows — so the fixture demonstrably discriminates decompositions there even with no order-sensitive edge in it. Over the 14 rows that do carry one (24–643 each), C1 is 14 of 14. The samefalseappears onbox_exact's rows inp-61.csv, which is one more way the two instruments agree.
elements_vertex_exact_p61,cut_edges_p61andtriangles_p61are blank on 48 of 80 rows, and blank is not a failure.p-61.csvhas no counterpart forsix_tet_benchor for either 24-tet arm, so those rows carry no baseline andp61_columns_matchdefaults totruefor them. The 32 rows that do carry a baseline — 16marching_cubesand 16six_tet_crate— all match on all four asserted columns.
Four fixture defects, every one caught by this harness's own controls rather than by review.
- C3's positive control was a fixture that could not fail, and the run aborted rather than
record a vacuous HELD. Its first version gave chunk B Kuhn's six anchored on corner 1 and
reported zero open edges —
M-44exactly. The diagnosis is worth keeping: Kuhn's diagonal on the face normal to axisajoins the face corner where the other two axes both carry the anchor's bits to the corner where both are flipped, so it depends only on the anchor's bits on those two axes.anchor = 1differs fromanchor = 0onxalone, so both split everyx-face on0–6/1–7and tile across anx-seam perfectly — they differ only inside the cell. Anx-seam needs an anchor whoseyorzbit differs, andanchor = 2splits everyx-face on2–4/3–5. Fixed, and the premise is now asserted structurally inmain()—diagonal(0) == [0,6],diagonal(1) == [0,6],diagonal(2) == [2,4]— so the control cannot silently go vacuous again. This narrowsP-3: "Kuhn tiles face-to-face only if every cell picks the same main diagonal" is true and not tight.anchor = 1picks the1–6diagonal, not0–7, and still tiles face-to-face alongx; by the rule above, so doesanchor = 7on all six faces. - A zero in a registered column had no provenance.
box_exact/33³barycentric_24reportshausdorffexactly0.000000000. Six accuracy-provenance columns and two asserts were added — both distance directions non-empty, andaccuracy's triangle accounting equal to the mesh's triangle count — after which the zero survives as a real exactness result rather than an empty measurement. Found on the second run; the committed file is the third and carries the columns. - A pre-existing crate artefact surfaced, and it is the reason the robustness check above
exists.
box_exact/33³ andcsg_difference/33³ are 72.41% and 61.24% zero-area triangles in the shipped six-tet extractor, against under 3% on every other row. That is a property of the crate at 33³ on axis-aligned fields, not of this ticket, and it is worth an id of its own: 7,560 zero-area triangles per chunk is index-buffer and vertex-shader cost a game pays for nothing. - The registration's name for the decomposition is ambiguous and the harness resolves it by the number. Kuhn/Freudenthal of a cube is six tetrahedra — the crate already ships it — and the full barycentric subdivision of a cube is forty-eight flag simplices. The invariant decomposition with exactly 24 is cell centre + face centre + face edge, and that is what was built and what the bench asserts structurally before anything is meshed (24 distinct tetrahedra, each coned to the centre slot, each with two cube corners differing in exactly one bit).
Measured and not scored: triangle-level equivariance did not come with C1's vertex-level
result. elements_triangle_exact for barycentric_24 is 6 of 48 on 14 rows, 12 on
thin_plate/33³ and 48 on box_exact/33³. This is not a registered clause, and marching_cubes
scores 1, 2 or 4 of 48 on the same column on its own 16 rows, so it is not a regression
against anything. The cause is local and cheap: the two-inside quad's fan starts at the
lowest-indexed cut edge, which is an axis-label-dependent choice, and a fan anchored on the
lexicographically smallest vertex-position bits would be label-free. Naming it as a follow-on
with its own id, not as a result of this one. (The column is also not comparable to p-61.csv's
column of the same name and is not asserted against it: triangle_keys here uses unordered
vertex-key triples, because half the octahedral group is a reflection and reverses winding, so an
ordered key would report at least 24 failures on a perfectly equivariant extractor.)
What changed as a result. Invariance is reachable by changing the decomposition rather than
the placement rule, and it prices out for a game. M-372's diagnosis is confirmed at the level
of the mechanism and its "no placement rule reaches that" is now correctly bounded: no placement
rule, but a different decomposition does — exactly, bit for bit, on all eight fields at both
resolutions. It costs 2.4405× the six-tet split's triangles on the mean, 2.7264× at worst, and
7.9353× / 10.5579× against Marching Cubes, against registered bars of 2× and 6×, and the
falsification survives the non-degenerate recomputation. A game would pay roughly eight triangles
for every one Marching Cubes emits to gain a property no player can see, so this is not built as
a shipping extractor — it stays a CAD-only option. No source change: crates/isomesh/src/**
was not touched and the 24-tet split lives only in the bench, which is also where the one-path
rule puts it — a second extractor with a second decomposition is the two-paths defect the crate
forbids, and 8× the triangles buys no exception. What is worth keeping at zero shipping cost is
the oracle: a decomposition with 48 independent bit-exact relations per fixture where the
shipped tetrahedral extractor has 12, on the extractor family whose reason for existing in this
crate is to be the topological reference, plus the only arm in the run that reproduces an
axis-aligned box exactly.
Would be shown wrong by: a barycentric_24 row under 48 on a fixture carrying an
order-sensitive edge, which would put the obstruction back in the marcher and re-open M-372; a
decomposition that is octahedrally invariant and costs under 2× the six-tet split, which would
re-open the price rather than the principle; a non-zero open_edges at a seam while
seam_control_open_edges still fires, which would kill C3 regardless of C1; or a fix to the
crate's degenerate-sliver output on axis-aligned fields, which would move box_exact/33³ and
csg_difference/33³ — their non-degenerate combined ratios already sit at 2.2789 and 3.1431 — and
would require C2's second half to be re-read on those two rows, though its first half fails
there at 2.1333 and 2.1230 either way.
💥 ✗79 / M-413 — C1 FALSIFIED at 3 of 16 and worse than shipped on 9 of them, C3 FALSIFIED by the two duals agreeing on 64 of 64 row-pairs, C2 HELD at a stated cost of 40 of 48 golden dual hashes: the registered key reorders a reduction A-016 already made invariant, and the one reduction that is not invariant is vec3::length — changing only that takes both duals to pure_permutation_exact 6 of 6 on 32 of 32 rows (P-101, R-101)
Ids needed, not invented. C1 and C3 are falsified, so this is 💥 and takes the next
✗after✗55. It also carries substantial measured material that no clause asked for — the obstruction is located, not merely argued — so it is dual-numbered on the✗52 / M-376precedent and also takes the nextM-afterM-384. Both placeholders above are for the file's owner to resolve.
M. cargo bench --bench experiment_p101, docs/experiments/p-101.csv, 320 rows, f64,
amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 320 data rows
across 76 columns — counted from the file, not from the brief. Two blocks: equivariance (128 rows —
eight fields × {25³, 33³} × two duals × four arms, each row one 48-element octahedral measurement on
P-57's mirror-closed grids reached through P-61, with the 25³ arm at 3L/32 because L/12 is not
dyadic and its grid does not mirror) and golden (192 rows — eight fields × {17³, 25³, 33³} × two duals ×
four arms, each row one extraction scored against the committed crates/isomesh/golden_hashes.json). The
shipped extractor is the fifth arm and rides on every row in the *_baseline columns. Committed at
fa17a34 — # commit fa17a34 on amd-ryzen-9-5900x-12-core at 2026-08-28T01:27:23Z, no
(WORKING TREE DIRTY), and git merge-base --is-ancestor fa17a34 HEAD passes (HEAD is e70f2e7,
p-101.csv - re-run on a clean tree).
| clause | registered | measured |
|---|---|---|
C1 the key order takes dual_contouring to 48 of 48 on ≥ 12 of 16 rows |
≥ 12 | FALSIFIED — c1_rows_at_48 = 3 of c1_population = 16, identical to baseline_rows_at_48_dual_contouring = 3, and strictly worse on 9 of 16 rows, better on none |
| C2 it is free: no golden hash moves except through the accumulation order, Hausdorff unchanged to 1e-12 | ≤ 1e-12 | HELD — hashes_moved 40 = hashes_moved_expected 40, max_hausdorff_delta 3.008704396734e-14, golden_counts_changed 0, topology_identical true on 320 of 320 |
C3 manifold_dual_contouring does worse than dual_contouring |
strictly worse | FALSIFIED — c3_rows_at_48_manifold = 3 = c1_rows_at_48 = 3; the two agree on elements_vertex_exact, pure_permutation_exact and pure_sign_flip_exact on 64 of 64 row-pairs (16 rows × 4 arms) |
c3_holdsreadsfalsebecause the two duals matched, which the registration itself names as "a stronger result". Nothing about thatfalsemeans the manifold path is worse, broken, or unmeasured — it means the cycle partition is already relabelling-invariant. And it is invariant rather than inert: under the registered arm the two extractors' vertex counts differ on 6 of 16 rows (gyroid33³ 5,240 against 5,268;noise_cavity33³ 6,176 against 6,426; alsogyroid25³,fbm_terrain33³/25³,noise_cavity25³), soCycleQefis actively splitting vertices and the equivariance counts coincide anyway.
share_reachable_before_runreadsfalse_the_accumulation_is_already_invarianton all 320 rows. That column is not a failure of anything. It is the harness's own pre-run verdict on C1, recorded in the artefact — see SHARE below.
bit_identical_to_shippedreadsfalseon 64 of the registered arm's 80 rows. That is the change under test being visible, not a defect: it readstrueon all 80 rows of theedge_slotreplica arm, which is the instrument check.
C1, per row — the 16 rows the clause is scored on
block = equivariance, accumulation_key = abs_value_abs_offset, extractor = dual_contouring. Every
elements_vertex_exact_baseline is asserted equal to docs/experiments/p-61.csv's own value
(baseline_matches_p61 true on 320 of 320); I re-checked all 128 of those comparisons against p-61.csv
independently and found 0 mismatches.
| field / res | shipped evx | arm evx | shipped perm | arm perm | sign flip (both) | positions moved | key ties | unbreakable |
|---|---|---|---|---|---|---|---|---|
sphere 33³ |
2 | 1 | 2 | 1 | 1 | 972 | 23,128 | 21,560 |
sphere 25³ |
2 | 1 | 2 | 1 | 1 | 416 | 17,248 | 17,248 |
torus 33³ |
2 | 2 | 2 | 2 | 1 | 816 | 6,664 | 4,440 |
torus 25³ |
4 | 2 | 4 | 2 | 1 | 340 | 3,136 | 2,940 |
box_exact 33³ |
48 | 48 | 6 | 6 | 8 | 0 | 198,352 | 25,480 |
box_exact 25³ |
48 | 48 | 6 | 6 | 8 | 0 | 106,624 | 18,424 |
csg_difference 33³ |
2 | 1 | 2 | 1 | 1 | 163 | 168,070 | 24,553 |
csg_difference 25³ |
2 | 1 | 2 | 1 | 1 | 90 | 92,953 | 17,807 |
thin_plate 33³ |
48 | 48 | 6 | 6 | 8 | 0 | 68,992 | 3,136 |
thin_plate 25³ |
24 | 24 | 6 | 6 | 4 | 0 | 37,632 | 2,352 |
gyroid 33³ |
2 | 1 | 2 | 1 | 1 | 3,687 | 17,591 | 13,283 |
gyroid 25³ |
2 | 1 | 2 | 1 | 1 | 1,565 | 11,907 | 9,533 |
fbm_terrain 33³ |
4 | 4 | 2 | 2 | 2 | 1,233 | 0 | 0 |
fbm_terrain 25³ |
2 | 2 | 2 | 2 | 1 | 670 | 0 | 0 |
noise_cavity 33³ |
2 | 1 | 2 | 1 | 1 | 3,691 | 22,981 | 16,178 |
noise_cavity 25³ |
2 | 1 | 2 | 1 | 1 | 1,362 | 13,426 | 10,273 |
The three tallies the clause needs, taken row by row against the same row's own baseline column:
| quantity | worse | same | better |
|---|---|---|---|
elements_vertex_exact vs elements_vertex_exact_baseline |
9 | 7 | 0 |
pure_permutation_exact vs pure_permutation_exact_baseline |
9 | 7 | 0 |
pure_sign_flip_exact vs pure_sign_flip_exact_baseline |
0 | 16 | 0 |
Nine of sixteen is more than half the rows, and nothing improves. elements_tested is 48 on every
equivariance row, so no row is short of the full group.
The distribution shift. elements_vertex_exact over the 16 rows goes
{2: 10 rows, 4: 2, 24: 1, 48: 3} → {1: 8, 2: 3, 4: 1, 24: 1, 48: 3}. The shipped minimum is 2; the
arm invents a bucket at 1 and puts eight rows in it. pure_permutation_exact goes
{2: 11, 4: 1, 6: 4} → {1: 8, 2: 4, 6: 4}. Sign flips do not move at all: {1: 11, 2: 1, 4: 1, 8: 3}
before and after.
The fields that fall all the way to the identity alone — elements_vertex_exact = 1, i.e. 1 of 48
octahedral elements exact, and 1 of 6 permutations, and 1 of 8 sign patterns: sphere, csg_difference,
gyroid and noise_cavity, at both 33³ and 25³ — eight rows. Each of those had the x↔y swap before
and loses it. torus 25³ falls 4 → 2 without reaching the identity. The identity is never lost: the
harness asserts the identity element vertex- and triangle-exact on all 128 equivariance measurements, and
elements_triangle_exact is ≥ 1 everywhere.
The exact set is always a product subgroup, which is what licenses scoring the two halves separately.
elements_vertex_exact == pure_permutation_exact × pure_sign_flip_exact on all 128 equivariance rows
and on all 128 baseline triples — 1 = 1×1, 48 = 6×8, 24 = 6×4, 12 = 6×2, 6 = 6×1, 4 = 2×2, 3 = 3×1. So
"the relabelling half" and "the negation half" are not a rhetorical split; they are separable factors in
every row of the file.
SHARE, recomputed — and it is a source audit, not an arithmetic one
✗51's rule is that a clause denominated in a fraction of a total must name the share of that total it can
move. C1 is not a ratio — it is a count of rows — so the 1/(1 − share/factor) form does not apply. What
does apply is the prior question the rule is really about: of the reductions this change can reach, how
many are the ones that break the property? The answer is 0 of 1, and it is decidable by reading
crates/isomesh/src/ before running anything.
Walk every reduction on the path from a cell's eight corner samples to its dual vertex:
| step | where | axis-index-ordered? |
|---|---|---|
| corner sampling | the field | no — one call per corner, no reduction |
cube::is_inside |
cube.rs:171 — value < R::ZERO |
no — a sign test, no arithmetic at all |
cube::edge_offset |
cube.rs:222 — ((a + b) * HALF) / (a - b) |
no — exactly antisymmetric under the simultaneous endpoint-and-sign swap, by P-61's four IEEE guarantees: fl(a+b) = fl(b+a); halving by a power of two is exact; fl(b−a) = −fl(a−b) because round-to-nearest is odd; fl(S/−D) = −fl(S/D) for the same reason |
cube::place, the cell origin |
cube.rs:233 — (lo + hi) * HALF + (hi − lo) * d, applied per axis in hermite.rs:96-100 |
no — componentwise; axis k of the output reads only axis k of the input |
Sdf::gradient |
the field | no — the rotated wrapper is g·∇f(g⁻¹p), so a permuted-and-signed input yields the permuted-and-signed gradient exactly |
vec3::length(gradient) |
hermite.rs:103 → vec3.rs:46 → vec3.rs:41 → vec3.rs:27-29 |
YES. length is length_squared(a).sqrt(), length_squared(a) is dot(a, a), and dot's body is the single line a[0] * b[0] + a[1] * b[1] + a[2] * b[2] — a three-term sum evaluated left to right in axis-index order. This is the whole survivor. |
HermiteCell::centroid |
hermite.rs:225-236 — [[R; EDGE_COUNT]; 3], then axes.map(sum_equivariant) |
no — twelve slots per axis, absent edges at R::ZERO, reduced by A-016's magnitude sort with M-175's signed-value tie-break; M-176 establishes the zero padding is transparent, negative zero included |
solve_with's AᵀA and g |
dual_contouring/solve.rs:289-298 — m_terms.map(sum_equivariant), g_terms.map(sum_equivariant) |
no — twelve slots per matrix entry and per gradient component, same reduction (A-016) |
determinant, adjugate, mul_vec |
solve.rs:215-220, 228-230 — mul_equivariant and dot_equivariant |
no — magnitude-ordered (M-24, which is the entry that established the determinant needed the same treatment as the dot) |
apply_clamp (Clamp::ToCell) |
dual_contouring.rs:192-201 — per-axis slot.clamp(centre − inset, centre + inset) |
no — componentwise min/max |
Exactly one axis-index-ordered reduction survives, and the registered change cannot reach it. The
registered change reorders the crossing accumulation, which is centroid plus AᵀA plus g — all three
of which have been order-independent since A-016. The share a different invariant order can move is
therefore 0 of the 1 remaining axis-index-dependent reduction. That is the finding, and the harness
recorded it before the run: the SHARE table above is the bench's own header, present verbatim in
22c9fa0 — "Phase 24 — thirty harnesses, committed before their runs" — and git diff 22c9fa0 HEAD --
crates/isomesh/benches/experiment_p101.rs is empty, so the file that says "C1 is arithmetically
unreachable before the run. It is run anyway" is byte-identical to the one that produced p-101.csv.
M-19's rule, satisfied structurally rather than by assertion.
The same conclusion from the committed data with no source read at all, which is the stronger argument.
docs/experiments/p-61.csv, block = equivariance, sphere at 33³:
| extractor | elements_vertex_exact |
pure_permutation_exact |
pure_sign_flip_exact |
fixture_can_fail |
|---|---|---|---|---|
surface_nets |
6 of 48 | 6 of 6 | 1 of 8 | true |
dual_contouring |
2 of 48 | 2 of 6 | 1 of 8 | true |
manifold_dual_contouring |
2 of 48 | 2 of 6 | 1 of 8 | true |
surface_nets is the dual with no normals at all and the same sum_equivariant centroid — it is
literally HermiteCell::centroid and nothing else. It reaches all six pure axis permutations where the QEF
duals reach two. The accumulation is common to both, so the four-element gap cannot be the
accumulation. And surface_nets reaches pure_sign_flip_exact 1 of 8 on that same row — the
sign-flip failure is fully present with the accumulation held constant, which is M-177 and not an
ordering question in any group.
What arithmetic could not reach before the run, and therefore what the run bought. C1's verdict was
derivable; its magnitude was not — that the key order is not merely useless but actively worse on 9 of
16 rows is a measurement, and the mechanism for it (the tie-break's own axis-index fallback, below) could
not be predicted from the reduction audit because the audit is about the reductions the crate ships, not
about the ones a candidate introduces. C2's predicate was near-tautological — the accumulation order is
the only thing the arm changes, so every moved hash is "through the accumulation order" by construction —
but its cost (40 of 48 hashes, 56.4% of vertices) is a number no argument produces. C3 was genuinely
undecidable in advance: HermiteCell::restricted changes which twelve slots are populated, not the order
they are reduced in, and whether restricting the slot set alters the exact-element count is an empirical
question. It does not — 64 of 64 row-pairs agree — and that is a new fact about CycleQef.
C2, and what "free" does and does not mean
block = golden, accumulation_key = abs_value_abs_offset, 48 rows (eight fields × three resolutions ×
two duals). mesh_hash_shipped == golden_hash_committed on all 48 (golden_fixture_matches_shipped true),
so hashes_moved is not measured against a stale fixture.
| quantity | column | value |
|---|---|---|
| golden dual rows scored | golden_dual_rows |
48 |
| hashes moved | hashes_moved / hashes_moved_expected |
40 / 40 |
| vertex positions moved | Σ positions_moved / Σ vertices |
37,764 / 66,930 = 56.4% |
| vertex counts changed | golden_counts_changed, vertices vs vertices_baseline |
0, equal on 320 of 320 |
| index buffers changed | indices_identical |
true on 320 of 320 |
| topology changed | topology_identical |
true on 320 of 320 |
| worst geometric move | max_hausdorff_delta |
3.008704396734e-14 against a bar of 1e-12 |
Every one of the 40 moved hashes is accounted for by a moved vertex position on the same row, and every
one of the 8 unmoved hashes by zero moved positions. I checked the biconditional
mesh_hash_moved == (positions_moved > 0) on all 48 rows: 0 mismatches. The 8 rows that hold are
box_exact and thin_plate at 17³ and 33³, both duals — which is an independent reproduction of M-178's
own four survivors: the axis-aligned fields at the resolutions whose cell size is a binary fraction of the
domain (0.25 and 0.125; the golden 25³ fixture's 2L/24 = 0.166666667 is not, and both fields move there,
by 69 and 10 positions). On exactly-representable crossing coordinates, reordering cannot change a result
that was never rounded. hausdorff_shipped and hausdorff_arm print identically to twelve digits on
48 of 48 rows.
The 1e-12 bar is cleared by a factor of 33.2, not by four orders. 1e-12 / 3.008704396734e-14 = 33.24
— between one and two orders of magnitude. The pre-run report's "unchanged four orders inside the
registered 1e-12 bar" is arithmetically wrong about the number it quotes in the same sentence, and it is
withdrawn here in favour of the ratio. The verdict is unaffected: the clause is HELD by 33×.
So it is a reordering and nothing else, and the geometry is unchanged well inside the bar. It is not costless to land, and the registration's word "free" means geometrically free. 40 of 48 committed golden dual hashes and 56.4% of golden dual vertices move — for a regression.
The mechanism, and it is located rather than argued
All four arms are in one binary and one run — M-281's prescription, rather than one arm here against
a committed CSV from another build — which is what makes the arm-to-arm comparison below admissible at all.
Aggregates over the 32 dual equivariance rows (16 per extractor, 48 elements each, 1,536 element-slots):
| arm | crossing accumulation | normal | rows @ 48 | rows @ perm 6 | Σ perm exact | Σ sign-flip exact | Σ evx | golden hashes moved | golden positions moved | max |ΔHausdorff| |
|---|---|---|---|---|---|---|---|---|---|---|
shipped (*_baseline cols) |
twelve slots, magnitude-ordered | vec3::length |
6/32 | 8/32 | 100/192 | 82/256 | 392 | — | — | — |
edge_slot (replica) |
same, retranscribed here | same | 6/32 | 8/32 | 100/192 | 82/256 | 392 | 0/48 | 0/66,930 | 0.000000000000e0 |
abs_value_abs_offset (registered) |
running sum in key order | same | 6/32 | 8/32 | 80/192 | 82/256 | 372 | 40/48 | 37,764 | 3.008704396734e-14 |
edge_slot_equivariant_normal |
twelve slots, magnitude-ordered | dot_equivariant(g,g).sqrt() |
6/32 | 32/32 | 192/192 | 82/256 | 492 | 34/48 | 9,115 | 2.879640970121e-16 |
abs_value_abs_offset_equivariant_normal |
running sum in key order | equivariant | 6/32 | 12/32 | 100/192 | 82/256 | 400 | 40/48 | 39,214 | 3.008704396734e-14 |
Read that table as four statements.
1. The instrument is sound. edge_slot is this bench's own transcription of HermiteCell::from_corners,
solve::solve_with and apply_clamp, driven through the public DualContouring::with_rule. It reproduces
the shipped extractor bit for bit — replica_bit_identical true on 320 of 320, bit_identical_to_shipped
true on all 80 of its rows, 0 of 48 golden hashes moved, 0 of 66,930 positions moved, max_hausdorff_delta
exactly 0.000000000000e0. Without it, every difference in a later arm could be a transcription error
rather than the change under test; with it, the instrument is demonstrably able to read zero, which is
what makes its non-zeros mean anything (E-208, M-44).
2. The relabelling obstruction is vec3::length, and one expression proves it. The
edge_slot_equivariant_normal arm changes exactly one line — the normal's length becomes
dot_equivariant(g, g).sqrt() — and nothing else. pure_permutation_exact goes from 8 of 32 rows at 6 of
6 to 32 of 32, and from 100 of 192 element-slots to 192 of 192. Perfect, on every field, at both
resolutions, on both duals. Per row for dual_contouring: sphere 2→6, torus 2→6 and 4→6,
csg_difference 2→6, gyroid 2→6, fbm_terrain 2→6 and 2→6, noise_cavity 2→6, with box_exact and
thin_plate already at 6. elements_vertex_exact rises on 12 of 16 rows per extractor with 0 worse:
{2: 10, 4: 2, 24: 1, 48: 3} → {6: 11, 12: 1, 24: 1, 48: 3}.
Why left-to-right is exactly two survivors, and why p-61.csv already recorded that number. dot(a, a)
evaluates (a₀² + a₁²) + a₂². Under an axis permutation π the gradient permutes exactly, so the sum
becomes (a²_π(0) + a²_π(1)) + a²_π(2). IEEE addition is commutative, so this is bit-identical to the
original precisely when π fixes {0, 1} as a set — the identity and the x↔y swap, and no others. It
is not identical in general when π moves a₂ into a partial sum, because associativity is what fails.
p-61.csv measured exactly that population before anyone had named the expression: ✗49 / M-372's own
table reads "dual_contouring / manifold_dual_contouring | 2 of 48, 22 rows | identity and the x↔y
swap". Two out of six, on the nose, from one three-term sum.
3. M-177 covers the negation half and nothing moved it. pure_sign_flip_exact is bit-identical to
the shipped value on every one of the 32 dual rows under all four arms — Σ 82 of 256 in every row of the
table above, and I verified the equality row by row across all 128 equivariance rows. Four accumulations
and two normalisations did not move the negation half by a single element. That is why rows @ 48 is
6 of 32 in every arm including the perfect one: elements_vertex_exact is the product of the two
factors, and a perfect permutation factor times a sign-flip factor of 1 is still 6 of 48. The
first_failing_element column says the same thing in one field: on all 26 failing equivariance rows in
every arm it reads perm=012;sign=-++ (24 rows) or perm=012;sign=+-+ (2 rows) — perm=012 is the
identity permutation, so the first element to fail is always a pure reflection, never a relabelling.
No row in the whole file fails first on a non-identity permutation.
4. The registered key order makes it worse, and the tie census says exactly how. A running sum needs a
total order on the crossings; a twelve-slot magnitude reduction needs no such thing, because it orders
the terms. The registered key (|a+b|, |edge_offset(a,b)|) plus its invariant tie-breaks — |a−b|, the
crossing position's three component magnitudes sorted descending, the normal's likewise — is not total on
these fixtures. When a pair ties on all of it the order falls back to edge index, which is precisely
what an axis relabelling permutes. Over the 128 equivariance rows total_key_ties = 6,304,928 and
total_unbreakable_key_ties = 1,523,248 (24.16%). Per row on the registered dual_contouring arm the
unbreakable fraction runs from 4.5% on thin_plate 33³ to 93.2% on sphere 33³ and 100.0% on
sphere 25³ (17,248 of 17,248 — every single primary tie survives every invariant tie-break). So the
registered "relabelling-invariant order" is strictly less invariant than what A-016 already ships,
and the tie count is the measure of by how much. This is M-175 arriving as a result rather than as a
warning: the tie-break the registration demanded be instrumented is the thing that breaks the mechanism.
The attribution of the 9 losses is a conjunction, and it is necessary but not sufficient — one row says
so. All 9 losing rows have both positions_moved > 0 and unbreakable_key_ties > 0. Of the 7 unchanged
rows: 4 are unchanged because positions_moved = 0 (box_exact 33³/25³, thin_plate 33³/25³ — the
equivariance block's 25³ cell size is the dyadic 0.1875, so M-178's exactness mechanism covers both
resolutions there, unlike the golden block's 0.166666667); 2 because exact_key_ties = 0
(fbm_terrain 33³/25³ — the key is already total on that field, so the edge-index fallback is never
reached, and its 1,233 and 670 moved positions cost it nothing); and 1, torus 33³, moves 816
positions and has 4,440 unbreakable ties and keeps both of its exact elements. So the conjunction does
not predict which rows break, and any claim that it does is withdrawn — torus 33³ is the counterexample
in the file.
5. The two changes fight. abs_value_abs_offset_equivariant_normal — the key order plus the
equivariant normal — reaches pure_permutation_exact 6 of 6 on only 12 of 32 rows and Σ 100 of 192,
back at the shipped total. Per row on dual_contouring: 9 worse than shipped, 3 better, 4 equal, with
torus landing on an order-3 subgroup (pure_permutation_exact = 3) at both resolutions. The key
order destroys most of what the normalisation buys, which is the same mechanism seen from the other side.
The vacuity control: two columns, both non-degenerate
Registered control 1 — vacuity_baseline_rows_still_at_48 = 6. p-61.csv's three already-passing dual
rows are box_exact 33³, box_exact 25³ and thin_plate 33³, and there are three of them per extractor,
so the counter's population is 6 of 6 — with baseline_rows_at_48_dual_contouring = 3 and
baseline_rows_at_48_manifold = 3 beside it in the file so the denominator is explicit rather than
inferred. All 6 still pass under the registered arm, at positions_moved = 0 and hausdorff_delta =
0.000000000000e0. They pass for M-178's reason and not by luck.
Registered control 2 — the tie-break is exercised: total_key_ties = 6,304,928, of which
total_unbreakable_key_ties = 1,523,248 fall through to edge index. M-175 is the precedent for a
tie-break that was never tested, survived 9,600 measured trials because those trials were the one case where
it happened to be true, and fell to the first test written about the tie itself. Here the tie is a column
before it is a conclusion.
Why that value proves the fixture could have failed. The tie census is not a constant of the harness:
it reads 0 on all 40 fbm_terrain rows (16 in the equivariance block, 24 in the golden block) and
198,352 on box_exact 33³ in the equivariance block. So the column distinguishes fields by three orders
of magnitude, a zero on a field that has ties would be visible, and the zero it does report is a property
of FbmTerrain's sample values rather than of the instrument. Two further tells that it is measuring
something real: the unbreakable fraction spans 4.5% to 100.0% across fields, and the causal direction is
visible in the verdict — both zero-tie rows are among the seven the registered change leaves alone, and the
two 100%/93% rows are among the nine it breaks worst. That is M-44's rule met on both sides: the zero
could have been non-zero elsewhere in the same column, and the non-zero could have been zero.
Three instrument checks beyond the two registered, each an assert! and a column.
replica_bit_identical = true (the bench's own transcription is bit-identical to the shipped extractor over
every position, normal and index on all 32 equivariance fixtures and all 48 golden rows);
baseline_matches_p61 = true (the shipped arm reproduces p-61.csv's elements_vertex_exact,
pure_permutation_exact and pure_sign_flip_exact on all 32 dual rows — re-verified here against
p-61.csv directly, 128 comparisons, 0 mismatches); golden_fixture_matches_shipped = true (the committed
golden_hashes.json equals the shipped arm's own hash on all 48 dual rows).
No clause is VACUOUS and none is BLOCKED. Every one of the three verdicts rests on a column that could
have read the other way: C1 on elements_vertex_exact against elements_vertex_exact_baseline on the same
row; C2 on the edge_slot arm demonstrating 0 moved hashes, 0 moved positions and 0.000000000000e0 on the
same instrument; C3 on the two duals' vertex counts differing on 6 of 16 rows while their equivariance
counts coincide. No clause named a second machine, so none is blocked on one.
And P-101 has no timing clause at all — every clause is an integer count, a bit-pattern comparison or an
exact-arithmetic bound, so ✗24's failure mode (a wall-clock ratio used as a gate) is structurally absent
rather than avoided. wall_ms is recorded on every row and is scored by nothing.
Fixture defects the harness's own controls caught
- The vacuity counter's numerator and denominator were over different sets. The first run printed
"already-passing rows still at 48: 6 of 3" — the counter spans both extractors while the label quoted
the per-extractor figure. Same shape as
✗49's two miscounted denominators. Caught before the artefact was final; the print now reads "6 of 6 (3 per extractor, both counted)" and the CSV carriesbaseline_rows_at_48_dual_contouring= 3 andbaseline_rows_at_48_manifold= 3 besidevacuity_baseline_rows_still_at_48= 6, so a reader cannot recover the wrong denominator from the file. - The registered key names a scalar an edge crossing does not have.
(|value|, |offset|)is underspecified: a crossing has two corner samples and no single "value". The harness fixed the reading in the committed header before running —value = a + b, symmetric in the two samples because a reflection along the edge's own axis swaps which corner is low;offset = cube::edge_offset(a, b), which that swap negates exactly, so|offset|is the invariant. A different reading (|a|+|b|,max(|a|,|b|),|a−b|) moves the tie count and not the verdict, because the failure mode is the edge-index fallback and any key built from edge-local scalars has unbreakable ties on a symmetric field —sphere25³ is 100% unbreakable with the position and normal magnitude multisets already added as tie-breaks. - The tie-break of last resort is axis-dependent, and it is counted rather than hidden. When two
crossings tie on
(|a+b|, |offset|, |a−b|, sorted |position|, sorted |normal|)the order falls back to edge index, which no group action fixes.unbreakable_key_tiesis that count, per row and in aggregate. Naming it is what makes C1's falsification mechanistic instead of merely negative. - A per-cell
Vecin the key sort would have made the run unaffordable, and the file prices it. The first draft ofsolve_cellallocated one per surface cell. Σcells_solvedover all 320 rows is 11,060,460 cell solves (10,792,740 in the equivariance block, 267,720 in the golden block) over Σcrossings_visited= 44,923,744 crossings, so the sort runs eleven million times and would have allocated eleven million times. Replaced by a fixed[(Key, u8); 12]with a sorted prefix slice before the first run. Not a correctness defect — a cost one, caught by arithmetic rather than by a timeout. (The pre-run report estimated this as "66,930 cells × 49 extractions × 128 rows ≈ 4×10⁸"; that multiplies a 48-row per-arm total by a per-row factor and overstates the run by 38×. The figure above is a sum of a committed column.) - The equivariance block's census columns are over 49 extractions, not one, and the file says so.
exact_key_ties,unbreakable_key_ties,cells_solvedandcrossings_visitedon an equivariance row cover the reference plus all 48 rotated meshes.cells_solvedmakes it checkable:cells_solved == 49 × verticeson all 128 equivariance rows (sphere33³ = 56,840 = 49 × 1,160), andcells_solved == verticeson all 192 golden rows. Every per-mesh figure quoted anywhere must come from the golden block, where the registered arm's totals are 36,274 primary ties and 8,082 unbreakable (22.28%) over 66,930 cells and 272,184 crossings. Stated so no reader divides by 49 unknowingly — or fails to. worst_component_ulpcarries two different quantities in one column, and the reading has to be stated per arm. Values near 9.2e18 are✗39's documented+x/−xpairing artefact of the sorted-merge multiset difference, which appears wherever the vertex sets differ at all; they are not displacements. On the registereddual_contouringarm the genuine displacements arebox_exact0 and 0,thin_plate33³ 0,thin_plate25³ 2,fbm_terrain33³ 5,376,fbm_terrain25³ 18,312 — and everything else on that arm is above 1e15. On theedge_slot_equivariant_normalarm the displacement-scale values are different numbers on different rows (thin_plate25³ 2,fbm_terrain25³ 5,584,fbm_terrain33³ 7,488,gyroid25³ 27,456). The pre-run report presented a single mixed list without naming the arm; that list is corrected here to two per-arm lists, because✗39's own rule is that a repaired instrument's column must be re-read from the artefact and quoted per row.multi_crossing_cellsis a column that cannot read anything else. It increments when a solved cell has more than one crossing, and it equalscells_solvedon all 320 rows — because a cell with a sign change has at least three cut edges, always. It confirms the sort always had something to order, and byM-44's standard it is not a measurement: it could not have come back lower. Recorded as a structural fact, not as evidence.
What changed as a result
No source change landed, and this is not a rebaseline. R-101 was registered as one of only two
permitted source changes in Phase 24, and the harness declined the permission: both candidate
accumulations are bench-local VertexRules driven through the public DualContouring::with_rule
(dual_contouring.rs:254, X-002's entry point and the same seam M-237 used to run Qef against
Centroid). Verified on the branch: git log main..HEAD touches no file under
crates/isomesh/src/dual_contouring.rs, dual_contouring/solve.rs, manifold_dual_contouring.rs,
hermite.rs, vec3.rs, golden.rs, or crates/isomesh/golden_hashes.json. The branch's only src
changes are error.rs, experiment.rs, lib.rs, mass.rs and mass/tests.rs — registration metadata
and P-73's module, none of them on the dual path. The 40 moved golden hashes are a measured cost of a
change that was never applied, not a new baseline: golden_hashes.json is byte-unchanged and
mesh_hash_shipped == golden_hash_committed on all 48 golden dual rows. That is also what makes this arm
better than the source edit the ticket authorised: M-281 is satisfied by construction, and the cost is
priced without rebaselining anything.
Landing a mechanism is not this row's call, and the decision to surface is that there is nothing to land. The registered change is not "not yet" — it is no. It is worse on 9 of 16 rows per extractor, better on none, and would move 40 of 48 golden dual hashes and 56.4% of golden dual vertices to buy that regression.
M-372's premise is falsified by measurement. ✗49 / M-372 says, in the FINDINGS.md sentence
P-101 was registered on: "Axis relabelling reorders the accumulation into AᵀA, and that is enough."
It is not enough and it has not been the mechanism since A-016: AᵀA is twelve sum_equivariant slots
per entry, surface_nets with the same centroid and no normals reaches 6 of 6 permutations where the QEF
reaches 2, and reordering the accumulation four different ways moves the permutation count down. The
diagnosis needs correcting where it is quoted.
M-177's obstruction does cover the octahedral case for the duals — for the negation half, which is the
half that binds. pure_sign_flip_exact did not move by one element under four accumulations and two
normalisations. The three of sixteen rows that already reach 48 are explained by something other than the
accumulation: box_exact and thin_plate at exactly-representable spacings, where the crossing
coordinates are never rounded and no ordering rule is doing any work (M-178). So "make the duals
octahedrally equivariant at 48 of 48" should be foreclosed as a goal, with a number: the reachable ceiling
for a dual whose vertex is a sum of rounded terms is the 6 pure relabellings, plus whatever the
exactly-representable fields give free. P-100's Kuhn subdivision is aimed at the same 48 and this row is
evidence about its ceiling too — a decomposition fix cannot reach the negation half either.
The remaining lead is vec3::length, and it is one call site. dot_equivariant already exists, is
already pub, and already runs three lines away in the same solve (solve.rs:103, called at
solve.rs:228-230). hermite.rs:103 calls vec3::length(gradient) instead. Measured cost of changing
only that: 34 of 48 golden dual hashes move, 9,115 of 66,930 vertices (13.6%), max_hausdorff_delta
2.879640970121e-16, topology_identical / counts_identical / indices_identical true on all 48,
golden_counts_changed 0, and 14 rows hold rather than 8 — box_exact and thin_plate at all three
resolutions plus sphere 17³, because on axis-aligned geometry the gradient has two zero components and
magnitude-ordering a sum of squares changes nothing. Measured benefit: pure_permutation_exact 6 of 6 on
32 of 32 dual rows, elements_vertex_exact up on 24 of 32 and down on none. It is simultaneously more
equivariant and 104× geometrically tighter (3.008704396734e-14 ÷ 2.879640970121e-16 = 104.5) than the
registered change. It is still a rebaseline of 34 golden hashes, and per the phase brief that is the
owner's call and not this row's. A wider variant — making vec3::dot itself magnitude-ordered — was not
measured here, and its blast radius is larger than the pre-run report stated: counted from the source,
vec3::dot has 25 non-test call sites, vec3::length_squared 8 and vec3::length 21 — 54
across 15 modules (brush, dual, hermite, marching_cubes/mod, marching_tetrahedra, normals,
orient, property, property/extraction, subgrid/extract, transvoxel/cell and
validate/{accuracy, sealing, self_intersection, tri_grid}). The report's "13 production call sites"
is a count of files and it omits property.rs and property/extraction.rs; the number of sites is
54. So that variant's blast radius is the whole 216-row golden fixture, not 48.
The instrument is the durable artefact. experiment_p101 is a reusable two-obstruction rig for any
future dual-equivariance claim: pure_permutation_exact and pure_sign_flip_exact separate the reachable
half from M-177's structural half — and the file proves they are separable, because
elements_vertex_exact is exactly their product on all 128 rows — while the edge_slot replica arm makes
any bench-local reimplementation of the DC vertex path provable bit-for-bit against the shipped one.
Would be shown wrong by: a crossing accumulation order — any order, not just this key — that raises
pure_sign_flip_exact above the shipped value on one dual row, which would mean M-177 does not bound the
negation half and the 48-of-48 goal should be reopened; a row where edge_slot_equivariant_normal fails to
reach pure_permutation_exact 6 of 6, which would mean vec3::length is not the only relabelling
obstruction and the SHARE audit missed a reduction; a positions_moved above zero on box_exact or
thin_plate at a dyadic spacing, which would break M-178's exactness mechanism and with it the
explanation of the 3 rows that already reach 48; a manifold_dual_contouring row whose equivariance triple
diverges from dual_contouring's, which would restore C3; or a key whose tie-break is total on these
fixtures — unbreakable_key_ties = 0 everywhere — reaching more than 8 of 32 rows at
pure_permutation_exact 6, which would mean the edge-index fallback and not the running sum was the whole
cost of the registered order.
🔬 M-414 — C1, C2 and C3 all HELD: ✗43's withdrawn rate reproduces exactly — 0 of 8,064 unclosed post-fix on five independent magnitude fixtures and 2 of 8,064 pre-fix at 6³ at t7c6o0+t9c6o0 — and C2's share is fan_configurations = 2, so "exactly 2" was reachable by exactly 2 and "zero elsewhere" was arithmetically forced rather than measured (P-102, R-102)
M. cargo bench --bench experiment_p102, docs/experiments/p-102.csv, 43 rows, scalar f64, Zen 3
(amd-ryzen-9-5900x-12-core). ✗43's own population, recovered rather than invented: 1,152 single-plane
caps max(|p| − 1.5, n·p − offset) — 16 θ × 8 cos φ × 9 offsets over property::unit_vector's
(0..τ, −1..=1) and convex_body's −0.8..=0.8 — meshed at each of 6³–12³ samples
(cells / configurations = 125 cells at 6³ to 1,331 at 12³) under six arms, plus ✗43's own reduced
plane as a one-configuration control row. Committed
at 7fc91fa, # commit header clean (no (WORKING TREE DIRTY)), and an ancestor of HEAD.
Every integer in this entry is the clean re-run's, and every integer the pre-run reported reproduced bit for bit.
interior_apexes4,462 / 4,990 / 4,904 / 4,983 / 4,949 / 0,triangles1,940,948 to 1,943,206 per live arm,fan_configurations2 and 0,unclosed_pre_fix2 and 0,zero_sample_configurations1,408 per arm, and the 942-against-936 artefact atexact/9³— all unchanged. The one quantity that is not in the file is a clock: the pre-run's "whole run ≈ 25–35 s" appears in no column and is not quoted here. What the file carries iswall_msper row — 99 to 728 on the 42 sweep rows, 0 on the one-configuration control — and 2,380 / 2,481 / 2,482 / 2,611 / 2,529 / 2,507 ms per arm. No verdict reads it: every clause here is an exact integer count, so nothing was BLOCKED on a second machine and nothing needed one.
| clause | registered | measured |
|---|---|---|
| C1 zero unclosed meshes post-fix over all 8,064, four magnitude seeds, per seed and never pooled | 0 of 8,064 | HELD — unclosed_post_fix = 0 on all 43 rows, unclosed_post_fix_where = none on all 43, non_manifold_vertices_post_fix = 0 on all 43. Five arms × 8,064 configurations, seven rows each |
| C2 the pre-fix single-apex fan gives exactly 2 at 6³ and zero elsewhere | 2 at 6³, 0 at 7³–12³ | HELD on the arm that is ✗43's fixture — unclosed_pre_fix = 2 at arm=exact size=6, unclosed_pre_fix_where = t7c6o0+t9c6o0, and 0 at sizes 7–12. VACUOUS on the 41 rows where fan_configurations = 0 |
| C3 the ±1 magnitude arm reports VOID rather than a pass | void = true |
HELD — void = true on all 7 unit rows with interior_apexes = 0; c3_holds = true on all 43 rows |
✗43's two headline numbers, side by side with the file that now contains them:
arm |
seed |
rows | Σ configurations |
Σ unclosed_post_fix |
Σ unclosed_pre_fix |
Σ fan_configurations |
Σ interior_apexes |
Σ triangles |
|---|---|---|---|---|---|---|---|---|
x43_fixture |
none |
1 | 1 | 0 | 1 | 1 | 2 | 48 |
exact |
none |
7 | 8,064 | 0 | 2 | 2 | 4,462 | 1,940,948 |
unit |
none |
7 | 8,064 | 0 | 0 | 0 | 0 | 1,931,192 |
generic |
0x00002026 |
7 | 8,064 | 0 | 0 | 0 | 4,990 | 1,943,064 |
generic |
0x0005eed1 |
7 | 8,064 | 0 | 0 | 0 | 4,904 | 1,942,888 |
generic |
0x00c0ffee |
7 | 8,064 | 0 | 0 | 0 | 4,983 | 1,943,206 |
generic |
0xdeadbeef |
7 | 8,064 | 0 | 0 | 0 | 4,949 | 1,943,070 |
The exact arm per size, which is the row ✗43 reported and could not cite:
| size | configurations |
cells |
trilinear_cells |
hexagon_cells |
interior_apexes |
interior_vertices |
fan_configurations |
unclosed_pre_fix |
unclosed_post_fix |
zero_sample_configurations |
|---|---|---|---|---|---|---|---|---|---|---|
| 6 | 1,152 | 144,000 | 912 | 16 | 362 | 458 | 2 | 2 | 0 | 0 |
| 7 | 1,152 | 248,832 | 2,692 | 0 | 1,142 | 1,142 | 0 | 0 | 0 | 128 |
| 8 | 1,152 | 395,136 | 952 | 0 | 360 | 360 | 0 | 0 | 0 | 0 |
| 9 | 1,152 | 589,824 | 1,864 | 0 | 942 | 936 | 0 | 0 | 0 | 1,152 |
| 10 | 1,152 | 839,808 | 784 | 0 | 352 | 352 | 0 | 0 | 0 | 0 |
| 11 | 1,152 | 1,152,000 | 1,520 | 0 | 736 | 736 | 0 | 0 | 0 | 128 |
| 12 | 1,152 | 1,533,312 | 1,152 | 0 | 568 | 568 | 0 | 0 | 0 | 0 |
29,417,597 cells meshed twice each — once post-fix, once through the reconstructed pre-fix fan — across the 43 rows.
SHARE, said out loud, and this is the transferable part of the row. No clause here is a ratio of times,
so ✗51's 1/(1 − share/factor) bar has nothing to divide: both rate clauses are counts over an
enumerated population, so their denominators are exact by construction — configurations = 1,152 per size
and 8,064 over the seven sizes, asserted in the harness before it sweeps rather than assumed.
- C1's share is 8,064 of 8,064. Every configuration is meshed and validated, so one unclosed mesh
anywhere moves the clause. C1's exposure is not arithmetic, it is vacuity — a zero over empty meshes — and
empty_meshes= 0 on all 43 rows against 1,940,948 to 1,943,206 triangles per live arm (11,644,416 over the file) says the population is real. - C2's share is
fan_configurations, not 1,152. Undoing the fix can only unclose a configuration that has a cell fanning two or more rings from one apex; every other configuration is bit-identical before and after, because a single fanned ring took the body saddle either way. Sounclosed_pre_fix ≤ unclosed_post_fix + fan_configurations. Measured:fan_configurations= 2 at 6³ on the exact arm and 0 on all 41 other sweep rows. So "exactly 2 at 6³" was reachable by exactly 2 — the tightest margin a count clause can have, one configuration of slack in neither direction — and "zero elsewhere" was arithmetically forced, not measured: on 41 rows the share is 0, sounclosed_pre_fixcould not have been anything but 0 however wrong the pre-fix fan is. That is✗51's rule applied to a count instead of a ratio, and the harness acts on it rather than narrating it:c2()returnsfalsewhenfan_configurations == 0, soc2_holdsis true on exactly 1 of 43 rows and false on 42 — false on 41 for zero share, and false on thex43_fixturecontrol row because that row is one configuration and itsunclosed_pre_fixof 1 is not C2's 2. A row whose share is 0 reportsfalsebeside a share column that says why, instead of banking a pass.share_bound_holds()is an assertion, not a column — it fires per row over the control row plus all 42 sweep rows — and the inequality is independently true on all 43 rows of the committed file. - C3 has no share. It is a statement about a fixture and moves nothing.
Mechanism, and it resizes what "0 of 8,064 after" is evidence for. 8,062 of the 8,064 exact-arm
configurations are bit-identical before and after the fix. The fix only changes a cell where two rings are
both longer than three vertices. On the exact arm interior_apexes = 4,462 with unfanned_apex_cells = 0
and apex_merges = 2, and a merge costs rings − 1, so the sweep's interior rule fired on
4,462 − 2 = 4,460 cells, of which 4,458 fanned exactly one ring — where post-fix places the apex at
the body saddle, precisely what pre-fix did — and 2 fanned two rings and contributed the two merges.
unfanned_apex_cells = 0 on all 43 rows, so ✗43's second artefact (an apex created for a cell no ring
fanned) does not occur in this population at all. The post-fix zero is therefore mostly a statement that
the rest of the extractor is closed on 8,064 caps; the fix's own share of it is two configurations, and
that is the honest denominator to quote the rate against.
Those two are one geometry, twice. unclosed_pre_fix_where names them t7c6o0 and t9c6o0, and
reading = theta_ladder+cosphi_endpoints fixes the ladders as θ = i·τ/16, cos φ = −1 + 2j/7,
offset = −0.8 + 0.2k. So both are cos φ = −1 + 12/7 = 5/7 at offset = −0.8, differing only in
θ = 7·360°/16 = 157.5° against 9·360°/16 = 202.5° — and 157.5° + 202.5° = 360°, so the two normals
share cos θ and cos φ and differ in the sign of sin θ alone. They are the same plane reflected in
y = 0, and ✗43's "2" is one geometric instance appearing twice because the θ ladder contains both
mirror images. Not a repeated computation — cos(157.5°) and cos(202.5°) are evaluated separately — but
one instance, not two.
Why the four magnitude seeds cannot host C2, which is the thing the registration did not predict.
Re-drawing every sample's magnitude while keeping its sign destroys both fanned cells outright —
fan_configurations = 0 on all 28 generic rows — while increasing the apex count (4,462 → 4,904–4,990).
Whether a cell fans two rings is not a property of its sign pattern; it is a property of where the body
saddles fall, and that is a property of the magnitudes. So the seed protocol tests the fix's robustness
across magnitude space, which is C1, and is structurally incapable of testing C2 — which is why C2 is HELD
on one arm and VACUOUS on the rest rather than HELD five times.
The vacuity control answers both ways inside one walk, which is M-44 by demonstration rather than by
assertion. The registered control is interior_apexes non-zero on every live arm, per seed, never
pooled — M-374's 282,084-to-283,694 shape. Measured over 8,064 configurations each: exact 4,462,
0x00002026 4,990, 0x0005eed1 4,904, 0x00c0ffee 4,983, 0xdeadbeef 4,949, each assert!ed > 0.
That value is what proves the fixture could have failed: the interior rule is the only code path ✗43's
defect can live in, so 4,460 cells reaching it, 2 of them fanning two rings to one apex, is the population
the clause is denominated in — and the pre-fix column returns 1 on the x43_fixture row and 2 on
exact/6³ from inside it, so the instrument is shown emitting bad news before its zeros are read.
And the same instrument reads 0 on the unit arm, over 9,876 trilinear cells — the identical
trilinear_cells total as every other arm, so nothing shrank — where
trilinear_cells == has_inner_hexagon_rejects == interior_vertex_rejects on every one of the seven rows
(912 / 2,692 / 952 / 1,864 / 784 / 1,520 / 1,152). At ±1 magnitude the interpolant's saddles are symmetric,
has_inner_hexagon's strict 0 < x < 1 rejects, interior_vertex() returns None, and the interior rule
never fires: every cell that takes the trilinear path rejects at both gates. Its 8,064 closed meshes are
the interior-rule-off arm's zeros wearing a different name, and void = true is the only honest verdict.
Deliberately, the harness does not assert interior_apexes == 0 there, and the bench says why in its
own comment: asserting it would make C3 a clause whose predicate an assertion in its own harness already
forces — a HELD with no instrument, which is the outcome this file records as VACUOUS and never as
HELD (✗51's C3). The unit arm's interior_apexes, void, c1_holds and c2_holds are measured,
written and printed; if the interior rule ever fires at ±1, the run completes and the row says so.
c1_holdsreadsfalseon the sevenunitrows, and that is not C1 failing anywhere.c1()is!void && empty_meshes == 0 && unclosed_post_fix == 0, so a void arm cannot bank a pass on a clause about the post-fix extractor.unclosed_post_fixis 0 on all 43 rows including those seven;c1_holds= true on the 36 live rows.
Four fixture defects, every one caught by this harness's own controls rather than by review.
- The interpolant blended two corners where it must return one, and no count in the experiment could
see it.
Interpolant::locatefirst reused the vertex-classification helper, which answers "which cell isxstrictly inside" and so returns the lower cell for anxsitting exactly on a sample plane; the weight came out one ULP short of1.0. The faithfulness control caught it on the first configuration it tried, as a one-ULP vertex displacement. Every integer column in this CSV would have been identical with the bug in place —M-143's shape in a bench fixture. zero_sample_configurations= 1,408 of 8,064 on every sweep arm — 128 at 7³, 1,152 at 9³, which is all of them, and 128 at 11³. At odd sizes the lattice contains 0 exactly; at 9³,h = 0.5puts the radius-1.5 bound's own surface on samples(±1.5, 0, 0)and permutations, so|p| − 1.5 = 0andcube::is_inside(0)is false. All 1,408 still meshed closed, so C1's zero is not hiding behind a degenerate sub-population — but the 9³ row is fully degenerate and a reader comparing it to 8³ needs to know.M-374's classification artefact reappeared, on exactly one row.interior_verticesequalsinterior_apexes + 6 · hexagon_cellson 42 of 43 rows; onexact/9³the predicted 942 exceeds the measured 936 by 6, because ath = 0.5six apexes land on a sample plane and the coordinate classification files them as face vertices. Confined to a column no verdict reads: the verdicts come from the predicted column and fromunclosed_*, and the merge path is separately guarded byclassification_mismatches= 0 on all 43 rows.- One deliberate departure from the pre-fix code, and the identity that bounds it. The reconstruction
leaves a merged-away apex in
positionsunreferenced instead of never creating it, sounreferenced_pre_fix = apex_merges + unfanned_apex_cells— verified on all 43 rows, 2 onexact/6³and 1 onx43_fixture— rather than the pre-fix code's own count. It cannot moveis_closed(), because χ is computed from referenced vertices, which is why thex43_fixturerow reproduces✗43's published pre-fix report (V 27, E 72, F 48, χ 3, components 2, non-manifold vertices 1, degenerate triangles 1,is_closed()false) number for number — asserted in the bench, corroborated in the file byunclosed_pre_fix1,non_manifold_vertices_pre_fix1,unclosed_post_fix0,non_manifold_vertices_post_fix0.
One thing the entry under-determines, and the harness prints rather than hides. ✗43 pins the four
factors but not the discretisation of each interval: 16 values of θ over a half-open interval and 8 values
of cos φ over a closed [−1, 1] each admit three readings, and only the 9 offsets are forced. The
harness therefore prints the pre-fix count at 6³ under all six readings before it sweeps and records the one
it swept under in the reading column — theta_ladder+cosphi_endpoints on all 43 rows, which is both the
reading the ticket instructs and the most literal reading of the three intervals. C1 and C3 hold under all
six; only C2's count depends on the choice, so the calibration table is the evidence for it and is
printed on every run. Those per-reading counts are printed, not columns, so they are not quoted here.
✗43's own reduced counterexample plane is on none of the six grids, which is consistent with the entry:
that plane came from proptest and the sweep was a separate prevalence scan.
What changed as a result: nothing in crates/isomesh/src/**, and that is the correct outcome. The
registration said so in advance ("this experiment reproduces a rate and moves nothing") and the file
agrees — the shipped extractor is closed on 8,064 configurations at five independent magnitude fixtures.
What changed is the evidence status of an existing entry, which is the whole point: ✗43's rate was
withdrawn at D-019 because "that sweep exists in no bench, no test and no CSV", and that was the one
audit item downgraded rather than fixed. It now exists — bench, CSV, pre-registered falsifier — and
CLAUDE.md hard rule 4 is discharged for it. Two things a future reader must carry forward:
✗43's claim that "the per-ring apex fix generalises" is now a measured claim over 8,064 configurations × five live magnitude fixtures, instead of one field at six grid sizes. Its "0 of 8,064 after" is 8,062 unchanged meshes plus 2 repaired ones, and its "2" is one mirror pair; quoting the rate without that denominator overstates what the sweep tests about the fix as opposed to about the rest of the extractor.- Do not build a magnitude-seeded version of C2. Four seeds were run and not one of them can host the
defect (
fan_configurations= 0 on all 28 generic rows). They earn their cost on C1 and are structurally incapable of testing C2. That is a completed result, and "do not build this" is the conclusion.
Would be shown wrong by: any row with unclosed_post_fix > 0, which reopens ✗43; the x43_fixture
row's pre-fix mesh coming back closed, which is the harness's own VOID assertion and would mean the
pre-fix column cannot report bad news on the one case known to have failed; any row with
unclosed_pre_fix > unclosed_post_fix + fan_configurations, which would mean the reconstruction moves
vertices the fix never touched and C2's 2 is measuring the bench rather than the defect; a
classification_mismatches above 0, which would mean the per-cell analysis and the mesh disagree about
which cells the fix touches and the pre-fix arm is undoing the wrong thing; interior_apexes coming back
non-zero on the unit arm, which would retire C3 and M-374's mechanism together; or a seventh reading
of the θ / cos φ ladders that reproduces ✗43's 2 at 6³ under a different pair of configurations,
which would mean the count is a property of the discretisation rather than of the geometry. It would be
weakened — not overturned — by a magnitude draw with fan_configurations ≥ 2 and unclosed_pre_fix
of 0: the share bound is one-sided, and such a row would show that fanning two rings is necessary for the
defect and not sufficient, which is a claim this file does not currently make either way.
Phase 25 — twenty registrations from the bit-packing sweep, each before its harness
Source: docs/research/2026-08-28-bitpacking-simd-acquisition-and-backlog.md — an acquisition of
seventeen papers into home-still (M-415), then twenty pre-registrations drawn from them. What changed
is the quantity being tested. ✗51 closed autovectorisation of float code with a null and a rule:
%ymm was zero in every one of eleven monomorphisations, the loop shape cost 3–7%, and the clause was
unreachable anyway because the sample loop is 11.6% of the marginal extraction cost. That result is
correct and it closed the wrong door. This sweep tests bit-parallel integer work, which is where this
crate's structure already is — M-337's active-cell bitmap is one bit per sample and already worth
5.5×, and nothing has asked what else fits in a word.
Phase 15's protocol applies in full, and all twenty P- entries are registered in
crates/isomesh/src/experiment.rs before any harness commit. Every row is bench-local:
crates/isomesh/src/** is read-only for the whole phase. Unlike Phase 24 there is no registered source
change — if a mechanism earns landing it lands as its own ticket afterwards, exactly as isomesh::mass
did, and a landing not registered in advance is V-45's failure mode.
✗51's Part 5 rule is applied here rather than remembered: a clause stated as a ratio of a total
must name the share of that total it can move. Every stanza below carries a SHARE line, and every
one carries a VACUITY CONTROL naming the column that proves the fixture could have failed — P-70's
C3 is the precedent for what happens without one.
Dependencies, stated once. P-121 runs first and gates P-103, P-104 and P-106. P-112
consumes P-107's directory. Everything else is independent.
Five foreclosures inherited, two added. Inherited: PEXT/PDEP, Morton for the sample grid, minimal
perfect hashing for the edge cache, and cache-oblivious layouts. Added by this sweep: WAH and EWAH,
because run-length encoding destroys the O(1) random access rank needs — which is the whole reason
P-115 is a Tree-Encoded-Bitmap row and not a WAH row — and la_vector's learned rank/select, which
needs the key set up front, the same requirement that killed the MPHF.
The FastLanes result that motivates Group A, quoted as the source document quotes it:
"Scalar_T64 uses 64-bit scalar registers as quasi-SIMD and beats naive Scalar up to 8x" and "when
incorporating FastLanes in future systems, we recommend just using the Scalar code paths". The fact that
makes it usable here is that Scalar_T64 is u64 shift, mask, AND and OR — no core::simd, no
intrinsics, no unsafe, no target gating. That is a constraint rather than a preference:
crates/isomesh/src/** today contains no unsafe block, no core::simd import and no
#[cfg(target_arch)] gate at all, and P-69's registration already records that core::simd is
nightly and staying nightly.
📖 M-415 — seventeen papers acquired and all four missing categories closed, and the eight that did not land are a resolver finding rather than a corpus one: the sweep's highest-value target has no DOI at all
M. A survey across twelve topics against home-still, then seventeen acquisitions, each verified
against all three of M-371's discriminators — markdown far above the ~2,000-character landing-page
floor, chunks_indexed never 1, and pdf_path ending in .pdf — and each additionally confirmed with
distill_exists. Corpus before: 9,520 documents / 290,647 chunks.
Four categories were entirely absent before this sweep: broadword/SWAR, compressed and hierarchical
bitmaps, SIMD integer codecs and bit-packing, and stream compaction without hardware PEXT. No Vigna,
no poppy, no Gog & Petri, no Roaring, no FastPFOR, no Stream VByte. What the corpus did have — VDB
(10.1145/2487228.2487235), sparse voxel DAGs (10.1145/2461912.2462024), Shewchuk
(10.1007/pl00009321) — is the voxel and predicate side, not the word side. All four holes are now
closed.
| DOI | Paper | md chars | chunks |
|---|---|---|---|
10.14778/3598581.3598587 |
Afroozeh & Boncz, The FastLanes Compression Layout, PVLDB 2023 | 69,236 | 22 |
10.48550/arXiv.1209.2137 |
Lemire & Boytsov, Decoding billions of integers per second through vectorization | 122,111 | 38 |
10.1016/j.ipl.2017.09.011 |
Lemire, Kurz & Rupp, Stream VByte, IPL 2018 | 26,085 | 9 |
10.1093/comjnl/bxx046 |
Muła, Kurz & Lemire, Faster Population Counts Using AVX2, Comput. J. 2017 | 46,837 | 15 |
10.1007/s00778-019-00578-5 |
Langdale & Lemire, Parsing gigabytes of JSON per second, VLDBJ 2019 | 99,962 | 31 |
10.1145/1572769.1572795 |
Billeter, Olsson & Assarsson, Efficient stream compaction on wide SIMD, HPG 2009 | 48,658 | 16 |
10.48550/arXiv.1206.4300 |
Vigna, Quasi-succinct indices (Elias–Fano), WSDM 2013 | 75,128 | 24 |
10.48550/arxiv.1301.5468 |
Vigna, Broadword Implementation of Parenthesis Queries | 27,872 | 9 |
10.1007/978-3-031-20643-6_19 |
Kurpicz, Engineering Compact Data Structures for Rank and Select (pasta), SPIRE 2022 | 41,829 | 14 |
10.1016/j.is.2021.101756 |
Pibiri & Kanda, Rank/select queries over mutable bitmaps, Inf. Syst. 2021 | 67,403 | 22 |
10.1002/spe.2402 |
Lemire, Ssi-Yan-Kai & Kaser, Consistently faster and smaller compressed bitmaps with Roaring, SPE 2016 | 107,472 | 33 |
10.1002/spe.2325 |
Chambi, Lemire, Kaser & Godin, Better bitmap performance with Roaring bitmaps, SPE 2015 | 37,249 | 13 |
10.1145/3318464.3380588 |
Lang et al., Tree-Encoded Bitmaps, SIGMOD 2020 | 84,626 | 26 |
10.1109/tpami.2021.3055337 |
Bolelli et al., One DAG to Rule Them All (GRAPHGEN), TPAMI 2021 | 66,962 | 21 |
10.1117/12.596105 |
Wu, Otoo & Shoshani, Optimizing connected component labeling algorithms, SPIE 2005 | 36,747 | 12 |
10.48550/arXiv.1505.05571 |
Neal, Fast exact summation using small and large superaccumulators | 63,572 | 20 |
10.48550/arXiv.2401.14906 |
Schroeder et al., A High-Performance SurfaceNets Discrete Isocontouring Algorithm | 60,007 | 19 |
Eight targets have open copies paper_download cannot reach, and that is the finding. It is a
sibling of M-371: a second way for an acquisition to look impossible when it is not.
| Paper | Where the open copy actually is | Why the resolver missed it |
|---|---|---|
| Vigna, Broadword Implementation of Rank/Select Queries — the highest-value target in the sweep | vigna.di.unimi.it/ftp/papers/Broadword.pdf, fetched and confirmed to be the right document |
It has no DOI at all. The only other identifier is ACM's 10.5555/1788888.1788900, which no provider resolves |
| Zhou, Andersen & Kaminsky, poppy / cs-poppy | ndownloader.figshare.com/files/12101855, 302-redirecting to a live PDF; the CMU KiltHub DOI 10.1184/R1/6609722.v1 is real and resolves in OpenAlex |
paper_download traverses arXiv and Unpaywall, not DataCite or figshare-hosted files |
| Inoue et al., set intersection | vldb.org/pvldb/vol8/p293-inoue.pdf |
The OA location is listed under the same DOI that failed |
| Gog & Petri | core.ac.uk/download/342989546.pdf |
Same |
| Demmel & Nguyen | eecs.berkeley.edu/~hdnguyen/public/papers/ARITH21_Fast_Sum.pdf |
Same |
| Flying Edges, HistoPyramids, Fujita | Kitware / MPI-Inf / publisher copies; no verified alternate identifier found | — |
The lever for three of them is not a better DOI — it is a fetch-by-URL path, because the metadata already lists an OA location the resolver does not follow.
Four traps identified and deliberately not taken, named individually because a near-miss acquisition
is worse than a miss: arXiv:1311.1249 is not Gog & Petri's paper; Berkeley EECS-2015-229 is not
Demmel & Nguyen's ARITH paper; the Hiroshima dissertation is not Fujita's; and the MPI-Inf report
HistoPyramids in Iso-Surface Extraction is not Dyken's CGF paper. The source document credits
"Rule 42" for that discipline and there is no rule 42 — CLAUDE.md has six numbered hard rules and
the applicable one is 5, "never guess algorithm details… say so and stop rather than inventing
one". A citation to a rule that does not exist is the same class of defect as the four traps it is
claiming credit for dodging, so it is corrected here rather than carried forward.
Two operational facts about the pipeline, both learned expensively, both now Part 5 rules.
scribe_convert is capped at 60 seconds by the MCP client while the job keeps running server-side
for 82–768 seconds, so a timeout carries no information about the job and catalog_read is the only
reliable completion check — one paper timed out and then silently produced no markdown, which looked
identical to a successful in-flight run, and catalog_read is the only thing that told them apart. And
the olmocr backend fails transiently under concurrency (0 completed pages (failed=N),
workspace/markdown does not exist) while scribe_health still reports status: ok; every one of
those converted on a sequential retry.
Would be shown wrong by: a fetch-by-URL path retrieving any of the three named OA locations and the
resulting markdown failing one of M-371's discriminators — which would move the defect from the
resolver to the document and make the table above an attribution error rather than a pipeline finding.
Group A - the word as a vector
FastLanes' central result is not about SIMD. Scalar_T64 — 64-bit scalar registers used as quasi-SIMD — "beats naive Scalar up to 8x", and their recommendation is "when incorporating FastLanes in future systems, we recommend just using the Scalar code paths". Every row here is u64 shift, mask, AND and OR. P-121 gates all four of P-103, P-104 and P-106; P-105 is independent because its baseline is bench-local.
P-103 — registered for R-103, before the harness: the case index computed 64 cells at a time from bit-sliced sign planes
Ticket: R-103 (M). Records: field, resolution, scalar, classify_share, instructions_per_cell_byte, instructions_per_cell_bitsliced, instruction_ratio, cases_identical, cells, corrupt_control_mismatches, hashes_moved, c1_holds, c2_holds, c3_holds.
Hypothesis. FASTLANES' SCALAR_T64 RESULT SAYS 64-BIT SCALAR REGISTERS USED AS QUASI-SIMD BEAT NAIVE SCALAR UP TO 8x, AND THE ONE QUANTITY IN THIS CRATE THAT IS ALREADY BOOLEAN IS THE EIGHT CORNER SIGNS OF A CELL. The comparand is exact and it is not a shared classifier: marching_cubes/mod.rs:258-268 builds the index inline with 'case |= 1 << c' guarded by is_inside (cube.rs:171, 'value < 0', so an exact zero is OUTSIDE), and there are SIX INDEPENDENT COPIES of that loop -- marching_cubes/mod.rs:266, manifold_dual_contouring.rs:210, property/extraction.rs:438 and :584, marching_cubes/ambiguity/tests.rs:260, and transvoxel/cell.rs:231 which widens it to u16. There is no shared classifier anywhere in the crate, so this row proposes the first one rather than modifying an existing one, and it is bench-local. Store the sign field as eight bit-planes instead of one array of bytes and a whole u64 of case indices falls out of eight shift-and-OR pairs. (C1) The case-classification stage is at least 10% of Marching Cubes extraction, using P-121's stage decomposition as the denominator and measuring the share BEFORE claiming any speedup. (C2) Eight sign bit-planes plus eight shift-and-OR pairs produce 64 case indices in under HALF the instructions per cell of the byte path. (C3) Zero movement in the 216 golden hashes, because the case index is an integer and an integer path that changes it is wrong rather than faster.
Falsified by. C1 by a classify share under 10%, which closes the row on arithmetic before C2 is measured. C2 by an instruction ratio worse than 2x, which is where the byte path's single table-free increment already wins. C3 by any golden hash moving, which would mean the bit-sliced index is not the same integer.
SHARE. C1 IS the share gate and it is checked first -- x51's rule applied at the top of the row rather than remembered at the bottom, since a 2x on a stage under 10% has a ceiling of 1/(1 - 0.10/2) = 1.05x and is not worth building.
VACUITY CONTROL. cases_identical must equal cells on every row, and corrupt_control_mismatches -- the same comparison with one sign plane deliberately flipped -- must be NON-ZERO, because a comparator that cannot report a mismatch has not reported a match.
P-104 — registered for R-104, before the harness: the interleaved layout for the active-cell bitmap, which packs samples and not cells
Ticket: R-104 (M). Records: field, resolution, layout, cycles_per_sample, tax_vs_127, instructions_per_cell, mesh_identical, resort_ns_per_vertex, c1_holds, c2_holds, c3_holds.
Hypothesis. THE ACTIVE-CELL BITMAP IS FASTLANES' HORIZONTAL LAYOUT, THE ONE THEY MEASURE AS THE OBSTACLE, AND TWO MEASUREMENTS IN THIS REPOSITORY ALREADY BLAME THE LAYOUT. Correction the research doc gets wrong and this registration carries: dual.rs:359-381 packs ONE BIT PER SAMPLE, 64 to a u64, ALONG X ONLY, with bit_row = size[0].div_ceil(64) -- the cell row is one shorter and is handled separately by cell_words = cells_x.div_ceil(64) at dual.rs:484 and by cell_mask at dual.rs:445. The doc and experiment.rs:3192 both say '64 cells per u64' and that is wrong by one; this row is about a SAMPLE plane relayout with a documented cell/word asymmetry underneath it. Second constraint, also from the source: dual.rs:496 walks set bits in ascending x SPECIFICALLY to keep vertex creation order, so any relayout must restore that order or C3 fails by construction -- and the restore cost is a column, resort_ns_per_vertex, not a footnote. (C1) A transposed packing -- bit k being the k-th cell of a 4x4x4 block rather than the k-th x -- brings M-287's 128 cubed tax BELOW 1.5x on M-287's own fixture. (C2) active_word's fused 'any & !all' fold survives the relayout within plus or minus 20% of its instructions per cell. (C3) The emitted mesh is bit-identical.
Falsified by. C1 by no improvement on the M-287 fixture, which would mean the tax is genuinely the stride and x28's conclusion needs revisiting. C2 by the fold costing more than 20% extra, which would mean the relayout buys the access pattern and sells the arithmetic. C3 by the re-sort that restores vertex creation order costing more than the layout saves.
SHARE. M-287's tax is 3.37x of cycles/sample at 128 cubed, so the quantity C1 moves is the whole traversal stage on the one grid size where it is worst; C2 and C3 are cost and correctness bounds, not speedups.
VACUITY CONTROL. tax_vs_127 measured on the UNMODIFIED layout must reproduce M-287's 3.37x to within 10%, because a harness that cannot see the tax cannot measure its removal.
P-105 — registered for R-105, before the harness: Harley–Seal carry-save popcount for a per-chunk active count the crate does not yet compute
Ticket: R-105 (S). Records: field, resolution, words, count_naive, count_harley_seal, counts_equal, ns_per_word_naive, ns_per_word_hs, ratio, instructions_per_word_naive, instructions_per_word_hs, control_counts_differ, c1_holds, c2_holds, c3_holds.
Hypothesis. M-349 ESTABLISHED THAT THE BITMAP'S CLAIM WAS ALWAYS A COUNT, SO THE COUNT IS THE QUANTITY THAT MATTERS -- AND NOTHING IN THE SHIPPED CRATE POPCOUNTS THE BITMAP TODAY. dual.rs's five consumers read whole words, fold four rows, or walk set bits (dual.rs:385, :395, :424, :490); there is no counting pass at all. So C1's denominator is a bench-local naive count and this row measures a stage the crate would have to ADD, which is stated here rather than discovered later. Harley-Seal carry-save addition turns n popcounts into about n/8 using only AND, XOR and OR -- safe scalar, no intrinsics -- and it is the reduction half of the AVX2 popcount paper rather than its kernels. (C1) At least 2x on the counting pass over a 64 cubed chunk's bitmap against iter().map(count_ones).sum(). (C2) The count is BIT-EXACT on every fixture: an equality, not a ratio, which is M-349's discipline. (C3) The advantage is monotone non-decreasing in the word count across 16 cubed, 32 cubed, 64 cubed and 128 cubed.
Falsified by. C1 by under 2x at 64 cubed. C2 by one count differing by a single bit, which is the falsifier that matters because a faster wrong count is worthless. C3 by a non-monotone ratio across the four word counts, which would mean the win is a fixture size rather than a mechanism.
SHARE. the counting pass only, and it is a stage that does not exist yet -- so this row prices a mechanism and does not claim a share of extraction. C1's 2x is against a named bench-local baseline, which is why it is legitimate to state as a ratio.
VACUITY CONTROL. control_counts_differ -- the same comparison against a copy with one bit deliberately flipped -- must be 1 on every row, or C2's equality is being asserted by an instrument that cannot see inequality.
P-106 — registered for R-106, before the harness: SWAR sign extraction and edge-crossing masks, exhaustively over all 256 patterns
Ticket: R-106 (M). Records: field, resolution, word_ops, masks_identical_patterns, patterns_tested, mutant_pattern_mismatches, instructions_per_cell_table, instructions_per_cell_swar, ratio, c1_holds, c2_holds, c3_holds.
Hypothesis. THE TWELVE CUT-EDGE FLAGS OF A CELL ARE A FIXED BOOLEAN CIRCUIT OVER ITS EIGHT SIGN BITS, SO SIXTY- FOUR CELLS' WORTH CAN BE EVALUATED IN ONE WORD EACH. Provenance correction this registration carries: Fujita's Bitwise Parallel Bulk Computation DID NOT DOWNLOAD, so the technique is registered against the acquired FastLanes and AVX2-popcount papers, and the paper's 13.4e9 cell-updates/s figure is QUOTED FROM THE RESEARCH DOC RATHER THAN FROM A PAPER IN THE CORPUS -- it is therefore not a comparand and must not be scored against. (C1) The twelve cut-edge flags for 64 cells derive from the eight sign planes in AT MOST 24 word operations. (C2) The SWAR circuit's masks equal the byte-table path's on ALL 256 sign patterns, exhaustively rather than sampled -- x50 is the incident that earns the word 'exhaustively', because there a SAMPLED bound became a release-build panic. (C3) Instructions per cell below the byte-table path's.
Falsified by. C1 by a circuit longer than 24 word operations, which is where the byte-table path wins on instruction count alone. C2 by any one of the 256 patterns disagreeing. C3 by no instruction-count win.
SHARE. the same stage P-121 measures for P-103, and this row inherits P-121's gate -- if integer work is under 15% of extraction, C3's win cannot move extraction and the row closes with C1 and C2 as facts about a circuit rather than as a performance result.
VACUITY CONTROL. patterns_tested must equal 256 exactly, and a deliberately broken circuit must produce mutant_pattern_mismatches greater than zero -- the 256 is only worth having if the comparison can fail.
Group B - rank instead of prefix sum
Flying Edges spends a prefix-sum pass to turn per-row counts into output offsets. A two-level rank directory makes the offset a lookup instead of a pass, at pasta's measured 3.51% space overhead. P-107 carries its own share check in C1 and may close immediately; P-109 and P-110 are both aimed at R-027a and both are scored against V-45 rather than around it.
P-107 — registered for R-107, before the harness: a rank directory over the active-cell bitmap gives the output slot index in O(1)
Ticket: R-107 (M). Records: field, resolution, offset_share, directory_bytes, bitmap_bytes, overhead_fraction, slots_equal, active_cells, short_directory_mismatches, ns_per_query_rank, ns_per_query_scan, c1_holds, c2_holds, c3_holds.
Hypothesis. FLYING EDGES SPENDS A PREFIX-SUM PASS TO TURN PER-ROW COUNTS INTO OUTPUT OFFSETS; A TWO-LEVEL RANK DIRECTORY MAKES THE OFFSET A LOOKUP INSTEAD OF A PASS. The bound available BEFORE the harness, and it is why C1 is checked first: M-135's stage breakdown (docs/measurements/stage_breakdown.csv, columns contour_ms, normals_ms, weld_ms, collider_ms, mean shares 29.0 / 0.4 / 25.5 / 45.0) puts the whole CONTOUR stage at 29%, and the offset work is a fraction of that -- so 5% is reachable but not comfortably. And x54 measured the GPU scan at 4.37% of gpu_total_ms with upload at 87.50%, which is the same quantity on the other path and is BELOW this clause's bar. The GPU figure is not the CPU figure: on the GPU the scan competes with a PCIe upload that dominates the frame, while on the CPU there is no upload at all and the offsets compete only with sampling, interpolation and the emit path -- so the CPU share could legitimately be several times larger, and could equally be smaller because the CPU scan is a sequential add rather than a multi-pass ladder. That is exactly why it is measured rather than inherited. (C1) The offset/compaction stage is at least 5% of CPU extraction, checked first. (C2) A two-level rank directory answers the slot query in O(1) at no more than 3.51% space overhead -- pasta's figure, cross-confirmed in two of the acquired papers -- which is about 1.1 KiB on a 64 cubed chunk's 32 KiB bitmap. (C3) The directory's answers equal the prefix sum's on EVERY cell.
Falsified by. C1 by the offset stage measuring under 5% of extraction, which makes this Amdahl-dead the way x51 was and closes the row before C2 is built. C2 by overhead above 3.51% or by a query that is not O(1) in the bitmap size. C3 by one cell's slot differing from the prefix sum's.
SHARE. C1 is the share and it gates the row; if the offset stage is under 5% this is Amdahl-dead the way x51 was, and saying so cheaply is the row's value.
VACUITY CONTROL. slots_equal must equal active_cells on every row, and a directory built one level short must give short_directory_mismatches greater than zero, or C3 is an equality between two names for the same computation.
P-108 — registered for R-108, before the harness: broadword select to walk the set bits, with no PEXT and no table
Ticket: R-108 (S). Records: field, resolution, active_fraction, set_bits, words, words_nonzero, ns_per_set_bit_walk, ns_per_set_bit_select, ratio, order_identical, c1_holds, c2_holds, c3_holds.
Hypothesis. PEXT AND PDEP ARE FORECLOSED FOR THREE INDEPENDENT REASONS, AND VIGNA'S BROADWORD SELECT IS A THIRD OPTION THAT NEEDS NEITHER THEM NOR A TABLE: multiply, shift, mask and count_ones, branchless. Two things belong on the row rather than hidden. First the honest published price of the foreclosure: Pandey, Bender and Johnson measured the PDEP-plus-TZCNT select at 2 to 4 TIMES the broadword one on Haswell, so this crate's constraint is being paid at a known rate. Second the regime: M-337's measured active fractions are 1.89% at 64 cubed, 0.93% at 128 cubed and 0.46% at 256 cubed on sphere, so a '97% zeros' fixture is not an assumption -- it is the measured regime, and the row cites it rather than positing it. The incumbent is dual.rs:489-497, 'trailing_zeros' plus 'active &= active - 1'. (C1) Broadword select beats that walk on a 97%-zero bitmap. (C2) Identical visitation order and identical emitted indices, because dual.rs:496 exists to keep vertex creation order. (C3) The advantage is reported PER SET BIT rather than per word, so words skipped entirely cannot carry the ratio.
Falsified by. C1 by not beating the current walk on a 97%-zero bitmap, where the 2026-08-23 dossier already argued the cost is dominated by words skipped entirely -- this is a registered expected null. C2 by any difference in order or indices. C3 by a per-word ratio being quoted where a per-set-bit one was promised.
SHARE. the set-bit walk inside place_vertices only, which M-337 measured as the stage the bitmap made 5.5x faster -- so the quantity is real but small, and C3 exists to stop the ratio being inflated by the 97% of words that neither arm touches.
VACUITY CONTROL. words_nonzero must be non-zero and set_bits must EXCEED words_nonzero on every row, or the per-set-bit denominator is one bit per word and the clause measures nothing.
P-109 — registered for R-109, before the harness: Elias–Fano for the edge→vertex structure, which is a dense flat vec and not a map
Ticket: R-109 (M). Records: field, resolution, crossings, samples, dense_bytes, ef_bytes, bits_per_crossing, ns_per_access_dense, ns_per_access_ef, access_ratio, values_equal, mutant_value_mismatches, c1_holds, c2_holds, c3_holds.
Hypothesis. VIGNA'S QUASI-SUCCINCT INDICES ENCODE A MONOTONE SEQUENCE IN ABOUT 2 + CEIL(LOG(U/N)) BITS WITH O(1) ACCESS, NO HASHING AND NO GLOBAL BUILD -- AND EDGE INDICES WITHIN A CHUNK ARE MONOTONE ONCE SWEPT IN ORDER. Three corrections this registration must carry, every one against the research doc. FIRST: there is NO edge-to-vertex MAP. A grep for 'edge_to_vertex', 'edge_cache', 'EdgeKey' and 'edge_id' over crates/isomesh/src/ returns nothing. The structure is 'edge_vertices: Vec
Falsified by. C1 by more than 4 bits per crossing, which is where the dense u32 array's 32 bits per SLOT stops being the thing to beat. C2 by access above 1.5x. C3 by one crossing differing.
SHARE. this row prices an ENCODING and moves no extraction time; C2 is a cost bound and C1 a space bound, so neither is a ratio of a total and x51's bar does not apply. What it feeds is R-027a's 45x ceiling, which M-318 measured and which nothing here re-claims.
VACUITY CONTROL. crossings must be non-zero on every row and values_equal must equal crossings; and a deliberately shifted low-bits width must give mutant_value_mismatches greater than zero, or the decoder is being checked against itself.
P-110 — registered for R-110, before the harness: mutable rank/select for a structure written during extraction, scored against the determinism gate
Ticket: R-110 (M). Records: field, resolution, flips, permutations, ns_per_flip, ns_per_rank_mutable, ns_per_rank_static, rank_ratio, final_structures_identical, distinct_final_states, control_distinct_final_states, c1_holds, c2_holds, c3_holds.
Hypothesis. PIBIRI AND KANDA'S CONTRIBUTION IS RANK/SELECT THAT SUPPORTS FLIP(I) WHILE STAYING FAST, WHICH IS THE SHAPE A STRUCTURE WRITTEN DURING A SWEEP NEEDS RATHER THAN ONE BUILT ONCE. The gate this row is scored AGAINST rather than around: validate/determinism.rs:268-300 runs the extractor three times, the third into a REUSED BUFFER, explicitly to fail when output depends on prior state -- its own doc comment says so. That gate is the reason R-027 was declined and split (V-45), and a mutable rank/select is only admissible here if its final state is a function of the flip SET and not of the flip ORDER. So order-independence is the clause, not the caveat. (C1) flip(i) plus rank stays within 2x of the static directory's rank cost. (C2) The final structure is INDEPENDENT OF THE ORDER THE FLIPS ARRIVE IN, bit-identical over a registered set of seeded permutations of one flip set. (C3) Rank answers equal the static directory's after every permutation.
Falsified by. C2 by any dependence on insertion order in the final structure, which is V-45's objection arriving again and closes the row immediately. C1 by rank costing more than 2x the static directory's. C3 by any rank answer differing after a permutation.
SHARE. no time is claimed of extraction; C1 is a cost bound against a named baseline and C2 is the property the crate's determinism gate demands. A row that passed C1 and failed C2 would be worthless here, which is why C2 is the falsifier that closes it.
VACUITY CONTROL. distinct_final_states must be 1 for a pass, AND a deliberately order-sensitive variant must report control_distinct_final_states greater than 1 in the same run -- the control is what proves the comparator can see disorder at all.
Group C - compaction without hardware help
PEXT/PDEP are foreclosed. simdjson's mechanism reduced to scalar is a [[u8; 8]; 256] const table — 2 KiB, const-evaluable, safe. P-112 consumes P-107's directory and is the phase's only other hard dependency.
P-111 — registered for R-111, before the harness: table-driven scalar compaction, 8 cells per lookup, branchless
Ticket: R-111 (S). Records: field, resolution, active_fraction, set_bits, ns_per_set_bit_walk, ns_per_set_bit_table, ratio, l1_misses_per_set_bit_walk, l1_misses_per_set_bit_table, order_identical, table_bytes, c1_holds, c2_holds, c3_holds.
Hypothesis. SIMDJSON'S COMPACTION MECHANISM IS A 256-ENTRY TABLE MAPPING AN 8-BIT MASK TO A PERMUTATION, AND REDUCED TO SCALAR IT IS A CONST TABLE THIS CRATE CAN ACTUALLY HAVE. A '[[u8; 8]; 256]' const table giving the set-bit positions of a byte is 2 KiB, const-evaluable, safe, deterministic, and it sidesteps _pext_u64 entirely -- which matters because crates/isomesh/src/ today contains zero unsafe, zero core::simd and zero cfg(target_arch), so the constraint is structural rather than a preference. The incumbent is dual.rs:489-497's set-bit walk. (C1) The table beats that walk on a 97%-zero bitmap -- M-337's measured 1.89% / 0.93% / 0.46% active fractions are the regime, not an assumption. (C2) Identical output order and identical indices. (C3) The table's L1 cost does not eat the win, measured as L1 misses per set bit from common::counters::Probe's Cache{L1D, READ, MISS} rather than argued.
Falsified by. C1 by not beating the set-bit walk. C3 by the table costing more L1 than it saves on a 97%-zero bitmap, which is the mechanism's own most likely failure and is why the counter arm is mandatory rather than nice.
SHARE. the set-bit walk inside place_vertices, the same stage P-108 targets; this row's clauses are denominated per SET BIT so the 97% of words that neither arm touches cannot inflate the ratio.
VACUITY CONTROL. set_bits non-zero on every row; order_identical true; and the counter arm must exit(1) on a non-Linux host rather than record a zero -- benches/common/mod.rs:26 is the single cfg(target_os = 'linux') gate and experiment_p12 is the refuse-and-exit precedent.
P-112 — registered for R-112, before the harness: count, scan, scatter, and the argument against the middle phase
Ticket: R-112 (M). Records: field, resolution, count_ms, scan_ms, scatter_ms, total_ms, residual_share, scan_share, scatter_share, rank_total_ms, speedup, output_identical, c1_holds, c2_holds, c3_holds.
Hypothesis. BILLETER'S COUNT-SCAN-SCATTER IS THE STANDARD DECOMPOSITION AND ITS MIDDLE PHASE IS A PREFIX SUM, WHICH P-107'S O(1) RANK REPLACES -- SO THIS ROW ACQUIRES THE COMPARISON RATHER THAN THE ALGORITHM. Runs AFTER P-107, whose rank directory it consumes; that is this row's only hard dependency besides the P-121 gate. (C1) Replacing phase 2 with P-107's O(1) rank cuts the three-phase compaction total by at least 1.25x. (C2) The scan phase is at least 20% of the three-phase total, because a phase under 20% cannot yield 1.25x however completely it is removed. (C3) All three arms emit identical output.
Falsified by. The scatter phase measuring above 70% of the total, which would mean the offsets were never the cost and closes C1 and C2 together. C1 by under 1.25x. C3 by any output difference.
SHARE. C2 IS the share clause and it is arithmetic rather than hopeful -- removing a phase of share s entirely gives at most 1/(1 - s), so 1.25x demands s of at least 0.20, which is exactly the number C2 asserts. The two clauses are therefore consistent by construction and either can close the row.
VACUITY CONTROL. the three phase timings must sum to the measured total with residual_share under 5% -- R-085's discipline, and the reason a stage decomposition is believable at all.
Group D - what shape the occupancy structure should be
Roaring switches container type at 4096 set values per 2¹⁶ chunk — 6.25% density. M-377 has just moved the optimum chunk to 4³, where a chunk is one word. The question all three rows share is whether a near-empty chunk should carry a bitmap at all.
P-113 — registered for R-113, before the harness: Roaring's density thresholds as the chunk-representation decision rule
Ticket: R-113 (S). Records: field, chunk_cells, active_cells, density, bitmap_bytes, array_bytes, bytes_per_active_cell_bitmap, bytes_per_active_cell_array, ns_per_walk_bitmap, ns_per_walk_array, winner, c1_holds, c2_holds, c3_holds.
Hypothesis. ROARING SWITCHES CONTAINER TYPE AT 4096 SET VALUES PER 2^16 CHUNK -- 6.25% DENSITY -- AND SAYS OUTRIGHT THAT 'when applications encounter integer sets with lower density (less than 0.1%) a bitmap is unlikely to be the proper data structure'. The correction this registration carries, and it is the row's most load-bearing content: M-306's 16.8% (gyroid, 688 of 4,096) and 95.1% (thin_plate, 3,896 of 4,096) are REJECTED-BRUSH SHARES, NOT ACTIVE-CELL DENSITIES, and they were measured at 17 cubed with SubgridMarchingTetrahedra at 16 samples per edge IN A DEBUG BUILD. The research doc's inference that 'thin_plate's active density is around 4.9%' is derived from them and MUST NOT BE QUOTED AS A MEASUREMENT; this harness measures density itself. And M-377 has moved the optimum chunk to 4 cubed, where a chunk is ONE WORD. (C1) Measured active-cell density straddles Roaring's 6.25% boundary across the eight reference fields -- at least one field below and one above -- so the representation is a decision rather than a constant. (C2) Below the threshold an array-of-indices beats the bitmap on BOTH bytes and the active-cell walk. (C3) At M-377's 4 cubed optimum a chunk is one word and the bitmap's per-chunk overhead exceeds its payload, measured as bytes per active cell.
Falsified by. C1 by one representation winning on all eight fields, which makes it a constant rather than a decision and is the outcome that closes the row. C2 by the bitmap winning below the threshold on either bytes or walk time. C3 by the bitmap's overhead staying under its payload at 4 cubed.
SHARE. no extraction time is claimed. This row produces a DECISION RULE and its clauses are a density span, a two-sided comparison and a bytes-per-active-cell ratio -- none of them a fraction of a total.
VACUITY CONTROL. active_cells non-zero on every row, and density must span at least one DECADE across the fixture, or the 6.25% boundary is untested by construction.
P-114 — registered for R-114, before the harness: a hierarchical bitmap above the active-cell bitmap
Ticket: R-114 (S). Records: field, resolution, active_fraction, levels, words_tested_flat, words_tested_hier, cells_skipped_per_test, ns_per_cell_flat, ns_per_cell_hier, ratio, mesh_identical, sparsest_field, c1_holds, c2_holds, c3_holds.
Hypothesis. ONE BIT PER 64 CELLS GIVES A SECOND LEVEL AT ONE SIXTY-FOURTH THE SIZE, AND TWO LEVELS SKIP 4,096 CELLS PER TEST. What this registration must state: VDB's node bitmask plus popcount child offset is the same object one level up, it is already in the corpus (10.1145/2487228.2487235), and dual.rs:417 already cites VDB as the source of the flat bitmap's mechanism -- so this row is a RE-MEASUREMENT OF A PUBLISHED STRUCTURE at this crate's granularity rather than a new structure. (C1) At least 1.5x on the active-cell traversal of the SPARSEST FIELD AS MEASURED, with that field named in the CSV rather than assumed. (C2) Two levels skip 4,096 cells per test, reported as cells skipped per word tested. (C3) Identical mesh.
Falsified by. C1 by under 1.5x on the sparsest field as measured, where it must win if it wins anywhere. C2 by cells_skipped_per_test falling short of 4,096 at two levels. C3 by any mesh difference.
SHARE. the active-cell traversal stage, which M-337 measured at 5.5x for the flat bitmap on a surface-free field -- so the stage is known to be large enough to matter and the question is only whether a second level finds anything the first did not. The sparsest field is derived from the run's own active_fraction column, never assumed: the research doc names thin_plate and this harness does not inherit that.
VACUITY CONTROL. words_tested_hier must be STRICTLY LESS than words_tested_flat on at least one row, and cells_skipped_per_test must be non-zero -- a hierarchy that skips nothing is not being tested.
P-115 — registered for R-115, before the harness: Tree-Encoded Bitmaps for a subblock-empty summary, because WAH and EWAH are foreclosed
Ticket: R-115 (S). Records: field, resolution, flat_bytes, teb_bytes, space_ratio, ns_per_access_flat, ns_per_access_teb, access_ratio, answers_equal, cells, truncated_tree_mismatches, c1_holds, c2_holds, c3_holds.
Hypothesis. TREE-ENCODED BITMAPS ARE THE ONLY RLE-FAMILY SCHEME THAT PRESERVES RANDOM ACCESS, WHICH IS THE PROPERTY RANK NEEDS AND THE PROPERTY WAH AND EWAH DESTROY. That is why this is a TEB row rather than a WAH row, and WAH and EWAH are foreclosed by this sweep for exactly that reason -- stated at registration so a later reader does not re-propose them. (C1) Random access costs at most 2x the flat bitmap's per access. (C2) Space saving of at least 1.5x against the flat bitmap. (C3) Identical answers on every cell.
Falsified by. C1 by random access above 2x the flat bitmap's, which is the whole reason to prefer TEB over WAH and therefore the falsifier that closes the family rather than just the row. C2 by under 1.5x space saving. C3 by any cell answering differently.
SHARE. no extraction time is claimed; C1 is a cost bound, C2 a space bound and C3 an equality, so none is a fraction of a total. What the row decides is whether a subblock-empty summary can be compressed without giving up the O(1) access P-107's directory is built on.
VACUITY CONTROL. answers_equal must equal cells, and a truncated tree must give truncated_tree_mismatches greater than zero.
Group E - generating the table instead of transcribing it
One row, and its premise correction is worth more than its clauses: CASES is already derived at compile time by a const fn, so the mistranscription risk the source doc names as the motivation is already mitigated in the shipped path.
P-116 — registered for R-116, before the harness: GRAPHGEN's decision-table pipeline against a case table that is already const-derived
Ticket: R-116 (M). Records: patterns_tested, triangulations_identical, tree_nodes, drag_nodes, average_path_len, instructions_per_cell_table, instructions_per_cell_generated, ratio, properties_held, sabotage_failed, kani_checks, c1_holds, c2_holds, c3_holds.
Hypothesis. GRAPHGEN TAKES A DECISION TABLE OVER BOOLEAN CONDITIONS, SYNTHESISES THE OPTIMAL DECISION TREE BY MINIMUM AVERAGE PATH LENGTH, COMPRESSES IT INTO A DRAG AND EMITS CODE -- AND A MARCHING-CUBES CASE TABLE IS A DECISION TABLE OVER EIGHT BOOLEAN CORNER CONDITIONS. The premise correction is this row's most valuable content and it contradicts the research doc's motivation: 'CASES: [McCase; 256]' at marching_cubes/table.rs:180 is ALREADY DERIVED AT COMPILE TIME by 'const fn build_cases()' at :182-194, and the transcribed Bourke tables (reference.rs:29 BOURKE_EDGE_TABLE, :53 BOURKE_TRI_TABLE) exist ONLY as a test cross-check, imported at marching_cubes/tests.rs:15. So the mistranscription risk the doc names as the motivation IS ALREADY MITIGATED IN THE SHIPPED PATH, and this row compares a synthesised decision tree against a const-fn derivation rather than against a transcription. x50 remains the real incident in this area and it was a BOUND, not a table. (C1) The synthesised decision tree, compressed to a DRAG and emitted as Rust, produces triangulations IDENTICAL TO CASES on all 256 patterns. (C2) The generated form is NOT SLOWER than the table lookup, in instructions per cell. (C3) P-64's four properties hold on the generated form, checked through the existing check_all_properties shape.
Falsified by. C2 by the generated form being slower than the current table lookup. C3 by any of P-64's four properties failing on it -- and that would be the INTERESTING outcome, because it would mean the synthesis is unsound rather than merely unhelpful.
SHARE. C2 is a not-slower bound rather than a speedup, so no share is claimed; the row's value is C1 and C3, which are equalities over an enumerated population of 256.
VACUITY CONTROL. patterns_tested must equal 256, plus a should_panic sabotage arm in the property checker -- proofs.rs:221's the_properties_can_fail is the precedent for the arm and experiment_p64.rs:175-188 is the precedent for asserting a non-zero check count so a vacuous SUCCESSFUL cannot pass.
Group F - determinism, and one live risk nobody has checked
P-117 is the highest-priority row in the group and it is a risk, not a gain: Shewchuk's error-free transformations are broken by FMA contraction, aarch64 fuses more eagerly than x86-64, M-31's hashes have held on both machines, and nobody has checked which of luck and structure is responsible.
P-117 — registered for R-117, before the harness: FMA contraction as a latent golden-hash divergence — a risk audit, not an optimisation
Ticket: R-117 (M). Records: expression_site, file, line, shape, fused_result, unfused_result, ulp_difference, reachable, target, fmadd_in_known_fused_probe, mul_add_call_sites, hashes_identical, golden_rows, c1_holds, c2_holds, c3_holds.
Hypothesis. A RISK AUDIT RATHER THAN AN OPTIMISATION, AND NOBODY HAS CHECKED IT. Shewchuk's error-free transformations are broken by FMA contraction and aarch64 fuses more eagerly than x86-64; M-31's golden hashes have held across both machines, so either nothing on the hot path is contraction-sensitive or the crate has been lucky. What this registration must state about the fixture: M-31's 216 is 8 reference fields x 9 algorithms x 3 resolutions {17, 25, 33} -- golden.rs:73 for the resolutions, :122 for Algorithm::ALL's nine, for_each_reference_field at fields/mod.rs:212 for the eight -- gated by golden_hashes_are_unchanged at golden/tests.rs:59 against crates/isomesh/golden_hashes.json. M-31's own text says 63 hashes, which was T-007's count; 216 is the CURRENT fixture count and the two must not be conflated. The gate is proven able to fire: P-61 moved 135 of the same 216. (C1) At least one expression in crates/isomesh/src/ is contraction-sensitive -- an ab + c shape whose fused and unfused evaluations differ in the last bit on an input the crate can reach. (C2) The 216 golden hashes are identical on x86_64-unknown-linux-gnu and aarch64-apple-darwin today. (C3) Any divergence found is attributed to a NAMED EXPRESSION and reproduced by an isolated probe, not merely observed at the mesh level. METHOD, fixed at registration so the implementer does not choose it: grep mul_add across crates/isomesh/src/ and record the count, since an explicit mul_add is the only way Rust REQUESTS fusion; confirm by DISASSEMBLY rather than assumption whether the aarch64 build fuses an unfused ab + c on the extraction path, with scripts/p69_asm.sh as the precedent instrument; and run the 216-hash fixture on mac_air, committing the digest artefact as an INPUT following docs/experiments/p-81-m5-digests.txt and p-83-m5-hashes.txt.
Falsified by. C1 by finding NO contraction-sensitive expression in crates/isomesh/src/ -- which is the outcome to hope for, is worth an afternoon to establish rather than assume, and is expected because rustc does not contract a*b + c by default. If the disassembly confirms no contraction, C1 is falsified WITH A REASON and that reason is the row's deliverable. C2 by any hash differing between the two targets. C3 by a divergence observed only at the mesh level with no named expression behind it.
SHARE. none. This row moves no time and claims no ratio; it establishes whether a latent divergence exists.
VACUITY CONTROL. the disassembly arm must show a KNOWN-FUSED probe fusing on aarch64 -- column fmadd_in_known_fused_probe must be true on the aarch64 arm -- because a reader that cannot see an fmadd where one must exist cannot claim to see its absence elsewhere. If mac_air is unreachable, C2 is recorded BLOCKED with the reason and C1 and C3 are still delivered from the Linux arm plus the disassembly; a zero-filled peer table is what R-081 shipped and had deleted.
P-118 — registered for R-118, before the harness: Neal's superaccumulator for cross-cell float accumulation, aimed at M-177
Ticket: R-118 (M). Records: field, resolution, rule, elements_vertex_exact, pure_permutation_exact, pure_sign_flip_exact, baseline_elements_vertex_exact, ns_per_solve_ordered, ns_per_solve_superacc, cost_ratio, hashes_moved, triangle_counts_moved, c1_holds, c2_holds, c3_holds.
Hypothesis. NEAL'S SUPERACCUMULATOR IS NOT A REORDERING -- IT IS A FIXED-POINT ACCUMULATOR, 67 CHUNKS OF 64 BITS WITH 32-BIT OVERLAP, THAT IS EXACTLY ORDER-INDEPENDENT -- SO IT IS A SECOND ROUTE TO P-101'S QUESTION THAT DOES NOT DEPEND ON FINDING AN INVARIANT KEY. The bar A-016 sets and this row is denominated in: the accumulator must be reduction-order-invariant UNDER A LATTICE ROTATION, not merely more accurate, and being exactly order-independent is a STRONGER property than agreeing on two platforms. METHOD: bench-local VertexRule through the public DualContouring::with_rule (dual_contouring.rs:254; VertexRule is crate::dual::VertexRule and dual is a pub mod at lib.rs:144), comparand dual_contouring/solve.rs's solve_with -- nine accumulators across twelve EDGE_COUNT slots scattered by edge label and reduced once by sum_equivariant. NO SOURCE CHANGE. (C1) An exactly order-independent accumulator reaches elements_vertex_exact 48 of 48 on the equivariance fixture, where the shipped solve is below it. (C2) Cost under 2x simple ordered summation, which is Neal's own figure. (C3) Golden-hash movement is confined to vertices whose accumulation order changes and NO TRIANGLE COUNT MOVES.
Falsified by. C1 by the duals still failing 48 of 48 with an exactly order-independent accumulator, which would prove M-177's obstruction covers the octahedral case and closes both P-101 and this row together. C2 by cost above 2x ordered summation. C3 by any triangle count moving, which would mean the accumulator changed the geometry rather than its reduction order.
SHARE. the dual vertex solve only. M-25 puts the sharp-feature solve at 3% over Surface Nets and at 6.5% ON ZEN 3, which is the machine this phase runs on; 6.5% is the number to use, so the ceiling is 1/(1 - 0.065) = 1.070x. C1 is therefore a CORRECTNESS clause and C2 a COST BOUND, and neither is or may become a speedup claim.
VACUITY CONTROL. the SHIPPED rule must reproduce x79 / M-413's own elements_vertex_exact reading in the same run -- a harness that cannot reproduce the baseline cannot measure a move away from it -- reported as baseline_elements_vertex_exact beside the measured one.
P-119 — registered for R-119, before the harness: double-buffering as the determinism mechanism
Ticket: R-119 (M). Records: field, extractor, permutations, baseline_spread, double_buffered_spread, mesh_identical_across_permutations, ns_per_cell_single, ns_per_cell_double, cost_ratio, peak_bytes_single, peak_bytes_double, c1_holds, c2_holds, c3_holds.
Hypothesis. PARALLEL SURFACENETS USES DOUBLE-BUFFERED SMOOTHING EXPLICITLY TO GUARANTEE DETERMINISM, AND THIS CRATE'S DETERMINISM TODAY RESTS ON THE LOOPS BEING SEQUENTIAL WITH NOTHING ENFORCING IT. P-9 already found that a chunked consumer appending chunks in a different order gets a different vertex count on noise_cavity. What this registration must state: the implicated path is Welder's first fit over NON-TRANSITIVE epsilon-closeness -- weld.rs:232 Welder, :296 weld, :338 weld_split_by, :220 epsilon_for -- which is why C1's falsifier points at the weld rather than at the traversal. And Parallel SurfaceNets' one-to-two-orders-of-magnitude figure is a PARALLEL result while this crate's loops are sequential, so it is not a comparand. (C1) Double-buffering removes P-9's vertex-count spread on noise_cavity -- 4 under dual_contouring and 2 under manifold_dual_contouring, FINDINGS.md:1641-1642 -- to exactly 0. (C2) The cost is under 1.25x the single-buffer path. (C3) The mesh is identical under every permutation of chunk append order.
Falsified by. C1 by double-buffering not removing P-9's spread, which would mean the order-dependence is in the weld rather than the traversal and would redirect the work to weld.rs. C2 by cost above 1.25x. C3 by any permutation producing a different mesh.
SHARE. C2 is a cost bound on the whole append path and C1 and C3 are determinism equalities, so no clause is a fraction of a total. The quantity at stake is a correctness property the crate currently gets by accident.
VACUITY CONTROL. the SINGLE-BUFFER arm must REPRODUCE THE SPREAD OF 4 AND 2 -- column baseline_spread must read 4 on the noise_cavity dual_contouring row and 2 on the noise_cavity manifold_dual_contouring row -- because a harness that cannot see P-9's defect cannot measure its removal.
P-120 — registered for R-120, before the harness: array-based union-find for per-chunk labelling, answering ✗26 rather than reopening it
Ticket: R-120 (M). Records: field, resolution, arm, chunk_cells, components, components_dug, ns_per_cell_flat, ns_per_cell_union_find, ratio, labels_consecutive, partition_identical, order_independent, c1_holds, c2_holds, c3_holds.
Hypothesis. WU, OTOO AND SHOSHANI REPLACE POINTER-BASED EQUIVALENCE TREES WITH A FLAT ARRAY AND REPORT 5x TO 100x ON RANDOM BINARY IMAGES, WHICH IS AN UPPER BOUND HERE AND NOT A PREDICTION -- VOXEL ISLANDS ARE NOT RANDOM BINARY IMAGES. What this registration must state, because it is the reason the row could look like a reopening: connectivity.rs:29-46 EXPLICITLY REFUSES a union-find in favour of flat labels, because it WAS a union-find and adding fill broke it (x26) -- parent pointers encode union history rather than spatial adjacency. The three union-finds in crates/isomesh/src/ are private and each justified in prose: validate.rs:541 Dsu, validate/sealing.rs:835 UnionFind, and connectivity/world.rs:387 rebuilt from scratch on every restitch. This row is the PER-CHUNK, REBUILT-FROM-SCRATCH kind, it is bench-local, and it ANSWERS x26 rather than reopening it. (C1) At least 2x against the shipped flat-label structure on per-chunk island labelling. (C2) Final labels are CONSECUTIVE and independent of iteration order. (C3) The label sets equal the flat-label path's partition exactly.
Falsified by. C1 by under 2x against the current structure. C2 by any label depending on iteration order, which is x26's defect in a new costume and closes the row. C3 by the two partitions differing.
SHARE. per-chunk labelling only, which is not on the extraction path at all -- so C1's 2x is against a named structure rather than a fraction of a total, and no extraction speedup is claimed or implied.
VACUITY CONTROL. components must exceed 1 on the DUG arm -- column components_dug asserted greater than 1 -- because a labeller tested on a connected world is not being tested.
Group G - the two that are measurements rather than mechanisms
P-121 runs first. It is a measurement, and a C2 total under 15% closes P-103, P-104 and P-106 before anyone writes a harness — which is ✗51's rule spent in advance rather than remembered afterwards.
P-121 — registered for R-121, before the harness: what fraction of extraction is bit work — runs first, gates Group A
Ticket: R-121 (M). Records: field, resolution, scalar, extractor, cycles_total, cycles_sample, cycles_classify, cycles_interpolate, cycles_solve, cycles_emit, cycles_residual, residual_share, float_share, integer_share, instructions_total, instructions_classify, instructions_emit, cells, active_cells, c1_holds, c2_holds, c3_holds.
Hypothesis. BEFORE ANY OF GROUP A IS BUILT, DECOMPOSE EXTRACTION INTO FLOAT WORK AND INTEGER WORK. x51's rule requires it and x51 is itself the example of what happens without it: P-69's C1 asked for 2x on the marginal extraction cost from restructuring the SAMPLE loop, and the loop is 11.6% of that marginal -- not the 11.5% the research doc says -- so its ceiling was 1/(1 - 0.116/2) = 1.061x and the clause was unreachable however well the loop vectorised. STAGES, fixed at registration: sample (field evaluation), classify (the eight-sign case index), interpolate (crossing positions and normals), solve (dual only), emit (table lookup, triangle and quad push, edge-cache indexing), residual. Float = sample + interpolate + solve. Integer = classify + emit. INSTRUMENT: stage counters via common::counters::Probe (benches/common/counters.rs:86, Linux-gated at benches/common/mod.rs:26), reporting CYCLES AND INSTRUCTIONS; the verdict reads the counter form and not the clock, per x24 and M-281. experiment_p15 is the precedent for stage attribution in this crate and experiment_p12 is the precedent for refusing to run without counters. (C1) The stage decomposition ACCOUNTS FOR THE TOTAL: residual_share under 5% of measured cycles on EVERY row. (C2) Integer work -- classification plus the emit path's indexing -- is at least 15% of extraction on at least one reference field at 65 cubed. (C3) The split is real: on a SURFACE-FREE field the classification stage still runs and the emit stage does not, and the measured stage cycles move in exactly those directions. The surface-free control already exists and is reused rather than reinvented: sphere_surface_free, the same sphere sampled a long way from itself so every cell is inactive, at crates/isomesh/benches/experiment_p40.rs:84-93 and listed in its FIELDS. M-337 and x28 both scored on it, so it is the fixture with a published baseline.
Falsified by. C1 by a residual_share above 5%, or any stage reading zero on a fixture where it must run -- either means the instrument cannot see what it claims to. A C2 total under 15% on every field CLOSES P-103, P-104 and P-106 ON THE SPOT, which is a cheap and valuable outcome and is NOT a failure of this row. C3 by emit cycles staying non-trivial on the surface-free arm or classify cycles falling to zero there.
SHARE. this row IS the share instrument. It moves nothing and claims nothing; it produces the denominator that P-103, P-104 and P-106 are denominated in.
VACUITY CONTROL. every stage's cycle count non-zero on a field where it must run; residual_share reported PER ROW rather than pooled; and the surface-free arm's emit cycles at or near zero WITH classify non-zero, which is what proves the two are separable at all.
P-122 — registered for R-122, before the harness: Stream VByte's control/data split, applied to the case stream
Ticket: R-122 (S). Records: field, resolution, arm, branch_misses_per_cell_single, branch_misses_per_cell_split, branch_miss_ratio, instructions_per_cell_single, instructions_per_cell_split, instruction_ratio, mesh_identical, c1_holds, c2_holds, c3_holds.
Hypothesis. STREAM VBYTE KEEPS A DENSE CONTROL STREAM AND A VARIABLE-LENGTH DATA STREAM SEPARATE SO THE DECODER NEVER BRANCHES ON PAYLOAD, AND ONLY THE LAYOUT TRANSFERS HERE. What this registration must state: Stream VByte's 4 billion integers per second on a 3.4 GHz Haswell is the SIMD path, so that figure is NOT A COMPARAND for a scalar arm and must not be scored against. (C1) Splitting the per-cell case index into a dense control stream and the variable-length vertex payload into a second stream REDUCES BRANCH MISPREDICTIONS PER CELL. (C2) Total instructions per cell rise by no more than 10%. (C3) Identical mesh. INSTRUMENT: common::counters::Probe's BRANCH_MISSES; refuse and exit(1) off Linux, because it is the only instrument that can see the quantity C1 is about.
Falsified by. C1 by no branch-misprediction reduction, measured with counters on Linux. C2 by instructions per cell rising more than 10%, which would mean the split pays for itself in the other currency. C3 by any mesh difference.
SHARE. C1 is a per-cell counter ratio rather than a fraction of extraction time, and C2 is a cost bound -- so no time claim is made and x51's bar does not apply. Whether a misprediction reduction is worth anything in wall time is a question this row deliberately does not answer.
VACUITY CONTROL. branch_misses_per_cell_single must be NON-ZERO on the single-stream arm, or there is no misprediction to remove and the ratio is division by a floor.
Phase 25 — the results, twenty entries against twenty registrations
Every row below was pre-registered in crates/isomesh/src/experiment.rs before its harness existed, its
harness was committed before it ran, and its dataset was re-run on a clean tree after every harness in
the phase had landed — so each # commit line names a commit a reader can check out, and
scripts/csv_provenance.sh passes with no new entry on its dirty-tree list. No row changed
crates/isomesh/src/ apart from the twenty registrations themselves, so nothing here moved a golden
hash or any consumer-visible behaviour; that was the phase's condition, not an outcome.
Sixty clauses: 34 HELD, 24 FALSIFIED, 2 VACUOUS. Seventeen of the twenty rows carry at least one
falsified clause and are dual-numbered ✗80–✗96; three do not (M-419, M-430, M-432). Reading the
falsifications rather than the checkmarks is the point, and this phase's are unusually load-bearing:
eleven of them were arithmetically decided before the harness ran and say so in a column, and five
refute a figure this repository or a cited paper had already published.
Two harnesses aborted on their own vacuity controls, and both aborts were worth more than the clause
they interrupted. experiment_p112.rs refused twice — torus 65³ at a residual share of 0.0920, then
sphere 65³ at 0.0692 — and instrumenting all five windows per repetition showed the three
prefix-differenced phases account for the total to the last retired instruction (0.000000 on 40 of
40) while the nanosecond residual reads 4–8% with a field-dependent sign and the two total windows
inside one repetition differ by up to 10%. The bar did not move; the unit did, and
residual_control_mutant_share now proves the resulting zero could have been non-zero (M-44).
experiment_p116.rs refused because emit_node writes the condition-true child first, so the emitted
source enumerates root-to-leaf path words descending while the cross-check walked them ascending — it
was comparing the text against its own reverse, and text == rev(binary) located the defect in exactly
one of three conjuncts.
One committed dataset was wrong in a column no verdict read, and it was replaced rather than annotated.
p-104.csv's values_row_stride recorded m.samples.to_string().len() — the number of decimal digits
in the sample count — and read 6 or 7 on all 72 rows. That is P-64's class of defect exactly: right
header, right row count, garbage value. Fixed to values_row_bytes, which reads 256 / 508 / 512 / 516
at n = 64 / 127 / 128 / 129, and re-run.
And that re-run produced the phase's sharpest method finding, because it re-measured the same binary on
the same fixture twice. Of the 65 columns the two p-104.csv datasets share, 30 are byte-identical
— every verdict column, and tax_vs_127_instructions on all 72 rows — and 35 moved. The split is
total: every instruction-denominated column moved at most 0.006%, and cycle-denominated columns moved
by up to 221.8% (torus 128³ m287_tax_vs_127_unpadded 1.8768 → 6.0389). M-280 says on a
governed CPU a nanosecond is not a unit and ✗24 says a wall-clock ratio is never a gate; this is
those two rules with a control attached, and it is why the coincidence P-104's first run appeared to
find — a 3.3714 against M-287's published 3.37 — is retracted in ✗81 rather than reported.
Nineteen of the twenty harnesses record target_feature_popcnt as false, because the repository sets no
target-cpu and no RUSTFLAGS, so count_ones lowers to a SWAR sequence rather than popcnt. Each row
that could be affected says which of its verdicts is contingent on that and by how much; none is, and
two rows checked it by reading their own machine code rather than asserting it.
💥 ✗80 / M-416 — C1 FALSIFIED as a whole-fixture gate at 21 of 32 rows clearing 0.10 (23 of 32 in instructions), C2 FALSIFIED on 32 of 32 with instruction_ratio spanning 0.579154–1.08354 against a bar of 0.5 and the bit-sliced arm strictly worse on all eight 65³ f32 rows, C3 HELD across 24 of 24 golden hashes, 811,008 case indices and 903,600 sign bits: cutting sign tests per cell from 8.0000 to 1.0476–1.0967 bought nothing because the sign test was never the instruction cost, and every row that looks like a win is a row where the byte comparand pays an f64 penalty — instructions_per_cell_byte 50.8118 against instructions_per_cell_bitsliced 29.4278 (P-103, R-103)
M. cargo bench --bench experiment_p103, docs/experiments/p-103.csv, 32 rows, amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 32 data rows across 64 columns — counted from the file, not from the brief. One block: eight reference fields × {33³, 65³} × {f32, f64}, sixteen rows at cells = 32,768 and sixteen at cells = 262,144, each row four classify arms (byte_dense, bitsliced_dense, swar8_dense, bitsliced_active) plus the shipped MarchingCubes::extract as the C1 denominator, measured in six flat sibling perf_event_open windows per repetition with the arm order rotated by repetition index. Committed at 36e1135 — # commit 36e1135 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:07:57Z, no (WORKING TREE DIRTY), and git merge-base --is-ancestor 36e1135 HEAD passes (the dataset landed as 57e7074, p-103.csv - re-run on a clean tree).
| clause | registered | measured |
|---|---|---|
C1 the case-classification stage is at least 10% of Marching Cubes extraction, P-121's stage boundary, share measured before any speedup is claimed |
≥ 0.10, scored per row | FALSIFIED — c1_holds true on 21 of 32 rows and false on 11; c1_rows_clearing_bar = 21, c1_rows_clearing_bar_instructions = 23, c1_holds_all_rows false on 32 of 32. classify_share spans 0.016235 (fbm_terrain 33³ f32) to 0.545819 (thin_plate 65³ f32); classify_share_instructions spans 0.023508–0.61888 |
| C2 eight sign bit-planes plus eight shift-and-OR pairs produce 64 case indices in under half the instructions per cell of the byte path | instruction_ratio < 0.5 on the worst row |
FALSIFIED — c2_holds false on 32 of 32, c2_holds_all_rows false. worst_instruction_ratio = 1.083542, best_instruction_ratio = 0.579154; instruction_ratio exceeds 1.0 on 8 rows (every 65³ f32 row, 1.051929–1.083542). instruction_ratio_rep_spread ≤ 0.000008, so the miss is not noise |
C3 zero movement in M-31's 216 golden hashes, because the case index is an integer |
0 | HELD — hashes_moved = 0 on 32 of 32; golden_hashes_reproduced = 24 of golden_hash_rows = 24; golden_case_mismatches = 0 over golden_cells_checked = 811,008; golden_sign_mismatches = 0 over golden_samples_checked = 903,600; sign_bits_identical = samples_checked (35,937 and 274,625) on every row |
The vacuity controls fired and they are the licence for the C3 zero.
cases_identicalequalscellson all 32 rows (32,768 and 262,144) — but so doescorrupt_control_mismatches, the same comparison with plane 3 inverted, which flips bit 3 of every cell's case index and is asserted to readcellsexactly rather than merely "> 0".single_bit_control_mismatchesreads 1 on all 32 rows: one flipped bit of plane 3, belonging to the centre cell, produces exactly one mismatch. The coarse control proves the comparator can see a difference; the single-bit control proves it is per-cell and not a length or a checksum. A C3 zero over a comparator that cannot report a mismatch would not have been a measurement.C1's
falseon 11 rows is not "the classify stage is cheap". It is field evaluation being expensive: the 11 rows aregyroid,fbm_terrainandnoise_cavity, where the denominatorns_per_cell_extractreaches 297.649 against 9.586324 on the cheapest row.gyroidcrosses the bar between resolutions on the identical mechanism —classify_share0.090709 at 33³f32(false) and 0.139003 at 65³f32(true) — which is why✗51's per-row scoring is the only honest reading and whyc1_holds_all_rowsis a separate column. The two rows that clear in instructions but not in cycles are bothgyroid(33³f32, 0.158395 against 0.090709; 65³f64, 0.110906 against 0.076753). The denominator is also the conservative one: it is the shippedMarchingCubes::extract, whichP-121measured at 15–24% more than its bit-identical classify-then-compact mirror, so everyclassify_sharehere is that much lower than the same share taken againstP-121's total. C1 was scored on the harder denominator and still cleared on 21 rows.C2's
falseon 32 of 32 locates the cost, and the location contradicts the hypothesis.sign_tests_per_cell_byteis 8.0000 on every row andsign_tests_per_cell_bitslicedis 1.0967 (33³) / 1.0476 (65³) — a 7.3–7.6× reduction in exactly the quantity FastLanes'Scalar_T64result targets — andinstruction_ratiostill never reaches 0.5. The instructions are in the deliverable: assembling 64 dense case bytes costsinstructions_per_cell_bitsliced26.6926–29.9596, a 12% band across all 32 rows, whileinstructions_per_cell_bytespans 24.7684–50.8118, a factor of 2.05. So the bit-sliced arm's cost is essentially independent of field and of scalar width, and every apparent win is the comparand getting worse:instruction_ratiois 0.579154 on all eight 33³f64rows and 0.598879 on all eight 65³f64rows purely becauseinstructions_per_cell_byteis 50.8118 and 44.6246 there, against 24.7684 at 65³f32where the bit-sliced arm loses at 1.083542. The mechanism is real and it is in the wrong column: the sign predicate was 8 tests and is now 1, and the case-index assembly — eight iterations of a four-operation lane spread, run eight times per word — costs what the eight tests did.Two arms that are columns and not clauses, because the registration named the other reading.
instruction_ratio_swar8(one sign byte per sample, eight lanes — the registration's literalp0 | p1 << 1 | … | p7 << 7) spans 0.451656–0.764293,worst_instruction_ratio_swar8= 0.764293, so the unscored reading also misses 0.5 on its worst row.instruction_ratio_active— the eight planes folded toany & !alland walked withtrailing_zeros, which is what a shared classifier would actually return — spans 0.248656–0.689462 and clears 0.5 on 27 of 32 rows overactive_fraction0.007812–0.188477. That is a smaller claim than C2's, not a rescue of it.instruction_ratio_vs_byte_compactreads 0.308582–0.34755 againstinstructions_per_cell_byte_compact85.4002–87.8943, i.e. the bit-sliced word beats the shipped branch-and-compact shape by ~3×; that comparison is deliberately not C2's, becausemod.rs:262-268consumescasein the same loop iteration and a bit-sliced word cannot, soinstruction_ratiois scored deliverable-for-deliverable against a dense byte store.No verdict here is contingent on the popcount lowering.
target_feature_popcntreadsfalseon all 32 rows — no.cargo/config.toml, notarget-cpu, socount_oneswould lower to the ~12-instruction SWAR sequence — andcount_ones_calls_per_cell_bitslicedandcount_ones_calls_per_cell_byteare both 0 on all 32 rows. Every arm is shifts, masks, adds, ORs, comparisons,trailing_zerosandx &= x − 1. Neither C1 nor C2 could move under-C target-cpu=native, which is the only reason it is legitimate not to have built one (M-281).No time claim is made or available.
cycle_ratiospans 0.460299–1.380015 andcycle_ratio_rep_worstreaches 1.73979 on a machine whose measuredghzmoves between 3.977 and 4.1893 inside this run alone and whose governor spans 1.96–5.62 GHz.ns_per_cell_byteandghzare recorded forM-280's reason and no clause consults them; the instruction form carries C2's verdict andinstruction_ratio_rep_spread≤ 0.000008 is why it can.
SHARE, recomputed. C1's share is classify_share, so the clause is its own ceiling and the row's ceiling is 1/(1 − classify_share·(1 − instruction_ratio)) computed in-row. The best row in the whole fixture is thin_plate 65³ f64: classify_share 0.453019 against instruction_ratio 0.598879 gives 1.2221×, and the unscored eight-lane arm's best is thin_plate 33³ f64 at 1.3037× (classify_share 0.424860, instruction_ratio_swar8 0.451656). C2's share is instructions_per_cell_byte itself — the quantity a halving would halve — and it was not halved on any row. Part of this row was decided by arithmetic before the harness existed and the registration says so in its own SHARE: sentence: 1/(1 − 0.10/2) = 1.05× fixes the value of a 2× on a sub-10% stage, which is why C1 is checked first and why the 11 falsified rows close on arithmetic rather than on C2. The gate that made the row live at all is R-121's measured integer_share maximum of 0.7245 at 65³ against a 0.15 bar; a classify stage that was not integer-dominated would have been Amdahl-dead before either clause was measured. What survives is C3 — a bit-sliced sign plane reproduces the shipped eight-sign integer on 811,008 cells and the shipped sign predicate on 903,600 samples, exactly, and it is the crate's first shared classifier — and the finding that its cost is field- and width-independent where the six inline copies' cost is not. Neither fact is a speedup and no ticket is filed for one.
💥 ✗81 / M-417 — C1 VACUOUS because the layout it is about is unreachable through the public API — the registered control read 1.0173× where it needed 3.37×, while C1's own figure of 1.0138× sat under its 1.5 bar — C2 FALSIFIED at a fold instruction ratio of 1.8054 against 1 ± 0.2, C3 HELD as a bit-identical equality on 72 of 72 rows; and the strongest thing in the file is a retraction: M-287's 3.37× tax, which the superseded dataset appeared to reproduce at 3.3714×, reads 8.1052× on the re-run — a 2.40× move on the same measurement of the same code, while c2_instruction_ratio_fold read 1.8054 on both (P-104, R-104)
M. cargo bench --bench experiment_p104, docs/experiments/p-104.csv, 72 rows, 66 columns, f32
throughout, amd-ryzen-9-5900x-12-core (Zen 3), ghz 4.1445–4.1860 on every row. Four # comment
lines plus one column header plus 72 data rows — counted from the file, not from the brief: nine
field values (sphere, torus, box_exact, csg_difference, thin_plate, gyroid, fbm_terrain,
noise_cavity, and sphere_surface_free as the ninth, M-287's own surface-free fixture) × four
resolution values {64, 127, 128, 129} × two layout values (along_x 36 rows, interleaved
36), reps = 5 sibling counter windows per arm, ten arms per row reduced to stages by prefix
difference. Committed at d12dddc — # commit d12dddc on amd-ryzen-9-5900x-12-core at
2026-08-29T01:10:18Z, no (WORKING TREE DIRTY); the dataset landed as bdb9baa
(p-104.csv - re-run on a clean tree), and git merge-base --is-ancestor bdb9baa HEAD passes.
| clause | registered | measured |
|---|---|---|
C1 bit k being the k-th cell of a 4×4×4 block brings M-287's 128³ tax below 1.5× on M-287's own fixture |
c1_bar = 1.5, and only if the vacuity control reproduces 3.37× to within 10% |
VACUOUS — c1_holds reads the literal string vacuous on 72 of 72 rows; c1_vacuity_control_reproduced = false, c1_vacuity_control_tax 1.0173 against c1_vacuity_control_target 3.37, and the m287 scaffold beside it m287_scaffold_control_tax 5.8267 — neither within 10%. C1's own figure, c1_tax_vs_127_interleaved = 1.0138 on c1_field = sphere_surface_free, is under the 1.5 bar and is worth nothing |
C2 active_word's fused any & !all fold survives the relayout within ±20% of its instructions per cell |
c2_tolerance = 0.20 about 1 |
FALSIFIED — c2_instruction_ratio_fold = 1.8054, and c2_instruction_ratio_fold_this_row 1.9166 / 1.8337 / 1.8054 / 1.6881 at 64 / 127 / 128 / 129, outside [0.8, 1.2] at every size; instructions_per_cell 1.652409–1.781632 along_x against 3.007599–3.167085 interleaved; c2_holds false on 72 of 72 |
| C3 the emitted mesh is bit-identical | equality | HELD — c3_holds and mesh_identical true on 72 of 72; c3_list_matches_scalar, c3_list_matches_shipped and c3_recording_wrapper_transparent true on 72 of 72. Cost, recorded not footnoted: resort_ns_per_vertex 1.615148–3.204712 on the 30 interleaved rows that have vertices |
A coincidence, retracted — and it is the most useful number in this row. This dataset supersedes
beebe8f, whose only difference in source is the one recorded column fixed ind12dddc(experiment_p104.rs:1564), outside every counted window: no measured quantity's code path moved between the two runs, and both were clean-tree. Yetm287_tax_vs_127_unpaddedonsphereat 128³ went 3.3714 → 8.1052, a 2.40× move, becausem287_cycles_per_sample_unpaddedwent 91.685142 → 135.475250 at 128 while the 127 denominator went 27.194825 → 16.714696. The superseded draft of this entry quoted 3.3714 as reproducingM-287's published 3.37 to four figures. That claim is withdrawn: a cycle ratio that reads 3.3714 on one clean run and 8.1052 on the next reproduces nothing, and the agreement was a coincidence of two independently drifting numbers.M-280and✗24arriving as a retraction rather than as advice. It strengthens C1'svacuousverdict — the control failed on both runs, once by reading no tax where it looked (c1_vacuity_control_tax0.9959 then 1.0173) and once by the scaffold beside it reading far more than 3.37 (7.9472 then 5.8267).The contrast, same file, same fixture, two clean runs. Of the 65 columns the two datasets share, 30 are byte-identical, including every verdict column (
c1_holds,c2_holds,c3_holds,mesh_identical, all threec3_list_*,c2_instruction_ratio_fold= 1.8054,tax_vs_127_instructionson all 72 rows) and every structural one (active_cells,cells,samples,bitmap_words,bitmap_bytes,m287_padded_row_samples,target_feature_popcnt,count_ones_calls_per_counted_window). 35 moved, and the split is total: the instruction-denominated ones moved by at most 0.006% (c2_instruction_ratio_fold_this_row1.8053 → 1.8054 on one row;instructions_per_cell0.001%), the cycle-denominated ones by up to 221.8% (m287_tax_vs_127_unpaddedontorus128³ 1.8768 → 6.0389;cycles_per_sampleup to 44.9%,tax_vs_127up to 80.3%,c1_ceiling_at_128's maximum 1.08274 → 1.00654). The second run is simply the quieter machine —tax_vs_127now spans 0.9894–1.1262 where it spanned 0.5565–1.9984,c2_cycle_ratio_fold_this_rowspans 1.7229–2.3844 with no zero rows where four rows previously collapsed to 0.0000 on a non-positive prefix difference, andresort_ns_per_vertexon the interleaved arm spans 1.615148–3.204712 where it previously reached 35.872449. C2's verdict survives both runs unchanged to four decimals; no cycle figure in this file survives either run as a quotable quantity.Why C1 is
vacuousand not falsified. The tax is nowhere near the bitmap:tax_vs_127on the unmodifiedalong_xbitmap stage at 128 onsphere_surface_freeis 1.0173, and the two aliasing periodsM-287separated are both inemit_quads(dual.rs:697-713:AXIS = 0walkszinnermost at arow · size[1] · 4= 64 KiB stride,AXIS = 2walksyinnermost at arow · 4= 512-byte one). Where the tax does live the scaffold arm sees it plainly — every 128³ row of the unpadded scaffold is taxed (m287_tax_vs_127_unpadded1.1245–8.1052,m287_l1d_misses_per_sample_unpadded5.291085–6.313110) and every padded twin is not (m287_tax_vs_127_padded1.0019–1.1526,m287_l1d_misses_per_sample_padded1.530724–1.546318). And no caller can reach the taxed layout any more: the tax is a property ofDualMesher::values, whose row stride isrow_stride(size) = size[0] | 1floats sinceA-024(dual.rs:333); anf3264 KiB plane needsrow · size[1] = 16384 = 2¹⁴, and an oddrowgreater than one cannot divide a power of two.m287_padded_row_samplesis that arithmetic in the file — 65 / 127 / 129 / 129 at the four sizes, so 128³ pads to 129 and the spike is gone before any relayout is proposed. The unpadded arm is therefore reconstructed bench-local, andvalues_row_bytes256 / 508 / 512 / 516 withvalues_plane_bytes16384 / 64516 / 65536 / 66564 is the reconstruction saying so: atn = 128exactly the 512-byte row and the 65,536-byte = 2¹⁶ planeM-287named. Had the control been waived, 1.0138 < 1.5 would have been recorded as C1 HELD on a fixture where nothing was ever taxed. That is the whole reason the control was registered.
c3_holds= true is not "the interleaved layout won". It is the equality it says it is: a 4×4×4 word can be walked back into the ascending-xorderdual.rs:489-497needs, exactly, with the mesh bit-identical — and the mirror is licensed, becausec3_list_matches_shippedis true on 72 of 72 against the traversal the shippedDualContouringactually performs, recovered through a recordingVertexRuleinjected with the publicDualContouring::with_rule. What did not happen is any saving:interleavedis slower thanalong_xon 36 of 36 (field, resolution) pairs,cycles_per_sampleratio 1.4570–1.8704 (along_x1.815406–2.260030 againstinterleaved3.048325–3.483571) — and that ordering is the one cycle-denominated statement here that held across both runs. The registered C3 falsifier — the re-sort costing more than the layout saves — therefore cannot be scored as a cost at all: there is nothing saved to pay the 1.615148–3.204712 ns/vertex re-sort out of.resort_ns_per_vertexreads the literalunavailableon 12 of 72 rows, exactly the rows whereactive_cells= 0 —sphere_surface_freeat all four sizes, andthin_plateat 64 and 128 against 8,192 active cells at 127 and 129. That is a per-vertex quantity refusing to divide by zero rather than recording a fabricated one.The instruction form carries C2, and the file shows why in both directions.
tax_vs_127_instructionsis 0.9918–1.0681 across all 72 rows — byte-identical to the superseded run — while the cycle tax spans 0.9894–1.1262 here and spanned 0.5565–1.9984 there: a cache-set stride effect is by construction invisible to an instruction count, and its absence there is the signature that the arm measures layout rather than work.target_feature_popcntisfalseandcount_ones_calls_per_counted_windowis0on 72 of 72 — this build emits nopopcnt, the fold arm accumulates withacc ^= wordand never popcounts, so no verdict here is contingent on the popcount question.The registration's own correction, which stands.
experiment.rs:3192says the active-cell bitmap packs "64 cells peru64" and that is wrong by one:dual.rs:359setsbit_row = size[0].div_ceil(64)and packs one bit per sample, alongxonly; the cell row is one word shorter and is handled separately bycell_words = cells_x.div_ceil(64)(dual.rs:484) andcell_mask(dual.rs:445).P-104's hypothesis carries that correction, which is where it belongs —experiment.rs:27-31forbids amending a registration after its run, so the documented-wrong line is not something to edit; the record corrects it. The asymmetry is priced, not decorative:E-307measured the packed stage going 0.451–0.470 ns/cell at 128 samples to 0.599–0.637 at 129, about 30% of the stage for a word that cannot contain a cell.One column was wrong and was fixed before this dataset.
values_row_striderecordedm.samples.to_string.len— the decimal digit count of the sample count, 6 or 7 on every row ofbeebe8f— and is replaced ind12dddcbyvalues_row_bytes, which reads 512 atn = 128as the module doc's "512-byte row" requires. No verdict read either form.
SHARE, recomputed. C1's share is measured in this run, not quoted:
bitmap_share_of_m287_scaffold — the along_x bitmap stage's cycles per sample over the m287
scaffold's, same field, same size, same run — is 0.002006–0.184607 over 72 rows and 0.019265 on
the row C1 is scored (sphere_surface_free, 128, along_x), because at that size the scaffold costs
96.749480 c/s and the bitmap stage 1.863848. c1_ceiling_at_128 = 1/(1 − share·(1 − 1/tax)) is
therefore at most 1.00654 across all 72 rows (sphere 129³ along_x) and reads 1.00033 /
1.00044 on the two rows the clause is actually scored on — so C1's ceiling was arithmetically
decided before the harness existed: even a perfect transposition buys under 0.05% of the scaffold where
the clause is registered. That conclusion is the one thing on the cycle side that both runs agree on —
the ceiling's maximum moved 1.08274 → 1.00654 between them, and ≈1 either way. The Group A gate that
put this row live rather than Amdahl-dead is R-121's measured integer_share maximum of 0.7245 at
65³ against a 0.15 bar; that gate says the integer work is worth attacking, and this row says the
active-cell bitmap is not the place. C2 is a cost bound and C3 an equality — neither is or may become a
speedup claim, and the one ratio here that could be mistaken for one (cycles_per_sample, interleaved
slower on 36 of 36) is a wall clock and is never a gate (✗24).
💥 ✗82 / M-418 — C1 FALSIFIED on 32 of 32 rows with the best c1_deciding_ratio at 64³ reading 1.039764 against a 2× bar, C2 HELD bit-exact on 32 of 32 with the one-bit control differing on all 32, C3 VACUOUS on 28 of 32 rows and FALSIFIED on the one field whose trend clears its own noise: LLVM autovectorises the naive fold to 8.75 = 35/4 instructions per word and leaves the carry-save chain scalar at 9.0625 = 145/16, so Harley–Seal executes more instructions per word on every row (instruction_ratio ≤ 0.965255) and the mechanism's saving is competing against a saving the compiler already took (P-105, R-105)
Verdict encoding. This harness writes
c1_holds/c2_holds/c3_holdsas0/1, notfalse/true—c1_holds=0on all 32,c2_holds=1on all 32,c3_holds=0on all 32. The0inc3_holdsis not the whole verdict: the string columnsc1_verdict/c2_verdict/c3_verdictcarry it, andc3_verdictreadsVACUOUSon 28 rows andFALSIFIEDon 4. Read the string columns; the integers cannot distinguish falsified from unscoreable.
M. cargo bench --bench experiment_p105, docs/experiments/p-105.csv, 32 rows, f64 (scalar on every row), amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 32 data rows across 54 columns — counted from the file, not from the brief. One block: eight fields (sphere, torus, box_exact, csg_difference, thin_plate, gyroid, fbm_terrain, noise_cavity) × four resolution values {16, 32, 64, 128}, giving words {256, 1024, 4096, 32768} and bitmap_bytes 2,048 → 262,144. Each row is two interleaved counted arms — naive iter.map(count_ones).sum against the sixteen-word Harley–Seal carry-save fold — with windows_per_arm = 5 and reps ∈ {65536, 16384, 4096, 512} chosen so every window processes about 2²⁴ words regardless of bitmap size. Measured on beebe8f — # commit beebe8f on amd-ryzen-9-5900x-12-core at 2026-08-29T00:09:21Z, no (WORKING TREE DIRTY) — and the dataset landed as f80dfde, p-105.csv - re-run on a clean tree; git merge-base --is-ancestor f80dfde HEAD passes.
| clause | registered | measured |
|---|---|---|
C1 at least 2× on the counting pass over a 64³ chunk's bitmap against iter.map(count_ones).sum |
≥ 2.0 at resolution = 64 |
FALSIFIED — c1_holds = 0 and c1_verdict = FALSIFIED on 32 of 32. c1_deciding_resolution = 64 on every row and c1_deciding_ratio spans 0.865097 (noise_cavity) to 1.039764 (thin_plate): the mechanism's best 64³ field is 4.0% faster, not 100%. Across all 32 rows ratio (cycle-denominated) runs 0.659020 – 1.070207 and ns_ratio runs 0.656369 – 1.072622; c1_disagreement = 0 on 32 of 32, so the cycle form and the wall-clock form agree about the 2× bar and the cycle form carries the verdict |
C2 the count is bit-exact on every fixture — an equality, not a ratio (M-349's discipline) |
exact equality | HELD — counts_equal = 1 and c2_verdict = HELD on 32 of 32; count_naive == count_harley_seal on every row, from 128 (thin_plate 16³) to 118,885 (noise_cavity 128³). The vacuity control fired: control_counts_differ = 1 on 32 of 32 with control_delta = 1 — one deliberately flipped bit, seen. tail_lengths_checked = 65 with tail_mismatches = 0 closes the remainder path the fixture cannot reach (all four words are multiples of 16) |
| C3 the advantage is monotone non-decreasing in the word count across 16³, 32³, 64³, 128³ | monotone, three steps | VACUOUS on 28 of 32 / FALSIFIED on 4 — c3_vacuous = 1 and c3_verdict = VACUOUS on the 28 rows of seven fields; c3_steps_separated = 0 on all 28, so no consecutive pair's [ratio_min, ratio_max] was ever disjoint. box_exact is the only field where the trend is resolvable — c3_trend_span 0.029351 > c3_noise_span 0.008606, c3_steps_separated = 1, advantage_exists = 1 on all four rows — and there C3 FALSIFIES: ratio goes 1.009483 → 1.038835 → 1.022979 → 1.011367 and monotone_step_holds = 0 at 64³ and 128³, i.e. the advantage decreases over the last two steps |
What C3's 28
VACUOUSrows mean, and what they do not. They do not mean the clause was skipped. Two of the harness's three registered unscoreability conditions fired, both from the run's own numbers:
- No advantage to be monotone in.
advantage_exists(ratio_min > 1, the lowest of the row's five window pairs) reads0on 7 of 32 rows —sphere16³,thin_plate16³,fbm_terrain16³/32³/128³,noise_cavity16³/64³. On those rows Harley–Seal is behind in at least one window;thin_plate16³'sratio_minis 0.655124 andfbm_terrain128³'s is 0.761105. Ordering a quantity that is not positive is not a monotonicity test.- The trend is inside the instrument. On 5 of 8 fields
c3_trend_span<c3_noise_span:sphere0.341790 < 0.381687,torus0.021846 < 0.085949,gyroid0.019872 < 0.043437,noise_cavity0.205110 < 0.382109, and worst of allfbm_terrain0.025024 < 0.623962 — the four-point trend is 25× narrower than one of its own rows' reproducibility across five interleaved windows. This isM-280/✗24exactly: on a governed CPU a nanosecond is not a unit, this machine ispowersave/balance_performancespanning 1.96–5.62 GHz, and a wall-clock ratio is never a gate.ghzis on every row (4.1616 – 4.1870, so the clock was in fact quiet) and it still does not license ranking inside the noise. Reporting the size of what cannot be resolved isR-085's discipline, andc3_trend_span/c3_noise_spanare that report.C1's
0is not a defect in the implementation — it is the compiler already holding the ground.instructions_per_word_naivereads exactly {8.8711, 8.7803, 8.7576, 8.7510} by resolution andinstructions_per_word_hsexactly {9.5040, 9.1729, 9.0901, 9.0660}. The disassembly says why: the naive fold is autovectorised — twomovdqu, twice thepsrlw/pand/psubb/paddbbyte-population sequence, closed bypsadbw/paddq— 35 SSE2 instructions over 4 words = 8.75 exactly; the carry-save chain's nine live accumulators keep it in general-purpose registers one word at a time, 145 scalar instructions over 16 words = 9.0625 exactly. At 128³ the counters read 8.7510 against 8.75 (0.011% over) and 9.0660 against 9.0625 (0.039% over), which is the check that the counted window contains the loop it claims to and nothing else. Soinstruction_ratio= naive/HS is < 1 on all 32 rows, 0.933416 → 0.965255: the mechanism issues more instructions per word, not fewer. This clause was decided by arithmetic available fromobjdump -dbefore any timer ran.The null was measured in the mechanism's best case, not its worst.
target_feature_popcnt=0on 32 of 32 — the repository sets notarget-cpuand noRUSTFLAGS,POPCNTis SSE4.2-era and not in the baselinex86_64, andobjdump -dfinds zeropopcntinstructions in the bench binary. That is the regime where the popcounts Harley–Seal removes are a ~12-instruction SWAR expansion rather than one instruction at four per cycle, i.e. the regime that favours the mechanism. It still does not win. A row measured undertarget_feature_popcnt=1is not comparable with these, and would only be worse for Harley–Seal.Where the mechanism does win, and why it cancels.
ipc_hsreaches 5.1396 againstipc_naive4.8493; the carry-save chain is the better-scheduled code. It also executes 3.5–7% more instructions per word. The two cancel:cycles_per_word_naive1.8046–2.8715 againstcycles_per_word_hs1.7661–2.9116, andratiosits on 1.0.The crate does not count the bitmap, and the harness checked rather than asserted it.
count_ones_in_dual_rs=0on 32 of 32, read out ofcrates/isomesh/src/dual.rson every run. The bitmap's five consumers read whole words (:385), read a word shifted by one (:395), fold four rows into an active-cell word (:424), mask off words carrying no cell (:445) and walk set bits (:490). The fixture mirrors the crate's own geometry rather than approximating it:bit_rowruns 1/1/2/3 whilecell_wordsruns 1/1/1/2, the documented sample-row/cell-row asymmetry atdual.rs:472-484.
SHARE, recomputed. C1's share of extraction is exactly zero, and count_ones_in_dual_rs = 0 is the column that says so — there is no counting pass in the shipped crate, so ✗51's 1/(1 − share·factor) ceiling has no share to divide and this row prices a stage the crate would have to add. What C1 is denominated in is words at resolution = 64 — 4,096 words, bitmap_bytes = 32,768, exact by construction — against a named bench-local baseline, which is the only reason stating it as a ratio is legitimate. C2's share is words: the equality is over every word of every bitmap, and it cannot be vacuous over an all-zero map because active_cells is asserted non-zero and runs 128 → 118,885 (active_fraction 0.003906 → 0.296387). C3's share is the span of words, 256 → 32,768, a factor of 128, with bitmap_bytes crossing out of L1 (32 KiB) into L2 — so its unscoreability is not an artefact of measuring inside one cache level. No clause here is or may become an extraction speedup claim, and none was made.
🔬 M-419 — C1, C2 and C3 all HELD on 8 of 8 rows: the circuit is 12 word operations and 24 including the plane build against a bar of 24, its masks equal the crate's own table on 256 of 256 patterns where a deliberately broken circuit misses 192, and it costs 11.3602 instructions per cell against the byte table's 94.3858 — ratio 0.1204, a 7.72–8.31× cut on the classify stage that buys an extraction ceiling of 2.4752× at best and 1.0231× on fbm_terrain, because the twelve flags take only 128 distinct values and so cannot feed CASES (P-106, R-106)
M. cargo bench --bench experiment_p106, docs/experiments/p-106.csv, 8 rows, 64 columns —
counted from the file: four # comment lines, one column header, eight data rows. The registration names
twelve of those columns; the harness records fifty-two more. One row per field — sphere, torus,
box_exact, csg_difference, thin_plate, gyroid, fbm_terrain, noise_cavity — all at
resolution = 65, i.e. samples = 274,625 and cells = 262,144 (64³), with sample_bit_row = 2,
cell_words_per_row = 1 and pad_lanes = 0, so no row is measured on a padded word. reps = 7, eight
sibling counter windows per repetition (never nested — Zen 3 has six general-purpose counters and Probe
opens six), and the two registered arms alternate which runs first by repetition parity.
amd-ryzen-9-5900x-12-core (Zen 3), ghz 4.1774–4.1848. Stamped f80dfde —
# commit f80dfde on amd-ryzen-9-5900x-12-core at 2026-08-29T00:09:45Z, no (WORKING TREE DIRTY) — and
landed as dd8ef7f (p-106.csv - re-run on a clean tree, that one file, 13 insertions).
git merge-base --is-ancestor passes for both against HEAD.
| clause | registered | measured |
|---|---|---|
| C1 the twelve cut-edge flags for 64 cells derive from the eight sign planes in at most 24 word operations | ≤ 24 | HELD, and exactly rather than by margin — word_ops = 12 (twelve XORs, one per edge, over EDGE_CORNERS) and word_ops_total = 24 = word_op_bar = 24, of which word_ops_plane_build = 12; c1_holds and c1_holds_with_plane_build both true on 8 of 8. The count is not estimated: the circuit is written once over a four-operation alphabet and instantiated twice, on u64 and on a counting word type, and tally_agrees_with_u64 = true on 8 of 8 is the assertion that the counted circuit is the measured one |
| C2 the SWAR masks equal the byte-table path's on all 256 sign patterns, exhaustively rather than sampled | 256 of 256 | HELD — masks_identical_patterns = patterns_tested = 256, tested packed 64 patterns to a word so each sits in a different bit lane; masks_identical_patterns_uniform = 256 is the weaker same-lane form, kept so a lane bug and a logic bug stay distinguishable. Extended past the pattern space on the same rows: cells_agreeing = cells = 262,144 and cells_agreeing_random = 262,144 on a 50%-dense pseudorandom sign field where every word boundary is crossed. The comparand table is itself derived twice and cross-checked — table_matches_cases_patterns = 256, asserted before any measurement runs |
| C3 instructions per cell below the byte-table path's | ratio < 1 | HELD on 8 of 8 — instructions_per_cell_swar 11.3602 (11.4408 on fbm_terrain) against instructions_per_cell_table 94.3858 on six rows, 88.3706 and 89.3701 on the other two; ratio = 0.1204 / 0.1271 / 0.1295, i.e. 7.72× to 8.31× fewer instructions. instruction_ratio_rep_spread ≤ 0.004092 across 7 repetitions, so the win is not a clock artefact — it is a count |
What the 8.31× is not.
distinct_cut_masks= 128 on all 8 rows andcomplement_pairs_agree= 256 of 256: complementing all eight signs preserves "these two differ", socut_mask(case) == cut_mask(case ^ 0xFF)— the classic Marching Cubes complement ambiguity, recorded as two columns rather than left as a remark. The twelve flags are strictly less information than the case index and cannot feedCASES, because that map is not injective. C3's win is on the crossing-allocation half of classification only; the triangle table still needs the case byte, and that isP-103's row, not this one.How much of the win is the circuit and how much is the shape of the answer. Within one layout,
ratio_planes_layout= 0.0720 (0.0725 onfbm_terrain) andratio_masks_layout= 0.6855 (0.7240, 0.7318) — 13.9× in the plane layout against 1.46× in the per-cell mask layout. The registeredratiocompares each arm in its own native layout, which is the honest comparison because there is no layout-neutral consumer, andinstructions_per_cell_table_planes= 157.8377 is an upper bound on the byte path in the plane layout: it converts with a per-cell scatter, not with a bit-matrix transpose, because a transpose is itself a SWAR mechanism and would make the comparand partly the thing under test.All four vacuity controls fired.
mutant_pattern_mismatches= 192 of 256 — edge 0 computed aslo & hiinstead oflo ^ hi, the bug a reader would most plausibly write — so the 256 is admissible rather than an equality between two names for one computation.mutant_cell_mismatches_carry= 3,861 of 262,144, the plane build withhi << 63dropped; it is scored on the pseudorandom field deliberately, because on every reference field the sample atx = n − 1is outside, its sign bit is 0, and dropping the carry-in changes nothing — that control would have read 0 and proved a live comparator dead.tally_agrees_with_u64true on 8 of 8, andcut_cells> 0 on every row (2,048 onthin_plateup to 28,375 onnoise_cavity), so no row compares two ways of computing zero.No verdict here is contingent on the popcount lowering.
target_feature_popcnt= false on all 8 rows, andcount_ones_calls_per_cell_swar=count_ones_calls_per_cell_table= 0: the circuit is XOR, shift and OR, the packer is a shift-and-OR fold, and the byte arm is a table index. A-C target-cpu=nativebuild could not moveratio, and measuring one would mean comparing across binaries, whichM-281forbids.The clock columns are provenance.
ns_per_cell_swar0.763000–0.782449 againstns_per_cell_table3.896408–4.149829,cycle_ratio0.1839–0.2002, besideghz. No clause consults them: on a governed CPU spanning 1.96–5.62 GHz a nanosecond is not a unit (✗24,M-280), and C3's verdict is carried by the instruction form.The named figure that is not a comparand. Fujita's Bitwise Parallel Bulk Computation did not download in
M-415's acquisition, and its 13.4 × 10⁹ cell-updates/s is quoted fromdocs/research/2026-08-28-bitpacking-simd-acquisition-and-backlog.md, not from any paper in the corpus. Nothing above is scored against it and no column is denominated in it.
SHARE, recomputed. swar_saving_share_instructions = (instructions_per_cell_table −
instructions_per_cell_swar) / instructions_extract_mc, per row, and extraction_ceiling =
1 / (1 − that) — ✗51's arithmetic, measured in this binary against the shipped MarchingCubes::extract
on the same grid in the same run. The best row is sphere: 83.0256 saved against 139.3075,
swar_saving_share_instructions = 0.595987, extraction_ceiling = 2.4752×. Then 2.3978 (torus),
2.0628 (thin_plate), 1.9759 (box_exact), 1.8550 (csg_difference) — and it collapses to 1.2132×
(gyroid), 1.0760× (noise_cavity) and 1.0231× (fbm_terrain), where instructions_extract_mc
is 3,411.8421 per cell and field evaluation owns almost all of it. An 8.31× on classify is not an 8.31×
on extraction: the largest honest number in this row is 2.4752×, and that is a ceiling at zero
implementation cost, not a speedup. The gate that opened this row is P-121's, quoted from
docs/experiments/p-121.csv rather than inherited: max_reference_integer_share_at_65 = 0.724533,
which is integer_share on the sphere 65³ f32 marching_cubes row against the 0.15 bar — and on the same
file fbm_terrain 65³ f32 marching_cubes reads integer_share 0.021974, which is precisely why this
row measures eight fields instead of quoting one. (Both figures moved on the clean tree: the harness's own
SHARE prose cites the pre-run's 0.7260 and 0.0215, and p-121.csv reads 0.724533 and
0.021974. Neither move changes a verdict here, and both are recorded so the two artefacts do not
silently differ.) Two more shares are on every row for the same reason: case_stream_share_instructions
0.006563–0.161172, the case-index build alone measured here rather than imported, and
cut_edge_share_instructions 0.025901–0.677535 — and stated plainly, the shipped extractor never
materialises a cut mask at all, so that column is what a cut-mask pass would cost as a fraction of a
whole extraction, not a stage share of the shipped path. C1's share is not a share: it is an exact integer
against an exact bar, identical in every build and on every machine. C2's is an enumerated population of
256, exact by construction.
💥 ✗83 / M-420 — C1 FALSIFIED on 24 of 24 rows with offset_share spanning 0.000328–0.009714 against a 0.05 bar, so the offset stage is at most 0.97% of extraction and the mechanism's whole extraction-level ceiling is 1/(1 − 0.009714) = 1.0098× — Amdahl-dead exactly the way ✗51 was, and the registration's own named falsifier; C2 HELD at 0.032227 space overhead against 0.0351 with a rank query folding at most 7 words at 33³, 65³ and 129³ alike, and C3 HELD with slots_equal = active_cells on all 24 rows (512–118,885) against a one-level-short directory that mismatches 47,104–1,651,200 times (P-107, R-107)
M. cargo bench --bench experiment_p107, docs/experiments/p-107.csv, 24 rows, f32 samples
(the harness's Bitmaps::build(values: &[f32], n: u32)),
amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 24 data rows
across 53 columns — counted from the file, not from the brief. The fixture is eight fields
(sphere, torus, box_exact, csg_difference, thin_plate, gyroid, fbm_terrain, noise_cavity)
× three resolutions (33, 65, 129), one row each; cells is 32,768 / 262,144 / 2,097,152 and
cells_checked — every bit position in the cell bitmap, not merely every cell — is 65,536 / 262,144 /
2,097,152. Run on dd8ef7f — # commit dd8ef7f on amd-ryzen-9-5900x-12-core at 2026-08-29T00:26:48Z,
no (WORKING TREE DIRTY) — and committed as 9918120 (p-107.csv - re-run on a clean tree);
git merge-base --is-ancestor 9918120 HEAD passes.
| clause | registered | measured |
|---|---|---|
| C1 the offset/compaction stage is at least 5% of CPU extraction, checked first | ≥ 0.05 | FALSIFIED — c1_holds false on 24 of 24. offset_share (numerator cycles_offset, denominator cycles_extract_mc) spans 0.000328 (fbm_terrain 129³) to 0.009714 (sphere 33³); 0 rows clear the bar. Every alternative denominator agrees: offset_share_dc ≤ 0.005629 (c1_holds_dc false 24/24), offset_share_instructions ≤ 0.008045 (c1_holds_instructions false 24/24), offset_share_scan_only ≤ 0.006004 |
| C2 a two-level rank directory answers the slot query in O(1) at no more than 3.51% space overhead | ≤ 0.0351 space, O(1) query | HELD — c2_holds true on 24 of 24. overhead_fraction = 0.032227 on every row (directory_bytes 264 / 1,056 / 8,448 over bitmap_bytes 8,192 / 32,768 / 262,144 — the registration's "about 1.1 KiB on a 64³ chunk's 32 KiB bitmap" is the 1,056-over-32,768 row). The O(1) half is a count, not a clock: max_words_scanned_rank = 7 on all 24 rows and does not move with resolution, while max_words_scanned_scan = 1,023 / 4,090 / 32,746 |
| C3 the directory's answers equal the prefix sum's on EVERY cell | every cell | HELD — c3_holds true on 24 of 24. slots_equal = active_cells on every row, 512 (thin_plate 33³) to 118,885 (noise_cavity 129³), and rank_equal_all_bits = cells_checked on every row, so the equality is over all 65,536 / 262,144 / 2,097,152 bit positions and not only the active ones. directory_total_equals_popcount true 24/24, pad_bits_set 0 on 24/24 |
Both vacuity controls fired, and C3 is admissible only because of the second one.
short_directory_mismatches— the same query answered by a directory deliberately built one level short — reads 47,104 to 1,651,200, never zero, so C3's equality is between two computations that could have disagreed rather than two names for one.bitmap_matches_scalaris true on 24 of 24, which pins the bitmap the directory ranks to the scalar predicate before any rank is taken.
c1_holdsreadingfalseon every row is the row's intended cheapest output, not a defect in the mechanism. The registration names this outcome infalsified_by— "C1 by the offset stage measuring under 5% of extraction, which makes this Amdahl-dead the way✗51was and closes the row before C2 is built" — and the falsification is conservative: the harness's numerator keys slots by cell and paysslot_table_bytes131,072 / 1,048,576 / 8,388,608, where the crate keys by(sample, axis)and payscrate_edge_table_bytes431,244 / 3,295,500 / 25,760,268, so the measured share is taken against a numerator about 3× smaller than the one the crate actually carries and still cannot reach 1%.The wall-clock ratio is reported and carries no verdict (
✗24,M-280).ns_per_query_rank5.7899–10.9673 againstns_per_query_scan256.8374–10,774.9345 givesquery_ratio_ns35.346–1,470.878 — on a run whose ownghzcolumn spans 1.3077–4.1834 across the 24 rows. The instruction form is the one that decides:instructions_per_query_rank126.754–131.868, flat in resolution, againstinstructions_per_query_scan4,776.389–166,672.475, which is not.The comparand that matters is
sequential, and the directory loses to it. The shipped path never asks a random slot question; it walks cells in order with a running counter, and that costsinstructions_per_query_sequential0.259–2.553 (ns_per_query_sequential0.0139–0.2712) — so the rank query is 51.7× to 496.1× dearer per query than the pass it would replace. The directory buys random access, not throughput, and that is exactly the propertyR-112needs.
target_feature_popcntisfalseon 24 of 24, and no verdict here is contingent on it. Acount_onesis the SWAR sequence, not an instruction;count_ones_per_query_rankis 4.566 on every row andcount_ones_per_query_scanis 507.836 / 2,069.836 / 16,253.836, so a hardware popcount would moverankandscanin the same direction. The offset stage makes none — it istrailing_zerosandword &= word − 1— so C1, the clause that gates the row, is popcount-independent.
SHARE, recomputed. C1 is the share, and the arithmetic that decides it was available before the
harness ran. The CSV's own # hypothesis: line records two priors — M-135's contour stage at 29% of
the pipeline, and ✗54's GPU scan at 4.37% of gpu_total_ms, already below this clause's 5% bar — and
experiment_p107.rs's module doc records a third from P-121 —
(cycles_emit_prepare + cycles_emit_walk) / cycles_total at 0.0800, a strict superset of the offset
work. The measurement lands an order of magnitude under even that: the largest
offset_share on the file is 0.009714, so an offset stage reduced to zero cost would move
extraction by 1/(1 − 0.009714) = 1.0098×, one part in a hundred; on dual_contouring
(offset_share_dc ≤ 0.005629) the ceiling is 1.0057×. No implementation of this mechanism, however
good, can clear that — which is ✗51's shape, and stating it for the cost of one bench is the row's
value. What the row still bought is not nothing: C2 and C3 held, so the structure is correct
(slots_equal = active_cells, rank_equal_all_bits = cells_checked, both against a live short-directory
control) and cheap (3.2227% space, 7 words folded at any resolution), and R-112 consumes exactly that
directory as the middle phase of its count/scan/scatter.
💥 ✗84 / M-421 — C1 FALSIFIED on 16 of 16 exactly as registered: broadword select costs +48.9 to +61.0 instructions per set bit over dual.rs:489-497, an instruction_ratio of 0.2085–0.3165 (3.2× to 4.8× worse) with zero count_ones calls to blame it on; C2 HELD with order_identical true on 16 of 16 behind 149,083 exhaustively verified (word, rank) pairs; C3 HELD with set_bits_per_nonzero_word 2.886–32.000; and the clause was Amdahl-dead before the harness existed — walk_share_of_extraction 0.000103–0.001462, so deleting the walk entirely buys at most 1.00146× (P-108, R-108)
M. cargo bench --bench experiment_p108, docs/experiments/p-108.csv, 16 rows, f32
(scalar on all 16), amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column
header plus 16 data rows across 58 columns — counted from the file, not from the brief. Eight
fields (box_exact, csg_difference, fbm_terrain, gyroid, noise_cavity, sphere,
thin_plate, torus) × two resolutions, words = 4,096 at 65³ and 32,768 at 129³ against
bitmap_words 8,450 and 49,923 — the one-word sample/cell asymmetry reproduced rather than smoothed.
Per row, five sibling counter windows (scan, walk, select_literal, select_broadword,
popcount) plus a whole-extraction denominator; every registered per-set-bit column is the marginal
(arm − scan) / set_bits. set_bits spans 2,048–118,885, words_nonzero 64–16,979,
active_fraction 0.003906–0.108242 — fourteen of sixteen rows at or under 5.7% active, gyroid
65³ (8.2%) and noise_cavity 65³ (10.8%) named rather than dropped. Committed at ff2ec47
(p-108.csv - re-run on a clean tree) and stamped
# commit 9918120 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:27:23Z, no (WORKING TREE DIRTY);
git merge-base --is-ancestor 9918120 HEAD and --is-ancestor ff2ec47 HEAD both pass.
| clause | registered | measured |
|---|---|---|
C1 broadword select beats dual.rs:489-497's trailing_zeros + active &= active - 1 walk on a 97%-zero bitmap |
ratio > 1 | FALSIFIED — c1_holds false on 16 of 16. instruction_ratio (walk over select, per set bit) 0.2085–0.3165, median 0.2475: instructions_per_set_bit_walk 13.065–28.266 against instructions_per_set_bit_select 61.978–89.297, i.e. extra_instructions_per_set_bit_select +48.913 to +61.031, median +53.32. c1_holds_cycles false on 16 of 16 with cycle_marginal_valid true on 16 of 16 (cycle_ratio 0.1110–0.3722), and the wall-clock form agrees at ratio 0.1112–0.3748 (ns_per_set_bit_walk 0.7565–2.2890 against ns_per_set_bit_select 4.4172–6.8031) |
C2 identical visitation order and identical emitted indices, because dual.rs:496 exists to keep vertex creation order |
exact equality | HELD — order_identical true on 16 of 16, asserted as well as recorded: all three walk arms emit element-for-element identical Vec<u32>s. select_ranks_verified = 149,083 (word, rank) pairs checked against a linear scan before any timing, plus byte_sums(x) >> 56 == x.count_ones on every one of those words |
| C3 the advantage is reported per set bit, not per word, so words skipped entirely cannot carry the ratio | words_nonzero > 0 and set_bits > words_nonzero |
HELD — c3_holds is literally that conjunction and is true on 16 of 16: words_nonzero 64–16,979 and set_bits_per_nonzero_word 2.886–32.000, median 6.96, so the tightest row still carries nearly three set bits per non-zero word. The discipline it protects is discharged on the row: ratio (per set bit, median 0.2101) sits beside whole_pass_ratio (identically the per-word ratio, median 0.6130), and scan_share_of_walk_pass is 0.4914–0.9238, median 0.8531 |
c1_holdsreadsfalseon every row and that is the registration's own forecast, not a surprise.falsified_bysays it in words — "C1 by not beating the current walk … this is a registered expected null" — because the 2026-08-23 dossier had already argued the pass is dominated by the words neither arm touches.scan_share_of_walk_pass0.4914–0.9238 is that argument turned into a number. What the null bought is the number and the mechanism, which is what a null with no measurement cannot buy: the walk had never been measured against another walk (M-337measured the bitmap against the eight-corner gather — the predicate, not the enumeration), so this is the first price for what a set bit costs to produce, 13.065–28.266 instructions; thePEXTforeclosure now has a published rate on every row (published_pdep_penalty=2x-4x, Pandey/Bender/Johnson'sPDEP+TZCNTselect on Haswell) rather than an unknown one; and the candidate's stated rationale — a countable trip count in place of a data-dependent loop exit — is refuted directly:branch_misses_per_set_bit_select0.00842–0.13109 againstbranch_misses_per_set_bit_walk0.00831–0.13101, agreeing row for row to three figures. The incumbent's loop-exit branch is already free; what mispredicts is the shared outer word loop, which both arms pay identically.The vacuity controls fired and are what makes C3's
truemean anything. The registered one is asserted per row, not merely recorded (words_nonzero > 0andset_bits > words_nonzero), so a fixture whose per-set-bit denominator had collapsed to one bit per word would have aborted the run instead of reporting a ratio. Two unregistered instrument checks sit beside it and also assert:scan_armreturnswords_nonzeroandpopcount_armreturnsset_bits, each compared against an independent population count — a baseline that scanned a different word set could not go unnoticed, and a wrong select rank would otherwise have surfaced as a C2 list disagreement, which is a worse diagnosis than a wrong rank.Which form carries C1.
c1_holdsisinstruction_ratio > 1.0;M-280/M-281forbid the nanosecond form from carrying it, andghz4.1816–4.1893 on this run is why the three forms happen to agree here, not a reason to trust the ns column. The instruction form is also the conservative one — 3.2×–4.8× where the ns form says 2.7×–9.0× — and it is a lower bound on the cycle gap, since both arms are pure ALU-and-L1 work with indistinguishable miss rates while broadword select is a long dependent chain against three independent instructions:cycle_ratiomedian 0.2103 againstinstruction_ratiomedian 0.2475.
target_feature_popcnt is false on all 16 rows, and no verdict here is contingent on it. The
build sets no target-cpu, so u64::count_ones is a SWAR sequence — priced in this binary at
instructions_per_count_ones 22.9373–30.5689, median 25.3264, on the nine rows where
count_ones_price_readable is true (count_ones_price_share ≥ 0.05); the other seven are flagged,
not averaged, and thin_plate's 149.5/150.0 readings rest on 1–2% of the pass and are the two loops'
compilation difference rather than a price. That handicap is deliberately kept off the verdict:
select_variant is broadword on 16 of 16 and
count_ones_per_set_bit_select_broadword = count_ones_per_set_bit_select = 0 on 16 of 16, the
same as count_ones_per_set_bit_walk — so -C target-cpu=native cannot make the scored arm cheaper
by one instruction. The contingent arm is the one not scored: select_literal makes
count_ones_per_set_bit_select_literal 1.0312–1.3465 calls per set bit and costs
instructions_per_set_bit_select_literal 76.0–103.3, +14.0 to +20.1 instructions per set bit
above the broadword arm on every row, so a hardware POPCNT would narrow the gap from about 4× to
about 3× and cannot close it — and the incumbent would get cheaper too, since active &= active - 1
becomes one BLSR. PEXT/PDEP are foreclosed for three independent reasons that no measurement can
lift — the crate forbids unsafe, core::simd and #[cfg(target_arch)], and _pext_u64 needs all
three — which is why the foreclosure is priced on the row instead of tested.
SHARE, recomputed. C1's share is walk_share_of_extraction: the set-bit walk's marginal cycles
over the shipped DualContouring::extract on the same field and grid, measured as a fifth sibling
window in the same run, against extraction_cycles_per_cell 40.40–1,165.93 as the denominator.
Measured 0.000103 (fbm_terrain 129³) to 0.001462 (thin_plate 65³) — between one part in
ten thousand and one and a half parts in a thousand of an extraction. So c1_ceiling = 1/(1 −
share) reads 1.000103× to 1.001464×, the column verbatim, which is what making
the walk free could give a whole extraction; ✗51's ceiling was 1.061× and it was reached by a
clause nobody thought was dead. The extremes are set by the field, not the walk —
extraction_cycles_per_cell is 1,011.92 on fbm_terrain 129³ against 45.93 on thin_plate
65³, so the same walk is a smaller part of the more expensive field. C2 has no share; it is an
equality.
C3's share is scan_share_of_walk_pass 0.4914–0.9238, median 0.8531, which is exactly the
quantity C3 exists to keep out of the numerator: quoting per-word instead of per-set-bit would have
reported a 1.6× loss (whole_pass_ratio median 0.6130) where the mechanism costs 4.8×, a dilution of
3.0× at the median.
💥 ✗85 / M-422 — C1 FALSIFIED on 24 of 24 at 7.2959–12.6711 bits per crossing against a 4.0-bit bar it could not have reached — low_bits_width equals ⌈log₂(u/n)⌉ on 24 of 24 and the fixture's densest row already has u/n = 16.5304 where 4 bits demands u/n ≤ 8 — C2 FALSIFIED on 24 of 24 at 36.841–158.737× the dense load in instructions, and C3 HELD on 24 of 24 with values_equal = crossings and the shifted-width mutant mismatching on every one of them: Elias–Fano is correct, cheap against the incumbent's space, and the wrong structure for a sequence this sparse in the universe it indexes (P-109, R-109)
M. cargo bench --bench experiment_p109, docs/experiments/p-109.csv, 24 rows across 61
columns — four # comment lines plus one column header plus 24 data rows, counted from the file, not
from the brief. Eight fields × {33³, 65³, 129³}, one row each, no scalar or extractor arm: every row is
one bench-local marching_cubes mirror of edge_vertices, its Elias–Fano re-encoding of the same key
sequence, and both structures replayed over the crate's own probe order (probes 3,048–717,252) and
over a uniform present-key order beside it. samples ∈ {35937, 274625, 2146689}, universe = 3 ·
samples on 24 of 24, dense_bytes ∈ {431244, 3295500, 25760268}, ef_bytes 700–130,820.
amd-ryzen-9-5900x-12-core (Zen 3), ghz 4.1697–4.1885 on every row. Run against ff2ec47 —
# commit ff2ec47 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:31:36Z, no (WORKING TREE DIRTY) — and
committed at d05a310 (p-109.csv - re-run on a clean tree); git merge-base --is-ancestor d05a310
HEAD passes.
| clause | registered | measured |
|---|---|---|
| C1 the encoded map costs at most 4 bits per crossing | ≤ 4.0 bits | FALSIFIED — c1_holds false on 24 of 24. bits_per_crossing 7.2959 (noise_cavity 33³) to 12.6711 (thin_plate 129³); bits_per_crossing_no_select 6.5354–11.7841, so dropping the select hints does not reach it either (c1_holds_no_select false on 24 of 24), and bits_per_crossing_with_values 39.2959–44.6711 is the whole structure with its unencoded 32-bit value_bytes |
| C2 access costs at most 1.5× the current direct addressing | ≤ 1.5× | FALSIFIED — c2_holds false on 24 of 24. access_ratio_instructions 36.8408 (gyroid 33³) to 158.7369 (thin_plate 129³): instructions_per_access_ef 294.7368–1269.9247 against instructions_per_access_dense 8.0000–8.0027. The nanosecond form agrees — access_ratio 52.8084–183.7042, c2_holds_ns false on 24 of 24 — and the random-order forms are worse, access_ratio_instructions_random 59.1506–252.9526 |
| C3 the decoded map equals the dense array on every crossing | 0 differing | HELD — c3_holds true on 24 of 24. values_equal = crossings on 24 of 24 (510–119,400), positional_values_equal = crossings on 24 of 24, and absent_sentinel_correct = absent_probed (3,841–4,093 per row), so a lookup that answered something for every key could not have passed |
C1 was decided by arithmetic available before the harness existed, and the harness says by how much. Elias–Fano spends
2 + ⌈log₂(u/n)⌉bits per element, so a 4-bit budget demandsu/n ≤ 8. Measureduniverse_per_crossingruns 16.5304 to 786.3330 — the densest row is already 2.07× the ceiling and the sparsest 98× it.low_bits_widthequals⌈log₂(u/n)⌉on 24 of 24, andbits_per_crossingexceeds2 + ⌈log₂(u/n)⌉by only 0.2638–0.9804 bits (the select hints), so the paper's own cost model is confirmed to under one bit and that model is what forecloses the clause: atu/n= 786.3330 the floor is about 12 bits and the row measured 12.6711; the cheapest encoding anywhere in the fixture is 7.2959. The universe is3 n³and the crossings are a surface,O(n²), sou/ngrows linearly in resolution — 33³ → 129³ movesthin_platefrom 211.3941 to 786.3330 and its cost from 10.9804 to 12.6711 bits. The clause was unreachable on every field at every resolution.C1's bar was tighter than the incumbent it was written against. The registration set 4 bits as "where the dense
u32array's 32 bits per SLOT stops being the thing to beat", but the incumbent's per-crossing figure isdense_bits_per_crossing528.9715–25,162.6549 — the active fraction1 / universe_per_crossingis 6.05% down to 0.13% — andspace_ratio_dense_over_efis 13.4612–563.2876. The encoding beats the shipped structure's space by up to 563× and still misses its registered bar by 1.8–3.2×. Both readings are true; the bar is the one that was registered.The instruction form carries C2's verdict (
M-280,M-281); the nanosecond form only agrees.ns_per_access_dense0.3372–0.6681 againstns_per_access_ef32.2171–67.0548, on a CPU governedpowersave/balance_performanceacross 1.96–5.62 GHz — corroboration, not the gate. The best instruction ratio measured anywhere is 36.8408 (gyroid33³) against a 1.5× bar.target_feature_popcntis false on 24 of 24 (notarget-cpu, socount_oneslowers to the ~12-instruction SWAR sequence), and the call count is measured rather than estimated: onsphere33³ a lookup makes 6.8217count_onescalls (count_ones_per_access_ef) and a positional access 5.1079 (count_ones_per_access_ef_positional), ranging 5.4856–16.8659 and 4.5757–5.2507 over the 24 rows. Crediting a one-cyclepopcntarithmetically still leavesaccess_ratio_instructions_popcnt_creditedat 27.8239–150.0834, andc2_contingent_on_popcntis false on 0 of 24 rows — the missing popcount did not decide C2. The gap is structural: one bounds-checkedu32load against aselect0, a bit-run scan, and a low-bits compare per candidate.C3's
trueis admissible only because the mutant fired.mutant_value_mismatches=crossingson 24 of 24 — a decoder rebuilt atmutant_low_bits_width=low_bits_width + 1(verifiedl + 1on 24 of 24) against a structure encoded atlmis-decodes every value. Without it C3 is an equality between two names for one computation, since the comparand is the array the mirror built. The mirror is checked twice more:shipped_vertices=crossingswithcentroid_vertices= 0 on 24 of 24 (V_mc = Crecovered from the run rather than quoted at it), andmirror_on_edge=crossingson 24 of 24, which places every mirrored vertex exactly on the grid edge its key names instead of merely counting them.What the row does not say. Nothing here is a defect in Vigna. The measurement confirms the paper's cost model to under a bit and confirms O(1) positional access:
instructions_per_access_ef_positional141.0577–154.0460 andns_per_access_ef_positional8.0780–9.6807 are flat innwhere the lookup form is not —P-107's "the directory buys random access, not throughput" in a second shape. Elias–Fano is the right structure for a monotone sequence that is dense in its universe; these are surface crossings in a volumetric edge universe, and the crate never performs the operation the paper makes O(1) — it performsedge_vertices[key]. This row forecloses the quasi-succinct family for this use, with the fixture's ownu/non every line, so no future ticket needs to re-measure it.
SHARE, recomputed. C1 is a space bound and C2 a cost bound against a named baseline; neither is a
ratio of an extraction total, so ✗51's 1/(1 − share/factor) bar does not apply and no speedup is
claimed. C1's share is bits_per_crossing (bar 4.0, key sequence only), bounded below by
universe_per_crossing and scored also as bits_per_crossing_no_select and
bits_per_crossing_with_values. C2's share is access_ratio_instructions (bar 1.5) over the crate's
own probe order. C3's share is values_equal / crossings, bar 1 — an equality over an enumerated
population, denominator exact by construction. The row prices an encoding and moves no extraction time;
what it feeds is R-027a's 45× buffer-churn ceiling, which M-318 measured and which nothing here
re-claims.
💥 ✗86 / M-423 — C1 FALSIFIED on 24 of 24 rows and in every unit (flip_plus_rank_ratio_instructions 2.2506–2.6863 against a bar of 2.0), while its rank-only conjunct is a 2.1–2.4% near miss whose sign the unit decides — rank_ratio_instructions 2.0419–2.0485 on the registered 65³ arm against a nanosecond rank_ratio of 1.9031–2.0209 that reads under the bar on 6 of those 8 rows; C2 and C3 HELD on 24 of 24, distinct_final_states 1 against control_distinct_final_states 128, rank_answers_equal 131,072 of 131,072 — so Pibiri & Kanda's counter tree is provably insertion-order-independent and costs about 2× a static directory's query to be so (P-110, R-110)
M. cargo bench --bench experiment_p110, docs/experiments/p-110.csv, 24 rows, 63 columns,
amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 24 data rows —
counted from the file, not from the brief: eight reference fields (sphere, torus, box_exact,
csg_difference, thin_plate, gyroid, fbm_terrain, noise_cavity) × three resolutions
{33³, 65³, 129³}, eight rows each, with registered_arm true on the eight 65³ rows and false on the other
sixteen. Every row is one flip set of flips = 4,096 distinct cell bits replayed under permutations =
128 seeded orderings (ordering 0 the identity, 1…127 seeded Fisher–Yates), three arms — static
(P-107's block+superblock directory), mutable (a BRANCH = 64 b-ary tree of counts), and journal
(the order-sensitive control) — over one shared Vec<u64> cell bitmap mirrored from dual.rs:359-381.
Committed at 17650e4 (p-110.csv - re-run on a clean tree); the run was taken on the tree the CSV
names, # commit d05a310 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:31:51Z, with no
(WORKING TREE DIRTY), and git merge-base --is-ancestor 17650e4 HEAD passes — as does the same check on
the stamped d05a310.
| clause | registered | measured |
|---|---|---|
C1 flip(i) plus rank stays within 2× of the static directory's rank cost |
≤ 2.0 | FALSIFIED — c1_holds false on 24 of 24, and so are c1_holds_ns and c1_holds_cycles. c1_holds is the conjunction taken over the instruction form; the hypothesis's own reading, flip_plus_rank_ratio_instructions, is 2.2506–2.6863 (registered arm 2.3712–2.3782) and the falsifier's reading, rank_ratio_instructions, is 1.9219–2.3569 (registered arm 2.0419–2.0485). instructions_per_rank_mutable 257.389–314.984 against instructions_per_rank_static 133.645–133.926 |
| C2 the final structure is independent of the order the flips arrive in, bit-identical over the registered permutations | distinct_final_states = 1 |
HELD — distinct_final_states = 1 and final_structures_identical true on 24 of 24, over permutations = 128 orderings of flips = 4,096, while control_distinct_final_states = 128 of 128 in the same run |
| C3 rank answers equal the static directory's after every permutation | all equal | HELD — rank_answers_equal = rank_answers_checked = 131,072 (128 orderings × 1,024 random cell bits) on 24 of 24, plus mutable_equals_prefix_all_bits = static_equals_prefix_all_bits = full_sweep_bits = 65,536 / 262,144 / 2,097,152 — an exhaustive sweep of every cell bit against a running prefix counter |
C2's
1against a control of128is this row's durable content, and it is the clause the registration named as the one that closes the row.V-45's objection — a structure written across calls cannot survivevalidate/determinism.rs's third, reused-buffer run — does not arise for this mechanism. Aflip(i)is one XOR on the word plus a ±1 on exactly one slot per level, and ±1 on an integer commutes, so the final tree is a function of the flip set. That is now measured rather than argued:1on every row, andfinal_structures_identicalis an exact bit-for-bit comparison of every level and every word against ordering 0, so a hash collision cannot report agreement that is not there.The
1is admissible because the comparator was shown able to hold128(M-44). Thejournalarm — keep the static counters, append flips to a log, rebuild atJOURNAL_CAP= 1000, correct queries from the residual — is a working mechanism, not a strawman:control_answers_correcttrue on 24 of 24,control_structures_identicalfalse on 24 of 24,control_distinct_final_states128. Withflips= 4,096 the residual log is non-empty (4,096 mod 1,000 = 96), which is what keeps the control itself non-vacuous. It is also expensive:instructions_per_rank_control691.631–702.663 against the static directory's 133.645–133.926, over 5×. So the obvious way to make a static directory mutable is both order-sensitive and far slower than the paper's.C1's
falsedoes not mean the cost is unexplained — it is located, and the location was derived before the run.tree_levelsreads 2 at all three resolutions whiletop_level_slotsreads 2 / 8 / 64, and a query scans the slots before its own child index at each level.instructions_per_rank_staticis flat at 133.645–133.926 across all 24 rows whileinstructions_per_rank_mutableclimbs monotonically with that width — 257.389–258.270 at 33³, 272.890–273.773 at 65³, 314.101–314.984 at 129³ — so the whole difference is the level scan the paper reaches for SIMD to fix andcrates/isomesh/src/cannot (zerounsafe, zerocore::simd, zero#[cfg(target_arch)]). Everything below the scan is identical by construction:max_words_scanned= 7 on 24 of 24,mutable_directory_bytesexceedsstatic_directory_bytesby exactly 4 bytes at every resolution (268/264, 1060/1056, 8452/8448), andmutable_overhead_fraction3.2242–3.2715% againststatic_overhead_fraction3.2227%.The unit changes the near miss, not the verdict — and the instruction form is the gate (
M-280,M-281,✗24;ghzreads 4.1759–4.1891 on apowersave/balance_performanceCPU spanning 1.96–5.62 GHz, so a nanosecond here is not a unit). On the rank-only conjunct the two forms disagree in sign: on the registered 65³ armrank_ratio_instructionsis 2.0419–2.0485, over the bar by 2.1–2.4% on all eight rows, while the nanosecondrank_ratiospans 1.9031–2.0209 and sits under 2.0 on six of the eight (box_exact2.0081 andthin_plate2.0209 are the two that do not). Scored on wall clock alone that conjunct would have read HELD on 6 of 8 rows; scored on retired instructions it reads FALSIFIED on 8 of 8. C1 as registered is falsified either way, because the hypothesis'sflip-plus-rank reading is 2.2400–2.3535 in nanoseconds and 2.3712–2.3782 in instructions on the same arm —flipcostsinstructions_per_flip44.003–44.098, a third of a whole static rank, and no unit hides that. This is exactly the shape✗24legislated for: had the harness gated on the clock, the phase would own a HELD that a re-run could flip.The null is measured in the mechanism's favourable regime.
target_feature_popcntis false on 24 of 24 — notarget-cpu, noRUSTFLAGS, socount_oneslowers to the ~12-instruction SWAR sequence. Both arms end in the sameblock_tailcall and make no other popcount call, socount_ones_per_rank_mutable=count_ones_per_rank_staticon every row (4.506 at 33³, 4.475 at 65³ and 129³; the harness's aggregate print quotes the 4.506 maximum), andcount_ones_per_flip= 0.000. Popcount is therefore a common additive termPin(P + M)/(P + S), and makingPcheaper moves that ratio further from 1 in the direction it already is. Since every ratio here is > 1, a build with hardwarepopcntwould report a larger ratio: C1 is falsified on that build too, without measuring it (M-281forbids comparing across binaries; the call counts are the honest substitute).Instrument checks.
bitmap_matches_scalartrue on 24 of 24 — every row re-classifies every cell by an eight-corner scalar test against the mirrored bitmap (M-279;R-120andR-121each caught a real defect that way) — andpad_bits_set= 0 on 24 of 24, before and after the flips, because the flip set is drawn over cells rather than raw bit indices.active_cells_before512–118,885 andactive_cells_after4,486–122,511 are both columns: the post-flip bitmap is deliberately no longer the field's own active set.
SHARE, recomputed. No time is claimed of extraction and this row has no Amdahl denominator — by
registration, C1 is a cost bound against a baseline named and re-measured in the same run on the same
bitmap (P-107's directory, 256b654), and C2 is the property validate/determinism.rs:273-303 demands.
So R-121's integer_share gate is not this row's ceiling and nothing here converts to a speedup. The
only share on the row is space: mutable_overhead_fraction 3.2242–3.2715% of the bitmap, four bytes
more than the static directory at every resolution. What C1 falsifies is the price: order-independent
mutability costs rank_ratio_instructions 1.9219–2.3569× the static directory's rank across the three
widths — 2.0419–2.0485× on the registered 65³ arm — and it grows with the top-level width, while
flip_plus_rank_ratio_instructions puts the registered arm's combined operation at 2.3712–2.3782×.
There is today no consumer to charge that to: nothing in crates/isomesh/src/ maintains a rank structure
across mutations, dual.rs's bitmap being built once per extraction and thrown away. The mechanism is
admissible and about 2× too expensive to land unasked; the number to quote when a sweep does need one is
rank_ratio_instructions at the width it will actually run at, not at 65³.
💥 ✗87 / M-424 — C1 FALSIFIED on 16 of 16 rows in all four recorded forms (ratio 0.41717–0.94158, instruction_ratio 0.32412–0.94875, and above 1 is where the table wins), C3 FALSIFIED on 14 of 16 and holding only on csg_difference 129³ and thin_plate 129³, C2 HELD on 16 of 16: the 2 KiB table is a bit-exact drop-in that issues 2.00000–22.17637 stores per set bit against the walk's 1.00000, and that ratio is analytic — it was decidable from the bitmap's own bit census before a clock was read (P-111, R-111)
M. cargo bench --bench experiment_p111, docs/experiments/p-111.csv, 16 rows, amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 16 data rows across 71 columns — counted from the file, not from the brief. Eight fields (sphere, torus, box_exact, csg_difference, thin_plate, gyroid, fbm_terrain, noise_cavity) × two resolution values, 65 and 129 — cells 262,144 and 2,097,152, cell_words_per_row 1 and 2, so dual.rs:484's cell/sample word asymmetry is exercised on both sides of the u64 boundary. The four arms (scan, walk, table, table_byteskip) ride every row as column families rather than as rows, and enumeration is a prefix difference of two sibling counter windows, never nested. reps 15 on all 16 rows, inner_reps 53–722, ghz 4.1813–4.1866 across the whole pass. Committed at 07fd713 (p-111.csv - re-run on a clean tree) from a run stamped one commit earlier in the serial pass — # commit 17650e4 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:32:19Z, no (WORKING TREE DIRTY), and git merge-base --is-ancestor 17650e4 HEAD and git merge-base --is-ancestor 07fd713 HEAD both pass.
| clause | registered | measured |
|---|---|---|
C1 the table beats dual.rs:489-497's set-bit walk on a 97%-zero bitmap |
ratio > 1 |
FALSIFIED on 16 of 16 — ratio 0.41717 (gyroid 65³) to 0.94158 (thin_plate 129³), against ratio_definition on every row reading "ns_per_set_bit_walk/ns_per_set_bit_table; above 1 means the table wins". ns_per_set_bit_walk 1.78496–26.77291 against ns_per_set_bit_table 3.07728–28.43399. The reproducible form agrees: instruction_ratio 0.32412–0.94875, cycle_ratio 0.41730–0.94287, ratio_from_rep_minima 0.41434–0.94209 — c1_holds, c1_holds_instructions, c1_holds_cycles and c1_holds_from_rep_minima all false on all 16 rows, c1_agreement true on all 16 |
| C2 identical output order and identical indices | exact | HELD on 16 of 16 — order_identical true 16 of 16, c2_holds true 16 of 16, and the unregistered table_byteskip arm agrees too: byteskip_order_identical true 16 of 16 |
| C3 the table's L1 cost does not eat the win, as L1D read misses per set bit | l1_misses_per_set_bit_table <= l1_misses_per_set_bit_walk, zero tolerance |
FALSIFIED on 14 of 16, HELD on 2 — held only on csg_difference 129³ (walk 0.33069 vs table 0.32699, l1_delta_per_set_bit_table_minus_walk −0.003701) and thin_plate 129³ (walk 0.87090 vs table 0.86673, delta −0.004173). On the other 14 the delta is positive, +0.001066 (fbm_terrain 129³) to +0.015307 (fbm_terrain 65³); l1_miss_ratio_table_over_walk 1.00416–1.09405 |
C3 is the mechanism's own most likely failure mode, the registration named it in advance — "the table costing more L1 than it saves on a 97%-zero bitmap" — and it is what happened, but only on 11 of the 16 rows does the reading survive the instrument.
c3_holdsis scored on the registration unamended, at zero tolerance, so a 0.4% difference between two hardware counter medians falsifies it exactly as loudly as a 9.4% one.c3_holds_within_instrument_spreadis the column that separates the two: it asksl1_misses_per_set_bit_table <= l1_misses_per_set_bit_walk_rep_max, i.e. whether the table's median lands at or below the walk arm's own worst of 15 repetitions. It readstrueon 5 of 16 rows — the 2 where C3 held (where it is true by construction) and 3 of the 14 falsified ones:sphere129³,fbm_terrain129³ andnoise_cavity129³. On those three the falsification is a measurement about the instrument and not about the table.M-280's rule was written for a governed clock, but it is a statement about instruments, not about nanoseconds: a difference smaller than the instrument's own run-to-run band is a reading of the band. The two rows where C3 held fail the same test in the other direction —thin_plate129³'s −0.479% sits inside a walk band of 0.85754–0.87162, so it is not a win either. That leavescsg_difference129³ as the single row in the fixture where the table genuinely reads fewer L1 misses per set bit (−1.119%, against a walk band of 0.33026–0.33105), and 11 of 16 rows where the registered failure mode is real and outside the band, the largest beinggyroid65³ at +9.407% andfbm_terrain65³ at +7.377% over walk bands of 0.12370–0.12402 and 0.20722–0.20782.
| row | l1_..._walk |
walk _rep_min–_rep_max |
l1_..._table |
l1_delta_..._table_minus_walk |
c3_holds |
..._within_instrument_spread |
|---|---|---|---|---|---|---|
csg_difference 129³ |
0.33069 | 0.33026–0.33105 | 0.32699 | −0.003701 | true | true |
thin_plate 129³ |
0.87090 | 0.85754–0.87162 | 0.86673 | −0.004173 | true | true |
sphere 129³ |
0.40248 | 0.39996–0.41515 | 0.40844 | +0.005967 | false | true |
fbm_terrain 129³ |
0.25638 | 0.25589–0.25988 | 0.25745 | +0.001066 | false | true |
noise_cavity 129³ |
0.12000 | 0.11991–0.12266 | 0.12179 | +0.001783 | false | true |
torus 129³ |
0.44163 | 0.43555–0.44397 | 0.44433 | +0.002697 | false | false |
fbm_terrain 65³ |
0.20754 | 0.20722–0.20782 | 0.22285 | +0.015307 | false | false |
gyroid 65³ |
0.12385 | 0.12370–0.12402 | 0.13550 | +0.011648 | false | false |
The eight rows not listed all read c3_holds false with c3_holds_within_instrument_spread false.
C1 was decided by arithmetic that existed before the harness did, and the harness records the arithmetic as columns.
stores_per_set_bit_walkis 1.00000 on 16 of 16 — the incumbent writes exactly one slot per set bit.stores_per_set_bit_tableis 2.00000–22.17637, and it is not a timing: it is64 · words_nonzero / set_bits, because the registered arm writes eight slots for each of a word's eight bytes unconditionally. I re-derived it fromwords_nonzeroandset_bitson the first three rows and it reproduces exactly. A mechanism that issues 2 to 22 stores per useful store cannot beat one that issues one, on any machine, and no clause needed a clock to know that.The table's best case is structural and the fixture contains it. The two rows where the table comes closest are
thin_plate129³ (ratio0.94158) andthin_plate65³ (0.90741), and they are exactly the two rows wherestores_per_set_bit_tablereads its floor of 2.00000 —words_nonzero256 againstset_bits8,192 and 64 against 2,048, i.e. exactly 32 set bits inside every word the arm touches. The table only becomes competitive when the set bits inside a touched word are dense,thin_plateis the one field in the fixture where they are, and it still loses by 6%.
table_byteskipnames the cause, which is why an unregistered arm was worth recording. Guarding the eight stores withif byte != 0dropsstores_per_set_bit_table_byteskipto 1.00000–3.30116 and the arm still loses on all 16 rows:ratio_byteskip0.61669–0.95226,instruction_ratio_byteskip0.59449–0.96628. So this is not the unconditional stores are a bad idea; it is the table lookup is a bad idea here. The prefix-differenced enumeration windows put it starkest, with the shared word scan subtracted:instructions_per_set_bit_enumeration_walk14.37935–35.17299 againstinstructions_per_set_bit_enumeration_table46.69463–218.81947,enumeration_instruction_ratio0.09596–0.60468 — the enumeration alone costs the table 1.65×–10.4× the walk's retired instructions.The clause was tested at and beyond its own registered regime. The hypothesis names
M-337's 1.89% / 0.93% / 0.46% active fractions as "the regime, not an assumption"; measuredactive_fractionspans 0.0039062–0.108242. Onlythin_plate(0.0039062, 0.0078125) andsphere/torus129³ (0.0091705, 0.0083122) sit inside that band —gyroid65³ at 0.0817566 andnoise_cavity65³ at 0.1082420 are an order of magnitude denser. C1 is falsified at both ends.A measurement-hygiene result that costs nothing and confirms the serial protocol. The harness's module doc (
experiment_p111.rs:178-192) records two consecutive runs of the identical binary, minutes apart under six concurrent bench agents, readingthin_plate129³'s walk arm at 26.32 then 43.74 ns per set bit — a 1.66× move that flippedc1_holdsfor that row fromfalsetotrue— whileinstruction_ratioread 0.9487 then 0.9488. This clean serial run readsns_per_set_bit_walk26.77291 for that row andinstruction_ratio0.94875: the clock reproduces the fast contended reading and the instruction form reproduces both to four figures.ghzheld inside 0.13% across all 16 rows, which is why the ns and instruction forms agree here at all — and is not a licence to gate on the ns form.Vacuity controls, all four, and none of them asserts an outcome.
set_bits2,048–118,885 on 16 of 16, so no per-set-bit denominator divides an empty population.words_nonzero64–16,979 andbytes_nonzero256–42,015, both non-zero on every row, so both arms actually entered their inner loops rather than scoring a ratio of two skipped passes.table_bytes2048 on 16 of 16, which is the registered "2 KiB" as an assertion rather than a claim. The counter arm iscfg(target_os = "linux")andexit(1)s elsewhere onexperiment_p12's precedent, so no off-Linux run could have recorded a fabricated cache zero — this pass ran on Linux and the L1 columns are real readings.order_identical,c1_holds,c2_holdsandc3_holdsare recorded and never asserted, which is the only reason a 14-of-16 falsification exists to read.
c1_holds = falseon every row is the row's product, not its failure. The registration asks whether the only admissible scalar reduction of simdjson's compaction beatsdual.rs:495-497. It does not, C2 proves the answer is not an artefact of measuring a different computation —order_identicalandbyteskip_order_identicalaretrueon all 16 rows, so the table produces the identical index sequence in the identical order and simply costs more to produce it — andtable_byteskiplocates the cost in the lookup rather than in the stores. That is a complete, causally-located do not build this.One contingency, named and not quantified. The registered arm advances its cursor with
byte.count_ones(experiment_p111.rs:477), eight calls per non-zero word, andtarget_feature_popcntisfalsein this build — the repository sets notarget-cpuand noRUSTFLAGS— so that advance lowers to a SWAR sequence rather than one instruction, while the walk'strailing_zerosis a single instruction on any x86-64. No column inp-111.csvisolates it. It cannot rescue C1:stores_per_set_bit_table/stores_per_set_bit_walkis analytic and popcnt-independent, andtable_byteskip, which callscount_onesstrictly less often, loses on all 16 rows anyway.
SHARE, recomputed. The stage this row competes in is cycles_emit_walk, and it is on every row as a column so no reader can mistake a per-set-bit ratio for an extraction speedup. p121_emit_walk_share_mc_65 is 0.0029–0.0601 and p121_emit_walk_share_dc_65 is 0.0002–0.0109, carried from P-121's 65³ stage decomposition. extraction_ceiling_mc 1.00291–1.06394 and extraction_ceiling_dc 1.00020–1.01102 are 1/(1 − share): deleting this stage entirely and perfectly buys at most 1.064× under marching_cubes (gyroid) and 1.011× under dual_contouring. What the measured ratio would actually buy is extraction_speedup_mc 0.92254–0.99895 and extraction_speedup_dc 0.98914–0.99992 — below 1 on 16 of 16 rows in both extractors, i.e. landing this mechanism would make marching_cubes extraction up to 7.7% slower. Per ✗51's rule the share was read before the harness was written and it bounds the consequence, not the result: C1, C2 and C3 are a per-set-bit comparison, an exact equality and a per-set-bit cache count, and they remain scoreable at any share. Note that the share columns are P-121's wave-time figures, taken while several bench agents were running, and the harness cites them as a prior rather than a measurement; they are a different P-121 quantity from the integer_share maximum of 0.7245 that opened the Group A gate, and no re-reading of them can change the direction here, since every extraction_speedup_* is below 1 for a ratio below 1 whatever the share is.
💥 ✗88 / M-425 — C1 FALSIFIED on 16 of 16 with the rank arm 2.2× to 8.6× slower (speedup 0.116376–0.461247 against a bar of 1.25), C2 FALSIFIED on 16 of 16 at scan_share 0.036580–0.158941 against 0.20 — which makes C1 arithmetically unreachable, since the largest scan share's scan-free ceiling is 1.1890× — the registered 70% scatter falsifier fires on 7 of 16 rows and closes C1 and C2 together, C3 HELD on 16 of 16; and the vacuity control fired first, which is how residual_share came to be denominated in retired instructions, where it reads 0.000000 while its own millisecond form reads 4–8% with a field-dependent sign (P-112, R-112)
M. cargo bench --bench experiment_p112, docs/experiments/p-112.csv, 16 rows across 107
columns, amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 16
data rows — counted from the file, not from the brief: eight fields × {65³, 129³}
(sphere torus box_exact csg_difference thin_plate gyroid fbm_terrain noise_cavity), five arms on every
row of which the registration scores three, reps 5, ghz on every row (4.1702–4.1849). Produced on a
clean tree at c00634c (R-112 - the residual control fired twice; the decomposition is exact and the
unit was wrong) — # commit c00634c on amd-ryzen-9-5900x-12-core at 2026-08-29T00:40:38Z, no
(WORKING TREE DIRTY) — and landed as a5eefa5 (p-112.csv - re-run on a clean tree).
git merge-base --is-ancestor c00634c HEAD and git merge-base --is-ancestor a5eefa5 HEAD both pass.
| clause | registered | measured |
|---|---|---|
C1 replacing phase 2 with P-107's O(1) rank cuts the three-phase compaction total by ≥ 1.25× |
≥ 1.25× | FALSIFIED — c1_holds false on 16 of 16; speedup = total_ms/rank_total_ms spans 0.116376 (gyroid 65³) to 0.461247 (thin_plate 129³) — the rank arm is 8.6× to 2.2× slower; rank_total_ms 0.025480–0.950802 against total_ms 0.008410–0.189266. Instruction twin agrees: c1_holds_instructions false on 16 of 16, speedup_instructions 0.103078–0.401029 |
| C2 the scan phase is ≥ 20% of the three-phase total | ≥ 0.20 | FALSIFIED — c2_holds false on 16 of 16; scan_share 0.036580 (noise_cavity 65³) to 0.158941 (thin_plate 129³), scan_ms 0.000990–0.008992 against count_ms 0.001781–0.014704 and scatter_ms 0.005139–0.167048. scatter_share 0.559306–0.882611, and the registered 70% falsifier (scatter_falsifier_fires) is true on 7 of 16 — sphere/torus/gyroid/fbm_terrain/noise_cavity at 65³ and gyroid/noise_cavity at 129³. c2_holds_instructions false on 16 of 16, scan_share_instructions 0.027528–0.089287 |
| C3 all three arms emit identical output | bit-for-bit | HELD — c3_holds true on 16 of 16: output_identical and output_identical_all_arms true on 16 of 16 over compacted_len = active_cells = 2,048–118,885 elements, bitmap_matches_scalar true on 16 of 16, rank_equal_all_bits = cells_checked (262,144 at 65³, 2,097,152 at 129³), short_directory_mismatches 122,880–1,651,200 > 0 and mutant_output_mismatches 2,048–118,885 > 0 |
The row was closed by its own registered falsifier, not merely by a missed bar. The registration says the scatter phase above 70% "would mean the offsets were never the cost and closes C1 and C2 together";
scatter_falsifier_firesis true on 7 of 16 rows, and the seven are exactly the rows with the lowestscan_shareand the worstspeedup—gyroid65³ carriesscatter_share0.846329,scan_share0.051563 andspeedup0.116376 together. The two verdict forms, milliseconds and retired instructions, agree on 16 of 16 rows; perM-280the instruction form is the one that carries.🎯 C2 makes C1 unreachable by arithmetic that existed before the harness did, and the registration said so. Removing a phase of share
sentirely gives at most1/(1 − s), so 1.25× demandss ≥ 0.20. The largest measured share isscan_share0.158941, whosespeedup_ceiling_scan_free= 1.188978× — under the 1.25 C1 asked for. A free scan on the best row in the fixture still misses C1.R-107had also already priced the mechanism: the shipped ascending walk costs 0.013–0.131 ns/cell and one O(1) rank query costs ~6 ns, two to three orders of magnitude apart, andexperiment_p112.rs:33-42records that expectation before the measurement rather than after it.🧪 The vacuity control fired twice, and the repair is the method finding on top of the result. The
R-085residual bar aborted the harness attorus65³ =0.0920and thensphere65³ =0.0692. Instrumenting all five windows per repetition at 65³ located the cause, and it was not the arithmetic:
field prenscut2nspostnsns residual instruction residual sphere9,723 10,277 9,640 −6.2% 0.000000 torus9,840 9,884 10,854 +4.5% 0.000000 box_exact11,077 10,300 10,896 +6.3% 0.000000 csg_difference11,183 10,475 11,333 +7.0% 0.000000 The three prefix-differenced phases account for the total to the last retired instruction on 40 of 40 repetitions; the nanosecond residual reads 4–8% with a field-dependent sign, and
pre/post— the identical body twice, 40 ms apart inside one repetition — differ by up to 10%. So the unit moved and the bar did not:RESIDUAL_BARis still0.05andresidual_sharereads 0.000000 on all 16 rows, four orders of margin and machine-independent.residual_control_mutant_share— the same arithmetic with the scatter phase dropped, asserted to exceed the bar — reads 0.626656 to 0.884974, so the zero could have been non-zero (M-44). Every wall-clock form is kept and read by nothing:residual_share_ms0.001380–0.075756,residual_share_ms_within_rep0.001899–0.074882,residual_share_ms_worst_repup to 0.078985, andtotal_pre_post_spread_share0.001648–0.119796 is the column that says the millisecond form was unmeasurable at a 5% bar — 12% of spread between two runs of the same body cannot resolve a 5% residual.ghzmoved by 0.35% across the whole run (4.1702–4.1849) and the millisecond residual still swung to 7.6%, so this is not a headline clock excursion; it isM-280at rest.
target_feature_popcntisfalseon all 16 rows, and both verdicts are contingent on it. Phase 1 is nothing but popcounts —count_ones_calls_count_phase=bitmap_words(4,096 at 65³, 32,768 at 129³) — whilecount_ones_calls_scan_phaseandcount_ones_calls_scatter_phaseare 0. A hardware popcount would shrink phase 1 only, which raisesscan_sharetoward C2's bar. The projection column says by how much:count_instructions_per_wordmeasures 8.7509–8.7571, below the 11-instruction SWAR excess, so the floor clamps to zero andscan_share_instructions_popcnt_floorprices phase 1 at free — and it still tops out at 0.124712, a ceiling of 1.1425×, under both 0.20 and 1.25. It is a labelled projection and no verdict reads it.Unregistered, reported and scored by nothing. Two formulations that replace the scan without a per-element query: one rank query per non-empty word tops out at
speedup_rank_word_unregistered0.845559 (thin_plate129³, 256 queries) and one per cell row atspeedup_rank_row_unregistered0.697513 (noise_cavity129³). Both are still losses, and their instruction twins are worse (0.625582 and 0.501183). No clause reads either;c1_holdsreadsspeedupand nothing else. Beside them,three_phase_over_sequential0.964879–2.245429 says Billeter's three phases are themselves up to 2.25× slower than the shippeddual.rs:489-497walk, and the instruction form is above 1 on 16 of 16 rows (1.093808–1.860825): the crate's existing running counter beats the decomposition this row was measuring inside.One control is vacuous by construction and says so:
pad_bits_possibleisfalseandpad_bits_setis0on all 16 rows, becausecells_xis 64 at 65³ and 128 at 129³ andcell_maskmasks nothing. Recorded asM-44's zero that could not have been non-zero, not counted as evidence.
SHARE, recomputed. C1 and C2 are ratios inside the three-phase compaction total, not fractions of
extraction, and this row measures the outer share rather than importing it:
compaction_share_of_extraction = total_cycles/cycles_extract_mc reads 0.00016218–0.00482468 —
the whole three-phase compaction is 0.0162% to 0.4825% of a marching_cubes extraction (instruction
form compaction_share_of_extraction_instructions 0.00018447–0.00516821, same order). So
extraction_ceiling_scan_free = 1/(1 − scan_share·compaction_share) reads 1.00001722× to
1.00062728×:
the best extraction-level speedup a scan removed entirely and for free could buy anywhere in this
fixture is 1.00063×. C1's 1.25× was a 1.25× on one part in a few hundred, and it was not reached
anyway. C3's share is an equality over an enumerated population of compacted_len elements; it moves no
time and has no ceiling. No ticket is earned here — the mechanism loses its own microbenchmark by
2.2×–8.6× and the stage it sits in cannot move an extraction by 0.1%.
💥 ✗89 / M-426 — C1 FALSIFIED at 0 of 4 granularities straddling 6.25% and 1 of 4 where the winner varies, C2 FALSIFIED by 2 of 8 rows below the boundary on bytes — both arithmetically fixed before the harness existed, because a 64³ chunk indexes in u32 and its byte crossover is 3.125%, not 6.25% — and C3 HELD on 32 of 32 at 24 B of per-chunk overhead against 8 B of payload: Roaring's boundary separates granularities, not fields (every field reads 0.2415–0.2859 at 4³ and 0.0039–0.0567 at 64³), so the container type is a compile-time consequence of chunk_cells and never a per-field runtime decision, which is the registration's own row-closing outcome; and the density the crate had never measured is 0.39%–5.67% at 128³, refuting the research doc's derived "thin_plate ≈ 4.9%" by 12.5× (P-113, R-113)
M. cargo bench --bench experiment_p113, docs/experiments/p-113.csv, 32 rows, 57 columns,
f64, amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 32 data
rows — counted from the file, not from the brief. Eight reference fields × four granularities
(chunk_cells ∈ {4, 8, 16, 64}) over one shared 128³ cell world (world_cells = 128 on all 32 rows), two
bench-local arms per row: the bitmap mirrored from dual.rs:405-436's fused any & !all fold, and an
array of chunk-local indices whose width is set by the chunk size (index_bytes 1 / 2 / 2 / 4). The walk
comparison is scored on cycles_per_active_cell_* from common::counters::Probe, with ns_per_walk_* and
a ghz column beside it (ghz 4.1532–4.1932 over the 32 rows). Measured against tree state 07fd713
— # commit 07fd713 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:32:37Z, no (WORKING TREE DIRTY) —
and committed as 776a9bb (p-113.csv - re-run on a clean tree); git merge-base --is-ancestor
776a9bb HEAD passes, as does the same check on 07fd713.
| clause | registered | measured |
|---|---|---|
| C1 measured active-cell density straddles Roaring's 6.25% across the eight fields — at least one below and one above — so the representation is a decision rather than a constant | ≥ 1 below and ≥ 1 above, with the winner varying |
FALSIFIED — c1_holds false on 32 of 32. granularities_straddling = 0 of 4, granularities_winner_varies = 1 of 4; c1_straddles_here false on 32 of 32, c1_winner_varies_here true only on the eight 64³ rows. distinct_winners = 1 at 4³/8³/16³ and 2 at 64³ |
| C2 below the threshold an array-of-indices beats the bitmap on both bytes and the active-cell walk | zero failures over the rows below 6.25% | FALSIFIED — c2_holds false on 32 of 32 with c2_failures = 2, both on the bytes half: gyroid@64³ array_bytes 346,512 ≥ bitmap_bytes 262,336, and noise_cavity@64³ 475,732 ≥ 262,336. rows_below_boundary = 8, so the clause was scored, not vacuous. The walk half recorded zero failures — cycles_per_active_cell_array 1.995388–2.073175 against cycles_per_active_cell_bitmap 3.000605–7.549405 — but see below on what that can support |
C3 at M-377's 4³ optimum a chunk is one word and the bitmap's per-chunk overhead exceeds its payload, measured as bytes per active cell |
overhead > payload on all 8 fields | HELD — c3_holds true on 32 of 32. At chunk_cells = 4, bitmap_overhead_bytes_per_active_cell 1.311587–1.553006 against bitmap_payload_bytes_per_active_cell 0.437196–0.517669, a ratio of exactly 3.000 on 8 of 8 rows: 24 B of Vec<u64> header against 8 B of payload, with words_per_chunk = 1 asserted rather than assumed (experiment_p113.rs:913-918) |
The boundary lies across chunk_cells, not across field — which is why C1 could not fire
| granularity | density over the eight fields |
fields_below_boundary |
fields_above_boundary |
distinct_winners |
c1_straddles_here |
c1_winner_varies_here |
byte_crossover_density |
|---|---|---|---|---|---|---|---|
| 4³ | 0.2414672 – 0.28591321 | 0 | 8 | 1 | false | false | 0.125000 |
| 8³ | 0.10380145 – 0.18710497 | 0 | 8 | 1 | false | false | 0.062500 |
| 16³ | 0.06250000 – 0.15774271 | 0 | 7 | 1 | false | false | 0.062500 |
| 64³ | 0.00390625 – 0.05668879 | 8 | 0 | 2 | false | true | 0.031250 |
At 16³ the two counts sum to 7 because thin_plate lands exactly on 6.25% — 8,192 active_cells over
32 chunks_occupied of 4,096 cells_per_chunk is precisely 1/16 — and is therefore neither below nor
above and counts for neither side. density_span_over_fixture = 73.193782, comfortably over the
registered one-decade bar, and every bit of that span is generated by chunk_cells: within any single
granularity the eight fields never cross the boundary. winner reads split on 26 rows and array on
6 (the six 64³ rows whose density is under 3.125%) and bitmap on none.
The array arm's walk column is a ceiling, and the entry states which direction it can carry.
array_walk_saturatedistrueon 32 of 32 rows andbitmap_walk_saturatedisfalseon 32 of 32.walk_floor_cycles_per_active_cell— the identical consumer driven over one contiguous ramp of the same length, the cheapest it can be driven at all — reads 1.995125–2.007284, andcycles_per_active_cell_arrayreads 1.995388–2.073175: the array arm sits on the floor at every index width.ns_per_walk_arrayspans only 0.476553–0.483389 across a 73.19× density sweep and four index widths, a 1.43% band. That flat line is the saturation.What it supports:
array < bitmap. A ceiling that already loses bounds the true cost from above, so the inequality holds a fortiori and C2's walk half is sound as an inequality.What it cannot support: any magnitude, and any claim in the other direction.
walk_cycle_ratio1.500920–3.777934 andwalk_cycle_difference1.001982–5.551116 are lower bounds on the bitmap's disadvantage, not measurements of it.bitmap < arraywas unobservable on a floor-clamped array arm, sowinnernever taking the valuebitmapon any of the 32 rows is not evidence that the bitmap never wins a walk — it is the instrument's own reach.The verdict rides on the instruction form, per
M-280/M-281.instructions_per_active_cell_bitmap8.961855–36.135714 againstinstructions_per_active_cell_array3.377593–4.998033 — 1.854× to 10.642× more retired instructions per active cell, machine-independent, sign-agreeing with the cycle columns on all 32 rows.target_feature_popcntisfalsein this build and does not bind here:count_onesappears only in fixture construction (experiment_p113.rs:301), outside every timed span, and the timed bitmap walk istrailing_zeros+x &= x - 1(:432-433), both baseline x86-64.Both falsified halves were decided by arithmetic that predates the harness.
byte_crossover_densityis1/(8 · index_bytes), andbitmap_overhead_bytesequalsarray_overhead_byteson every row (size_of::<Vec<W>>is 24 for everyW), so the bytes comparison reduces to payload alone: the array is smaller exactly whendensity < 1/(8 · index_bytes). Roaring's 4,096-of-2¹⁶ is the two-byte case, so it coincides with this fixture only at 8³ and 16³; at 64³ the index isu32and the crossover is 3.125%. C2's two failures are therefore forced:gyroid(0.04128456) andnoise_cavity(0.05668879) are the only two fields whose 64³densityexceeds 3.125% while sitting under 6.25%, and the remaining six 64³ rows (0.00390625–0.01646996) are under both. C3 is the same shape in the other direction —size_of::<Vec<u64>>= 24 against 4³/64 × 8 = 8 bytes is exactly 3×, field-independent — so the run's contribution to C3 was assertingwords_per_chunk= 1 and populating the denominators, not deciding the inequality.
c2_holdsreadingfalseis not "the array loses". It reads false because the registered threshold is the wrong constant for two of the four granularities, which is a defect in the rule, not in the representation. The mechanism the row was asked to price is intact and now has a closed form.The vacuity controls fired, and one of them fired during authoring.
active_cellsis non-zero on 32 of 32 rows (8,192–118,885).walk_checksumis asserted equal and non-zero across both arms withfold_mismatches= 0 on 32 of 32, which is what proves the two arms visited the same cells in the same order. That non-zero assertion had already refused a run: with^as the consumer the checksum cancelled to exactly zero on both arms at 4³, because XOR is GF(2)-linear and a sphere's 4³ chunks repeat one 6-bit pattern by the thousand; the consumer iswrapping_addfor that reason (experiment_p113.rs:114-119). The one-decade density-span control passed at 73.19× — and passing it while still failing C1 is the row's sharpest method point: a span control proves the range is wide, not that the range is wide along the axis the clause quantifies over.
SHARE, recomputed. No extraction time is claimed, so ✗51's 1/(1 − share/factor) bar does not apply
to any clause here and none of the three is a fraction of a total. C1's share is
fields_below_boundary + fields_above_boundary — 8 at 4³/8³/64³ and 7 at 16³, where one field
sits on the boundary. C2's share is rows_below_boundary = 8 of 32, non-empty, so the clause is
FALSIFIED rather than VACUOUS. C3's share is the 8 rows at chunk_cells = 4. What the row delivers
past its clauses is the number it was registered to obtain: world_density, the active-cell density of
this crate's eight reference fields at 128³ in a release build, is 0.00390625–0.05668879 — every field
below Roaring's 6.25% container boundary and every field above its 0.1% "bitmap is unlikely to be
the proper data structure" floor. thin_plate's measured world density is 0.390625%, so the research
doc's inference of "around 4.9%" — derived from M-306's rejected-brush shares at 17³ in a debug build —
is high by 12.5× and must not be quoted again. And because density within a granularity is effectively
field-independent, the representation is selected by chunk_cells at compile time; there is no runtime
container-type switch to build, which is exactly the falsifier the registration named as the outcome that
closes the row.
💥 ✗90 / M-427 — C1 HELD at 1.612× (65³) and 2.568× (129³) on the sparsest field as measured, and stronger in instructions — 2.129× and 3.318× — but the win is confined to sparsity: at 4.1% and 5.7% active the hierarchy loses (gyroid 129³ 0.909×, noise_cavity 129³ 0.914×); C2 FALSIFIED on 21 of 32 rows, 16 of them arithmetically before the harness existed, because 4,096 is the one-level ceiling and the two-level best case, not a mean; C3 HELD on 32 of 32 with mesh_identical true everywhere; and the measured share retires the mechanism anyway — traversal_share_of_extraction peaks at 0.000994, so extraction_speedup_ceiling peaks at 1.00039× (P-114, R-114)
M. cargo bench --bench experiment_p114, docs/experiments/p-114.csv, 32 rows across 57
columns, amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 32
data rows — counted from the file, not from the brief. One block: eight fields (sphere, torus,
box_exact, csg_difference, thin_plate, gyroid, fbm_terrain, noise_cavity) × two
resolutions (cells reads 262,144 and 2,097,152, i.e. 65³ and 129³ samples — the two grids whose cell
rows are exactly one and two u64 wide) × two summary depths (levels = 1 on 16 rows, 2 on 16). The
flat arm is not a fourth axis: it is built once, shared, and rides on every row in words_tested_flat
(4,096 at 65³, 32,768 at 129³) and ns_per_cell_flat. reps = 5 windows per quantity on all 32 rows.
Committed at 8d5ab93 (p-114.csv - re-run on a clean tree); the header line names the tree the run
was taken on — # commit a5eefa5 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:41:06Z, no
(WORKING TREE DIRTY) — and git merge-base --is-ancestor 8d5ab93 HEAD passes.
| clause | registered | measured |
|---|---|---|
| C1 at least 1.5× on the active-cell traversal of the sparsest field as measured, that field named in the CSV | ≥ 1.5× | HELD — sparsest_field = thin_plate on 32 of 32 rows; sparsest_field_active_fraction 0.00781250 at 65³ and 0.00390625 at 129³, the smallest active_fraction at each resolution. sparsest_field_ratio = 1.6123 (65³, two levels) and 2.5678 (129³, two levels); one level reads 1.7808 and 2.2976. sparsest_field_ratio_instructions = 2.1285 and 3.3182 (one level 2.1141, 3.2027). c1_holds, c1_holds_cycles and c1_holds_instructions are all true on 32 of 32 — the three forms agree, and the instruction form is the larger margin on all four readings |
| C2 two levels skip 4,096 cells per test, reported as cells skipped per word tested | ≥ 4,096.0 | FALSIFIED — c2_holds false on 21 of 32 rows, true on 11. cells_skipped_per_test spans 1,820.000 (gyroid 65³, one level) to 15,299.765 (thin_plate 129³, two levels). All 16 levels = 1 rows fail, at 3,072.000–4,064.000. Five levels = 2 rows fail, and active_fraction separates them cleanly: every cleared row is at 0.00390625–0.02294159, every failing two-level row at 0.03209305–0.10824203 — fbm_terrain 65³ 3,458.954 at 0.03209305, gyroid 129³ 2,488.906 at 0.04128456, noise_cavity 129³ 3,347.721 at 0.05668879, gyroid 65³ 2,043.509 at 0.08175659, noise_cavity 65³ 2,889.143 at 0.10824203. The eleven that cleared are the two-level rows of sphere, torus, box_exact, csg_difference and thin_plate at both resolutions, plus fbm_terrain 129³ |
| C3 identical mesh | any difference falsifies | HELD — mesh_identical true on 32 of 32, c3_holds true on 32 of 32. Five ordered active-cell lists agree, including the list the shipped extractor traverses, recovered through a bench-local recording VertexRule behind the public DualContouring::with_rule |
The 16
levels= 1 failures were decided by arithmetic before the harness was written, and the file is built to show it.cells_skipped_per_testiscells_skipped_total / summary_words_tested. At one levelsummary_words_tested=level_1_words=level_0_words / 64— 64 at 65³, 512 at 129³ — so the quotient is at mostcells / level_1_words= 262,144/64 = 2,097,152/512 = exactly 4,096, attained only by a bitmap with no active cell at all. The sparsest row in the fixture,thin_plate129³, reads 4,064.000 = 4,096 × (2,080,768/2,097,152); a clause registered as "≥ 4,096" over a population with 8,192active_cellscannot fire upward. C2 is registered "at two levels", and the module doc states that the one-level rows carry the same column and the same bar so the discrimination is visible in the data instead of argued in prose — the verdict reports both because the column reports both.The five two-level failures are the same arithmetic from the other side, and they name the mechanism's limit exactly. At two levels the divisor is
level_2_words + level_1_words_nonzero, so 4,096 is reachable only when a level-2 word is wholly empty; the registered figure is the fan-out of one zero top-level bit (cells_per_top_level_zero_bit, which reads 4096.0 on 15 of the 16 two-level rows), i.e. a best case, andcells_skipped_per_testis the mean over every summary word tested. Where level 1 is dense the mean cannot approach it:gyroid129³ haslevel_1_words_nonzero398 oflevel_1_words512,noise_cavity129³ 336 of 512,gyroid65³ 56 of 64,noise_cavity65³ 48 of 64.fbm_terrain65³ is the extreme: 64 of 64 level-1 words are non-empty, so the second level adds a divisor and removes nothing, and the row'scells_skipped_per_testfalls from 3,513.000 at one level to 3,458.954 at two. It is also the one row withtop_level_fanout_verifiedfalse andzero_top_level_bits0 — at 65³ one level-1 word spans a wholezslice and a heightfield crosses every slice, which the module doc predicted in advance rather than discovered.Where the hierarchy loses, in the run's own columns.
ratio=ns_per_cell_flat / ns_per_cell_hierspans 0.9049 to 2.5678; it is below 1 on 8 of 32 rows — everygyroidand everynoise_cavityrow, at both depths. Two-level readings, with each row'sactive_fraction:
field / res active_fractionratioratio_instructionswords_tested_hier/_flatbreakeven_traversalsthin_plate129³0.00390625 2.5678 3.3182 392 / 32,768 2.052 thin_plate65³0.00781250 1.6123 2.1285 97 / 4,096 2.525 fbm_terrain129³0.01646996 1.1475 1.4059 3,796 / 32,768 2.582 gyroid129³0.04128456 0.9087 1.0014 17,385 / 32,768 inf noise_cavity129³0.05668879 0.9137 1.0203 15,118 / 32,768 inf gyroid65³0.08175659 0.9889 0.9931 2,333 / 4,096 inf noise_cavity65³0.10824203 0.9937 1.0097 1,933 / 4,096 inf At 4.1% and 5.7% active the second level is a net cost in both units, and
breakeven_traversalsreadsinfon all 8 losing rows — no number of traversals amortises a build whose per-traversal saving is negative. On the 24 winning rows it reads 1.367 to 5.351, which is the honest single-shot caveat: the summary must be shared across at least two traversals before it is ahead.ghzspans 4.1653–4.1875 andclock_ratio_hier_over_flat0.9976–1.0035 across all 32 rows, so noratiohere is a clock artefact — but perM-280the nanosecond form is still not the gate, and it isratio_instructionsthat puts the eight losing rows at 0.9931–1.0296 whereratioputs them at 0.9049–0.9937 — seven of the eight are at or above parity in instructions. The traversal walks set bits withtrailing_zeros+a &= a - 1(dual.rs:489-497), notcount_ones, so this row's instruction counts are not contingent ontarget_feature_popcntbeingfalsein this build.Both vacuity controls fired, and the first fired hard.
words_tested_hieris strictly less thanwords_tested_flaton 32 of 32 rows, not merely one:word_ratiospans 1.7504 (gyroid65³, one level) to 83.5918 (thin_plate129³, two levels), and the sparsest row tests 97 words against the flat arm's 4,096 — a 42.2× reduction in words tested (word_ratio42.2268) that buys only 1.612× of wall clock, which is the clearest statement in the file that the flat walk's cost is not in the word tests.cells_skipped_per_testis non-zero on 32 of 32 (minimum 1,820.000). The hypothesis's own first sentence is verified rather than asserted:level_1_size_ratioandlevel_2_size_ratioread 64.0000 on 32 of 32, andsummary_overhead_fractionis 0.015869 (= 65/4096, the two summary levels overlevel_0_words) on every row.
SHARE, recomputed — and it is what actually closes this row. The registration inherited M-337's
5.5× for the flat bitmap on a surface-free field and said "the stage is known to be large enough to
matter". The harness measured the share instead of inheriting it, and the inherited premise does not
survive: traversal_share_of_extraction — the flat traversal's cycles per cell over the shipped
DualContouring::extract's cycles per cell, same grid, same run — reads 0.000088 to 0.000994, i.e.
the active-cell walk is under one tenth of one percent of an extraction. So
extraction_speedup_ceiling = 1/(1 − share·(1 − 1/ratio)) reads 1.00039× at its best (thin_plate
129³) and 0.99994× on the gyroid 129³ row. C1 is a stage clause and its 1.5× bar has no Amdahl
ceiling, so C1 held on its own terms and this does not retract it — the mechanism is real, it is
VDB's node bitmask one level up re-measured at this crate's granularity, and 2.568× / 3.318× on a
sparse field is a true reading. But a mechanism that wins its microbenchmark and moves under 0.1% of
an extraction earns no landing ticket: this is the ✗51 / R-114 shape, and refusing to land it is the
result. crates/isomesh/src/** did not change; the whole hierarchy is bench-local, mirroring
row_stride, build_inside_bits, inside_word, active_word and cell_mask line for line.
💥 ✗91 / M-428 — C1 FALSIFIED on 16 of 16 rows at access_ratio 57.7683–115.7726 against a registered bar of 2.0 — random access is 29× to 58× past it, and past it on the second rank granularity too (access_ratio_teb64 31.7068–77.5062) — while C2 HELD on 16 of 16 at space_ratio 2.3666–563.7505 against 1.5 and C3 HELD with answers_equal = cells on 16 of 16: this is the falsifier the registration named in advance as closing the family rather than just the row, so TEB, WAH and EWAH are all retired for this crate's active-cell bitmap in one measurement (P-115, R-115)
M. cargo bench --bench experiment_p115, docs/experiments/p-115.csv, 16 rows, f32
(scalar = f32 on all 16), amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one
column header plus 16 data rows across 67 columns — counted from the file, not from the brief.
One row per (field, resolution): eight fields (sphere, torus, box_exact, csg_difference,
thin_plate, gyroid, fbm_terrain, noise_cavity) × {65³, 129³}, so cells is 262,144 on eight
rows and 2,097,152 on eight. Each row carries four sibling counter windows over one shared index
array — flat, TEB, TEB-with-word-granularity-rank, and a do-nothing floor — each batched to its own
inner_reps (inner_reps_flat 708–1,898, inner_reps_teb 14–31, inner_reps_teb64 23–54,
inner_reps_floor 3,036–3,151), over accesses = 16,384 random indices drawn from
access_seed = 0x000001155eed1115, reps = 15. Committed at d369458 —
# commit 8d5ab93 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:41:27Z, no (WORKING TREE DIRTY),
and git merge-base --is-ancestor d369458 HEAD passes (HEAD is an ancestor-consistent tip,
p-115.csv - re-run on a clean tree).
| clause | registered | measured |
|---|---|---|
| C1 random access costs at most 2× the flat bitmap's per access | ≤ 2.0 (c1_bar = 2.0, c1_carrier = cycles) |
FALSIFIED on 16 of 16 — access_ratio 57.7683 (fbm_terrain 129³) to 115.7726 (noise_cavity 129³); cycles_per_access_flat 1.8028–2.4760 against cycles_per_access_teb 108.6049–251.8176. c1_holds_instructions is also false on 16 of 16: instruction_access_ratio 27.8098–59.2286, instructions_per_access_flat 11.5005 (constant) against instructions_per_access_teb 319.8256–681.1577 |
| C2 space saving of at least 1.5× against the flat bitmap | ≥ 1.5 (c2_bar = 1.5) |
HELD on 16 of 16 — space_ratio 2.3666 (gyroid 65³) to 563.7505 (thin_plate 129³); flat_bytes ∈ {32768, 262144} against teb_bytes 225–71,878, broken out as tree_bytes + label_bytes + rank_bytes + metadata_bytes (= 32 on every row). Survives the faster rank too: space_ratio_teb64 1.8778–454.3224, ≥ 1.5 on 16 of 16 |
| C3 identical answers on every cell | equality, population = every cell | HELD on 16 of 16 — answers_equal = cells exactly: 262,144 on the eight 65³ rows and 2,097,152 on the eight 129³ rows, an exhaustive sweep and not a sample |
C1 is falsified by the structure, not by a tuning constant, and not by the harness's own overhead. The paper names the rank granularity as an empirical space/time trade-off, so the same tree, labels and
prune_depthwere re-encoded with oneu32per tree word in the same binary:access_ratio_teb64still reads 31.7068–77.5062, a minimum of 15.9× the bar. And the raw windows are the form most favourable to the clause, because the floor is a common addend — subtractcycles_per_access_floor(1.2253–1.2267, flat across sixteen rows of identical work) and the cycle ratio moves up to 125.5–338.8; subtractinstructions_per_access_floor(7.0005, constant) and the instruction ratio moves up to 69.5–149.8. PerM-280the wall-clock form (ns_access_ratio,ns_per_access_flat0.4306–0.5917 againstns_per_access_teb25.9662–60.1676 atghz4.1787–4.1864) is recorded and consulted by no clause;c1_carrier=cyclesnames the unit the verdict is carried in, with the deterministic instruction form beside it agreeing.This clause was arithmetically decided before the harness existed, and the registration says so in its own falsifier. A flat access is one masked load:
instructions_per_access_flat= 11.5005, i.e. 4.5 instructions above the floor. A TEB lookup is a dependent path walk ofmean_node_visits2.5937–6.4773 levels (max_node_visits9–20,tree_height18 or 21), and each level is a rank —popcounts_per_access_teb8.3516–23.3634 againstpopcounts_per_access_flat0. Withtarget_feature_popcnt= false on 16 of 16 (notarget-cpu, noRUSTFLAGS, socount_oneslowers to the ~12-instruction SWAR sequence and the bench binary contains zeropopcnt), ~9–23 popcounts plus 2.6–6.5 serialised loads cannot land within 2× of 4.5 instructions. Free hardwarePOPCNTwould not save it either:instruction_access_ratio_teb64is 12.1377–28.6045 with the popcount work already reduced to one maskedcount_ones, still 6–14× the bar.The comparand is not a strawman and C2's win is not an artefact of an unoptimised encoding. Both of the paper's space optimisations are in: implicit tree nodes take
teb_unoptimised_bytesdown toteb_bytesby 9.63%–14.12% on the eight 65³ rows, andbest_prune_depthsearches allh + 1instances, where the fully pruned tree is not the smallest on 6 of 16 rows (teb_bytes<teb_fully_pruned_bytes—torus65³ 2,633 against 2,634;gyroid129³ 67,177 against 67,253;noise_cavity129³ 71,878 against 71,898; alsogyroid65³,noise_cavity65³,torus129³), withprune_depth0–11.Both vacuity controls fired. C3's equality is worthless from an instrument that cannot see inequality, so every row also encodes the fully pruned tree with its deepest level cut off (
truncated_cut_depth13–20) and sweeps every cell through that too:truncated_tree_mismatchesreads 1,168 (torus65³) to 37,903 (noise_cavity129³), non-zero on 16 of 16. That is what makesanswers_equal=cellsadmissible rather than tautological. The floor window is the second control, and it is what lets the C1 falsification be attributed to the structure rather than to the index walk.
✗91forecloses the whole RLE family for this crate's active-cell bitmap, and the registration pre-committed to that reading. Itsfalsified_byis explicit: C1 fails "by random access above 2x the flat bitmap's, which is the whole reason to prefer TEB over WAH and therefore the falsifier that closes the family rather than just the row." WAH and EWAH store a bitmap as fill and literal words whose bit-kposition is knowable only by decoding every preceding word — random access is O(words), not O(1) — so they were never candidates for a summary thatP-107's directory needsrank(k)from. TEB is the one RLE-family scheme that keeps O(1) access, it was measured with the paper's own navigation, its own rank granularity and a faster one, and it lost by 29× to 58×. There is no surviving member. TEB, WAH and EWAH are retired here; a later reader re-proposing any of the three is re-proposing a measured 58× regression.
SHARE, recomputed — and C2's win is enormous and worthless, which is the finding. No extraction time
is claimed: C1 is a cost bound, C2 a space bound, C3 an equality, and none is a fraction of a total.
The object being compressed is flat_bytes = 262,144 bytes = 256 KiB at 129³ (one bit per cell,
cells = 2,097,152) and 32,768 bytes = 32 KiB at 65³. So the entire upside available to any
compression of this structure is 256 KiB, once, for a whole 129³ extraction. thin_plate 129³ takes
teb_bytes to 465 — space_ratio 563.7505, a saving of 261,679 bytes ≈ 255.5 KiB — and pays
access_ratio 63.8770 for it (cycles_per_access_flat 2.4760 against cycles_per_access_teb
158.1867). Priced over the population the bitmap is actually read on, one lookup per cell:
2,097,152 × (158.1867 − 2.4760) = 3.265 × 10⁸ cycles ≈ 78.1 ms at ghz 4.1800, against 255.5 KiB
saved. That is the trade in full, and it is not one this crate can take at any compression ratio —
the registered clause is random access and an extraction's own scan is sequential, so treat 78 ms as
the random-access bound rather than the measured scan cost, but the bound is four orders of magnitude
larger than the thing being bought. The harness's own SHARE section puts the ceiling on any downstream
use at 1/(1 − 0.0800) = 1.087×, from P-121's measured offset/compaction share of extraction
(0.0073–0.0800), which is why no clause here is or may become a speedup claim. A structure that is
563× smaller and 64× slower to read is a strictly worse summary than 256 KiB of flat bits.
💥 ✗92 / M-429 — C1 HELD at 256 of 256 triangulations identical to CASES, C3 HELD with 4 of 4 properties over 8,712 checks and 0 violations, C2 FALSIFIED on 0 of 8 rows at ratio 1.016528–1.038325; and the row's real content is that GRAPHGEN is inert on this table — the synthesised optimal tree is the complete eight-level tree (average_path_len 8.000000, min_average_path_len = max_average_path_len) and the DRAG merges exactly one node of 511, so 99.8043% of the tree survives compression (P-116, R-116)
M. cargo bench --bench experiment_p116, docs/experiments/p-116.csv, 8 rows across 63
columns — counted from the file, not from the brief: four # comment lines, one column header, eight
data rows, one per reference field (sphere, torus, box_exact, csg_difference, thin_plate,
gyroid, fbm_terrain, noise_cavity) at the single grid resolution 65 / cells 262,144, each
row reps 16 with the arm order alternating and inner batched per field between 8 and 23
passes. amd-ryzen-9-5900x-12-core (Zen 3), ghz 4.1792–4.1826 on all eight rows. Committed at
a0c027e — # commit a0c027e on amd-ryzen-9-5900x-12-core at 2026-08-29T00:44:36Z, no
(WORKING TREE DIRTY), and git merge-base --is-ancestor a0c027e HEAD passes; the dataset landed in
0e7ae35 (p-116.csv - re-run on a clean tree), also an ancestor of HEAD.
| clause | registered | measured |
|---|---|---|
C1 the synthesised tree, compressed to a DRAG and emitted as Rust, produces triangulations identical to CASES on all 256 patterns |
256 of 256 | HELD — patterns_tested 256 = triangulations_identical 256, c1_holds true on 8 of 8; mesh_identical and mesh_identical_to_shipped both true on 8 of 8; mutant_tree_mismatches 2, so the comparator can fail |
| C2 the generated form is not slower than the table lookup, in instructions per cell | ratio ≤ 1.00 |
FALSIFIED on 0 of 8 rows — ratio 1.016528–1.038325, instructions_per_cell_table 130.6919–316.3329 against instructions_per_cell_generated 135.7007–321.5613, c2_holds false on 8 of 8, and instruction_ratio_spread 0.000000 on every row |
C3 P-64's four properties hold on the generated form |
4 of 4, 0 violations | HELD — properties_held 4, property_violations 0 over property_checks 8,712 on patterns_tested 256, c3_holds true on 8 of 8; sabotages_caught 4 of 4, sabotage_failed true |
GRAPHGEN is sound and inert here, and that is a structural fact about the Marching Cubes case table rather than about GRAPHGEN. Bolelli et al.'s DRAG compression is driven by don't-care entries and by condition combinations that share an action. This table has neither to give:
dont_care_entries0 (all 256 assignments specified),distinct_actions255 over 256 patterns,shared_action_patterns1. The dynamic program was run for the maximum as well as the minimum overdp_subcube_states6,561 memoised subcube states, andmin_average_path_len=max_average_path_len= 8.000000 — every ordering of the eight conditions is optimal, there is no shorter tree, andcondition_orderis the identity01234567. Sotree_nodes511 =tree_internal_nodes255 +tree_leaf_nodes256, and the DRAG merges exactly one node:drag_nodes510,drag_nodes_merged1,drag_compression0.998043. The merge is a leaf merge —drag_internal_nodes255 =tree_internal_nodes255,drag_leaf_nodes255 againsttree_leaf_nodes256 — i.e. the one duplicated action collapses two leaves into one and nothing above the leaves shares at all. A pipeline whose entire compression budget on a 256-row table is one leaf has nothing to exploit; it emitted correct code (C1,emitted_rust_compilestrue,emitted_rustc_messageok) and bought nothing.
c2_holdsreadingfalseis not noise and not a defect.instruction_ratio_spreadis 0.000000 on 8 of 8 rows, so the count is exactly reproducible across the 16 repetitions and the bar needs no tolerance. The verdict is carried by the instruction form and by nothing else:cycle_ratio1.058465–1.196361,branch_miss_ratio0.988585–1.869089 andns_per_cell_table/ns_per_cell_generated(6.785424–21.254511 against 8.019250–22.481447) are beside it and gate nothing —M-280,M-281, on a governed CPU spanning 1.96–5.62 GHz a nanosecond is not a unit. And the ratio's spread across fields is entirely its denominator's. The absolute cost is field-independent:instructions_per_cell_generated − instructions_per_cell_tableis +5.0088 (thin_plate) to +5.5280 (fbm_terrain) instructions per cell on every row, which is the eight-deep compare-and-branch chain replacingcase_of's eight branchlesscase |= 1 << cand one indexed load.noise_cavityshows the lowest ratio (1.016528) only because its march is the most expensive (316.3329), not because the mechanism is cheaper there. Quote the +5 instructions, not the percentage.The harness's own emitted-text cross-check fired on the first clean-tree run, and the repair is on record as
a0c027e.emit_nodewrites the condition-TRUE child first, so the emitted source enumerates root-to-leaf path words in descending order — text head[0, 127, 191, 63, …]against binary head[0, 128, 64, 192, …]— while the comparand walked0..PATTERNSupward and therefore compared the text against its own reverse. It could never have passed. The defect was located rather than guessed:text == rev(binary)andtext == emitted_leaf_orderboth held, which pins it to exactly one of the three conjuncts, the path enumeration; the fix walksPATTERNS - 1 - i. No clause was weakened and no bar moved. Soemitted_matches_compiledtrue on 8 of 8 is a repaired check, and the emitted artefact —emitted_bytes88,761,emitted_lines1,311, accepted byrustc --emit metadata— is now known leaf-for-leaf to be the same decision function as the expansion C2 counted instructions on, which is whatM-281requires.The vacuity controls, all six, fired or were asserted.
patterns_tested256 equalstriangulations_identical;mutant_tree_mismatches2 (two leaf ids swapped in a copy ofLEAF_OF_CASE, and the C1 comparator saw it — without which C1 is an equality between two names for the onetriangulate(segment_links(…)));property_checks8,712, non-zero, because "SUCCESSFUL over zero checks" prints the same word as a proof;sabotages_caught4 of 4, one per property, each required to trip its own property — count pastMAX_TRIANGLES, a live triangle carryingNO_EDGE, a triangle naming an uncut edge, and a triangle carrying two equal codes, all fourCAUGHT;emitted_rust_compiles/emitted_matches_compiledboth true; andmin_average_path_len=max_average_path_len, without which the fixed condition order the emitted code uses is not known to be optimal.Kani ran, and what it proves is narrower than what C3 says.
kani_versioncargo-kani 0.67.0,kani_statusSUCCESSFUL overkani_checks62 withkani_failed_checks0 inkani_solver_seconds2.0410 (a0c027e's own message quotes 2.06 s from the run that aborted; the committed clean run reads 2.0410). Its sabotage arm readskani_sabotage_statusSUCCESSFUL (encountered one or more panics as expected) overkani_sabotage_checks71 withkani_sabotage_failed_checks2 — that arm passing is the load-bearing part: it means the prover can see a defect, so the 0-of-62 above is not a solver that proves everything. INSTRUMENT, per the registration: C3's verdict is the exhaustive 256-pattern Rust check, not Kani, becausecrates/isomesh/src/**is read-only for the whole of Phase 25 andmarching_cubes::proofsiscfg(kani)inside it, so a#[kani::proof]cannot be placed over a bench-local form. The 62 checks are a proof about the shippedCASESand reach the generated form only through C1's pointwise identity over all 256 patterns.The premise the ticket was motivated by does not exist, and the registration says so first.
CASES: [McCase; 256](marching_cubes/table.rs:180) is already derived at compile time byconst fn build_cases(:182-194); the transcribed Bourke tables (reference.rs:29,:53) are imported only bymarching_cubes/tests.rs:15as a cross-check and are nowhere on the extraction path. The mistranscription risk is already mitigated in the shipped path, so this row never compared a synthesised tree against a transcription — it compared one against aconst fn.✗50remains the real incident in this area and it was a bound, not a table; a code generator would not have caught it.
SHARE, recomputed. C2 is a not-slower bound and not a speedup, so the registration claims no share
and this entry does not smuggle one back in — there is no 1/(1 − s) to compute and nothing here is
Amdahl-gated. What the falsification bounds is the opposite direction: the generated form's
+5.0088–5.5280 instructions per cell is measured over the whole Marching Cubes march (both arms share
experiment::gather and emit_cell, so the delta is the case lookup and only the case lookup), against a
march costing instructions_per_cell_table 130.6919–316.3329 per cell — a 1.65%–3.83% whole-march
regression for zero compression. C1 and C3 carry no share either: both are equalities over an enumerated
population whose denominator is exact by construction at 256. Neither arm popcounts and neither reads
a u64 bitmap — zero count_ones calls per cell in either — so this build's target_feature_popcnt
= false cannot reach any verdict on this row. Nothing lands: R-116 earns no ticket, and the reason is
min_average_path_len = max_average_path_len = 8.000000, not the ratio.
🔬 M-430 — C1 HELD by 11 contraction-sensitive expressions under crates/isomesh/src/, two of them crossing an exact zero (marching_cubes::corner_position and dual::place_vertices, both 4377498837804122113 ULP, relative_difference 1.0); C2 HELD with 216 golden hashes and 0 differing across x86_64-unknown-linux-gnu and aarch64-apple-darwin; C3 HELD with no unattributed divergence — the risk is real, named, and entirely unrealised, because mul_add_call_sites is 0 and fma_instructions_isomesh_text is 0 on both targets (P-117, R-117)
M. cargo bench --bench experiment_p117, docs/experiments/p-117.csv, 34 rows, f64 throughout (scalar = f64 on 34 of 34), amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 34 data rows across 45 columns — counted from the file, not from the brief. The shape is 17 expression_site values × 2 target values: 15 subject sites spread over 9 files under crates/isomesh/src/ (fields/noise.rs 4, dual_contouring/solve.rs 3, vec3.rs 2, then cube.rs, marching_cubes/mod.rs, dual.rs, hermite.rs, predicates.rs, fields/mod.rs one each) plus 2 controls, and target reads x86_64-unknown-linux-gnu on 17 rows and aarch64-apple-darwin on 17. docs/experiments/p-117-m5-fma.txt is an INPUT to this bench, not an output — the peer's 216 hashes, its disassembly reading and its per-site ULP gaps, produced under ISOMESH_P117_PEER=1 on apple-m5 and read back here to fill every aarch64 row; without it C2 would have been recorded BLOCKED, never zero-filled. Toolchains differ by design and are recorded: peer rustc 1.96.1 (31fca3adb 2026-06-26) on aarch64-apple-darwin / apple-m5 (rustc=rustc~1.96.1~(31fca3adb~2026-06-26) in the artefact), local rustc 1.98.0 (88d9e12ae 2026-08-18). Committed at 6c72319 (p-117.csv - re-run on a clean tree) — header line # commit 0e7ae35 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:45:04Z, naming the clean tree the bench ran on, no (WORKING TREE DIRTY), and git merge-base --is-ancestor 0e7ae35 HEAD passes.
| clause | registered | measured |
|---|---|---|
C1 at least one expression in crates/isomesh/src/ is contraction-sensitive — fused and unfused differ in the last bit on a reachable input |
≥ 1 site with ulp_difference > 0 |
HELD — c1_holds true on 34 of 34; 11 of the 15 subject sites read ulp_difference > 0, the other 4 read exactly 0; reachable is true on 32 of 34 rows (false only on the two control::searched_separator rows, whose triple is searched for rather than harvested) |
C2 the 216 golden hashes are identical on x86_64-unknown-linux-gnu and aarch64-apple-darwin today |
0 differing | HELD — c2_holds true on 34 of 34, hashes_identical true on 34 of 34, golden_rows = 216 on 34 of 34, golden_hashes_differing = 0, golden_cross_machine_identical true, golden_matches_committed_fixture true on 34 of 34, c2_blocker = - |
| C3 any divergence is attributed to a named expression and reproduced by an isolated probe, not merely observed at the mesh level | no unattributed divergence | HELD — c3_holds true on 34 of 34; probe_reproduced true on 34 of 34, every row carrying expression_site, file, line, shape, fusion_variant and worst_input; unattributed divergences: none |
C1 — the eleven sites, with the divergence deliberate fusion buys
Every figure is ulp_difference / inputs_differing / inputs_tried / fusion_variant from the row for that expression_site. All eleven read identically on both targets — the ULP measurement is a source-level both-ways evaluation over inputs harvested from the eight reference fields, so it is a property of the arithmetic, not of the backend.
| expression site | file:line | shape | ULP | differing / tried | variant |
|---|---|---|---|---|---|
cube::place |
cube.rs:234 |
(lo + hi) * HALF + (hi - lo) * d |
93 | 4,164 / 408,276 | fuse-offset-term |
marching_cubes::corner_position |
marching_cubes/mod.rs:761 |
origin[0] + cell_size * R::from_f64(…) |
4377498837804122113 | 83,936 / 408,276 | fuse-product |
dual::place_vertices |
dual.rs:616 |
origin[0] + cell_size * R::from_f64(f64::from(x)) |
4377498837804122113 | 152,064 / 1,216,512 | fuse-product |
hermite::HermiteCell::from_corners |
hermite.rs:99 |
cell_origin[axis] + cell_size * place(from, to, d) |
171 | 5,291 / 408,276 | fuse-product |
vec3::dot |
vec3.rs:29 |
a[0]*b[0] + a[1]*b[1] + a[2]*b[2] |
2 | 23,990 / 136,092 | fuse-both-adds |
vec3::cross |
vec3.rs:33 |
a[1]*b[2] - a[2]*b[1] |
4359373239303840856 | 16,731 / 33,121 | fuse-first-product |
solve::Symmetric3::adjugate |
dual_contouring/solve.rs:186 |
self.yy*self.zz - self.yz*self.yz |
64 | 19,297 / 33,121 | fuse-second-product |
solve::dot_equivariant |
dual_contouring/solve.rs:104 |
sum_equivariant([a[0]*b[0], …]) |
8796093022208 | 65,270 / 136,092 | fuse-into-sorted-sum |
noise::fade |
fields/noise.rs:96 |
t3 * (t * (t * six - fifteen) + ten) |
8 | 7,642 / 24,036 | fuse-inner |
noise::perlin_value_accumulation |
fields/noise.rs:168 |
value += w * dot |
121 | 6,302 / 64,096 | fuse-product |
noise::fbm_lattice_offset |
fields/noise.rs:237 |
p[0] * freq + k * R::from_f64(OCTAVE_OFFSET[0]) |
4 | 133 / 24,036 | fuse-offset |
The two figures near 2⁶² are not large numerical errors — they are sign-crossings, and that is worse. On both marching_cubes::corner_position and dual::place_vertices, unfused_value is exactly 0.00000000000000000e0 (unfused_result 0x0000000000000000) and fused_value is -4.44089209850062616e-16 (fused_result 0xbcc0000000000000); vec3::cross goes from exact 0 to 2.74129141882754686e-17. ulp_difference is an integer bit distance, so crossing the sign bit costs about 2⁶² of it. relative_difference reads 1.0 on all three and worst_case_cancels reads true — the meaningful statement is that a grid coordinate that lands exactly on a lattice plane stops doing so, which is a predicate flip in a surface-crossing test, not a rounding wobble.
The other four subject sites read 0 ULP over the same harvest and are as much of the deliverable: solve::Symmetric3::determinant 0 / 33,121 (fuse-product), predicates::two_product 0 / 33,121 (fuse-every-cross-product — Shewchuk's roundoff y = (a_lo * b_lo) - err3, the one shape the registration expected FMA to break, and on_extraction_path is false there because the extractors never call the module), noise::fbm_octave_accumulation 0 / 8,012, FbmTerrain::sample 0 / 2,003.
The controls are what make C1's non-zeros and C3's zero admissible, and both are two-sided.
control::exact_products—perlin'sg · datfields/noise.rs:145, a real site whose gradient components are exactly0and±1so every product is exact — readscontrol_exact_products_ulp= 0 on 34 of 34, and must: a non-zero there means the comparator cries wolf and every ULP in the table above is noise.control::searched_separator— a triple searched for with SplitMix64 rather than chosen by hand, oncube.rs:349-356's precedent — readscontrol_searched_separator_ulp= 1 on 34 of 34, over 470 differing of 4,096, and must exceed zero: a comparator that reports 0 everywhere is blind, not clean. Both areassert!ed before a row is written. The disassembly reader has its own control.fmadd_in_known_fused_probeis true on 34 of 34 andfma_instructions_in_known_fused_probe= 1, withknown_fused_probe_evidencenaming the mnemonic actually seen rather than asserting the category:dispatch-to-fma:vfmadd213sdon x86-64 (inknown_fused_dispatch_symbol=compiler_builtins::…::fma_with_fma) andfmaddonaarch64-apple-darwin/apple-m5(inp117_probe_known_fused). A reader that cannot see an FMA where one must exist cannot claim to see its absence anywhere else — which is exactly what the C1 codegen column claims:contracted_in_codegenis false on 34 of 34 andfma_instructions_isomesh_textis 0 on 34 of 34, overisomesh_symbols_scanned153 on x86-64 and 96 on aarch64 (fma_instructions_isomesh_extract= 0 over 20 and 9 extractor symbols respectively).C2 HELD is the reassuring half, and the two halves together are the finding: the risk is real and unrealised. 216 golden rows,
golden_hashes_differing= 0 across the two targets, andgolden_matches_committed_fixturetrue on both arms againstcrates/isomesh/golden_hashes.json. Beside that,mul_add_call_sites= 0 on 34 of 34 — the crate never requests fusion;mul_add_mentions= 6 and all six are prose (experiment.rs3,fields/noise.rs1,predicates.rs1,real.rs1). Sorustcdeclining to contracta*b + cby default is the entire reason eleven measured sensitivities have never moved a hash. This is not a target-feature accident.fma_instructions_binary_totalreads 2 on x86-64 and 24 onaarch64-apple-darwin: the aarch64 backend emits FMA in that binary two dozen times and zero of them land in any of the 96 isomesh symbols, so the aarch64 zero is a refusal to contract, not an unavailable instruction. On the x86-64 arm the repository sets notarget-cpuand noRUSTFLAGS— the same fact that leavestarget_feature_popcntfalsein this build — so+fmais off there as well, and both zeros are contingent on build flags nothing in the repository pins. Any future-ffast-math-equivalent, anytarget-feature=+fmabuild, or one hand-writtenmul_addat any of the eleven named sites moves golden hashes; two of them do it by turning an exact zero into a signed epsilon. C1 holding is therefore not a defect report — it is the list of eleven lines to guard, andP-61already proved the 216-hash gate can fire by moving 135 of them.
SHARE, recomputed. None, and that was registered rather than discovered. This row moves no time, claims no ratio and has no Amdahl ceiling; M-280 does not apply because no clause here is a nanosecond. What stands in a share's place is one column per clause, and each verdict above is quoted from it: C1 from ulp_difference per expression_site with inputs_tried / inputs_differing as denominator and numerator and worst_input carrying the reproducing bits; C2 from hashes_identical over golden_rows, with golden_hashes_differing and golden_matches_committed_fixture behind the boolean; C3 from probe_reproduced beside expression_site, file and line, with contracted_in_codegen as the machine-code half of the same question. The audit's own cost was one afternoon and its output is an eleven-line watch list; the registration's stated hope was that C1 would be falsified — that no sensitive expression existed at all — and the measurement says otherwise on 11 of 15 sites while C2 says the crate has not yet paid for it.
💥 ✗93 / M-431 — C1 FALSIFIED with the registered arm lifting 0 of 26 rows and reading the shipped baseline's 6 of 32 exactly, C2 FALSIFIED at 7.926391× retired instructions against a 2.0× bar, C3 HELD at hashes_moved 40 = hashes_moved_expected 40 and 0 triangle counts moved: with every reduction on the dual vertex path exact, pure_sign_flip_exact still reads 6 of 32, so M-177 is not an accumulation defect and P-101, P-118 and R-118 close together (P-118, R-118)
M. cargo bench --bench experiment_p118, docs/experiments/p-118.csv, 400 rows, f64,
amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 400 data rows
across 105 columns — counted from the file, not from the brief. Five rule arms at 80 rows each
(edge_slot, ordered_naive, superaccumulator_solve_nine, superaccumulator_all_twelve — the
registered arm — and superaccumulator_all_twelve_and_normal), split into block = equivariance
(160 rows: eight fields × {25³, 33³} × two duals × five arms, equivariance_rows = 32 per arm, each row
one elements_tested = 48 octahedral measurement) and block = golden (240 rows: eight fields ×
{17³, 25³, 33³} × two duals × five arms, golden_dual_rows = 48 per arm, each scored against the
committed crates/isomesh/golden_hashes.json). The shipped extractor rides every row in
baseline_elements_vertex_exact. Committed at 77a9d7a —
# commit 77a9d7a on amd-ryzen-9-5900x-12-core at 2026-08-29T00:52:17Z, no (WORKING TREE DIRTY), and
git merge-base --is-ancestor 77a9d7a HEAD passes (HEAD is an ancestor-consistent tip, p-118.csv - re-run on a clean
tree).
| clause | registered | measured |
|---|---|---|
C1 an exactly order-independent accumulator reaches elements_vertex_exact 48 of 48 on the equivariance fixture, where the shipped solve is below it |
all 26 | FALSIFIED — c1_rows_lifted = 0 of c1_population = 26; c1_rows_at_48 = 6 of equivariance_rows = 32, identical to baseline_rows_at_48 = 6, and arm_superaccumulator_all_twelve_rows_at_sign_8 = 6 of 32, the shipped reading unchanged |
| C2 cost under 2× simple ordered summation, which is Neal's own figure | c2_bar = 2.0 |
FALSIFIED — cost_ratio 7.926391, from instructions_per_solve_superacc 14897.3072 over instructions_per_solve_ordered 1879.4565 |
| C3 golden-hash movement confined to vertices whose accumulation order changes and NO TRIANGLE COUNT MOVES | 0 counts | HELD — hashes_moved 40 = hashes_moved_expected 40, triangle_counts_moved 0, max_hausdorff_delta 4.818367926873e-14, and topology_identical / triangle_count_identical / indices_identical / counts_identical true on 400 of 400 |
C1 was arithmetically out of reach before this harness existed, and the file says so in a column.
c1_reachable_before_run reads false_p101_locates_the_obstruction_in_vec3_length_and_m177 on all 400
rows. From docs/experiments/p-101.csv, already on disk: edge_slot_equivariant_normal reaches
pure_permutation_exact = 6 on 32 of 32 equivariance rows — the permutation half is vec3::length's
naive dot, not the accumulation — while pure_sign_flip_exact = 8 stays at 6 of 32 for the shipped
extractor and for all four of P-101's arms, which is M-177. elements_vertex_exact = 48 needs both
halves. The row was run anyway, with a fifth arm arranged to locate the failure rather than argue it.
rule |
rows at 48 (of 32) | rows at perm 6 | rows at sign 8 | golden hashes moved (of 48) | triangle counts moved |
|---|---|---|---|---|---|
edge_slot (instrument check) |
6 | 8 | 6 | 0 | 0 |
ordered_naive |
6 | 8 | 6 | 40 | 0 |
superaccumulator_solve_nine |
6 | 8 | 6 | 36 | 0 |
superaccumulator_all_twelve (registered) |
6 | 8 | 6 | 40 | 0 |
superaccumulator_all_twelve_and_normal |
6 | 32 | 6 | 40 | 0 |
M-177is not an accumulation defect, and that is this row's result. The registered arm's three equivariance columns are identical to the shipped baseline —arm_superaccumulator_all_twelve_rows_at_486,_rows_at_perm_68,_rows_at_sign_86 againstarm_edge_slot_*6 / 8 / 6 — so exactness moves nothing. The fifth arm then makes every reduction on the dual vertex path exact, superaccumulating all twelve slots and the normal's length, and takes_rows_at_perm_6to 32 of 32 while_rows_at_sign_8stays at 6. An accumulator that is exactly order-independent, rounded once rather than eleven times, buys the permutation half and buys nothing at all on the sign-flip half.M-177's obstruction covers the octahedral case, which is precisely the falsifier's stated consequence:P-101,P-118andR-118close together.The vacuity controls fired, all of them.
baseline_elements_vertex_exactis populated on 400 of 400 rows and takes six distinct values (2 on 240 rows, 48 on 80, 4 on 40, 6 on 20, 16 and 24 on 10 each) —baseline_matches_p101is true on 400 of 400, so the run reproduces✗79 / M-413's own reading before it measures a move away from it.replica_bit_identicalandgolden_fixture_matches_shippedare true on 400 of 400, andbit_identical_to_shippedis true on all 80edge_slotrows and false on 252 of the other 320 — the change under test being visible, not a defect. The accumulator itself was tested before any mesh was built:superacc_exact_cases10,superacc_integer_oracle_cases5 (i128 oracle),superacc_permutation_cases10 at 64 shuffles each,superacc_negation_cases10, andsuperacc_cases_where_shipped_differs4 — that last is the battery's own control, because a battery on whichsum_equivariantand the superaccumulator never disagree proves nothing.worst_chunk_magnitude_bitsreads 54 of 64 over the battery and the whole cost corpus (the harness's stdout prints 53, which is the battery-only census), against the module doc's no-carry-propagation bound of12 · 2^53 < 2^57.
C2's failure has a mechanism, not just a number. superacc_reductions_per_solve = 12 (3 centroid +
6 matrix + 3 gradient), and each one pays a whole superacc_chunks = 67-chunk read-out over
superacc_mean_terms_per_reduction = 3.993103 terms (cost_corpus_crossings 4632 over
cost_corpus_solved 1160). Neal's 2× is an array figure; a four-term reduction cannot amortise a
fixed-size read-out, so the bar was unreachable for a structural reason the corpus makes explicit. The
verdict is scored in retired instructions. ns_cost_ratio 8.135137 (from ns_per_solve_ordered
143.3831 and ns_per_solve_superacc 1166.4407) and cycles_per_solve_ordered 599.5316 /
cycles_per_solve_superacc 4876.8079 are recorded beside it and no verdict reads them — on a governed
CPU spanning 1.96–5.62 GHz a nanosecond is not a unit (M-280, ✗24).
Incidental, and measured here for the first time: what A-016 costs.
instructions_per_solve_edge_slot 8715.1955 against instructions_per_solve_ordered 1879.4565
gives shipped_over_ordered_instruction_ratio 4.637083 — the shipped sum_equivariant path costs
4.64× a naive ordered sum on the dual vertex solve. No clause asked for that; it is the price of
equivariance on the path, and a reader can now see it without inferring it.
C3 held, and it agrees with a different experiment. The 40 golden rows that moved are the same 40
(field, resolution, dual) configurations ✗79 / M-413 recorded: comparing mesh_hash_moved per golden row
against p-101.csv's abs_value_abs_offset arm gives an identical set of 40, symmetric difference empty —
two mechanisms with nothing in common, a canonical key reorder and an exact fixed-point accumulator,
displacing exactly the same vertices. max_hausdorff_delta here is 4.818367926873e-14 against p-101.csv's
3.008704396734e-14. grid_mirrors reads false on the 80 golden 25³ rows (eight fields × two duals × five
arms) because 2L/24 is not dyadic and that grid does not mirror bit-exactly — which is exactly why C1 is
scored on the equivariance block only: a non-mirroring row would be falsified by the fixture rather than
by the extractor.
SHARE, recomputed. The dual vertex solve only. M-25 puts the sharp-feature solve at 3% over Surface
Nets and at 6.5% on Zen 3, the machine this phase runs on, so the ceiling is 1/(1 − 0.065) =
1.070×. C1 is a correctness clause and C2 a cost bound; neither is or may become a speedup claim, and
no column in this file is a speedup. The mechanism is refused on both counts and gets no landing ticket:
it lifts c1_rows_lifted = 0 rows and would cost cost_ratio 7.926391 inside a 1.070× envelope.
🔬 M-432 — C1 VACUOUS on all 16 rows because the registered perturbation had nothing to move (baseline_spread 0, and buckets_of_three_or_more_spanning_chunks = 0 on 16 of 16 says why), C2 HELD at instruction_cost_ratio 1.0888–1.1059 against a 1.25 bar, C3 HELD on 768 welds — and the mechanism itself is not in doubt, because the vacuity control reproduced P-9 exactly (baseline_spread_within_bucket 4 and 2 against p9_published_spread 4 and 2, p9_reproduced true on 16 of 16) and the double buffer took both to 0 (P-119, R-119)
M. cargo bench --bench experiment_p119, docs/experiments/p-119.csv, 16 rows, f64,
amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 16 data rows
across 64 columns — counted from the file, not from the brief. Eight distinct field values
(sphere, torus, box_exact, csg_difference, thin_plate, gyroid, fbm_terrain, noise_cavity)
× two extractor values, one row each; cells = 46,656 on every row (eight chunks of 18³, P-9's
own fixture); permutations = 8 and permutations_extended = 32. Three welds share one
broadphase per row — single (a line-by-line mirror of Welder::weld_split_by, mirror_matches_shipped
true on 16 of 16 and asserted), double_indexed (double-buffering and nothing else) and double
(double-buffering plus the canonical tie-break). Committed at 6c72319 —
# commit 6c72319 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:45:28Z, no (WORKING TREE DIRTY),
and git merge-base --is-ancestor 6c72319 HEAD passes; the dataset landed as 2a9b234
(p-119.csv - re-run on a clean tree), also an ancestor of HEAD.
| clause | registered | measured |
|---|---|---|
C1 double-buffering removes P-9's vertex-count spread — 4 under dual_contouring, 2 under manifold_dual_contouring — to exactly 0 |
spread → 0 | VACUOUS — c1_holds reads the literal string vacuous on 16 of 16. The registered column baseline_spread is over chunk append order and reads 0 on 16 of 16, baseline_spread_extended 0 on 16 of 16 over 32 orders; control_fires (baseline_spread > 0) is false on every row, so double_buffered_spread = 0 is a zero removed from a zero. The mechanism is still shown to work, on the other perturbation family — see below. |
| C2 the cost is under 1.25× the single-buffer path | ≤ 1.25 | HELD — instruction_cost_ratio 1.0888–1.1059, c2_holds true on 16 of 16. The clock agrees: cost_ratio (the registered column, and it is the nanosecond ratio) 1.0802–1.1686, c2_holds_ns true on 16 of 16, cycle_cost_ratio 1.0793–1.1665 at ghz 4.1802–4.1877 |
| C3 the mesh is identical under every permutation of chunk append order | equality | HELD — mesh_identical_across_permutations true on 16 of 16, distinct_canonical_meshes_double = 1 on 16 of 16. Scored as a conjunction over three families: 8 chunk orders, 32 extended chunk orders (double_buffered_spread_extended 0) and P-9's 8 within-bucket permutations (mesh_identical_across_permutations_within_bucket true on 16 of 16) — 48 welds per row, 768 in the file. The control gives it meaning: mesh_identical_across_permutations_single is false on the two torus rows, where distinct_canonical_meshes_single = 6 of 8 |
The census is what turns
baseline_spread = 0from a hope into an explanation, and it is decided by the fixture rather than by the sweep. Seven columns that no clause reads —buckets_of_two_or_more,buckets_of_three_or_more,p9_published_buckets_of_three_or_more,buckets_spanning_chunks,buckets_of_three_or_more_spanning_chunks,largest_bucket,chunk_orders_distinct— were wired out in0b51cd8, and they answer the only question the vacuity control exists to ask. The perturbation was genuinely applied:chunk_orders_distinct= 8 of 8 seeds on every row. It simply had no purchase.buckets_of_three_or_more_spanning_chunksis 0 on 16 of 16 — and that is the only kind of bucket whose member count chunk append order can change, because first fit only elects a different number of representatives from a chain of three or more, and only a bucket straddling a chunk boundary has its member order moved by the append. Twelve rows have no bucket at all (buckets_of_two_or_more= 0).torushas 4 cross-chunk buckets butlargest_bucket= 2, and a bucket of exactly two elects one representative in either order.noise_cavityhas the only chains —buckets_of_three_or_more1 underdual_contouringand 2 undermanifold_dual_contouring, equal top9_published_buckets_of_three_or_moreon both rows,largest_bucket3 — andbuckets_spanning_chunks= 0 on both, so they sit inside one chunk and the append never reorders them. C1's vacuity was therefore decided by the geometry of the block before a single permutation ran; the census is a function of the identity-order mesh only.
vacuoushere does not mean the mechanism failed, and the registration's own control proves it. The registered control is that the single-buffer arm reproduceP-9's published spread, and it fired in the right direction on all 16 rows:p9_reproducedtrue 16 of 16, which assertsbaseline_spread_within_bucket==p9_published_spreadanddistinct_outputs_within_bucket==p9_published_distinct_outputson every row — including the two that move,noise_cavity/dual_contouringat 4 andnoise_cavity/manifold_dual_contouringat 2, and the nine-distinct-output rows (torus5,noise_cavity8). Under that same protocoldouble_buffered_spread_within_bucketis 0 on 16 of 16. So the double buffer does removeP-9's spread; what is vacuous is the registered column, because the registration named chunk append order while the 4 and the 2 came from within-bucket permutation. Those are two statements and the harness ran both rather than substituting one for the other.The two halves of the mechanism are separated in the file, and only one of them is double-buffering.
spread_double_indexed= 0 on 16 of 16: double-buffering alone makes the partition a function of the ε-graph, so the vertex count is order-free by construction. It does not make the mesh order-free —mesh_identical_across_permutations_indexedis false on the twotorusrows. C3 is bought by the canonical tie-break, which is a different device, and the entry should not be read as C3 crediting the double buffer.Three costs no clause bounded, reported and unscored. (1) Memory:
peak_bytes_ratio2.8577– 4.2813× (peak_bytes_single23,976–294,076 againstpeak_bytes_double88,448–840,384). That is a real price for determinism and nothing in the registration capped it. (2) The answer moves. Label propagation converges to the transitive closure of ε-closeness, whichweld.rs:41-52refuses on purpose:vertex_deltareads −4 and −2 on the twonoise_cavityrows (vertices_single7,700 →vertices_double7,696; 7,938 → 7,936) and 0 on the other fourteen — the closure removes exactly as many representatives as ordering could elect, which is the same 4 and 2. (3) The ε guarantee is exceeded:max_move_over_epsilonreads 1.732051 (√3) on bothnoise_cavityrows and 1.000000 on bothtorusrows, so the chain-draggingweld.rswarns about is real on this fixture, not theoretical. This is a different weld that is deterministic, not a deterministic version of the shipped one.
target_feature_popcntisfalseon 16 of 16 and no verdict here is contingent on it —count_ones_calls_per_vertexis 0 on every row; neither arm is a bitmap.
SHARE, recomputed. C1 and C3 are determinism equalities and C2 is a cost bound, so no clause is a
fraction of a total and none is a speedup claim — the measured mechanism is 8.9–10.6% more
expensive, not faster. C2's denominator is named: instructions_per_cell_single, 96.9447–1421.9796
instructions per cell over the 46,656 cells of the eight-chunk block, against
instructions_per_cell_double 107.0542–1562.3943. The window is the weld alone, prefix-differenced
against a sibling restore window that both arms pay (instructions_per_cell_restore 0.0906–1.1215,
under 0.1% of the single arm, so the dilution is negligible and visible: cost_ratio_undiluted
1.0802–1.1686 against cost_ratio_with_restore 1.0800–1.1682). Per M-280/M-281 the instruction
form carries the verdict and the nanosecond form is recorded beside it for comparison; on this row
they agree, which is the useful thing to be able to say. The share C1 could have moved is
baseline_spread itself, and it was 0 — the crate's chunked-append path has no vertex-count
order-dependence on this fixture to buy back. Parallel SurfaceNets' one-to-two-orders-of-magnitude
figure is a parallel result and every loop in crates/isomesh/src/** is sequential; nothing here is
scored against it.
💥 ✗94 / M-433 — C1 FALSIFIED on 4 of 32 rows, all four fbm_terrain, ratio 1.7965–1.9008 against a 2.0× bar and every one of them decided (ratio_band_decides true, nine-repetition band topping out at 1.8221); C2 HELD on 32 of 32 — order_independent, labels_consecutive and distinct_final_states = 1 across orders_tested = 3, so ✗26's defect does not reproduce in a per-chunk union-find that is never asked to delete; C3 HELD on 32 of 32 (partition_identical) against a mutant that mismatches on 125,877–2,222,208 samples; and on the deterministic instruction_ratio the 2× bar is cleared on only 14 of 32 (P-120, R-120)
M. cargo bench --bench experiment_p120, docs/experiments/p-120.csv, 32 rows, f64,
amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 32 data rows
across 52 columns — counted from the file, not from the brief. Eight fields × {65³, 129³} ×
{base, dug}, sixteen rows per arm; chunk_cells 32,768 and samples_per_chunk 35,937 on all 32,
chunks 8 at 65³ and 64 at 129³, reps 9 and orders_tested 3 on all 32. Committed at 2a9b234 —
# commit 2a9b234 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:46:15Z, no (WORKING TREE DIRTY), and
git merge-base --is-ancestor 2a9b234 HEAD passes (HEAD is an ancestor-consistent tip; the dataset landed in 3cb450a,
p-120.csv - re-run on a clean tree).
| clause | registered | measured |
|---|---|---|
| C1 at least 2× against the shipped flat-label structure on per-chunk island labelling | ≥ 2.0× | FALSIFIED — c1_holds true on 28 of 32, false on 4: fbm_terrain 65³ base ratio 1.8128, 65³ dug 1.7973, 129³ base 1.9008, 129³ dug 1.7965. Every other row clears it, ratio topping out at 2.3759 (thin_plate 129³ base). ratio is cycles_per_cell_flat / cycles_per_cell_union_find — the scoring form, per M-280/M-281; ns_ratio agrees to four figures on all four failing rows (1.8134, 1.7961, 1.9006, 1.7961), and instruction_ratio is lower still (1.6732, 1.6197, 1.6967, 1.6213) |
| C2 final labels are consecutive and independent of iteration order | exact | HELD — labels_consecutive true on 32 of 32 and order_independent true on 32 of 32, with distinct_final_states = 1 on 32 of 32 over scan orders [forward reverse z_fast] (orders_tested = 3): the final label array is bit-identical across all three, not merely partition-equivalent |
| C3 the label sets equal the flat-label path's partition exactly | exact | HELD — partition_identical true on 32 of 32, and mirror_matches_shipped true on 32 of 32, so the flat comparand is checked against a real isomesh::connectivity::Air on the same chunk values rather than assumed |
28 of 32 is not "held", and the entry says so in both directions. C1 is a per-row gate and it failed on four rows; the heading is 💥 for that reason alone. But the four are not a noise near-miss:
ratio_band_decidesis true on all four, meaning the whole nine-repetition band (ratio_rep_min–ratio_rep_max) lies below 2.0 — widest isfbm_terrain129³dugat 1.7271–1.8112. The shortfall survives the strictest reading too:instruction_ratioon those rows is 1.6197–1.6967, lower than both the cycle and the nanosecond form, so no clock artefact rescues them.Symmetrically, three of the 28 "true" rows are undecided.
ratio_band_decidesis false onnoise_cavity65³dug(band 1.9834–2.0305),gyroid129³dug(1.9686–2.1194) andnoise_cavity129³base(1.9943–2.1532) — the band straddles the bar, soc1_holds= true there is a property of which repetition was medianed. The defensible tally is 25 held, 4 falsified, 3 undecided. And oninstruction_ratio, the reproducible form, only 14 of 32 rows reach 2.0:forms_agreeis false on 14 rows where the cycle ratio clears the bar and the instruction ratio does not (e.g.sphere129³dug,ratio2.2111 againstinstruction_ratio1.9994). The harness scores cycles on purpose and the reason is mechanical: the mechanism under test is locality, and an instruction count is blind to it by construction.The locality is the mechanism, and it is structural rather than a timing accident.
l1_misses_per_cell_union_findis 0.15625–0.15923 on all 32 rows — flat, field-independent, a raster scan over one array.l1_misses_per_cell_flatis 1.35212–2.91384: BFS flood fill touching ±1, ±33 and ±1089 in an order no prefetcher follows.l1_miss_ratiois therefore 8.6187×–18.6289×. The four failing rows are exactly the four where the comparand got cheap, not where the union-find got slow:fbm_terrainis the only field withair_fraction0.44993–0.48887 against a minimum of 0.76214 everywhere else, itsl1_misses_per_cell_flatcollapses to 1.35212–1.45887 (l1_miss_ratio8.6187–9.3367 against 14.2863–18.6289 on the other 28), andinstructions_per_cell_flatfalls to 80.66688–87.39525 from ≥ 132.6428. Both arms get cheaper on a half-solid field; the flat arm gets cheaper faster, and 2× is where that crosses.What C2 licenses and what it does not.
connectivity.rs:29-46explicitly refuses a union-find in favour of flat labels because it was one and addingfillbroke it —✗26: parent pointers encode union history, not spatial adjacency. C2 is that defect measured rather than argued: the final id of a component is fixed by pass two, which walks ascending raster order always, so it is a function of the partition alone. Measured, the specific defect✗26recorded does not reproduce here —order_independenttrue on 32 of 32,labels_consecutivetrue on 32 of 32,partition_identicaltrue on 32 of 32. That is a claim about this union-find: per-chunk, bench-local, rebuilt from scratch, three scan orders, and never asked to delete.✗26condemned an incrementally maintained structure asked to handlefill, and nothing on any of these 32 rows exercises a deletion. C2 is not a licence to revisitconnectivity.rs:29-46;connectivity/world.rs:387already states the surviving discipline — every restitch builds it from scratch, so it only ever unions.Both vacuity controls fired. The registered one — components must exceed 1 on the DUG arm —
components_dugreads 9–53 on all 32 rows (it is carried onto the base rows, so the assertion is checkable from any row), againstcomponents1–53. It was needed:componentsis 1 on 10 of the 16baserows, and on those rowscontrol_distinct_final_statesreads 1 — an order-sensitive flattening produces one labelling too when a chunk has one component, so those ten rows cannot testify for C2 and the harness does not assert them. On the other 22 rows the control reads 3 (21 rows) or 2 (gyroid65³base,components= 2) againstdistinct_final_states= 1, which is where C2's evidence actually lives. C3's control,mutant_partition_mismatches— a union-find with the −z unions dropped — is non-zero on all 32 rows at 125,877–2,222,208 samples, sopartition_identicalis not a comparator that cannot see a severed component.No verdict here is contingent on the missing
popcnt.target_feature_popcntis false on 32 of 32, as everywhere in this build, andcount_ones_per_cell_flatandcount_ones_per_cell_union_findare 0 on 32 of 32 — neither arm population-counts anything. This is a scan-and-equivalence-table result, not a bitmap one, and C1 would not move under-C target-cpu=native.
SHARE, recomputed. Per-chunk island labelling is not on the extraction path at all, so ✗51's
1/(1 − share/factor) ceiling does not apply and no extraction speedup is claimed or implied by any
clause here. C1's share is ns_per_cell_flat in full — the denominator is a named structure,
Air::build's flood fill on the same chunk, not a fraction of a total — and the comparand is priced
conservatively: ns_per_cell_shipped_air / ns_per_cell_flat is 1.8247×–2.0175×, so the bench-local
mirror excludes roughly half of what the real Air::build costs (its set_size bookkeeping and its
O(6n) solid_faces pass, dropped from both arms). Against the whole shipped structure,
ns_per_cell_shipped_air / ns_per_cell_union_find is 3.3999×–4.6860×, and 3.4000×–3.8345× on the
four rows that falsified C1 — which is the number anyone deciding whether to land this should read, and
it is not the number the clause was written against. C2's share is the enumerated population
chunks × orders_tested = 3,456 labelling runs, all compared; C3's share is air_samples =
33,828,137 of samples_labelled 41,399,424. Wu, Otoo & Shoshani's 5×–100× was registered as an
upper bound and not a prediction, and the gap is the size of the registration's caution: the best row
here is 2.3759×, a factor of 2.1 below the bottom of the published band. Voxel islands are not
random binary images.
💥 ✗95 / M-434 — C1 HELD with the worst residual_share at 0.005195 against a 0.05 bar, C2 HELD with max_reference_integer_share_at_65 = 0.724533 against 0.15 — the gate that made P-103, P-104 and P-106 live rather than Amdahl-dead — and C3 FALSIFIED on 18 of 72 rows by the cycle form of the emit-walk collapse reading 0.176007 and 0.119866 at 65³ under dual contouring while the retired-instruction form of the identical conjunct read 0.000051: classify and emit are not cleanly separable in cycles, so every integer_share this phase is denominated in is a share of their sum (P-121, R-121)
M. cargo bench --bench experiment_p121, docs/experiments/p-121.csv, 72 rows, 49 columns — four # comment lines plus one column header plus 72 data rows, counted from the file rather than from the brief. One block: 9 fields × {33³, 65³} × {f32, f64} × {marching_cubes, dual_contouring} = 72, cells reading 32768 on 36 rows and 262144 on 36 ((n−1)³), active_cells 0 – 28,375, inner_reps 1 – 195 chosen per row for a ~30 ms counter window. The ninth field is sphere_surface_free — C3's registered surface-free control, the canonical sphere sampled a long way from itself (crates/isomesh/benches/experiment_p40.rs:84-93, already scored on by M-337 and ✗28) — and it carries active_cells = vertices = triangles = 0 on all 8 of its rows. It is a control and not a reference field, so it is excluded from C2's maximum by construction; that exclusion is load-bearing, because the file's overall integer_share maximum is 0.759249 on sphere_surface_free 65³ f32 dual_contouring, higher than the gate number, and on a field with no surface integer work is trivially most of what is left. amd-ryzen-9-5900x-12-core (Zen 3), governed powersave/balance_performance, ghz 4.1727 – 4.2213 across all 72 rows. Stamped 3cb450a — # commit 3cb450a on amd-ryzen-9-5900x-12-core at 2026-08-29T00:49:28Z, no (WORKING TREE DIRTY) — and committed as 8098ba4 (p-121.csv - re-run on a clean tree); git merge-base --is-ancestor 8098ba4 HEAD passes.
| clause | registered | measured |
|---|---|---|
C1 the decomposition accounts for the total: residual_share under 5% of measured cycles on every row, and no stage reads zero on a fixture where it must run |
< 0.05 per row |
HELD — residual_share spans 0.000005 (thin_plate 65³ f32 marching_cubes) to 0.005195 (thin_plate 33³ f64 marching_cubes), median 0.000728; residual_share_row_worst 0.005195, a factor of ten inside the bar; c1_holds true on 72 of 72. cycles_sample ≥ 184439.1 and cycles_classify ≥ 453230.3 on every row. cycles_solve reads 0.0 on 36 rows and all 36 are marching_cubes, where the registration puts solve on the dual path only. |
| C2 integer work — classification plus the emit path's indexing — is at least 15% of extraction on at least one reference field at 65³ | ≥ 0.15 on ≥ 1 of 8 |
HELD — max_reference_integer_share_at_65 = 0.724533 on all 72 rows, attained at sphere 65³ f32 marching_cubes: integer_share 0.724533 = (cycles_classify 4284697.4 + cycles_emit 522256.2) / cycles_total 6634558.9. Not marginal and not a single row — 6 of the 8 reference fields clear the bar at 65³ (sphere 0.7245, torus 0.5978, thin_plate 0.5869, box_exact 0.5741, csg_difference 0.4678, gyroid 0.2037) and 21 of 32 reference rows at 65³ do. c2_holds true on 72 of 72. |
| C3 the split is real: on a surface-free field classification still runs and the emit stage does not, and the stage cycles move in exactly those directions | c3_classify_hold ≥ 0.5, c3_emit_walk_collapse < 0.05 in cycles and instructions, nothing emitted |
FALSIFIED — c3_holds false on 18 of 72 rows. C3 is scored per (resolution, scalar, extractor) group and stamped on all nine fields of the group, so 18 of 72 is 2 of 8 groups: 65³ f32 dual_contouring and 65³ f64 dual_contouring. Exactly one of the four conjuncts failed: c3_emit_walk_collapse reads 0.176007 and 0.119866 against the 0.05 ceiling. The other three held on all eight groups — c3_classify_hold 0.9501 – 0.9950 against a 0.5 floor, c3_emit_walk_collapse_instructions 0.000020 – 0.000208 (0.000051 on the two failing groups), and active_cells/vertices/triangles all zero on every surface-free arm. |
The half that failed is the half the harness named in advance as the one that could not carry a verdict.
experiment_p121.rs:180-187states, before the run: "on the surface-free armemit_walkis the difference of two nearly equal windows, so its cycle ratio has an unbounded relative noise floor, while an instruction count is deterministic and cache-independent" — and then requires both, "which can only make the clause harder". It did. On the two failing groups the surface-freecycles_emit_walkis 27,797.6 (f32) and 20,673.2 (f64) for 25 retired instructions — 1,112 and 827 cycles per retired instruction, againstipc_totalof4.1652and3.3372on the same rows — and it is 0.47% and 0.29% of those rows' owncycles_total(5944514.6,7216944.8). It clears the 0.05 ceiling only because the denominator,sphere'scycles_emit_walkunder dual contouring at 65³, is itself small (157934.5and172469.5, ~2.7% of extraction). The registered clause reads cycles, so the falsification stands as scored; perM-280/M-281the retired-instruction form of the same ratio —0.000051, a factor of 980 inside the bar — is the form that is a count, and it says the emit walk does collapse.What the false reading costs, stated because three other rows in this phase are denominated in it. C3 is the clause that proves classify and emit are separable at all. With it falsified on the two 65³ dual-contouring groups,
integer_shareis not a share of classification; it is a share ofcycles_classify + cycles_emitand the boundary between the two is only reliable in retired instructions. Any Group A ceiling quoted against0.724533is a ceiling on the sum of the two integer stages, and a mechanism that touches only classification inherits a smaller share than that number. This is a qualification on the denominator, not a retraction of it: on the gate row (marching_cubes)cycles_emitis522256.2againstcycles_classify4284697.4, so classification alone is 0.6458 ofcycles_totaland clears the 0.15 bar by itself.Several stage columns read negative, and that is prefix arithmetic, not negative work. A stage is
cut[k] − cut[k−1]over two counter windows (experiment_p121.rs:108-115), so two adjacent cuts inverting by less than the window's own reproducibility produces a negative difference.cycles_interpolategoes negative on 3 rows (worst −1581.5,sphere_surface_free 33³ f64 dual_contouring),cycles_solveon 3 (worst −5708.5,sphere_surface_free 65³ f64 dual_contouring),cycles_emiton 2 (worst −638.2,sphere_surface_free 33³ f64 dual_contouring) — all eight of those readings are on the surface-free control, where the stage in question genuinely does nothing and the true value is zero.cycles_residualgoes negative on 12 rows across the reference fields, worst −58493.0 onfbm_terrain 65³ f32 marching_cubes, which against that row'scycles_totalof245411974.0isresidual_signed_share−0.000238. The unregistered sub-splitcycles_emit_prepareis negative on 25 of 72 rows (worst −528553.0,noise_cavity 65³ f32 dual_contouring).M-280's point applies directly: on a governed CPU spanning 1.96–5.62 GHz a cycle window is a measurement with a noise floor, and at these magnitudes an inverted pair of cuts is clock and cache movement between two windows over the same function body. C1 is the clause that bounds the damage, and it is the reason a negative reading is disclosed rather than clamped:residual_shareis|residual| / totalprecisely so a 3% overshoot cannot pass as a 3% shortfall (:137-141), and it reads at most 0.005195 — half a percent — on every row.Vacuity controls, all three registered, all three fired. (1) Every stage's cycle count non-zero on a field where it must run — asserted per row, not merely recorded. (2)
residual_sharereported per row rather than pooled: pooling would have hidden the0.005195worst case behind a0.001043mean. (3) The surface-free arm's emit at or near zero with classify non-zero —instructions_emitfalls to 36.0 on the surface-free dual rows against a file maximum of8596148.0, whilecycles_classifythere reads4477616.1and4713889.3, i.e. 96.3% and 97.1% ofsphere's. Beside them, the instrument's own agreement check:mesh_identical_to_shippedis true on 72 of 72 — positions, normals and indices compared as bit patterns in creation order, which isM-279's rule that a new instrument's first job is to agree with the old one.agreement_ratio(mirror cycles over shipped cycles) spans 0.7798 – 1.0279, so the mirror is up to 22% cheaper than the shipped extractor on the cheapest Marching Cubes rows even while emitting its mesh bit for bit; the shares are therefore shares of the mirror's cycle profile, and that is disclosed rather than assumed away.residual_share_rep_worstreads 0.166282 — the single worst repetition anywhere in the file, reported and explicitly not scored on.A measurement-hygiene note that changes no verdict.
af62b6d's commit message recordedinteger_share 0.7260from a dirty-tree run; this clean-tree dataset reads 0.724533 inmax_reference_integer_share_at_65. A 0.2% disagreement on the phase's own gate number, in the direction of the clean run being slightly smaller. The gate opens either way, every Group A ceiling below is computed from0.724533, and the dirty number is not quoted anywhere in this entry.No verdict here is contingent on
target_feature_popcntbeingfalsein this build. The file contains nocount_onesat all and onetrailing_zeros(:774, the dual path's bit-packed word scan). C2's gate row ismarching_cubes, whoseclassifyis the inlinecase |= 1 << cloop over eight corners.
SHARE, recomputed. This row is the share instrument: it moves nothing, claims nothing, and has no 1/(1 − share/factor) ceiling of its own. What it produces is the denominator. integer_share = (cycles_classify + cycles_emit) / cycles_total reaches 0.724533 on a reference field at 65³, so a Group A mechanism that halves the integer stages has a whole-extraction ceiling of 1/(1 − 0.724533/2) = 1.568× and one that removes them entirely has 1/(1 − 0.724533) = 3.629×. That is the number R-103, R-104 and R-106 are scored against, and it is what the harness's own line "Group A proceeds: P-103, P-104 and P-106 have a reachable denominator" records. Set against ✗51: P-69's C1 asked for 2× on a stage that was 11.6% of the marginal, ceiling 1.061×, unreachable however well it vectorised — Group A's stage is 6.2× that share. The gate is an existential over fields and it is not uniform: integer_share spans 0.011925 – 0.759249 across the file and float_share 0.242021 – 0.988286, and the two sample-dominated reference fields fail the bar at 65³ (noise_cavity 0.1138, fbm_terrain 0.0237). On fbm_terrain the same complete removal of integer work buys 1/(1 − 0.023719) = 1.024×, so Group A is Amdahl-dead on expensive fields and only live on cheap ones. Every clause here reads cycles or retired instructions; ns_per_cell (4.7314 – 361.2853) and ghz are on the row as provenance and no clause consults either.
💥 ✗96 / M-435 — C1 FALSIFIED on 0 of 16 rows with branch_miss_ratio spanning 1.001214–1.983313 — the split doubles mispredictions at worst and reduces them nowhere — while C2 HELD at a worst instruction_ratio of 0.970606 against a bar of 1.10, i.e. the split is cheaper in instructions on every row, and C3 HELD bit for bit on 32 of 32: the control/data layout transfers, but the second traversal of the cell space costs +0.96 to +1.01 extra mispredictions per innermost-loop exit at 129³, which is the whole difference (P-122, R-122)
M. cargo bench --bench experiment_p122, docs/experiments/p-122.csv, 32 rows, f32, extractor = marching_cubes on all 32, amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 32 data rows across 55 columns — counted from the file, not from the brief. The shape is 16 (field, resolution) pairs — eight fields (sphere, torus, box_exact, csg_difference, thin_plate, gyroid, fbm_terrain, noise_cavity) × {65³, 129³} — each emitted twice, once with arm = single_stream and once with arm = split_stream (16 rows each). The paired comparison columns (branch_miss_ratio, instruction_ratio, the two ordering medians, extra_branch_misses_per_*) are identical on both rows of a pair; the nine columns that actually differ between the two rows of a pair are the un-suffixed per-arm ones — branch_misses_per_cell, instructions_per_cell, cycles_per_cell, ns_per_cell, ipc, cache_misses_per_cell, l1d_read_misses_per_cell, ghz — so every clause is scored on 16 comparisons, not 32, and rows_total = 16 on all 32 rows says so. reps = 16, inner_reps 4–58. Committed at 77a9d7a (p-122.csv - re-run on a clean tree) and stamped from the tree at 8098ba4 — # commit 8098ba4 on amd-ryzen-9-5900x-12-core at 2026-08-29T00:50:29Z, no (WORKING TREE DIRTY), and git merge-base --is-ancestor 77a9d7a HEAD passes; 8098ba4 is p-121.csv's own commit and is an ancestor too.
| clause | registered | measured |
|---|---|---|
| C1 splitting the case index into a dense control stream and the payload into a second stream reduces branch mispredictions per cell | any reduction, per row | FALSIFIED — rows_reducing_branch_misses = 0 of rows_total = 16 on all 32 rows; branch_miss_ratio 1.001214 (gyroid 65³, = best_branch_miss_ratio) to 1.983313 (thin_plate 129³, = worst_branch_miss_ratio); branch_misses_per_cell_single 0.008008–0.250699 against branch_misses_per_cell_split 0.015883–0.251252; c1_holds and c1_holds_all_rows both false on 32 of 32 |
| C2 total instructions per cell rise by no more than 10% | instruction_ratio ≤ 1.10, worst row |
HELD — worst_instruction_ratio = 0.970606 on all 32 rows; per-row instruction_ratio 0.853904 (thin_plate 129³) to 0.970606 (noise_cavity 65³); instructions_per_cell_single 119.6579–306.5750 against instructions_per_cell_split 102.1763–297.5637; instruction_ratio_rep_spread = 0.000000 on 32 of 32; c2_holds and c2_holds_all_rows true on 32 of 32 |
| C3 identical mesh | bit-for-bit equality | HELD — mesh_identical true on 32 of 32 and mesh_identical_to_shipped true on 32 of 32: split == single and single == MarchingCubes::extract, positions, normals and indices compared as bit patterns in creation order; c3_holds, c3_holds_all_rows true on 32 of 32 |
C2 holding is not the mild result it looks like: the ratio is below 1 on all sixteen rows, so the split is between 2.9% and 14.6% cheaper in instructions, not up to 10% dearer. The registration bounded a cost it expected to pay and the cost came back negative. The module doc predicted the direction — the control pass is a straight loop the optimiser can do things to that it cannot do to the fused body — and named it a consequence of the split rather than a corner-gather saving. Three columns close that alternative explanation:
gather_calls_single=cells(262,144 at 65³, 2,097,152 at 129³),gather_calls_split=cells + emitting_cells(264,192–2,216,037), andgather_calls_ratio1.003906–1.108242 — strictly above 1 on every row, so the split arm gathers corners more often andP-121's 15–24% corner-gather saving is provably not what is being credited here.instruction_ratio_rep_spread= 0.000000 on all 32 rows demonstratesM-279's determinism rather than asserting it, which is why the instruction form of the clause is the one carrying a verdict.The vacuity control fired, and the number it fired with is the finding.
branch_misses_per_cell_singleis non-zero on all 16 single-stream rows, spanning 0.008008–0.250699 — asserted per row, not merely recorded, because a ratio against a floor of zero is not a measurement. But the floor is low: atthin_plate129³ the shipped shape mispredicts 0.008 times per cell, under one misprediction per 125 cells, at anactive_fractionof 0.003906. C1's entire reachable share on that row was 0.8% of a branch per cell, and the split added 0.0079 more instead of removing any. The compact fields (0.008–0.025) are where the ratio is worst and the noisy fields (gyroid0.230113,noise_cavity0.250699 at 65³) are where it is nearest 1.000 — the mechanism removes nothing anywhere, and where there was most to remove it removed least.Where the mispredictions went, rather than merely that they did not fall.
extra_branch_misses_per_passis the signed difference (+73.2 to +16,619.6) andextra_branch_misses_per_x_rowdivides it byx_rows, the innermost-loop exits in one traversal (4,096 at 65³, 16,384 at 129³). The split traverses the cell space twice, so it paysx_rowsextra loop exits — and at 129³ that column reads 0.9615–1.0144 on all eight rows, which attributes essentially the entire difference to the second traversal's loop exits rather than leaving it a mystery. At 65³ it reads 0.0179–0.8690, so the accounting is only complete at the larger grid.One of the sixteen rows is ordering-fragile and the harness refuses to quote it as firm. The arms alternate order by repetition parity, and
branch_miss_ratio_single_first/branch_miss_ratio_split_firstare the medians within each ordering. Ongyroid65³ they straddle unity —1.002346single-first against0.999613split-first — so whether the split reduced mispredictions on that row is decided by which arm inherited the other's cache and predictor state. That isM-280at row granularity: the printed summary counts it as "rows whose verdict flips with the ordering: 1 of 16 — the two orderings' medians are columns, so a fragile row cannot be quoted as a firm one", andgyroid65³ is exactly the row whose firmbranch_miss_ratioof 1.001214 is the most favourable of all sixteen. Had C1's verdict rested on a single best row it would have rested on the one row that cannot bear it. It does not — 0 of 16 is the verdict — but the fragility is a column, not a footnote.branch_miss_ratio_rep_bestalso dips below 1 on four rows (csg_difference65³ at 0.745632,gyroid65³ 0.989480,fbm_terrain65³ 0.999837,noise_cavity65³ 0.980458) againstbranch_miss_ratio_rep_worst1.066253–2.249289; a single lucky repetition is not a reduction either.The popcount baseline, checked against the machine code rather than asserted.
target_feature_popcnt=falseon all 32 rows, sou64::count_oneslowers to a ~12-instruction SWAR sequence in this build. Neither arm touches that quantity:count_ones_calls_per_cell_singleandcount_ones_calls_per_cell_splitare both 0.0 on 32 of 32. The control stream is one case byte per cell —control_stream_bytes=cellsexactly (256 KiB at 65³, 2 MiB at 129³), scanned through apayload_length_table_bytes= 256 length table — not a bitmap, so there is no rank, no select and no word-population fold to pay for. And the harness reads its own binary:objdump -don the bench greps 0popcntinstructions and 0 occurrences of0x3333333333333333, the SWAR magic constant — no popcount in either form, hardware or emulated, anywhere in the linked binary, while the sibling row that found the build fact reports 18 of that constant in its own, so the grep discriminates. No verdict in this row is contingent on the popcount lowering and both are invariant to-C target-cpu=native— established by reading the machine code, not by reading the call graph correctly.Stream VByte's headline figure is not a comparand and nothing here is scored against it. 4 billion integers per second on a 3.4 GHz Haswell is the SIMD path (
_mm_shuffle_epi8over sixteen bytes); this harness has no SIMD arm andcrates/isomesh/src/**contains nocore::simd, no intrinsics and nounsafe. The registration says so in its own hypothesis text. Only the layout transferred, and the layout is what was measured.
SHARE, recomputed. C1 is a per-cell counter ratio, not a fraction of extraction time, and C2 is a cost bound — so no time claim is made and ✗51's share bar does not apply. C1's share is branch_misses_per_cell_single, the misprediction rate of the shipped shape, which is the entire quantity available to remove: 0.008008–0.250699 per cell. C2's share is instructions_per_cell_single, 119.6579–306.5750 per cell, the rate a 10% rise would be 10% of, scored on the worst row because dilution by an expensive field can only push a ratio toward 1.0 and never above the maximum — field sampling is deliberately outside both windows for that reason, since P-121 measured field evaluation at 94% of extraction on fbm_terrain and counting it would make C2 hold by dilution. C3's share is the mesh and is an equality, not a share. ns_per_cell (5.095504–20.698171) and ghz (4.1775–4.1836) ride on every row as provenance for what clock the counts were taken at, and no clause consults either — the clock happened to be steady across this run, which is luck and not a licence. Whether a misprediction reduction would have been worth anything in wall time is a question this row deliberately does not answer, and since there was no reduction to price, it does not arise.
Phase 26 — four registrations for the experiments the backlog had left unregistered, each before its harness
Source: the tickets themselves and the research docs they were drawn from —
docs/research/2026-08-23-findings-audit-and-phase-20-registrations.md and
2026-08-23-phase-20-source-corrections.md for R-052 and R-053. These four are not a new sweep. They
are the experiments that were already in BACKLOG.md, unblocked, and had never been registered: R-027a
split out of R-027 on V-45 in Phase 17, R-052 and R-053 left as the successors to R-050 and
R-048 when Phase 20 closed, and R-072 named in O-12's own text and then filed by nobody — so an open
question has been invisible to scripts/backlog_gate.sh since Phase 23 closed, which is exactly the drift
clause 6 exists to make visible and could not, because there was no P- id to be missing.
Three of the four are corrections to an experiment that already ran, and each names the error it is not
repeating. P-123 decomposes a ceiling M-318 measured and must not reopen the shape V-45 stopped.
P-124 moves P-55's predicate off the complex ✗36 proved it was saturated on, and fixes the
tolerance in the registration because a tolerance that vanishes at the endpoints is what ✗36 caught.
P-126 re-asks P-63's C3 on a block that can host the configuration, and says in its own text that
P-63 derived its expected population from the wrong census. P-125 is the one that lands a source
change, and it is registered in advance — the P-61 and P-69 way — because a landing not registered in
advance is what V-45 cost.
P-123 — registered for R-027a, before the harness: where M-318's 45x goes, decomposed into three terms
Ticket: R-027a (S). Records: field, resolution, edits, churn_total, churn_geometric, churn_predecessor_shift, churn_order_only, residual_share, order_only_share, geometric_matches_m318, canonical_control_order_only, c1_holds, c2_holds, c3_holds.
Hypothesis. M-318 MEASURED THE CEILING AND NOBODY HAS ASKED WHERE THE 45x IS SPENT. A grid-edge naming takes buffer churn from 15,706 to 346 at 129 cubed -- 45x, FLAT IN n, and equal to the true geometric change -- and M-318 simultaneously established that the ENCODING is not the obstacle. Those two facts together leave the decomposition unmeasured, which is what this row supplies. DECOMPOSITION, fixed at registration into three terms that partition the churn by construction: GEOMETRIC, a value that changed because its crossing moved; PREDECESSOR-SHIFT, a value that is bit-identical to a value in the previous extraction but sits at a different slot because a cell earlier in traversal order emitted a different number of vertices; and ORDER-ONLY, a value that is bit-identical AND whose owning edge is unchanged, differing only in where the emission order put it. The three are measured as a prefix partition of the same diff so they sum to the churn exactly, and residual_share is recorded PER ROW -- R-085's discipline, and P-112 is the precedent for what happens when a residual is denominated in a clock. METHOD: BENCH-LOCAL, instrumenting the existing edit_trace bench. NO NEW FIELD, NO NEW EXTRACTOR, NO SOURCE CHANGE. (C1) The three terms account for the churn with residual_share under 5% in RETIRED INSTRUCTIONS-free integer counting -- these are counts of values, not times, so the residual is exact and a non-zero one is a decomposition defect rather than noise. (C2) The order-only term is at least 50% of the churn on at least one reference field, which is the threshold at which a canonical reorder AT EMISSION recovers the gap without touching extract_into. (C3) The geometric term equals M-318's own 346 at 129 cubed to within the fixture's own edit set, which is the check that this harness is measuring M-318's quantity and not a new one.
Falsified by. C1 by a residual_share above 5%, which would mean the three terms do not partition the churn and no share below it is believable. C2 by the order-only term under 50% on every field -- which CLOSES R-027 for good rather than failing this row, because a reorder at emission then cannot recover the gap and the only remaining shape is the persistent edge-to-slot map V-45 already refused. C3 by the geometric term disagreeing with M-318's 346, which would mean this harness and M-318 are counting different things and the 45x it inherits is not this row's to decompose.
SHARE. this row moves nothing. It decides whether R-027 stays declined, and it must not reopen the shape V-45 stopped: R-027's only working form turns validate/determinism.rs:268's reused-buffer run from a GATE into its INTENT, and no clause here proposes that.
VACUITY CONTROL. the churn must be NON-ZERO on every row before any share of it is reported, and the order-only term must be shown able to read zero -- a control arm that emits in a canonical edge order must drive it to exactly 0 while leaving the geometric term unchanged. A decomposition whose order-only term cannot reach zero is measuring the traversal rather than the ordering.
P-124 — registered for R-052, before the harness: the monotone-edge condition on the ambient complex, where x36 says it belongs
Ticket: R-052 (M). Records: field, resolution, cells, tets, tet_edges, non_monotone_edges, non_monotone_cells, diagonal_only_failures, critical_points_lower_bound, box_exact_population_ratio, mesh_edge_control_non_monotone, c1_holds, c2_holds, c3_holds.
Hypothesis. x36 PROVED P-55'S ZERO UNREACHABLE BY PROOF RATHER THAN BY MEASUREMENT, AND THE REASON IS THE COMPLEX THE PREDICATE WAS EVALUATED ON. A mesh edge is a chord of the zero set, so a monotonicity predicate over mesh edges is saturated by geometry before it measures anything -- that is a fact about the domain and no fixture can rescue it. Finken et al.'s PL function lives on the AMBIENT complex, and this row ports it there. METHOD: a fixed simplicial subdivision of the grid -- Kuhn/Freudenthal's SIX tetrahedra per cell, which this crate already ships and P-100 already proved tiles across chunk seams at 0 open edges -- with monotonicity evaluated over TET EDGES INCLUDING THE DIAGONALS, which is the set a mesh-edge predicate structurally cannot reach. BENCH-LOCAL, NO SOURCE CHANGE. THE TOLERANCE IS THE ROW'S MOST LOAD-BEARING DECISION and it is fixed here rather than after the first surprise: it is scaled by max(|f(a)|, |f(b)|) over the edge's two endpoints, a quantity that is NOT identically zero at the endpoints, because x36's defect was a tolerance that vanished exactly where the predicate had to discriminate. (C1) Gated on the CONTRAPOSITIVE of Theorem 1 part 2b -- all tet edges monotone implies zero or at least 2 interior critical points -- evaluated AS AN INTEGER over every cell, ONE FAILING CELL SUFFICES to reject a cell and the count is exact. (C2) box_exact is the resolution witness the falsifier already handed over: its non-monotone corner population is O(n) and HALVES PER REFINEMENT, so the count at 33 cubed, 65 cubed and 129 cubed must fall by a factor in [1.7, 2.3] per doubling. (C3) The predicate discriminates: the non-monotone cell count is strictly between 0 and cells on at least six of the eight reference fields.
Falsified by. C1 by the integer count being 0 on every cell of every field, which would mean the ambient predicate is saturated too and closes the whole Finken et al. line rather than only P-55's reading of it; or by cells where the count equals the cell count, which would mean the tolerance is so tight that nothing is monotone and the predicate is measuring the tolerance. C2 by box_exact's population not halving -- a factor outside [1.7, 2.3] on either doubling -- which would mean it is not a resolution witness and x36's own falsifier does not transfer. C3 by the count being 0 or cells on three or more fields.
SHARE. this row moves nothing and proposes no source change. It decides whether the ambient reading of Finken et al. is measurable at all, which x36 left open by closing only the mesh-edge reading.
VACUITY CONTROL. 157-160: every clause here is an integer over an enumerated population whose denominator is exact by construction, so each can be checked for can-it-fire without a run. C1 can fire in both directions and both are reported. C2's [1.7, 2.3] band is two-sided on purpose -- a population that FELL FASTER than O(n) would be as much a refutation of the witness as one that did not fall. C3 is the discrimination control itself. And the instrument must be shown able to read a non-monotone edge: a control arm evaluating the SAME predicate over MESH edges must reproduce x36's saturation -- 0 non-monotone -- in the same run, which is what proves the ambient count is a property of the complex and not of the tolerance.
P-125 — registered for R-053, before the harness: the pinch predicate, shipped as a validate report and registered in advance
Ticket: R-053 (S). Records: fixture, vertices, triangles, collapse_groups, pinch_groups, components_welded, components_before, components_after, max_snap_distance, order_permutations, distinct_censuses, constructed_pinch_expected, constructed_pinch_reported, share_control_all_true, c1_holds, c2_holds, c3_holds.
Hypothesis. M-352 MEASURED THE =-CORNER REPAIR REMOVING EVERY DEGENERATE TRIANGLE ON BOTH CT VOLUMES AND CHANGING THE TOPOLOGY OF ONE: 516 of 17,201 collapse groups on bonsai are pinches, welding 520 components, against 0 of 50 on fuel. The decision is a graph property computable BEFORE the repair, so a caller can ask whether the repair is safe on ITS data rather than being shipped a repair that is safe on some data. THE PREDICATE: a union-find over the BASELINE triangles, asking whether two vertices that snap to the same corner ALREADY SHARE A TRIANGLE. If they do the collapse is a fold within one component and removes a degenerate; if they do not it is a PINCH and welds two components that the baseline mesh kept apart. THIS ROW LANDS A SOURCE CHANGE AND IT IS REGISTERED IN ADVANCE, the P-61 and P-69 way, because a landing not registered in advance is exactly what V-45 cost: a new report beside validate::sealing in crates/isomesh/src/validate/, reporting the pinch census for a mesh and its snap epsilon. The repair itself moves NO geometry -- M-352 measured max_snap_distance exactly 0 -- so this is a pure connectivity decision and the report claims nothing about position. (C1) The predicate separates the two volumes as M-352 measured them: 516 of 17,201 on bonsai and 0 of 50 on fuel, both exactly, computed from the baseline mesh alone with no repair applied. (C2) The report is O(V + F) in time and allocates once, and its answer is INDEPENDENT of triangle iteration order -- 128 permutations of the face list give one identical census, which is x26's objection asked in advance rather than after a landing. (C3) The census predicts the repair: applying the repair and counting the components it welds reproduces the report's pinch count exactly, on every fixture.
Falsified by. C1 by either figure not reproducing exactly -- these are integers over an enumerated population and there is no tolerance to hide in. C2 by any dependence on face iteration order, which is x26's defect in a new costume and closes the row immediately; or by the report allocating per group rather than once. C3 by the welded component count disagreeing with the predicted pinch count, which would mean the predicate names a different property from the one the repair acts on and the report would be answering a question a caller did not ask.
SHARE. the report is a validate-time query and is on no extraction path, so it has NO extraction share and no clause here is or may become a speedup claim. x51's bar does not apply.
VACUITY CONTROL. fuel's 0 of 50 is a zero and a zero that could not have been non-zero is not a measurement (M-44), so the SAME instrument must return non-zero on bonsai in the SAME run -- which C1 already requires -- and additionally a deliberately pinched fixture, constructed rather than sampled the way x22's was, must report a pinch count equal to its construction. And the union-find must be shown able to answer NO: a control that asks the predicate of two vertices which demonstrably share a triangle must return share = true on every one of them.
P-126 — registered for R-072, before the harness: O-12's remaining half — the dual vertex link at 2^27, as a nightly gate
Ticket: R-072 (L). Records: arm, block_cells, block_corners, patterns_swept, dual_vertices, dual_vertices_with_complete_link, worst_link_components, worst_link_pattern, max_incident_faces, link_defective_vertices, is_control, wall_seconds, c1_holds, c2_holds, c3_holds.
Hypothesis. O-12'S REMAINING HALF, AND P-63'S OWN C3 IS THE STRONGEST RECORD OF WHY IT IS STILL OPEN. P-63 closed the PRIMAL half by exhaustion -- M-374, 11 arms x 262,144 sign patterns over an 18-corner block, worst_link_components 1 on every non-control arm against a control yielding 5,302 link-defective vertices -- and it ran the DUAL arms on that same block and came back VACUOUS, max_incident_faces 2 on all three. A dual vertex lives at a cell CENTRE and its link needs the cell's 26 neighbours, so the block must be 3 x 3 x 3 CELLS = 4 cubed = 64 CORNERS and the sweep is 2^27 = 134,217,728 sign patterns. An 18-corner block cannot host the configuration at all, and zero there is not evidence. (C1) Over the full 2^27 sweep, worst_link_components is 1 on every non-control arm -- the dual vertex link is a single connected cycle, so the dual output is a manifold at the vertex. (C2) The control arm, which deliberately partitions a cell's edge cycles the way manifold_dual_contouring's FaceAmbiguity::Connected does, reads worst_link_components GREATER THAN 1, so the instrument is shown emitting bad news before its ones are read. (C3) The population is derived FROM THE BLOCK THIS SWEEP SWEEPS and not from a census taken elsewhere: dual_vertices_with_complete_link is reported per arm and asserted non-zero, and its expected value is computed from the 64 corners the sweep enumerates. THE NAMED ERROR THIS REGISTRATION EXISTS NOT TO REPEAT: P-63's C3 derived its expected population from the CRITICAL census when the population it needed was dual vertices carrying a COMPLETE link, which in an 18-corner block is empty -- so it measured a zero over an empty set and reported vacuous. THIS NEEDS A NEW P- ID AND NOT AN AMENDMENT, because experiment.rs's rule is that a registration is not amended after its run and P-63 has run. INSTRUMENT AND SCHEDULE: an estimated 4 to 45 minutes single-threaded, which is a NIGHTLY gate and not a cargo bench run, and the bench IS the gate -- after writing its CSV it exits non-zero when worst_link_components exceeds 1 on any non-control arm, naming the arm and the pattern, so one binary answers the question once and gates it forever. There is no second path and no verdict logic anywhere else.
Falsified by. C1 by any non-control arm reading worst_link_components above 1, which would mean the dual output is NON-MANIFOLD at a vertex on a reachable sign pattern -- and that is the valuable outcome, because A-017 documents MDC's non-manifoldness as a limit of the algorithm and this would name the configuration exactly. C2 by the control reading 1, which is the P-63-C3 failure mode arriving again -- a zero over an empty or unreachable population -- and ABORTS THE RUN rather than recording a pass. C3 by dual_vertices_with_complete_link reading zero on any arm, for the same reason: the 18-corner block's vacuity is precisely what a complete-link population of zero looks like, and a sweep that reproduces it has not fixed the fixture.
SHARE. this row moves nothing and proposes no source change. It decides a question named in O-12's own text that has been invisible to backlog_gate.sh since Phase 23 closed.
VACUITY CONTROL. dual_vertices_with_complete_link asserted non-zero PER ARM and never pooled; patterns_swept asserted equal to 134,217,728 exactly, so a sweep that silently narrowed its own domain is a failure rather than a fast pass; and the control arm's link_defective_vertices asserted greater than zero in the same run.
Phase 26 — the results, four entries against four registrations
Every row below was pre-registered in crates/isomesh/src/experiment.rs before its harness existed, its
harness was committed before it ran, and its dataset was re-run on a clean tree in one serial pass —
so each # commit line names a commit a reader can check out, and scripts/csv_provenance.sh passes
with no new entry on its dirty-tree list. Where a # commit sha names the previous dataset's commit,
that is the serial loop working as designed: each run starts on the clean tree the last commit left.
Twelve clauses: 9 held, 2 falsified, 1 vacuous. Two rows held every clause (M-437, M-439) and two
are dual-numbered (✗97, ✗98). One landed a source change, P-125, registered in advance the
P-61/P-69 way — because a landing not registered in advance is what V-45 cost.
Three of these four registrations were written the same day and contained an error the harness author
found and reported rather than amended, and all four errors were available before any harness existed:
P-124's C2 confuses an O(n) count with a density, and its vacuity sentence demands a zero one
sentence after demanding the same instrument be shown able to read non-zero; P-126 writes 2²⁷ for a
64-corner block, and names a FaceAmbiguity::Connected that does not exist. P-123's hypothesis claims
its three terms sum exactly when the exact partition is at the slot level and the scored term counts
crossings. Every one is recorded in its entry with the column that shows it, and
crates/isomesh/src/experiment.rs:27-31 is why none was edited.
Three of the four contain no clock at all — every column is an integer count over an enumerated
population — so M-280 has nothing to move and their clean re-runs could not have shifted a digit.
💥 ✗97 / M-436 — C2 FALSIFIED on 6 of 6 with order_only_share topping out at 0.001373626 against a 0.50 bar, C1 HELD on 6 of 6 at a worst residual_share of 0.008160237 with every residual exactly accounted by an integer identity, C3 HELD on 3 of 3 scored rows by reproducing M-318's keyed 318 / 310 / 346 and its 15,706 to the digit and VACUOUS on the 3 noise_cavity rows that have no published comparand: the churn is 77.2255%–99.4445% predecessor-shift, a canonical reorder at emission recovers at most 0.137% of it and measurably makes the churn 1.6%–4.8% worse, so R-027 closes on its own registered falsifier (P-123, R-027a)
M. cargo bench --bench experiment_p123, docs/experiments/p-123.csv, 6 rows — four # comment lines plus one column header plus 6 data rows across 56 columns, counted from the file rather than from the brief. The fixture shape, also counted from the file: two fields × three resolutions (sphere and noise_cavity at 33³, 65³, 129³), edits = 515 and dirty_cells = 792 and brush_radius_samples = 5.0 identical on all six rows, cells = 32,768 / 262,144 / 2,097,152, and three emission arms per row in one binary — the shipped scan order carrying the subject, plus the canonical_control_* and permuted_control_* column families, which is why an arm-to-arm difference is the emission order and nothing else. amd-ryzen-9-5900x-12-core (Zen 3). The header reads # commit 5e5ff1b on amd-ryzen-9-5900x-12-core at 2026-08-29T02:23:46Z, with no (WORKING TREE DIRTY); the dataset landed as 675d912 (p-123.csv - re-run on a clean tree, the child of the 5e5ff1b the run was stamped at), and git merge-base --is-ancestor 675d912 HEAD passes.
| clause | registered | measured |
|---|---|---|
C1 the three terms account for the churn with residual_share under 5%, per row |
< 0.050000 (c1_bar) |
HELD — c1_holds true on 6 of 6, residual_share 0.008160237 / 0.000939629 / 0.000764039 (sphere 33³/65³/129³) and 0.006083203 / 0.000159898 / 0.000043858 (noise_cavity), a worst case 6.1× under the bar; and the residual is not slack but an exact integer, churn_residual = −11 / +4 / −12 / −31 / +3 / −3, equal on all six rows to churn_geometric_slots − churn_geometric (307−318, 314−310, 334−346, 688−719, 594−591, 380−383) and to edges_moved − geometric_slot_collisions (12−23, 12−8, 0−12, 51−82, 49−46, 13−16) |
| C2 the order-only term is at least 50% of the churn on at least one reference field | ≥ 0.500000 (c2_bar) |
FALSIFIED — c2_holds false on 6 of 6; order_only_share_max = 0.001373626 on c2_best_field = noise_cavity, which is 364× short of the bar. churn_order_only is 0 / 0 / 2 of 1,348 / 4,257 / 15,706 on sphere and 7 / 2 / 0 of 5,096 / 18,762 / 68,403 on noise_cavity, against churn_predecessor_shift of 1,041 / 3,943 / 15,370 and 4,401 / 18,166 / 68,023 — 77.2255%, 92.6239%, 97.8607%, 86.3619%, 96.8234% and 99.4445% of the churn |
C3 the geometric term equals M-318's own keyed column |
318 / 310 / 346 | HELD on 3 of 3 scored rows, VACUOUS on 3 — geometric_matches_m318 true on the three sphere rows with churn_geometric = 318 / 310 / 346 equal to m318_keyed_moved = 318 / 310 / 346, and m318_buffer_moved_reproduced / m318_vertices_reproduced both true, so churn_total = 1,348 / 4,257 / 15,706 and the vertex counts 1,758 / 6,918 / 27,822 reproduce M-318's published row at every resolution rather than only at the one it quotes. noise_cavity reads vacuous on both columns: M-318 never ran that field, so there is no comparand and a clause that could not have fired is not HELD (docs/experiments.md:237-242) |
c2_holdsreadingfalseon 6 of 6 is not this row failing — it is this row's registered falsifier firing, and what it falsifies isR-027, notP-123. The registration says so in as many words: C2 under 50% on every field "CLOSES R-027 for good rather than failing this row, because a reorder at emission then cannot recover the gap and the only remaining shape is the persistent edge-to-slot mapV-45already refused." Sofalsehere does not mean the churn was mismeasured (churn_totalreproducesM-318'sbuffer_movedexactly on all three comparable rows), does not mean the 45× prize is smaller than advertised (it is larger — see SHARE), and does not mean a canonical emission order is merely unhelpful: thecanonical_control_totalcolumn reads 1,413 / 4,403 / 16,011 / 5,339 / 19,279 / 69,521 againstchurn_total's 1,348 / 4,257 / 15,706 / 5,096 / 18,762 / 68,403, so grid-edge emission order makes the churn 1.63%–4.82% worse on 6 of 6 rows by moving slots out of order-only and into predecessor-shift.M-318's own prediction for that shape was "Does not help"; measured, it hurts.Six vacuity controls fired, and two of them are
M-44read in both directions on the same detector in the same run. (1)churn_total > 0before any share of it is reported — 1,348 to 68,403, asserted per row. (2)canonical_control_order_only= 0 exactly on 6 of 6 whilecanonical_control_geometric= 318 / 310 / 346 / 719 / 591 / 383 is bit-identical tochurn_geometricon 6 of 6, with the canonical arm's edge multiset asserted equal to thescanarm's, so the reorder is provably a permutation and the geometry provably untouched. (3) The same detector readspermuted_control_order_only= 1,388 / 2,810 / 23,814 / 5,230 / 25,962 / 106,474 — 0.660× to 1.557× of the churn — so the three zeros inchurn_order_onlyand the six incanonical_control_order_onlyare measurements rather than the instrument's inability to speak, and C2's 50% bar is demonstrably reachable by this instrument on this fixture. (4)replica_bit_identicaltrue on 6 of 6, so the transcribed march is the shipped one before any arm's difference is attributed to ordering. (5)cut_edges_before=vertices_beforeandcut_edges_after=vertices_afteron 6 of 6 (1,758 / 6,918 / 27,822 / 6,522 / 28,882 / 119,400 before), which is✗1/M-2/M-22'sV_mc = Cand is what makes the transcribed edge cache provably complete. (6) The one remaining zero,edges_moved= 0 atsphere/129³, is admissible because the same column reads 12 / 12 / 51 / 49 / 13 on the other five rows and becausechurn_geometricthere decomposes exactly as 245 appeared + 101 vanished + 0 moved = 346 — an independent reproduction ofM-318's inference that "at 129³ they are identical, so nothing merely moved there", whichM-318could only read off a coincidence between two totals.
The mechanism, so no reader needs the code. Vertices are appended in scan order and indices name positions in that buffer, so a cell that emits a different number of vertices shifts every index after it — "a sequential counter is the classic instability in Acar's sense, and nothing about the field's locality protects against it" (edit_trace.rs:25-29, this row's own subject bench). That is 77.2%–99.4% of a gap M-318 reported as 45×, and the column that says it most directly is shifted_survivors against survivors: 1,041 of 1,641, 3,943 of 6,817, 15,372 of 27,721, 4,408 of 6,132, 18,168 of 28,636, 68,023 of 119,263 — that is 55.45%–71.89% of the crossings that did not change at all sitting at a different slot, and churn_predecessor_shift + churn_order_only == shifted_survivors on 6 of 6. Locality of the edit is not the problem and never was: 515 edited samples and 792 dirty cells produce 68,403 moved slots at noise_cavity/129³, of which zero are recoverable by reordering.
The registration is wrong about the residual, and this entry records that rather than amending it. The hypothesis states the three terms are "a prefix partition of the same diff so they sum to the churn exactly", and C1 then calls "a non-zero [residual] a decomposition defect rather than noise". Both cannot be true of the same instrument, and measured, the residual is non-zero on 6 of 6 and is not a defect. The exact partition is at the slot level — churn_geometric_slots + churn_predecessor_shift + churn_order_only == churn_total, asserted per arm — while the registered geometric term is a count of crossings, and the gap between the two readings is exactly the definitional one M-318 had already named (FINDINGS.md:5977-5979): a crossing that moves claims a slot in each extraction and is one changed value, while a slot that loses a vanished crossing and gains an appeared one hosts two changed values and is one slot. The harness asserts that identity per row rather than tolerating it (experiment_p123.rs:1078-1083), so C1's 5% bar is a bound on an exactly-predicted integer and not on noise. The crossing-level reading is not a convenience: the registered vacuity control demands the geometric term be unchanged by a reorder, and it is the slot-level reading that fails that — canonical_control_geometric_slots = 312 / 320 / 341 / 700 / 590 / 374 moves against churn_geometric_slots = 307 / 314 / 334 / 688 / 594 / 380 on 6 of 6 rows, in both directions. churn_geometric_slots is recorded beside churn_geometric so that the choice is auditable from the file rather than trusted.
noise_cavity is a deviation from the registration's fixture, taken deliberately, and it is what makes C2 a disjunction at all. C2 is registered as "at least 50% … on at least one reference field", and one field cannot support a disjunction; M-318's own "would be shown wrong by" names the same field as its untested risk — "a field whose edits change crossings far from the dirty set … noise_cavity is the candidate and was not run". Run, it answers the risk in the opposite direction from the worry: churn_geometric on noise_cavity reads 719 / 591 / 383, declining in n exactly as sphere's 318 / 310 / 346 is flat, so long-range field structure does not inflate the keyed column. What it does inflate is the churn — 68,403 against sphere's 15,706 at 129³.
No clock and no hardware counter exists anywhere in this dataset. verdict_unit reads integer_value_counts on 6 of 6 and there is no ns_ column among the 56, so M-280's governed-CPU problem — a nanosecond is not a unit and a wall-clock ratio is never a gate — has nothing here to move, and ✗24 has no ratio to object to. That is also the strongest thing that can be said about the clean re-run: every column is an integer count of values or an exact ratio of two such counts, so the re-run could not have shifted a digit, and the three integers M-318 published for this fixture came back identical.
SHARE, recomputed. This row moves nothing, proposes no source change and has no extraction share, so ✗51's 1/(1 − share) form does not apply — no clause here is or may become a speedup claim. What stands in a share's place is the denominator each clause is a fraction of, and the measured file revises the registration's pre-run arithmetic upward. The irreducible floor — what a grid-edge naming leaves behind — is churn_geometric / churn_total: 346 of 15,706 = 2.20298% at sphere/129³, and 383 of 68,403 = 0.55992% at noise_cavity/129³. The whole prize is its complement, 97.79702% and 99.44008%, i.e. a per-row ceiling of 4.239× / 13.732× / 45.393× on sphere and 7.088× / 31.746× / 178.598× on noise_cavity — so M-318's 45× is the smallest of the two 129³ figures and the untested field's ceiling is nearly four times larger. The share a canonical reorder at emission could remove is churn_order_only / churn_total: 0.000000%, 0.000000%, 0.012734%, 0.137363%, 0.010660%, 0.000000% — at most 7 slots of 5,096, and exactly 0 on three of six rows. The prize is real, larger than reported, and none of it is reachable by the one shape that leaves extract_into a pure function of its inputs. The only remaining shape is the persistent edge → slot map, which is state carried across extractions and which V-45 refused because validate/determinism.rs:268-272's third run exists to fail on output that depends on the buffer's prior state. No clause in this row proposes it and no column here is evidence for it.
🔬 M-437 — C1, C2 and C3 all HELD on 24 of 24 rows: on the ambient complex the predicate discriminates on 8 of 8 fields at every resolution against a bar of 6, box_exact's density halves at 1.967635 / 1.982970, and the signal is almost entirely in edges the old reading structurally could not see — 100% of sphere's rejections and 99.96% of box_exact's are diagonal-only, with non_monotone_axis_edges reading 0 and 1 respectively (P-124, R-052)
M. cargo bench --bench experiment_p124, docs/experiments/p-124.csv, 24 rows, f64,
amd-ryzen-9-5900x-12-core (Zen 3). Four # comment lines plus one column header plus 24 data rows
across 68 columns — counted from the file, not from the brief. The fixture is eight reference fields
× {33³, 65³, 129³}, one row per pair, and every row carries two arms from one binary: the ambient
sweep over every distinct tet edge of the shipped Kuhn/Freudenthal six-tetrahedra split — cells = (n−1)³
= 32,768 / 262,144 / 2,097,152, tets = 6·cells = 196,608 / 1,572,864 / 12,582,912, tet_edges
= 238,688 / 1,872,064 / 14,827,904, identical on all eight fields at a given resolution because the
complex is a property of the grid — and the mesh-edge control, which is ✗36's own reading run through
the same examine on the same fields in the same run. Committed at 675d912 —
# commit 675d912 on amd-ryzen-9-5900x-12-core at 2026-08-29T02:24:09Z, no (WORKING TREE DIRTY); that
sha is the previous dataset commit (p-123.csv - re-run on a clean tree), which is the serial
one-run-one-commit discipline visible on the artefact. The dataset itself landed in 2392c20
(p-124.csv - re-run on a clean tree) and git merge-base --is-ancestor 2392c20 HEAD passes.
| clause | registered | measured |
|---|---|---|
| C1 the contrapositive of Theorem 1 part 2b as an integer over every cell, one failing tet edge rejecting a cell | neither 0 everywhere nor equal to cells |
HELD — non_monotone_cells spans 2,599 to 1,526,016 over 24 rows and is never 0 and never cells; the extremes are box_exact 33³ at 2,599 of 32,768 (non_monotone_cell_rate 0.079315186) and fbm_terrain 129³ at 1,526,016 of 2,097,152 (0.727661133), so both registered falsifiers miss by a wide margin; c1_holds true on 24 of 24 |
C2 box_exact is the resolution witness ✗36 handed over — a factor in [1.7, 2.3] per doubling |
1.7 ≤ r ≤ 2.3 on both doublings | HELD on the density, which is the only reading that can sit in a band — box_exact_population_ratio 1.967635 (total_cmp-selected as the worse of the two doublings), box_exact_rate_ratio_33_to_65 1.967635 and box_exact_rate_ratio_65_to_129 1.982970, from rates 79.315186 / 40.309906 / 20.328045 per 1k. The literal count reading is recorded beside it and fails: box_exact_count_falls false on 24 of 24, counts 2,599 → 10,567 → 42,631, box_exact_count_ratio_33_to_65 4.065795 and ..._65_to_129 4.034352 |
C3 the count is strictly between 0 and cells on at least six of the eight reference fields |
≥ 6 of 8 | HELD at the ceiling — discriminating_fields_here 8 at 33³, 8 at 65³ and 8 at 129³ against discriminating_fields_bar 6, and c1_row_discriminates true on 24 of 24; the eight per-field 65³ counts are sphere 17,862, torus 32,858, box_exact 10,567, csg_difference 16,140, thin_plate 13,693, gyroid 85,051, fbm_terrain 236,992, noise_cavity 65,859, all against cells = 262,144 |
The three
falsereadings in this file are not bad news, and one of them is the row's sharpest finding.box_exact_count_fallsis false on 24 of 24 and that is the registration being wrong rather than the witness failing: C2 as written says the population "is O(n) and halves per refinement, so the count … must fall by a factor in [1.7, 2.3] per doubling", and anO(n)population's count grows — it is the density that halves.✗36's own table is a density (178.1 / 86.1 / 42.3 / 21.0 per 1k, ratios 2.07 / 2.04 / 2.01), so the literal reading was arithmetically dead before this harness existed and the band was always a band on the rate. The registration is not amended —experiment.rs:27-31forbids it — so both readings are in the file and the count ratios settle it at ≈4× per doubling, which is the signature of a 2D locus in a 3D complex: on the ambient complex‖∇f‖= 1 andgis constant inside each face's slab, so what is left is the interior medial axis, not✗36's 1D box-edge chord population. Different dimensions, same codimension, which is exactly why the band transfers when theO(n)does not.
guard_inertreadsfalseon 15 of 24 rows and that is the tolerance repair being visible.✗36scaled by|f(a)| + |f(b)|— the residual at two vertices that are on the zero set — and measuredmax_abs_toleranceexactly 0.0 onbox_exactat all four resolutions. Here the registered scale ismax(|f(a)|, |f(b)|)over grid samples, andmax_abs_toleranceis non-zero on every one of the 24 rows,box_exact's three included (1.732051e-12), spanning 1.732051e-12 to 9.621357e-12;nonzero_g_discarded_at_1e12reaches 9,980 onsphere129³ where the control's is 0–20, so the guard now performs substantive work. What is not claimed: it is still not verdict-bearing.counts_equal_across_tolerancesis true on 24 of 24 andnon_monotone_edges_at_1e14=non_monotone_edges=non_monotone_edges_at_1e10on every row, becauseworst_reversalis exactlywonsphere,box_exactandthin_plate,√2·wontorusand√3·woncsg_differenceandgyroid— an edge-length quantity 10 to 11 orders above the guard, where✗36's deciding reversal was the chord sagitta falling ash². The reversal here falls ash¹, halving exactly per doubling, and that change of power law is independent evidence that the complex, not the fixture, moved. The coefficient isP-55's own 1e-12 with 1e-14 and 1e-10 recorded beside it as a sensitivity strip, fixed at registration rather than after the first surprise.
mesh_edge_control_saturatedreadsfalseon 9 of 24 rows and the assertion is deliberately scoped tosphereonly.✗36's chord theorem is about a strictly convex surface;box_exact's faces are planar, so the chord's component along an axis-aligned unit gradient is an exactf64zero (zero_g_samples162,784 / 1,207,736 / 9,286,156 on the ambient arm) and nothing is flagged —mesh_edge_control_per_1k86.05 / 42.33 / 21.00. A control asserted saturated everywhere could not have passed, and asserting it would have been theP-63-C3 error in the other direction.Which vacuity controls fired, all four of them, as
assert!s rather than as columns (M-44). (i)mesh_edge_control_non_monotone > 0on every row — 348 to 279,285 — so the sameexamine, in the same run, is demonstrably able to flag a non-monotone edge before any ambient count is believed. (ii)2 · control_non_monotone > control_edgesonsphereat every resolution — 3,156 of 3,468, 13,092 of 14,268, 51,732 of 57,684, i.e. 910.03 / 917.58 / 896.82 per 1k. That is the control showing the mesh reading is saturated rather than discriminating, which a control that merely fired would not show, and it is the whole reason the ambient count is attributable to the complex: 8 of 8 fields discriminate on the ambient complex while the chord reading returns a strict majority on five of them (sphere,torus,gyroid,fbm_terrain,noise_cavity). (iii) The diagonals were swept:tet_edges_face_diagonal+tet_edges_body_diagonal> 0 on every row (101,376 + 32,768 at 33³, 6,340,608 + 2,097,152 at 129³), andtet_edge_count_matches_closed_formis true on 24 of 24 against3n²(n−1) + 3n(n−1)² + (n−1)³=tet_edges_closed_form, so a zero indiagonal_only_failureswould have meant swept and monotone rather than never visited. (iv)pl_local_extremais recorded besidecritical_points_lower_bound, and the pair separates the two ways a zero arises:thin_plateandfbm_terrainread 0 extrema on the grid at all, whilegyroidreads 173 / 373 / 928 andnoise_cavity429 / 864 / 1,706 with a certified count of 0 — every extremum sitting in a rejected star.spherecertifies 1 andtorus4 at all three resolutions, which is Theorem 1 Part 1 over monotone stars; the column gates nothing, because the 3D transport of Part 1 is exactly as unproved as Part 2b's 2D pigeonhole.The control is not merely a control: it reproduces
✗36's committed mesh-edge arm bit for bit on 24 of 24 overlapping rows.mesh_edge_control_edges,mesh_edge_control_non_monotoneandmesh_edge_control_per_1kequaldocs/experiments/p-55.csv'sedges,non_monotone_edgesandnon_monotone_per_1kon every (field, resolution) the two files share —sphere65³ 14,268/13,092/ 917.577796,torus65³ 12,624/11,282/893.694550,box_exact65³ 17,292/732/42.331714 — andmesh_edge_control_max_abs_tolerancereproducesp-55.csv's0.000000e0on all threebox_exactrows.p-55.csvis pinned incsv_provenance.sh'sDIRTY_DEBTand its header reads# commit db0ca10 (WORKING TREE DIRTY), so✗36's published integers now have a clean-tree witness under a secondP-id. The pin does not move and is not claimed to:check_pinfails when a pinned file stops violating, andp-55.csvis still the dirty artefact.What the ambient reading bought, which is the whole hypothesis, in one column.
diagonal_only_failures— cells rejected by a face or body diagonal with every axis edge monotone — is the part of the complex a chord predicate structurally cannot reach, and it partitions the rejections exactly:axis_only_reachable_cells+diagonal_only_failures=non_monotone_cellson 24 of 24. At 65³ it is 100.000% onsphere(17,862 of 17,862, withnon_monotone_axis_edges= 0 — the ambient axis-edge reading reachesP-55's registered zero, on the field✗36proved it unreachable for), 99.962% onbox_exact(10,563 of 10,567,non_monotone_axis_edges= 1), 92.522% onthin_plate, 75.848% ontorus, 69.672% oncsg_difference, 41.957% ongyroid, 23.388% onnoise_cavityand 18.958% onfbm_terrain— 173,277 of 479,022 cells over the resolution, rising to 42.25% of 2,696,419 at 129³. Had that column read 0 the ambient reading would have been the axis-edge reading with extra work, and it does not.
k_samples_min2,k_samples_max3 on 24 of 24, so an axis edge is decided by its two endpoint gradients and a diagonal by those plus one interior sample —gradient_evalsequalssample_evals+tet_edges_face_diagonal+tet_edges_body_diagonalexactly on all 24 rows (35,937 + 101,376 + 32,768 = 170,081; 2,146,689 + 6,340,608 + 2,097,152 = 10,584,449), which is why the count is field-independent. All eight fields reach an analyticSdf::gradient, the correction✗36had to make toP-55's own registration, so every∇fhere is exact rather thanO(h²).degenerate_edgesis 0 on all 24 ambient rows, andnonfinite_g_samplesreads 14 at every resolution onsphere— the Freudenthal vertex figure exactly, one per tet edge incident to the single grid sample sitting on the sphere's centre, where∇(‖p‖ − r)is0/0; atotal_cmpon the edge length routes it todegeneraterather than to an unordered comparison.
SHARE, recomputed. Zero, and registered as zero rather than discovered to be zero. No clause here
is a cost, a wall-clock ratio or a fraction of an extraction: C1 and C3 are integer comparisons and C2 is
a ratio of two integer populations over denominators that are exact by construction — one
cross-multiplied division of integers-as-f64, identical on any machine at any clock. So M-280 and
✗24 do not bite, no perf_event_open counter is opened, and this governed CPU's 1.96–5.62 GHz span
under powersave/balance_performance cannot move a verdict. predicate_ns (11,140,723 to
2,222,229,874), predicate_ns_per_edge (46.41–150.30) and control_extract_ns are in the file and are
read by nothing; ✗51's share bar has nothing to apply to, because nothing in crates/isomesh/src/
evaluates monotonicity of anything and there is therefore no total for a fraction of it to be taken from.
What stands in a share's place is one integer per clause over an exactly enumerated denominator: C1's is
cells = (n−1)³, C2's is the same, and C3's is the 8 fields of for_each_reference_field!. The
complex is the shipped one, reached through the public
isomesh::marching_tetrahedra::table::{TETS, TET_EDGES}, so it is bit-for-bit what MarchingTetrahedra
marches and P-100's seam result transfers unchanged — ✗78 / M-412 measured open_edges 0 on 80 of
80 rows across a chunk seam against a mismatched-diagonal control reading 80–3,765, so "the tet edge
{v, v+δ}" is well defined without asking which cell named it, and the 36 edge instances (6 tets × 6
edges) are derived, not transcribed, down to 19 distinct cell-local edges — 12 axis, 6 face
diagonal, 1 body diagonal — asserted as [12, 6, 1] before the first field is sampled. The one number
that was decided in advance and is load-bearing is C2's witness. Of the eight fields' own density ratios
(rate_ratio_from_previous), only five sit inside [1.7, 2.3] — sphere 1.937521/1.968753, torus
1.809970/1.896785, box_exact 1.967635/1.982970, csg_difference 1.871623/1.924177, thin_plate
1.914555/1.955130 — while gyroid (1.441770/1.625530), noise_cavity (1.388178/1.405378) and
fbm_terrain (1.070483/1.242409) would each have falsified it. box_exact was fixed as the
witness by ✗36's own falsifier before this harness existed, so C2 is a clause about a pre-named field
and not a clause about the best of eight.
💥 ✗98 / M-438 — C1 HELD to the integer (516 of 17,201 pinches on bonsai, 0 of 50 on fuel), C2 HELD with distinct_censuses 1 over 128 face permutations on 6 of 6 rows, C3 FALSIFIED on 2 of 6: the census predicts 520 pieces joined and the repair welds 129 components, because a pinch count is an upper bound on a weld and can never be an equality — the report is sound as a clearance and unsound as a count (P-125, R-053)
M. cargo bench --bench experiment_p125, docs/experiments/p-125.csv, 6 rows across 34
columns — four # comment lines plus one column header plus 6 data rows, counted from the file
rather than from the brief; 17 of the 34 columns are P-125's registered records and the other 17 are
M-273 extras. The fixture, also counted from the file: four CT rows with is_control = false —
fuel_iso32 and fuel_half_offset, both 64³ uint8 at 3,200 vertices / 6,338 triangles, at
isovalue 32 and 32.5; bonsai_iso32 and bonsai_half_offset, both 256³ uint8 at 533,221
vertices / 1,061,042 triangles, at the same two isovalues — plus two hand-built rows with
is_control = true, constructed_pinch at 38 vertices / 14 triangles and constructed_long_range at 10
vertices / 8 triangles, both isovalue = none. f64 throughout, amd-ryzen-9-5900x-12-core (Zen 3).
Run on a clean tree — # commit 2392c20 on amd-ryzen-9-5900x-12-core at 2026-08-29T02:26:01Z, with no
(WORKING TREE DIRTY) on that line — and committed as p-125.csv - re-run on a clean tree at
1f95b95, for which git merge-base --is-ancestor 1f95b95 HEAD passes. The run-level verdict is
taken over the four CT rows, the two constructed rows being controls: C1 held on 4 of 4, C2 on 4 of 4,
C3 on 3 of 4.
| clause | registered | measured |
|---|---|---|
C1 the predicate separates the two volumes as M-352 measured them — 516 of 17,201 on bonsai and 0 of 50 on fuel, both exactly, from the baseline mesh alone |
both integers exactly, no tolerance | HELD — collapse_groups 17,201 and pinch_groups 516 on bonsai_iso32 against expected_collapse_groups 17,201 / expected_pinch_groups 516; collapse_groups 50 and pinch_groups 0 on fuel_iso32 against 50 / 0. c1_holds true on 6 of 6 rows. Corroborated downstream in the same rows: folding_faces 164 on fuel and 58,097 on bonsai reproduce M-352's triangles_dropped exactly, triangles_after 6,338 − 164 = 6,174 and 1,061,042 − 58,097 = 1,002,945, and vertices_removed = collapsing_vertices − collapse_groups on every row (132 − 50 = 82; 47,001 − 17,201 = 29,800) |
| C2 the answer is independent of triangle iteration order — 128 permutations of the face list give one identical census — and the report allocates once rather than per group | distinct_censuses = 1; no per-group allocation |
HELD — distinct_censuses 1 against order_permutations 128 on 6 of 6 rows, i.e. 768 permuted censuses collapsing to six, including on bonsai's 17,201 groups; buffers_reserved_exactly true on 6 of 6, so len == capacity on all three returned buffers, which only a Vec that never grew can satisfy. c2_holds true on 6 of 6 |
| C3 the census predicts the repair: applying the repair and counting the components it welds reproduces the report's pinch count exactly, on every fixture | equality, every fixture | FALSIFIED — c3_holds false on 2 of 6 (3 of 4 CT rows hold). bonsai_iso32: pinch_excess_components 520 against components_welded 129, with components_before 814 → components_after 655. constructed_long_range: pinch_excess_components 1 against components_welded 0, components_before 1 → components_after 1. The literal reading of the clause is worse still — components_welded_equals_pinch_groups is false on 3 of 6 rows (129 ≠ 516 on bonsai, 5 ≠ 4 on constructed_pinch, 0 ≠ 1 on constructed_long_range) |
c3_holdsreadingfalsedoes not mean the predicate is wrong, does not mean the shipped report is wrong, and does not mean a caller was told anything untrue. C3 asked a local census to predict a global count, and no local census can. A pinch is a group whose members fall into two or more sharing clusters — pieces of the surface meeting only at that point — andpieces_joinedsumsclusters − 1over the group's own members. Two facts make that a bound rather than an equality, and both are visible in this file. (i) Several pinches can weld the same pair of components: onbonsaithe 516 pinch groups are scattered over a plant scan with only 814 baseline components to join, so the second and every later pinch between one pair of pieces is a union that finds the two already merged and counts nothing —welded_componentstallies successful unions, which is why 520 local joins reduce to 129 global welds. (ii) A pinch entirely inside one component welds nothing:constructed_long_rangeis that case built on purpose — two vertices at one position that share no triangle, so the predicate correctly calls the group a pinch, joined by a six-triangle strip that already connects them, socomponents_weldedreads 0 overcomponents_before1. The module states the direction in advance: the welder joins a vertex to the lowest-indexed representative within ε and therefore stops a chain, so the welder's classes refine the closure (pinch.rs:78-83), andpinch.rs:115-124reserves the gap explicitly —pieces_joinedcounts pieces the group's own members lie on, not components of the whole mesh, and "that gap isP-125's C3 and is measured by the harness, not asserted here". So what the clause licenses is exactly this: the report is sound as a clearance and unsound as a count.is_pinch_free()is the safe direction — zero pinches means zero welds, confirmed on three independent rows in this run (fuel_iso32,fuel_half_offsetandbonsai_half_offsetall readpinch_groups0,components_welded0 andcomponents_before=components_after) — and a non-zero pinch count is an upper bound on what a weld could reach, never the number of components it will reach.Four vacuity controls fired, and they are assertions rather than columns — a run that could not fire aborts instead of recording a pass. (1) The same instrument returned non-zero in the same run:
bonsai_iso32'spinch_groups516 is asserted> 0, sofuel's 0 of 50 is a zero that could have been non-zero (M-44). (2) The constructed fixture reported its construction:constructed_pinch_reported4 =constructed_pinch_expected4 on all six rows, withpinch_excess_componentsasserted 5 on that row — the fixture is built so 4 and 5 differ, so a harness that conflated group count with pieces joined could not have passed. (3) The union-find was shown able to answer yes, they share:share_control_all_truetrue on 6 of 6, overshare_control_pairs212 / 0 / 80,501 / 0 / 2 / 0 — 80,715 pairs asked run-wide, every one answering with a single cluster label.share_control_pairsequalssharing_edgeson all six rows, so the bench's independent enumeration of member-pairs-inside-a-face and the module's ownsharing_edgesagree exactly. (4) C3 was proved able to read both ways in this run:constructed_pinchis built so C3 holds and itsc3_holdsis asserted true (components_welded5 =pinch_excess_components5,components_before12 →components_after7),constructed_long_rangeis built so C3 fails and itsc3_holdsis asserted false. A control reading the wrong way there isP-63-C3's failure mode — a zero over a population that cannot host the phenomenon — and aborts the run. One fixture-integrity cross-check rides beside them on every row:repair_matches_reporttrue on 6 of 6, so the faces the bench actually dropped equal the shipped report'sfolding_facesand C3 is not comparing a repair the census never described.
M-352's own 520 is a third number, and it reconciles rather than conflicting. Three distinct
figures describe bonsai and only the first two are M-352's: 516 pinch groups, 520 pieces
joined, 129 components welded. M-352 quoted its own pinch_excess_components column correctly —
"counts 520 previously separate pieces joined" — and that column is the sum of clusters − 1 over the
pinch groups, so 520 − 516 = 4 bonsai groups span three or more sharing clusters. What M-352 did
not measure, and its prose called "520 components" without qualification, is the global figure;
P-125 measures it as 129, and the accounting closes on the row:
components_drift_from_dropped_faces is −30, and 129 welds plus 30 components lost to dropped faces
is exactly the 814 → 655 fall of 159. A fold whose only face is dropped removes a component and a
dropped bridge splits one, and neither is a weld — which is why the drift column exists rather than
the difference being attributed to the predicate. So M-352's number stands as a local count and is
not a component count; the registration inherited the loose word and C3 inherited the error.
C3's registered form was arithmetically undecidable before this harness ran, and the harness recorded
that rather than resolving it silently. The clause says the weld count "reproduces the report's pinch
count exactly", and the report has two pinch figures that M-352 had already measured as different —
516 and 520. A group spanning three clusters welds two components, so an identity against the group
count is impossible on any fixture where a group spans three, and M-352's own 520 ≠ 516 says four
bonsai groups do. c3_holds is therefore scored on the only reading that could hold,
components_welded == pinch_excess_components, and the other reading is carried beside it as
components_welded_equals_pinch_groups so the entry can quote either. Both fail on bonsai. The
registration is not amended — crates/isomesh/src/experiment.rs:27-31 forbids it — and this is
recorded as the finding it is.
The two half_offset rows read collapse_groups 0 and they are VACUOUS for C1, not HELD. At
isovalue 32.5 a uint8 sample cannot equal the isosurface, so no crossing lands on a sample, no two
cut edges place a vertex at the same point, and the mechanism's precondition is removed rather than
tested: their expected_collapse_groups and expected_pinch_groups are both 0, so c1_holds on
those rows is 0 == 0 && 0 == 0 and could not have read false. The clause that could not fire is
VACUOUS. C1's registered content is carried entirely by the two iso32 rows, and it is carried there
without vacuity because bonsai_iso32's 516 and fuel_iso32's 0 are the same instrument in the same
run. What the half_offset rows are is a negative control on the precondition — the census does not
invent groups where there is nothing to collapse, collapsing_vertices 0, folding_faces 0,
sharing_edges 0, triangles_after = triangles, components_before = components_after — and they
are an independent reproduction of M-352's own C3 control at the same two isovalues. They are recorded
as instrument evidence, not as two more C1 passes.
A false clearance was measured and rejected while the module was being written, and it is the reason a
group is an ε-connected component. ε-closeness is not transitive, so "every pair within ε" is not a
partition at all; its transitive closure is, and so is the other candidate — equality on the lattice
cell key, which is MeshReport::weld_buckets' own notion and a genuine equivalence relation. On
sphere at 25³, where M-48 recorded Welder::weld removing 48 vertices and 96 triangles at this
very epsilon, the bucket reading finds 17 groups over 47 vertices — 30 of the 48 merges and 60 of the
96 folding faces — because a coincidence class straddling a cell face is split between two buckets.
The closure finds 24 groups over 72 vertices: 48 and 96, exactly the weld, with sharing_edges
144 licensing its is_pinch_free(). A census that under-reports a collapse is a false clearance,
and issuing clearances is this report's entire job, so the bucket reading is disqualified in the
direction that matters and the closure errs in the direction that is safe — the same refinement fact
that makes C3's number an upper bound is what makes the clearance trustworthy. Both readings were
measured, not argued: validate::pinch::tests::the_census_predicts_the_weld_on_a_real_extraction.
This is Phase 26's only landed source change, and it was registered in advance — the P-61/P-69
way, because a landing that was not registered in advance is exactly what V-45 cost. The registration
names it before the module existed: "a new report beside validate::sealing in
crates/isomesh/src/validate/, reporting the pinch census for a mesh and its snap epsilon." What landed
is crates/isomesh/src/validate/pinch.rs (674 lines) with pinch/tests.rs (336 lines), declared mod
pinch; at crates/isomesh/src/validate.rs:43 and re-exported one line later at :53 as
pub use pinch::{PinchGroups, PinchReport, pinch_census, pinch_features};. The new public surface is
exactly those four items plus their methods: pinch_census — the whole census as eleven counts;
pinch_features — the same plus which vertices, for a caller that has to draw the answer;
PinchReport with vertices, triangles, trailing_indices, faces_skipped, collapse_groups,
collapsing_vertices, pinch_groups, pieces_joined, folding_faces, sharing_edges,
groups_moving_geometry, the two opt-in predicates is_pinch_free and moves_no_geometry, and a
Display impl; and PinchGroups, compressed-row storage over vertices/starts/clusters with
group_count, members, clusters_of, clusters_in and clusters_are_split. Every entry point takes
slices rather than a MeshBuffer, for the reason validate_indexed does — the callers that matter do not
have one — and nothing is required of the mesh: it need not be welded, closed, manifold or well-formed,
and a malformed face is skipped and counted rather than dereferenced (faces_skipped, 0 on all six rows
here). is_pinch_free() is the shipped answer to the question M-352 closed with and could not answer:
"The precondition is cheap to test — one union-find over the baseline triangles — and that is the
shippable result here, not the label." The landing commit is 21ac389, "R-053 - the pinch predicate, as
a validate report registered before it was written", and it touches exactly four files: the module, its
tests, the two added lines in validate.rs, and the bench. No extractor, no golden_hashes.json, no
golden hash: the report is additive and no consumer-visible behaviour moved.
C2 asked ✗26's question in advance rather than after a landing, and that is the clause worth
copying. distinct_censuses 1 over order_permutations 128 on all six rows: the face list is
shuffled 128 ways from a fixed SplitMix64 seed and every census — report and compressed-row groups
and cluster labels — comes back identical. It is designed for rather than hoped for: super::Dsu
unions by size and its determinism rests on callers unioning in sorted order, but the second phase here
unions in face order, so the module's union-find keeps the lower index as the root. Every set's
root is then its least member, PinchGroups::clusters carries a canonical vertex index whichever order
the faces arrived in, and the cluster count is free — a cluster has exactly one root, that root is a
member, so counting members that are their own label needs no per-group allocation, which is the other
half of C2's falsifier. Two things the registration overstated are recorded rather than amended: O(V +
F) is O(V log V + V·k + F) — the log V is validate's sort-then-scan convention and the k is the
27-cell probe weld itself uses — and "allocates once" is seven buffers, allocated once each and
none per group.
Nothing here is timed, no geometry moved, and there is no share — so M-280/✗24 and ✗51 both have
nothing to bite on. Every clause is an integer equality over an enumerated population; the file
contains no nanosecond, no cycle and no ratio column, so the governed CPU spanning 1.96–5.62 GHz cannot
reach any verdict in it and this is the one row in the phase whose clean re-run could not have moved
anything by re-running. max_snap_distance is exactly 0e0 on 6 of 6 rows and
groups_moving_geometry is 0 on 6 of 6, independently reproducing M-352's exact zero: the
vertices are already at the corner, only indices merge, so the pinch question is a decision rather than
an approximation and the report claims nothing about position. faces_skipped is 0 on all six rows, so
no row's population was quietly reduced by an unusable face.
SHARE, recomputed. None, and it is registered as none — recomputed by grep rather than quoted.
The only occurrences of pinch_census, pinch_features, PinchReport or PinchGroups anywhere in
crates/ are crates/isomesh/src/validate/pinch.rs, its pinch/tests.rs, the two-item re-export at
crates/isomesh/src/validate.rs:53, and crates/isomesh/benches/experiment_p125.rs. Nothing in
extractor.rs, marching_cubes/, dual_contouring/ or chunk/ calls it, and it did not exist before
this ticket, so there is no extraction fraction for a 1/(1 − share) ceiling to be computed against,
✗51's bar does not apply, and no clause here is or may become a speedup claim. The prior question
✗51 is really about — of the thing the change can reach, how much is the thing that matters? — has an
answer here too, and it is the clearance/count split: of the two questions a caller can ask this report,
it answers one soundly. "Is this repair safe on my data?" is answered exactly, by an integer, from
the baseline mesh alone, before any repair is applied. "How many components will it weld?" is answered
only as an upper bound, and pinch.rs:113-124 says so in the shipped documentation.
🔬 M-439 — C1, C2 and C3 all HELD and O-12's dual half is closed by exhaustion: worst_link_components 1 on every non-control arm over all 134,217,728 sign patterns of a 3 × 3 × 3-cell block, against three controls reading 2 at 113,246,208 / 221,792,256 / 99,876,864 link-defective vertices — C1 was decided by two exhaustively-checked lemmas before the sweep and the sweep's job is that no reachable pattern escapes them, control/open_block reproduces P-63's truncation as a measurement at the right block size (860,880,896 complete links of 5,067,767,808), and two registration errors are reported rather than amended (P-126, R-072)
M. cargo bench --bench experiment_p126, docs/experiments/p-126.csv, 6 rows across 43 columns — four # comment lines plus one column header plus six data rows, eleven lines in the file, counted from it rather than from the brief. The shape, also counted from the file: six arms in one binary, is_control false on three and true on three; block_cells 27, block_corners 64, distinct_corner_sites 27 and patterns_swept 134,217,728 on every one of the six; corner_identification period_3_per_axis on all six; boundary periodic on five and open on one; vertex_rule one_per_marching_cubes_cycle on five and one_per_cell on one; ambiguous_face_pairing taking five distinct values over the six rows (separate on three, every_ambiguous_face_joined, consistent_per_grid_face, high_x_face_of_each_cell). Six arms × 27 cells × 2²⁷ patterns is 21,743,271,936 cell evaluations and Σ dual_vertices = 28,214,247,016 link walks. amd-ryzen-9-5900x-12-core (Zen 3). Committed at f28d557 — the file's own provenance line reads # commit 1f95b95 on amd-ryzen-9-5900x-12-core at 2026-08-29T02:43:08Z, with no (WORKING TREE DIRTY), and git merge-base --is-ancestor f28d557 HEAD passes. The two shas are not a discrepancy and the distinction is the point: 1f95b95 is the tree the harness measured, stamped by the harness itself before the dataset existed, and f28d557 is the commit that carries the dataset — p-126.csv - re-run on a clean tree, one file, eleven insertions, nothing else.
| clause | registered | measured |
|---|---|---|
C1 over the full 2²⁷ sweep, worst_link_components is 1 on every non-control arm — the dual vertex link is a single connected cycle, so the dual output is a manifold at the vertex |
= 1 | HELD — worst_link_components 1 with worst_link_pattern none on all three non-control arms (mdc/separate, mdc/every_ambiguous_face_joined, mdc/mixed_consistent), each over patterns_swept 134,217,728 and 27 cells, with link_defective_vertices 0 and incomplete_link_vertices 0; the denominators are dual_vertices 5,067,767,808, 5,067,767,808 and 4,630,724,200, and max_incident_faces reaches 7, 7 and 12, so the length-12 cycles the case table's MAX_TRIANGLES is about are inside the swept population rather than outside it |
C2 the control arm, which deliberately partitions a cell's edge cycles, reads worst_link_components greater than 1, so the instrument is shown emitting bad news before its ones are read |
> 1 | HELD on a corrected control, three times over — worst_link_components 2 on all three is_control = true arms with link_defective_vertices 113,246,208 (control/one_vertex_per_cell, at worst_link_pattern 0x0000210, worst_link_case 0x18, worst_link_cell 0), 221,792,256 (control/inconsistent_join_x, 0x0000208 / 0x28 / cell 2) and 99,876,864 (control/open_block, 0x0000426 / 0x1b / cell 1). The registration names the mechanism as "the way manifold_dual_contouring's FaceAmbiguity::Connected does" and that variant does not exist, so the clause as literally written could not have fired; the harness reports that instead of inventing it, files the always-joined arm as a non-control, and re-seats C2 on a shipped extractor's rule |
C3 the population is derived from the block this sweep sweeps and not from a census taken elsewhere: dual_vertices_with_complete_link per arm, non-zero, against a value computed from the 64 corners the sweep enumerates |
> 0 per arm, never pooled, equal to the closed form | HELD — dual_vertices_with_complete_link 5,067,767,808 / 5,067,767,808 / 4,630,724,200 / 3,595,567,104 / 4,784,652,288 on the five stitched arms and 860,880,896 on control/open_block, every one asserted non-zero per arm; active_cells = expected_active_cells = 3,595,567,104 = 27 × 2¹⁹ × 254 on all six rows, and dual_vertices = expected_dual_vertices on the five arms whose joined mask is a function of the cell's own sign byte — 27 × 2¹⁹ × cycles_per_256_sign_bytes at 358, 358, 254 and 338, with expected_dual_vertices honestly unavailable on mdc/mixed_consistent, whose mask is drawn per grid face from the pattern and therefore has no per-sign-byte closed form |
The three verdict columns are per-arm complements, and a reader who does not know that will misread every row.
c1_holdsis!is_control && worst_link_components == 1;c2_holdsisis_control && worst_link_components > 1 && link_defective_vertices > 0;c3_holdsis the population identity and is true on all six. Soc1_holdsreadstrueon the three non-control arms andfalseon the three controls, andc2_holdsreads exactly the reverse. Neitherfalseis a failure of anything. C1 is not defined on a control — a control that satisfied C1 would abort the run, which is the registration's own instruction — and C2 is not defined on a non-control. There is no row in this file on which both clauses are scored, and no clause is FALSIFIED:worst_link_componentsreads 1 exactly where C1 asks for 1 and 2 exactly where C2 asks for more than 1.Three further
falsereadings, none of them bad news.pairing_is_consistentisfalseoncontrol/inconsistent_join_xalone; that is the arm's entire design — it joins each cell's high-xface and separates its low one, so the two cells sharing anx-face always disagree, breaking the one property C1's proof rests on and nothing else.target_feature_popcntisfalseon all six rows: a build fact carried fromP-105(notarget-cpu, noRUSTFLAGS), and the reason a 4 KB 12-bit population table stands in foru64::count_onesrather than a lowered SWAR sequence. Andworst_link_patternreadsnoneon the non-control arms because there is no breach to name, whileworst_link_case0x01andworst_link_cell0beside it are not a breach either: those two are set whenever the component count exceeds the running worst, which starts at zero, so on a non-control arm they record the first vertex that reached one component — one corner inside, cell 0 — and not a defect.All four registered vacuity controls fired, and so did four structural ones the registration did not name. (1)
patterns_sweptis asserted equal to 134,217,728 on every arm, so a sweep that silently narrowed its own domain is a failure rather than a fast pass. (2)dual_vertices_with_complete_link > 0is asserted per arm and never pooled — and the counter is shown able to read less rather than only "complete":control/open_blockruns the identical shipped rule on the unstitched block and readsincomplete_link_vertices4,206,886,912 againstdual_vertices_with_complete_link860,880,896, withisolated_vertices689,963,008 inside that — a cycle whose every owned edge lacks its quad. On the five stitched armsincomplete_link_verticesis asserted 0. (3) Each control'sworst_link_components > 1andlink_defective_vertices > 0are assertions, so a control reading 1 aborts rather than banking a pass. (4) The closed forms are exact integer identities over the block, asserted before any verdict is read:active_cells= 27 × 2¹⁹ × 254 anddual_vertices= 27 × 2¹⁹ ×cycles_per_256_sign_bytes, so a fixture that drifted by one cell cannot pass. Beside those:face_disconnected_sign_bytes8 is asserted greater than zero — 8 of 256 sign bytes have a face-disconnected cut set, and without them the one-vertex-per-cell control could not fire and C1's ones would prove nothing;replica_quad_link_agreements242,776 is asserted greater than zero, or one of the two link walks is not measuring a link; and the block's own completeness is asserted structurally, 27 of 27 cells carrying all twelve quads and all six faces when stitched, exactly 1 of 27 when open.
M-44applied to each zero in the file, by naming the control that makes it admissible.link_defective_vertices0 on the three non-control arms is admissible because the same walk in the same run reads 113,246,208, 221,792,256 and 99,876,864 on the three controls.incomplete_link_vertices0 andisolated_vertices0 on the five stitched arms are admissible becausecontrol/open_blockreads 4,206,886,912 and 689,963,008 with the identical rule.pairing_disagreements0 is admissible becausecontrol/inconsistent_join_xis the arm built to break exactly that property and readspairing_is_consistentfalse.cycle_adjacency_violations0 andtwo_cut_edge_face_splits0 are over enumerated domains — 256 cases × 64 masks, and every face of every case — and their sibling counterface_disconnected_sign_bytesreads 8 on the same tables, so the face machinery is shown able to report a non-zero. One zero is arithmetically forced and is recorded as such rather than counted as evidence:replica_diagonal_merges0 cannot read anything else oncereplica_quad_link_agreements242,776 equalsreplica_vertices242,776, because a diagonal can only merge components and there was never a second component to merge.
C1 is proved, not only swept, and that is the strongest form this result can take. Two lemmas are verified over their whole domains at start-up, before a pattern is drawn, and asserted zero. First, a cycle's consecutive edges always share a face of the cell — next[e] is the segment leaving e on one of e's two faces — checked over all 256 cases × all 64 joined masks: cycle_adjacency_violations 0, with two_cut_edge_face_splits 0 beside it for the case where a face carries exactly two cut edges. Second, with the joined bit agreed, the two cells sharing a face induce the identical pairing on that face's cut edges — checked over 3 axes × 2 sides × 256 near cases × 16 far patterns × both bits = 49,152 combinations: pairing_disagreements 0. Together they close it: every consecutive pair of a cycle is linked in the neighbour too, so the cycle's link is connected and worst_link_components is 1. So C1 was decided by arithmetic available before the harness existed, and what the 2²⁷ sweep buys is precisely two things and not a third — that the bench-local integer model of the dual topology is the shipped one, and that no reachable pattern escapes the argument. A proof plus an exhaustive check of its transcription is a stronger statement than either, and it is the same shape M-374 used on the primal half.
P-63's named error is not repeated, and this file proves that rather than promising it. M-374's C3 derived its expected population from the critical census — 524,288 2D- or 3D-ambiguous cells — when the population it needed was dual vertices carrying a complete link, which in a 3 × 3 × 2 block of 18 corners is empty: a dual vertex lives at a cell centre and its link needs the cell's 26 neighbours, so max_incident_faces came back 2 on all three dual arms and the verdict was correctly "FALSIFIED, and vacuously". Here every population is a closed form asserted at start-up: active_cells 3,595,567,104 on every arm, and dual_vertices from cycles_per_256_sign_bytes over the 256 sign bytes. And the truncation is not merely avoided — control/open_block reproduces it as a measurement at the right block size. Same shipped rule, same 134,217,728 patterns, unstitched: dual_vertices 5,067,767,808 of which only 860,880,896 carry a complete link, incomplete_link_vertices 4,206,886,912, isolated_vertices 689,963,008. That is 16.99% complete against 83.01% truncated, and it is 4.5866× the centre cell's whole share of the vertices (5,067,767,808 / 27 = 187,695,104) — so completeness on an open block is not "the centre cell only", it is any cycle that happens to avoid the boundary, which is a sharper statement about what P-63's block was doing than P-63 could make from inside it. The same arm reads worst_link_components 2 and link_defective_vertices 99,876,864: on a truncated block the shipped rule is non-manifold at a vertex, and stitching is what buys C1.
Two registration errors, both reported and neither amended, because experiment.rs:27-31 forbids amending a registration after its run. (a) Sixty-four free corners is 2⁶⁴, not 2²⁷. The registration fixes both 64 corners and 2²⁷ = 134,217,728 patterns, and those cannot both describe a free sweep. The harness reconciles them by naming the identification that makes both true and reporting it as a column on every row: corner_identification period_3_per_axis, with block_corners 64 and distinct_corner_sites 27 side by side — the block is 4 × 4 × 4 corners at coordinates 0..=3 and corner 3 is corner 0 on every axis, so the 64 corners take 27 distinct values and the sweep is exactly 2²⁷. The choice is argued rather than convenient: a 4³ corner lattice has cube-group orbits of size 8, 24, 24 and 8, no union of which is 27, so every 27-bit sub-lattice of a 64-corner block breaks the cube symmetry and freezes some cell's corners, whereas 3-periodicity extends the field to all of ℤ³ and leaves all 27 cells with all 26 neighbours — the property P-63's block did not have and the one C3 is about. The cost is stated and not hidden: the sweep is exhaustive over 3-periodic sign fields, 2²⁷ of the 2⁶⁴ a free 4³ block admits, and because a cell's link is decided by 20 of the 27 sites (its own eight and its six face-neighbours', asserted equal to 20 at start-up) each distinct link configuration is visited 2⁷ = 128 times. All 27 cells are censused rather than one because shifting a 3-periodic pattern is a bijection of the domain, so the census sees not one configuration more — it is chosen for the denominator, which is why dual_vertices runs to 5,067,767,808 instead of 187,695,104. (b) FaceAmbiguity::Connected does not exist. marching_cubes/ambiguity.rs ships exactly Separate and AsymptoticDecider; the registration's C2 names a third variant, so C2 as literally written cannot fire, and the harness says so rather than fabricating the variant. mdc/every_ambiguous_face_joined is what such a rule would do, and it is filed as a non-control on an argument the file also checks: an always-joined rule is still a function of the shared face's four corner signs, so both cells reach the same answer, and lemma 2 — pairing_disagreements 0 — says a link cannot split when they do. The measurement is blunter than the argument: that arm's row is identical to mdc/separate in every column of this file except arm, ambiguous_face_pairing and wall_seconds — cycles_per_256_sign_bytes 358 both, dual_vertices 5,067,767,808 both, max_incident_faces 7 both. The file carries the aggregate and not the per-case distribution, so the coincidence is recorded and deliberately not explained; what it does establish is that the arm meant to carry the registered wording is indistinguishable from the shipped default at every resolution this dataset has. mdc/mixed_consistent is the arm that is not: one bit per grid face drawn from the pattern and handed to both cells, sweeping the whole family of crack-free pairings of which the asymptotic decider is one member — the only arm reaching max_incident_faces 12, unreachable from either uniform extreme, and the only one with no closed form for dual_vertices.
The model is asserted to be the shipped path, and replica_bit_identical reads true on all six rows. Before the sweep the harness runs the shipped DualContouring and ManifoldDualContouring under both shipped face rules — replica_shipped_arms 3 over replica_patterns 1,024, so 3,072 real extractions on an open 5 × 5 × 5-sample grid with SplitMix64 magnitudes, P-63's own fixture at a block that can host a complete link — and asserts per pattern and per arm that mesh.positions.len() equals the model's dual-vertex count exactly, that mesh.indices.len() equals 6 × the model's quad count exactly, and that the per-vertex incident-triangle count, element for element in emission order, equals the model's prediction. replica_vertices 242,776 and replica_triangles 330,612 are the totals that carries — 165,306 quads, 991,836 indices — and replica_decider_face_disagreements 0 is the shipped asymptotic decider agreeing across every interior grid face, which is the one property mdc/mixed_consistent stands in for. replica_quad_link_agreements 242,776 equals replica_vertices exactly: the quad-level link and the link walked through the triangulator's slot-0–slot-2 diagonal agreed on every vertex, replica_diagonal_merges 0. That diagonal is an output-format artefact and a link walked through it answers a question about emit_quad_axis rather than about the dual; adding it can only merge components, so a quad-level 1 implies a triangulated 1 — the direction C1 needs — and the harness measures both and asserts the inequality instead of asserting the argument. A transcription of shipped arithmetic is not attributable until it has been asserted identical to the shipped path, which is experiment_p101.rs's edge_slot discipline, and 3,072 extractions against 0 mismatches is what discharges it here.
The bench is the gate, there is no second path, and that is the row's only durable output. After writing the CSV the harness filters its recorded non-control breaches and prints P-126 GATE: PASS — every non-control arm read worst_link_components 1 over all 134217728 patterns of the 3 x 3 x 3 block.; on any breach it eprintln!s the arm, the worst_link_components value and the worst_link_pattern, cites A-017's record of MDC's non-manifoldness as a limit of the algorithm, and std::process::exit(1)s — so a future failure names the configuration rather than reporting that one exists. A control reading 1 aborts earlier still, on an assertion, because that is P-63's C3 failure mode arriving again. .github/workflows/nightly.yml runs it on a schedule cron at 07:00 UTC plus workflow_dispatch, reads the toolchain out of the manifest the way ci.yml's msrv job does, and contains no verdict logic at all — checkout, read the declared MSRV, install it, cargo bench -p isomesh --bench experiment_p126, report the exit code. That matters for a specific reason: a gate whose verdict lives in YAML has two implementations of the question and they drift, which is the two-paths defect this crate forbids; here one binary answers the question once and gates it forever, and the workflow's only claim is an exit status. Pinning the toolchain buys reproducibility of a failure against a named compiler and nothing more, because every clause on this row is an integer count over an enumerated population and no toolchain can move it.
wall_seconds sums to 1,015.200 s — 16 minutes 55 seconds — inside the registration's own 4-to-45-minute estimate, and no clause reads a clock. Per arm: 156.154, 156.537, 243.777, 131.558, 161.548, 165.626. P-126 has no timing clause of any kind, so M-280 and ✗24 have nothing to move here: on a governed CPU spanning 1.96–5.62 GHz under powersave/balance_performance a nanosecond is not a unit and a wall-clock ratio is never a gate, and this row structurally avoids both rather than surviving them. The consequence for this phase's clean re-run is worth stating plainly: every scored column in this file is an exact integer over a domain fixed by construction, so the clean-tree re-run could not have moved a verdict — wall_seconds is the only quantity in the file free to differ from any earlier run, and it is read by no clause, no assertion and no exit code. Two observations are therefore recorded and explicitly not scored: mdc/mixed_consistent at 243.777 s is 1.56× the uniform arms, consistent with its component table being 256 × 64 rows rather than 256 (393 KB against 6 KB, out of L1 rather than in it); and control/one_vertex_per_cell at 131.558 s is the fastest, having one component per cell to walk instead of cycles_per_256_sign_bytes/254 ≈ 1.41. Neither is a claim, neither is a ratio anyone may quote, and the sweep contains no common::counters::Probe because there is no cost clause on this row for a retired-instruction count to be the right unit for.
No source change landed, and O-12 is closed on a stated half. R-072's harness commit touches exactly two files — crates/isomesh/benches/experiment_p126.rs and .github/workflows/nightly.yml — and nothing whatsoever under crates/isomesh/src/, so no consumer-visible behaviour moved, no golden hash moved, and there is nothing to rebaseline. O-12 asked for "an exhaustive search over configurations spanning more than two cells … or a proof that a cell-local cycle triangulation plus shared face segments cannot produce a non-manifold vertex". M-374/P-63 delivered the first for Marching Cubes' edge vertices at 2¹⁸ and left the dual case standing, because its block could not host it. This row delivers both halves for the dual: a proof, in two lemmas asserted zero over 256 × 64 and 49,152 combinations, and an exhaustive check of that proof's transcription over 134,217,728 patterns × 27 cells on the smallest block in which a cell has all 26 neighbours, against three controls that read 2. What remains open is named rather than left to the reader. Exhaustivity is over signs and 3-periodic fields — 2²⁷ of the 2⁶⁴ a free 4³ block admits, each configuration visited 128 times — and over no magnitudes at all, which is not a gap in the way M-374's magnitude sampling was a gap, because every clause here is a function of the sign byte and the joined mask and the sweep sweeps both exhaustively; the residue is a free non-periodic field of more than 3 × 3 × 3 cells, which the nightly gate does not reach and no clause claims. And this row is silent about the other non-manifoldness: M-224/M-225 locate MDC's defect at an edge — an ambiguous grid face whose four cut edges lie in one cycle on both sides puts four quads on one dual edge, predicted exactly from the grid at 30, 64, 8 and 40 with zero error — and M-234 closed that by decision rather than by code. A manifold vertex link is not a manifold mesh, the two mechanisms are independent, and nothing here weakens M-234's stated limit.
SHARE, recomputed. None, and it was registered that way. This row moves nothing, proposes no source change, and no clause here is or may become a speedup claim, so ✗51's bar — a mechanism that wins its microbenchmark and moves under 1% of an extraction earns no ticket — has no share to divide and there is no Amdahl ceiling to compute. What stands in a share's place is the column each clause is read from, with its denominator exact by construction. C1: worst_link_components over dual_vertices, per arm — 5,067,767,808 on mdc/separate, the same on mdc/every_ambiguous_face_joined, 4,630,724,200 on mdc/mixed_consistent — an integer count of connected components with no tolerance in it. C2: worst_link_components and link_defective_vertices on the three controls, and control/one_vertex_per_cell's figure is predicted in closed form and asserted rather than merely observed non-zero — 113,246,208 = 27 cells × 2¹⁹ × 8, the 8 of 256 sign bytes whose cut set is face-disconnected, which is exactly 8/254 = 3.1496% of that arm's dual_vertices = active_cells = 3,595,567,104. So the control is not just non-zero, it is the right non-zero, to the unit. The other two controls carry expected_link_defective_vertices unavailable and are honest about it: an inconsistent joined bit and an open boundary are not functions of the sign byte alone, so their 221,792,256 and 99,876,864 are asserted greater than zero and not against a formula. C3: dual_vertices_with_complete_link per arm, never pooled, against expected_dual_vertices computed from the 256 sign bytes at start-up. A shipped extractor is invoked 3,072 times in the replica check and zero times in the sweep — 134,217,728 extractions is not the experiment, and the sweep builds no mesh, allocates nothing and evaluates no field.
Would be shown wrong by: a non-control arm reading worst_link_components above 1 on any future nightly, which the gate would name to the pattern and which would falsify a proof rather than a sample and locate A-017's limit at a vertex; a free, non-periodic sign field over a larger block producing a split dual vertex link, which the 3-periodic identification does not reach and this row does not claim; a shipped FaceAmbiguity variant whose joined bit is not a function of the shared face's four corner signs, which would break lemma 2 and put control/inconsistent_join_x's 221,792,256 defects on the shipped path; a change to dual.rs's quad-to-cell correspondence or to manifold_dual_contouring.rs's cycle walk that made replica_bit_identical read false, which would retire the model and every number above with it; or a replica_diagonal_merges above zero, which would mean the quad-level link and the triangulated link had diverged and that C1's chosen link is the wrong one to have walked.
Phase 27 — fifty registrations from eighteen fields of mathematics, each before its harness
Date: 2026-08-29 · Repo state: 466dd07, 482 findings entries, 52 open tickets
Corpus: home-still, 9,537 documents, 291,094 chunks, both scribe instances healthy
Companion: docs/research/2026-08-29-phase-27-axes-and-vocabulary-v2.md (the words)
Numbering. Drafted as P-103–P-152, shifted by twenty to P-123–P-172 on the source branch
because Phase 25's bit-packing sweep had already registered P-103–P-122 in crates/isomesh/src/experiment.rs,
then shifted by four again at this merge, because the merged main's closed Phase 26a/26b had landed
experiments P-123–P-126: every artefact in this phase — this section, the fifty backlog rows and both
source documents — carries the final numbers P-127–P-176, and nothing else moved.
Method. Eighteen areas of mathematics were probed against the corpus and against the repository simultaneously, on the rule the 2026-08-23 sweep earned: an area with a paper in the library and no reference anywhere in the repo is unmined with the source already paid for, and absence from the ledger is not evidence of absence from the library. Five parallel probes ran roughly 200 semantic queries and 40 word-boundary greps. Fourteen papers were acquired and converted during the session; six are paywalled and are recorded as such rather than cited.
The calibration, stated once. On this corpus a query about a subject genuinely present scores 0.65–0.72; the noise floor for an absent subject is 0.54–0.60 and the top hit is visibly unrelated. Every ABSENT verdict below is that pattern, and every one was cross-checked with a grep.
0. The headline, and it is not a paper
crates/isomesh/src/marching_cubes/trilinear.rs:246 computes b*b - 4*a*c from coefficients built at
:200-214, attributed to Grosso and defended by M-207's divergence from the textbook quadratic.
That expression is identically Cayley's 2×2×2 hyperdeterminant of the eight corner values.
Not proportional. Not numerically close. Symbolically equal — both are the same 12-term,
degree-4 homogeneous polynomial in f₀…f₇, and their difference simplifies to zero under the corner
indexing the crate already uses (f[u + 2v + 4w], read off twist_lo/du_lo/dv_lo). Three further
properties were proved in the same check:
- It is the pencil determinant.
disc(det(A₀ + λA₁))— whereA₀,A₁are the two opposite-face2×2corner matrices — equals it exactly, and equals it for all three axis pairings (0123|4567,0145|2367,0246|1357).M-206's "two independently derived constructions locate the same body saddles, to1.1e-12" is not a coincidence; it is two of the three slicings of one pencil. - Its sign is a
GL(2)³invariant.Δ(g·A) = (det g₁ · det g₂ · det g₃)² · Δ(A), verified over 40 random invertible triples in exact rationals. The weight is a square, so the sign — and therefore the body-saddle count — is invariant under every independent per-axis invertible reparametrisation. Non-cubic cells cannot change it. Nothing in the ledger currently asserts that. - It is invariant under all 48 octahedral relabellings and under negating the field, absolutely
rather than merely in sign.
✗39,✗49andM-177establish equivariance facts of exactly this shape by empirical sweeps; here they are algebra.
What the literature says about the object. de Silva & Lim, Tensor rank and the ill-posedness of
the best low-rank approximation problem, arXiv:math/0607647 — acquired, converted (44 pp., 100 chunks)
and indexed during this session — devotes §5–§7 to real 2×2×2 classification. Verbatim, §6: "the
rank of a tensor is 2 on the set {A | Det₂,₂,₂(A) > 0} and 3 on the set {A | Det₂,₂,₂(A) < 0}."
Their Prop 5.9 is Δ(A) > 0 ⟹ rank_⊗(A) ≤ 2; Prop 5.10 is rank_⊗(A) ≤ 2 ⟹ Δ(A) ≥ 0. Their sign
convention (discriminant of det(λ₁A₁ + λ₂A₂)) agrees with the standard explicit Cayley normalisation
and therefore with ours.
Two corrections that must travel with the identity, or it will be misused. (i) Δ = 0 is not
the degenerate stratum — de Silva & Lim's Prop 7.3 and remark record that tensors on Δ = 0 are
generically rank 3, and Δ = 0 carries ranks 0, 1, 2 and 3. The crate's discriminant == 0
branch therefore models a stratum whose structure it has not checked. (ii) sign(Δ) alone does not
classify the orbit; §7.2 needs the pair (sign Δ, rank_⊞) — multilinear rank as well — to separate
the eight real orbits. Any registration promising "the case taxonomy becomes a corollary" that cites
only the sign is overclaiming.
And one thing the identity does not do. The repo's quadratic solves for intersections of the
face level-set hyperbolas, which lie on the zero level set — not for ∇f = 0. Verified: on a
random trilinear, the repo's roots give |f| ≤ 5e-16 while the true critical points sit elsewhere. So
the separate BKK result below bounds a different two, and SADDLE_COUNT = 2 is not derived from it.
1. What the eighteen probes found, in one table
| Area | Corpus | Repo cites | Verdict |
|---|---|---|---|
| Cayley hyperdeterminant / tensor orbits | ABSENT (0.542) → acquired | 0 | Identity proved. Group A. |
| BKK / mixed volume / Newton polytopes | ABSENT (0.608) | 0 | MV = 2, verified two ways. Group B |
| Viro patchworking / toric | ABSENT (0.564) → acquired | 0 | Hinges on Kuhn regularity. Group B |
| CAD / real quantifier elimination | ABSENT (0.573) | 1 line, rejected on the wrong axis | Group B |
| Minimal-surface topology (TPMS genus) | — | 0 | χ oracle exists. Group C |
| Metric-based anisotropic adaptation | PRESENT, 0.713, 5 papers | 0 | Biggest paid-for gap. Group D |
Jones β-numbers / rectifiability |
ABSENT (0.578) → acquired | 0 | Group E |
| Strang–Fix / quasi-interpolation | ABSENT (0.62 = the Blu paper already held) | 0 | Group F |
| Sparse grids / Smolyak | ABSENT (0.597) | 0 | Registered expecting a null. Group F |
| Information-based complexity | ABSENT (0.561) → acquired | 0 | The denominator. Group G |
N-term / adaptive approximation classes |
PRESENT, 0.62–0.64, 4 papers | 0 (Stevenson cited only for NVB closure) | Cheapest. Group G |
| Lattice quantization | ABSENT → acquired | 0 | Group H |
| Min rectangle partition | PRESENT but wrong objective → acquired Eppstein | ranked #8, never done | Group I |
| Analysis of Boolean functions | ABSENT (0.584) → acquired | 0 | Group J |
| PL continuation (Allgower & Schmidt) | root ABSENT, descendant present | 0 for the root | 1985 precedence. Group K |
| Conley index | PRESENT (0.662) | 0 | Registered expecting death. Group K |
| Discrete Hodge / Helmholtz | PRESENT, never applied to Hermite data | 0 across the whole repo | Group L |
| Varifolds; intrinsic triangulations | 0.637 / PRESENT 0.677 | 0 | Group L |
Nodal percolation (ℓ_c > 0, d ≥ 3) |
ABSENT → acquired | 0 | Group M |
Killed during the probe, so nobody re-searches them. Random matrix theory for QEF conditioning
and pseudospectra for the truncation threshold — the QEF matrix M = Σnᵢnᵢᵀ is symmetric hence
normal, so its ε-pseudospectra are ε-balls around its eigenvalues and hand back exactly the
singular-value threshold they were meant to replace; RandNLA dies separately on M being 3×3.
Scheduling theory — per-cell output is bounded, so span T_∞ = O(1) and Blumofe–Leiserson collapses
to the trivial bound. Geometric separators for chunking — an axis-aligned cube already achieves the
Θ(n^{2/3}) isoperimetric optimum. Ising/dimer/limit shapes — the 2D results rest on bipartite
determinantal structure the 3D sign grid has not got. Renormalization group for LOD — no critical
point to define relevance against. Compressed sensing — deterministic grid, no fixed sparsity basis.
Helly/LP-type certificates for the cell clamp — the target is a 30-flop 3×3 adjugate; nothing
cheaper is worth writing.
Corrections owed to earlier documents. 2026-08-16-research-backlog-sota.md:5 says persistent
homology "returns zero"; that is true of BACKLOG.md and false of the corpus, which holds Dey, Hou
& Morozov on zigzag updates and Dey, Fan & Wang on simplicial-map persistence. The
2026-08-26 audit rejected CAD as "global, doubly exponential, needs arbitrary precision" — correct
at runtime, and irrelevant to deriving a table once, offline. 2026-08-26-audit...md:365 flags
Etiene et al.'s DOI as unverified; it is 10.1109/tvcg.2011.109. And docs/measurements/resolution_sweep.csv
is sphere-only by construction (benches/resolution_sweep.rs:128 hard-codes Sphere::canonical()).
Blocked acquisitions — paywalled, no open-access route found this session. Loseille & Alauzet
Part I 10.1137/090754078 and Part II 10.1137/10078654X (landing pages only; the framework is
restated verbatim in NASA NTRS 20200003084, which is what Group D cites); Binev–Dahmen–DeVore
10.1007/s00211-003-0492-7; Novak 10.1006/jcom.1996.0015; Blu & Unser Part I 10.1109/78.790659;
Nemhauser–Wolsey–Fisher 10.1007/BF01588971; Boissonnat & Wintraecken 10.4230/LIPIcs.SoCG.2020.20;
Allgower & Schmidt 10.1137/0722020; Pöthkow et al. 10.1111/j.1467-8659.2011.01942.x. DOI trap:
10.1137/0722019 is not Allgower & Schmidt — it is Nanda on the QR algorithm, same volume and issue.
Protocol. Phase 15's protocol applies in full. All fifty P- entries are registered in
crates/isomesh/src/experiment.rs before any harness commit — that registration is the first
commit of the phase and is the only write to crates/isomesh/src/** that precedes a measurement.
✗51's rule is applied: every clause stated as a ratio of a total carries a SHARE line, and every
registration carries a VACUITY CONTROL naming the column that proves the fixture could have failed.
Nine registrations are expected to return nulls, and that is registered rather than hoped:
P-136, P-150, P-158, P-159 (whose null is the most valuable result in the phase), P-163,
P-166, P-168, P-172, P-174.
Dependencies, stated once. P-127 runs before everything else in Group A. P-131 rides P-127.
P-142 runs before P-143 and P-145. P-146 runs before P-147, P-149 and P-151. P-155
runs before P-156 and P-157. P-152 runs before P-153 and P-154. Everything else is
independent, and eleven rows are S.
Group A — the cell is a tensor (real algebraic geometry, tensor geometry, invariant theory)
P-127 — registered for R-127, before the harness: The body-saddle discriminant is Cayley's hyperdeterminant, and the proof is a test rather than a comment
Ticket: R-127 (S). Records: expression, terms_disc, terms_cayley, total_degree, symbolic_difference_is_zero, pencil_axis_pairing, pencil_matches, random_rational_trials, max_abs_ratio_deviation, f32_sign_disagreements, f64_sign_disagreements, c1_holds, c2_holds, c3_holds.
Hypothesis. THE CRATE HAS SHIPPED A CLASSICAL INVARIANT FOR ITS ENTIRE LIFE AND CALLED IT A TRANSCRIBED QUADRATIC. (C1) b*b - 4*a*c from BodySaddles::coefficients is identically Cayley's 2×2×2 hyperdeterminant of [f₀..f₇] under the indexing f[u + 2v + 4w]: same 12 terms, total degree 4, symbolic difference exactly zero — asserted by a committed symbolic check, not by a numeric sample. (C2) The same polynomial equals disc(det(A₀ + λA₁)) for the two opposite-face 2×2 corner matrices, and does so for all three axis pairings, which is the mechanism behind M-206. (C3) In exact rational arithmetic over at least 3,000 random 8-tuples the two expressions agree with ratio exactly 1 and zero sign disagreements; in f32 they do not, and the disagreement count is the number P-134 exists to act on. SHARE: C1 and C2 move no runtime cost at all — this row is a renaming plus two theorems, and its whole value is what Group A's other rows can then assume.
Falsified by. C1 by any non-zero symbolic difference, which would mean the indexing convention was misread and every downstream row in Group A collapses. C2 by any axis pairing disagreeing, which would make M-206 a coincidence after all. C3 by zero f32 disagreements, which would retire P-134 before it is written. VACUITY CONTROL: the trial set must contain 8-tuples of both discriminant signs and at least 50 within 1e-6 of zero, reported as counts, or C3 is sampling only the easy stratum.
P-128 — registered for R-128, before the harness: The saddle count cannot depend on cell aspect ratio, and this is the first thing in the ledger that says so
Ticket: R-128 (S). Records: field, resolution, cell_aspect_ratio, axis_scales, saddle_count_isotropic, saddle_count_anisotropic, count_disagreements, sign_delta_isotropic, sign_delta_anisotropic, sign_disagreements, gl2_weight_check, c1_holds, c2_holds.
Hypothesis. Δ(g·A) = (det g₁ det g₂ det g₃)²·Δ(A) — the weight is a perfect square, so sign(Δ) is an absolute invariant of the GL(2)³ action, and the body-saddle count is a property of the eight values alone. (C1) On all eight reference fields at 33³ and 65³, meshing with per-axis cell scales of (1,1,1), (1,2,4) and (1,1,8) produces bit-identical body-saddle counts per cell, with zero disagreements. (C2) The relative-invariant weight holds numerically: for 500 random invertible g triples, Δ(g·A)/Δ(A) equals (det g₁ det g₂ det g₃)² to f64 rounding. SHARE: C1 is a correctness clause and moves no cost; it removes an untested assumption from every anisotropic-cell path, including all of Group D.
Falsified by. C1 by any disagreement, which would mean the extractor's saddle path depends on geometry the invariant says it cannot — i.e. a bug, and a valuable one. C2 by a weight that is not a square, which would mean the indexing or the action is wrong and P-127 C1 must be re-read. VACUITY CONTROL: the anisotropic arms must produce a non-zero count of cells whose vertex positions move, reported as a column, or the fixture is not exercising anisotropy at all.
P-129 — registered for R-129, before the harness: Octahedral and negation invariance as algebra, at a fraction of the cost of the 48-element sweep
Ticket: R-129 (S). Records: element, sweep_ms, invariant_ms, speedup, cells_checked, sweep_violations, invariant_violations, agreement, negation_violations, c1_holds, c2_holds, c3_holds.
Hypothesis. ✗49 established bit-exact octahedral equivariance of plain Marching Cubes by sweeping all 48 elements; Δ is invariant under all 48 and under negating the field, provably. (C1) A Δ-based check agrees with the 48-element sweep on every cell of every reference field — zero disagreements — while costing at least 10× less. (C2) Δ is invariant under field negation on every cell, which M-177 says reordering cannot buy for vertex placement; the contrast localises M-177's obstruction to the solve, not to the classification. (C3) The invariant check catches at least one configuration class the sweep is structurally blind to, or reports honestly that it catches none. SHARE: C1 moves the equivariance-test stage of CI, currently the 48-element sweep in full.
Falsified by. C1 by any disagreement or under 10×. C2 by a negation violation, which would contradict the symbolic proof and send P-127 back. C3 by "none", which is a fine outcome and should be recorded as such rather than hunted. VACUITY CONTROL: the sweep arm must report a non-zero violation count on a deliberately broken table, or both instruments are agreeing on nothing.
P-130 — registered for R-130, before the harness: Δ > 0 means real tensor rank 2, and the census says whether rank predicts anything
Ticket: R-130 (M). Records: field, resolution, cells, delta_positive, delta_negative, delta_zero, rank_two_cells, rank_three_cells, ambiguous_cells, rank_vs_case_index_agreement, mutual_information, c1_holds, c2_holds, c3_holds.
Hypothesis. de Silva & Lim §6: rank is 2 on {Δ > 0} and 3 on {Δ < 0}. A cell's real tensor rank is therefore computable from a sign the crate already computes. (C1) Across eight fields at three resolutions, the (Δ > 0, Δ < 0, Δ = 0) partition is stable and Δ = 0 is rare — under 0.1% of surface cells at f64. (C2) Real tensor rank carries information about ambiguity that the 8-bit case index does not: mutual information between rank and "this cell is ambiguous" exceeds that between rank and the case index by a stated margin. (C3) On sphere, where no cell is ambiguous, rank is 2 on essentially every surface cell — the control that says the statistic is not measuring noise. SHARE: C1 and C2 are counts, not timings, and move nothing; they decide whether Group A continues past P-131.
Falsified by. C1 by an unstable partition or Δ = 0 above 0.1%, the latter meaning the degenerate stratum is common enough that P-131 becomes urgent rather than optional. C2 by rank being a function of the case index, which would make it a renaming with no new signal — the most likely outcome and worth knowing cheaply. C3 by sphere showing rank-3 cells, which would say the statistic is dominated by arithmetic rather than geometry. VACUITY CONTROL: gyroid and csg_difference must contribute a non-zero ambiguous-cell count, or C2's mutual information is computed against a constant.
P-131 — registered for R-131, before the harness: Δ = 0 is not the degenerate case, and the branch that assumes it is has never been audited
Ticket: R-131 (M). Records: field, resolution, discriminant_zero_hits, a_zero_hits, double_root_hits, border_rank_two, true_rank_three, w_state_like, roots_reported, roots_true, mesh_delta_triangles, c1_holds, c2_holds, c3_holds.
Hypothesis. roots() treats discriminant == 0 as "a double root is one intersection point", which is correct arithmetic about the quadratic and may be the wrong model of the configuration: de Silva & Lim Prop 7.3 records that tensors on Δ = 0 are generically rank 3, with border rank 2 — the W-state is the canonical example, Δ = 0 exactly with real rank 3. (C1) The discriminant == 0 branch fires on at least one reference field at f64, and the count is reported per field rather than assumed zero. (C2) On the cells where it fires, the true configuration is classified — rank 1, 2, or 3 — and at least one is not the tangential-touch case the comment describes. (C3) Correcting the classification changes at least one triangle on at least one field, or provably changes none, and which of those is true is stated as the result. SHARE: C3 moves only the cells C1 counts, which is why C1 is reported first and separately.
Falsified by. C1 by the branch never firing on any field at any resolution, which retires the row and is worth the afternoon. C2 by every hit being a genuine tangency, which would vindicate the comment. C3 by no mesh change, which would make this a documentation fix and should be recorded as one. VACUITY CONTROL: a synthetic W-state cell must be added to the fixture and must reach the branch, or C2 cannot distinguish "no such cells exist" from "the fixture has none".
P-132 — registered for R-132, before the harness: The eight real orbits, and whether orbit class predicts the defects the validity suite finds
Ticket: R-132 (M). Records: field, resolution, orbit_class, sign_delta, multilinear_rank, cells_in_orbit, nonmanifold_edges_in_orbit, self_intersections_in_orbit, orphaned_vertices_in_orbit, defect_rate_per_orbit, chi_square, c1_holds, c2_holds, c3_holds.
Hypothesis. de Silva & Lim §7.2: orbit class is determined by the pair (sign Δ, rank_⊞) — the sign alone is not enough, and any claim that the taxonomy follows from Δ must carry the multilinear rank too. (C1) All eight real orbits are populated across the reference fields, or the unpopulated ones are named. (C2) T-001 defect rates differ significantly across orbits — chi-square against the null that defects are orbit-independent. (C3) The orbit partition is not a relabelling of the 256-case index: at least one case index spans two orbits and at least one orbit spans two case indices. SHARE: C2 is a rate per orbit, not a share of a total; the population counts are reported so the rates have denominators.
Falsified by. C1 by orbits that no field reaches, which narrows the taxonomy usefully. C2 by orbit-independent defects, which would mean the classification is mathematically real and operationally inert — the honest and quite likely outcome. C3 by a bijection with the case index, which would make the whole orbit apparatus a renaming. VACUITY CONTROL: the defect columns must be non-zero in total, asserted from T-001's own counts, or C2 is a chi-square on an empty table.
P-133 — registered for R-133, before the harness: An exact sign for the hyperdeterminant, and how often f32 gets it wrong
Ticket: R-133 (M). Records: field, resolution, scalar, cells, sign_disagreements_f32, sign_disagreements_f64, disagreement_rate, exact_ms, float_ms, overhead_ratio, filtered_fallback_rate, triangles_changed, nonmanifold_delta, c1_holds, c2_holds, c3_holds.
Hypothesis. Δ is a degree-4 polynomial in 8 inputs — squarely in the range where Shewchuk's adaptive-precision expansions (10.1007/pl00009321, already mined at 5 files) give an exactly-correct sign, and where a floating-point filter takes the exact path on a small minority of cells. (C1) At f32, the sign of Δ disagrees with the exact sign on a non-zero fraction of surface cells on at least two reference fields. (C2) A filtered exact predicate costs under 1.5× the naive float evaluation in aggregate, because the filter succeeds on the overwhelming majority of cells. (C3) Correcting the sign changes the mesh — a non-zero triangle delta, or a non-zero change in T-001's non-manifold-edge count — on at least one field. SHARE: C2 moves the body-saddle stage only, whose share of extraction must be reported alongside.
Falsified by. C1 by zero disagreements at f32, which would say the predicate is not near-degenerate on real fields and retire C2 and C3 with it. C2 by above 1.5×. C3 by no mesh change, which would mean the sign errors fall on cells whose classification does not reach the output — interesting, and a reason to look at where they do fall. VACUITY CONTROL: at least one field must produce cells with |Δ| below the f32 error bound, reported as a count, or C1 is measuring a problem the fixture excludes.
P-134 — registered for R-134, before the harness: |Δ| normalised as a continuous ambiguity magnitude, instead of a binary test
Ticket: R-134 (S). Records: field, resolution, normalisation, delta_magnitude, scale_invariance_error, rank_correlation_with_defects, rank_correlation_with_hausdorff, threshold_sweep, cells_above_threshold, c1_holds, c2_holds.
Hypothesis. Δ is homogeneous of degree 4, so |Δ| / (max|fᵢ|)⁴ is scale-free and is a candidate magnitude of ambiguity where the crate currently has only a sign — the same move persistence makes against the interior test, but computable in O(1) from data already in hand. (C1) The normalised magnitude is invariant under scaling all eight corner values, to f64 rounding, and under the 48 octahedral elements. (C2) It rank-correlates with per-cell symmetric Hausdorff error above 0.5 on at least four of eight fields, making it a candidate refinement criterion rather than merely a classifier. SHARE: C2 offers a criterion for the adaptivity stage; it does not by itself move any cost.
Falsified by. C1 by scale dependence, which would mean the normalisation is wrong. C2 by correlation below 0.5 on five or more fields, which would say ambiguity magnitude and geometric error are different phenomena — likely, and it would close the row cleanly. VACUITY CONTROL: the per-cell Hausdorff column must have non-zero variance on every field, or the correlation is against a constant.
P-135 — registered for R-135, before the harness: Where the identity stops holding, which is the boundary of everything Group A claims
Ticket: R-135 (S). Records: reconstruction, is_multi_affine, identity_holds, symbolic_residual_terms, smooth_min_k, deviation_at_k, tricubic_degree, cases_touched, c1_holds, c2_holds.
Hypothesis. Every claim in Group A rests on the reconstruction being multi-affine. That is a hypothesis about the filter, not a fact about the crate, and it must be recorded as a boundary before anything downstream leans on it. (C1) The identity holds for the trilinear and fails for any reconstruction that is not multi-affine — demonstrated symbolically for a tricubic and for smooth_min(k) with k > 0, with the residual reported rather than merely asserted non-zero. (C2) Under smooth_min(k), the deviation from the multi-affine Δ grows with k and is bounded in the O(k) seam shell the 2026-08-23 memo measured — connecting Group A's boundary to M-38's smoothing result rather than leaving it a separate fact. SHARE: none — this is a scope statement and moves nothing.
Falsified by. C1 by the identity surviving a non-multi-affine reconstruction, which would be a strictly better result and would widen Group A. C2 by deviation that does not track k, which would mean the smoothing and the invariant are unrelated and M-38 gains nothing here. VACUITY CONTROL: the tricubic arm must produce a symbolic residual with named non-zero terms, not a numeric non-zero, or C1 has not established the failure structurally.
P-136 — registered for R-136, before the harness: A null registered on purpose — the hyperdeterminant does not resolve the interior test
Ticket: R-136 (S). Records: configuration_class, delta_sign, interior_test_verdict, agreement_rate, cases_where_delta_insufficient, chernyaev_disagreement_overlap, c1_holds, c2_holds.
Hypothesis. THIS ROW EXISTS TO STOP AN OVERCLAIM BEFORE SOMEBODY MAKES IT. It is tempting to read Group A as "the 730-subcase table becomes a corollary of an invariant". It does not, and the registration says why in advance: sign(Δ) counts hyperbola intersections in the plane of a pencil, and the interior test asks which side of the surface a tunnel opens on, which is a different question with a different answer. (C1) Over the configurations M-165 identifies (Chernyaev's numerator-only test wrong on 1,966 of 15,6xx), sign(Δ) alone agrees with the correct interior verdict on strictly fewer than all of them, and the disagreement set is characterised. (C2) The classes where Δ is insufficient are named explicitly, so the boundary is in the ledger rather than in somebody's head. SHARE: none — this is a negative result registered before its positive twin can be believed.
Falsified by. C1 by full agreement, which would be a major and unexpected win and would justify reopening the A-002 interior line entirely. C2 by an uncharacterisable disagreement set, which would mean the instrument is too coarse. VACUITY CONTROL: the configuration set must reproduce M-165's 12.6% disagreement rate as a control column, or the fixture is not the population M-165 measured.
Group B — Newton polytopes, patchworking, and machine-derived tables (algebraic geometry, toric geometry, symbolic computation)
P-137 — registered for R-137, before the harness: A trilinear has at most two critical points, and that is a theorem rather than an assertion
Ticket: R-137 (S). Records: field, resolution, mixed_volume, critical_points_complex, critical_points_real, critical_points_in_cell, cells_with_zero, cells_with_one, cells_with_two, on_hyperplane_count, saddle_count_relationship, c1_holds, c2_holds, c3_holds.
Hypothesis. ∂f/∂xᵢ of a multi-affine f is multi-affine in the other two variables, so its Newton polytope is a unit square; the mixed volume of the three squares is Vol([0,2]³) − 3·2 + 0 = 8 − 6 = 2, verified by convex hull and independently by symbolic solution of ∇f = 0. By Bernstein's theorem f has at most 2 critical points in (ℂ*)³. (C1) The mixed volume computation is committed as a check, and a census over the reference fields reports how many cells have 0, 1 or 2 real critical points inside the unit cell — the bound is on neither. (C2) At least one cell on at least one field has a critical point on a coordinate hyperplane, which Bernstein's count excludes by construction, demonstrating the caveat rather than stating it. (C3) THE RELATIONSHIP TO SADDLE_COUNT IS STATED AS A NON-IDENTITY: the repo's quadratic solves for face-hyperbola intersections on the zero level set, not for ∇f = 0, and the two 2s are shown to be different by exhibiting a cell where the root sets differ. SHARE: none — this replaces an authority citation with a derivation.
Falsified by. C1 by any cell with three or more real critical points, which would refute the mixed-volume computation. C2 by no hyperplane cases, which would make the caveat vacuous here and is worth recording. C3 by the two root sets coinciding, which would be a much stronger result and would mean SADDLE_COUNT is derivable from BKK. VACUITY CONTROL: the census must include cells of all three counts, reported as a distribution, or the bound is being checked against a single stratum.
P-138 — registered for R-138, before the harness: What the case explosion would cost at tricubic, priced before anyone proposes it
Ticket: R-138 (M). Records: reconstruction, degree_per_variable, mixed_volume, critical_points_bound, bernstein_route_alive, subdivision_exactness, estimated_case_count, c1_holds, c2_holds.
Hypothesis. The 2026-08-23 memo killed Bernstein–Bézier form for the trilinear and said explicitly: revisit the entire hypothesis if the crate ever adopts a tricubic reconstruction filter. P-157 may propose exactly that, so the price should be on the table first. (C1) The mixed volume for ∇f = 0 with a tricubic reconstruction is computed and reported, giving the critical-point bound that would replace the trilinear's 2. (C2) The Bernstein-form arguments the memo killed are re-checked at degree 3 per variable and reported as alive or dead, with the specific reason — the memo predicts alive, and a prediction registered before the check is worth more than one after. SHARE: none — this prices a decision, it does not make one.
Falsified by. C1 by a mixed volume that makes the tricubic case space computationally hopeless, which would be a strong argument against P-157 and should be said plainly. C2 by the Bernstein arguments staying dead at degree 3, which would contradict the memo's own prediction. VACUITY CONTROL: the trilinear must be run through the same pipeline and reproduce MV = 2, or the tricubic number has no calibration.
P-139 — registered for R-139, before the harness: Is the Kuhn triangulation regular, and does marching tetrahedra therefore inherit a 1980s theorem
Ticket: R-139 (M). Records: triangulation, lifting_function, is_regular, secondary_polytope_vertex, patchworking_applies, isotopy_agreement, pv_disagreements, cells_checked, c1_holds, c2_holds, c3_holds.
Hypothesis. Viro's combinatorial patchworking builds a real algebraic hypersurface from signs at the lattice points of a Newton polytope, glued over a triangulation, and states when the piecewise-linear result is isotopic to the true hypersurface. Signs at the eight corners of a cube, glued over the Kuhn/Freudenthal triangulation, is marching tetrahedra. The theorem's hypothesis is that the triangulation be regular (induced by a convex lifting). (C1) The Kuhn triangulation of the unit cube is regular, demonstrated by exhibiting an explicit convex lifting function, or shown not to be — this single fact decides the whole transfer. (C2) If regular, the patchworked surface is isotopic to a real algebraic hypersurface, and that isotopy claim agrees with T-015's Plantinga–Vegter checker on every cell of every reference field. (C3) The connection to the existing Lovász-extension framing is made explicit: the Lovász extension is PL interpolation over exactly this triangulation, so 2026-08-23's "marching tetrahedra contours the Lovász extension" and Viro's construction are the same statement from two fields. SHARE: none — this is a theorem acquisition.
Falsified by. C1 by non-regularity, which kills the transfer in an afternoon and is the outcome to hope for if the alternative is a long shot. C2 by disagreement with T-015, which would mean one of the two instruments is wrong and finding out which is worth more than the transfer. C3 by the two framings differing, which would be genuinely surprising. VACUITY CONTROL: T-015 must report at least one isotopy failure somewhere in the corpus of test cells, or C2's agreement is agreement on a constant.
P-140 — registered for R-140, before the harness: Fields whose topology is known by construction, generated rather than measured
Ticket: R-140 (M). Records: construction, prescribed_genus, prescribed_chi, measured_chi, chi_agreement, resolution, cells, nonmanifold_edges, extractors_tested, c1_holds, c2_holds.
Hypothesis. CLAUDE.md records that χ cannot be asserted on gyroid or fbm_terrain, so those fields have no topological gate beyond manifoldness. Viro's construction is a generator: prescribe the topology, get a field. That turns the oracle problem inside out. (C1) At least three patchworked fields with prescribed, non-trivial genus are added as fixtures, and every extractor in the crate reproduces the prescribed χ at sufficient resolution. (C2) The resolution at which each extractor first reproduces the prescribed χ is reported per extractor, which is a sampling-adequacy curve the crate does not currently have for any field with known topology beyond the sphere and torus. SHARE: none — this adds test coverage, and its value is the coverage.
Falsified by. C1 by any extractor failing to converge to the prescribed χ at any resolution, which would be a defect and the point of the fixture. C2 by all extractors converging at the same resolution, which would make the curve uninformative but is still worth one line. VACUITY CONTROL: at least one prescribed field must have genus above 1, or the fixture is a sphere in disguise.
P-141 — registered for R-141, before the harness: Deriving the case table by quantifier elimination, offline, once
Ticket: R-141 (L). Records: solver, configuration, wall_clock_s, terminated, cases_derived, cases_matching_table, cases_disagreeing, custodio_disagreement_overlap, machine_checkable_certificate, c1_holds, c2_holds, c3_holds.
Hypothesis. THE REPOSITORY REJECTED CAD ON THE WRONG AXIS. discovery-dossier.md:298 dismisses it as "global, doubly exponential, needs arbitrary precision" — all true, and all irrelevant, because deriving a case table is an offline computation run once in the project's lifetime, not a runtime cost. The A-002 series' recurring expense is transcription (M-207, M-219, M-221, ✗22, M-228, M-231), which is exactly what machine derivation removes. (C1) A real-quantifier-elimination engine — nlsat via Z3, or QEPCAD — terminates on the single-cell topology query over the 8 corner parameters within a stated wall-clock budget, or is reported as not terminating, which is itself the answer. (C2) The derived taxonomy is compared against the crate's committed table, and every disagreement is adjudicated by hand against the trilinear. (C3) Any disagreement is checked against Custodio et al.'s published corrections to Chernyaev, so a machine disagreement is either a known bug or a new one. SHARE: none at runtime; this changes how the table is produced, not what it costs.
Falsified by. C1 by non-termination within budget, which closes the row honestly and is a real possibility. C2 by zero disagreements, which would be a strong independent validation of validate_table() and worth the whole ticket. C3 by disagreements outside Custodio's set that survive adjudication, which would be a genuine new finding. VACUITY CONTROL: the pipeline must first re-derive a known-correct sub-case the table already contains, or a clean run proves nothing about the solver's fidelity.
Group C — deterministic topological oracles (minimal surface theory)
P-142 — registered for R-142, before the harness: The gyroid's Euler characteristic is −8 per cubic cell, and the hole CLAUDE.md records is closable
Ticket: R-142 (S). Records: field, periods_per_axis, resolution, wrap_mode, chi_predicted, chi_measured, chi_agreement, genus_measured, boundary_edges, nonmanifold_edges, cells, c1_holds, c2_holds, c3_holds.
Hypothesis. CLAUDE.md records that χ cannot be asserted on gyroid, which has left that field with no topological gate. It is assertable, and the reason the project could not see it is that the extraction box is not periodic-conforming. Triply periodic minimal surfaces have genus 3 per primitive translational cell; the gyroid's primitive lattice is body-centred cubic, so the conventional cubic cell holds two primitive cells and χ = −8, not −4. Verified numerically on the nodal surfaces at 32, 64, 96 and 128 voxels per period: Schwarz P −4, gyroid −8, Schwarz D −16 per conventional cubic cell, stable across resolution. (C1) Extracting the gyroid over an integer number of periods with periodic wrap gives χ = −8N³ exactly, for N in {1, 2, 3}, on every extractor in the crate that produces a closed surface. (C2) The measured genus is 1 + 4N³, consistent with C1 through χ = 2 − 2g. (C3) The oracle is added to the validity suite as a gate for gyroid, closing a hole the ledger currently records as permanent. SHARE: none — this is a correctness gate where there was none.
Falsified by. C1 by any N disagreeing, which would mean the extraction is not periodic-conforming and the wrap is where the defect is — itself a finding, since chunk seams are the recurring defect class. C2 by an inconsistent genus, which would mean the surface is not closed and orientable and C1's arithmetic does not apply. C3 by the gate being unimplementable within the existing suite. VACUITY CONTROL: the non-wrapped arm must be run and must fail the −8N³ prediction, or the experiment has not shown that periodicity is what matters.
P-143 — registered for R-143, before the harness: Schwarz P and D as second and third fields with exactly known topology
Ticket: R-143 (S). Records: field, space_group, primitive_lattice, chi_per_cubic_cell, chi_predicted, chi_measured, periods, resolution, body_centering_invariance, c1_holds, c2_holds.
Hypothesis. The crate has exactly two fields with analytically known topology — sphere and torus — and both are genus ≤ 1. Schwarz P (χ = −4 per cubic cell) and Schwarz D (χ = −16) add two high-genus fields whose predictions differ from the gyroid's and from each other, so a single arithmetic error cannot pass all three. (C1) Both are added as reference fields and both reproduce χ = N³·χ_cell under periodic wrap. (C2) THE MECHANISM IS ASSERTED RATHER THAN ASSUMED: the gyroid's nodal function is invariant under the body-centring shift (π,π,π) while P's and D's are negated by it, which is exactly why the gyroid's cubic cell holds two primitive cells and theirs do not — checked as a symbolic identity, not inferred from the χ values it explains. SHARE: none.
Falsified by. C1 by either field disagreeing. C2 by the invariance failing, which would mean the explanation for the factor of two is wrong even if the numbers are right — and an unexplained correct number is exactly what M-206 was before P-127. VACUITY CONTROL: the three fields must produce three different χ values at N = 1, or the suite cannot distinguish a correct oracle from a constant.
P-144 — registered for R-144, before the harness: Whether a periodic value-noise terrain admits an oracle at all
Ticket: R-144 (M). Records: field, octaves, period, wrap_mode, chi_measured, chi_variance_across_seeds, chi_stable, oracle_exists, resolution_convergence, c1_holds, c2_holds.
Hypothesis. P-142 closes gyroid; fbm_terrain remains open, and the question is whether it can be closed at all rather than whether some formula applies. A periodic lattice-noise field with a fixed seed is a deterministic function with a definite χ, so the question is empirical: does it converge with resolution, and is it stable enough to gate on? (C1) With periodic wrap and a fixed seed, measured χ converges as resolution increases and is stable to at least 65³. (C2) χ varies across seeds, so the gate must be per-seed rather than per-field — stated in advance so nobody writes a single constant into the suite. SHARE: none.
Falsified by. C1 by χ still moving at the highest tested resolution, which would say the field is not resolved and no oracle is available at game resolutions — the likely outcome and worth recording. C2 by seed-independent χ, which would be surprising and would make the gate much cheaper. VACUITY CONTROL: at least three seeds must be run, or C2 cannot fire.
P-145 — registered for R-145, before the harness: Stratified Morse ground truth, and the citation this repository has had wrong since Phase 23
Ticket: R-145 (M). Records: field, resolution, chi_stratified_morse, chi_extracted, agreement, disagreement_cells, method_cost_ms, applicable_fields, doi_verified, c1_holds, c2_holds.
Hypothesis. 2026-08-26-audit-and-phase-23-registrations.md:365 flags Etiene et al. 2012's DOI as unverified. It is 10.1109/tvcg.2011.109, TVCG 18(6), and the paper computes ground-truth topological invariants per instance using stratified Morse theory and digital topology — a deterministic oracle, strictly stronger than any statistical one wherever it applies. (C1) The method computes a ground-truth χ on at least two fields where the crate currently has none, and agrees with P-142's analytic prediction on gyroid, which is the cross-check that validates both. (C2) The cost is reported and the set of fields where it applies is stated, because an oracle that costs more than the mesh is a test-only instrument and should be labelled one. SHARE: none — verification cost, not runtime cost.
Falsified by. C1 by disagreement with P-142, which would put one of the two oracles in doubt and is the most informative possible outcome. C2 by inapplicability to every field the crate cares about. VACUITY CONTROL: the method must be run on sphere and return χ = 2, or it is not calibrated.
Group D — element shape and anisotropy (Riemannian geometry, adaptive FEM)
P-146 — registered for R-146, before the harness: A metric built from the trilinear's own Hessian, and what it does to the triangle count at fixed error
Ticket: R-146 (L). Records: field, resolution, metric, p_norm, complexity_target, triangles_isotropic, triangles_anisotropic, hausdorff_isotropic, hausdorff_anisotropic, triangles_at_matched_hausdorff, ratio, aspect_ratio_max, aspect_ratio_mean, metric_ms, metric_share, c1_holds, c2_holds, c3_holds.
Hypothesis. THE LARGEST PAID-FOR GAP THIS SWEEP FOUND. The corpus holds five papers on metric-based anisotropic adaptation at 0.70–0.71 — Yano & Darmofal, Cao, Bawin et al., ParMmg, Mirebeau — and the repository cites none of them; Loseille, Alauzet, metric tensor and log-Euclidean are zero across every file. The optimal L^p metric is M_Lp = D_Lp · det(|H_u|)^(−1/(2p+d)) · |H_u| with complexity C(M) = ∫√det M standing in for vertex count (NASA NTRS 20200003084, restating Loseille & Alauzet verbatim; the SIAM originals are paywalled). The Hessian is available: the crate already samples the trilinear and already computes central differences at cell size (M-65). (C1) At matched symmetric Hausdorff error, a metric-driven mesh uses at least 25% fewer triangles than uniform refinement on at least three of eight reference fields. (C2) The fields where it wins are the ones with a flat direction — ridges, creases, the CSG box edges — and the fields where it does not win are the isotropically curved ones, predicted per field before the run. (C3) Computing the metric costs under 15% of extraction. SHARE: C1 moves the triangle budget, whose share of frame cost M-135 puts at 29% for the contour and 45% for the collider check.
Falsified by. C1 by under 25% everywhere, which would mean our fields have no exploitable anisotropy and closes Group D's largest row. C2 by the win landing on the wrong fields, which would mean the mechanism is not the one claimed even if the number is real. C3 by above 15%. VACUITY CONTROL: the reported maximum aspect ratio must exceed 3 on at least one field, or the "anisotropic" arm is isotropic and C1 is measuring noise.
P-147 — registered for R-147, before the harness: The rate does not improve and the constant does, stated before the measurement rather than discovered in it
Ticket: R-147 (M). Records: field, resolution_series, fitted_exponent_isotropic, fitted_exponent_anisotropic, exponent_difference, fitted_constant_isotropic, fitted_constant_anisotropic, constant_ratio, am_gm_gap, flat_direction_fraction, c1_holds, c2_holds, c3_holds.
Hypothesis. THE SEDUCTIVE VERSION OF GROUP D IS WRONG AND THE REGISTRATION SAYS SO IN ADVANCE. For W^{2,p} regularity, uniform refinement gives O(N^(−2/3)) in 3D and the optimal anisotropic mesh gives O(N^(−2/3)) — the same exponent; Bonito, Canuto, Nochetto & Veeser (Acta Numerica 2024, in corpus at 10.1017/s0962492924000011) state flatly that the order "cannot be improved upon assuming either higher regularity … or a graded mesh". What anisotropy buys is the constant: ‖√|det H|‖_{L^τ} replaces |f|_{W^{2,p}}, and by AM–GM the former is never larger. (C1) The fitted error exponent is statistically indistinguishable between isotropic and anisotropic arms — |Δexponent| < 0.1 — on every smooth field. (C2) The fitted constant improves, and its improvement tracks the measured AM–GM gap ‖√|det H|‖ / ‖tr|H|/d‖ per field, rank correlation above 0.7. (C3) A field lacking W^{2,p} regularity — csg_difference, whose gradient is discontinuous — shows an exponent difference above 0.1, because that is the one regime where grading wins in the exponent. SHARE: none — this is M-12's law, decomposed.
Falsified by. C1 by an exponent gain on a smooth field, which would contradict the cited theory and would be the more interesting result. C2 by a constant improvement uncorrelated with the AM–GM gap, which would mean the mechanism is not the one the theory names. C3 by no exponent difference on the CSG field, which would say our sharp fields are smoother than assumed. VACUITY CONTROL: the AM–GM gap column must vary by at least 2× across fields, or C2's correlation is against a constant.
P-148 — registered for R-148, before the harness: Metric interpolation across a chunk seam, where averaging matrices is not averaging
Ticket: R-148 (M). Records: interpolation_scheme, seam_axis, determinant_swell_max, determinant_swell_mean, seam_vertices_moved, seam_open_edges, hashes_moved, bit_exact_seam, cell_size_power_of_two, c1_holds, c2_holds, c3_holds.
Hypothesis. A metric field must be interpolated, and component-wise interpolation of symmetric positive-definite matrices is not intrinsic — it can swell determinants, which in mesh terms means spuriously coarsening. The log-Euclidean scheme exp((1−t)log M₁ + t log M₂) is determinant-monotone. This lands directly on M-32: seams are bit-exact only when the cell size is a power of two, and a matrix logarithm is not obviously going to preserve that. (C1) Component-wise interpolation produces measurable determinant swell — above 5% on at least one field — and log-Euclidean does not. (C2) Log-Euclidean interpolation preserves M-32's power-of-two bit-exactness, or it does not, and which is stated as the result rather than assumed. (C3) The seam remains closed under both schemes: zero additional open edges against the existing seam counter. SHARE: C1 moves the metric-construction stage, whose share P-146 C3 reports.
Falsified by. C1 by no swell, which would mean the intrinsic scheme is unnecessary here and saves the transcendental cost. C2 by loss of bit-exactness, which would make log-Euclidean incompatible with the crate's determinism goal and is the outcome that decides the row. C3 by new open edges under either scheme. VACUITY CONTROL: the fixture must contain a seam where the two chunks' metrics genuinely differ, reported as a metric-distance column, or both schemes are interpolating between equal endpoints.
P-149 — registered for R-149, before the harness: The features where a flat direction exists, isolated and measured on their own
Ticket: R-149 (M). Records: feature_class, principal_curvature_ratio, cells, triangles_isotropic, triangles_anisotropic, saving, hausdorff_delta, saving_vs_curvature_ratio_correlation, c1_holds, c2_holds.
Hypothesis. P-146 measures the aggregate; this measures the mechanism. The AM–GM gap collapses toward zero exactly where one principal curvature vanishes, so the saving should be a function of the curvature ratio and nothing else. (C1) Binning surface cells by principal-curvature ratio, the anisotropic triangle saving is monotone in the ratio, with correlation above 0.7. (C2) Cells with ratio near 1 — spherical caps — show no saving, which is the control that says the effect is anisotropy rather than a general refinement improvement. SHARE: C1 decomposes P-146's C1 saving by feature class; the bin populations are reported so each saving has a denominator.
Falsified by. C1 by a non-monotone relationship, which would mean the saving comes from somewhere other than anisotropy. C2 by a saving on isotropic cells, same conclusion and more damning. VACUITY CONTROL: every curvature-ratio bin must be non-empty on at least one field, reported as counts, or the monotonicity is fitted through gaps.
P-150 — registered for R-150, before the harness: A null registered on purpose — the L¹ anomaly in the source's own table
Ticket: R-150 (S). Records: norm, metric, element_count, error_measured, optimal_metric_wins, anomaly_reproduced, cao_table_agreement, c1_holds, c2_holds.
Hypothesis. THIS ROW EXISTS BECAUSE THE HEADLINE NUMBER FOR GROUP D IS NOT WHAT IT LOOKS LIKE. Cao's Table 2 (10.1090/S0025-5718-07-01981-3, in corpus) does show 5.43e-7 versus 2.79e-6 at N_e ≈ 16,000 — a real 5.1× spread, and the element counts match to within 1.4%, not exactly. But the two metrics are optimised for different norms: in H¹ the ranking reverses. And Cao writes that his theory holds "in all the cases except the L¹-error of quadratic interpolation" — the L¹ column is the one place his own optimal metric does not win. Building on that column is the weakest available ground and the registration says so before anyone quotes 5.1× as a free win. (C1) On our fields, the metric optimised for a given norm wins in that norm — the property Cao's theory asserts and his L¹ column violates. (C2) Any violation we find is characterised, and the comparison is always reported within a norm, never across two. SHARE: none — this is a methodology guard.
Falsified by. C1 by a violation, which would reproduce Cao's anomaly on different data and would be a genuine contribution to a question his paper leaves open. C2 by an uncharacterisable violation. VACUITY CONTROL: at least three norms must be run, or "within a norm" is not a constraint.
P-151 — registered for R-151, before the harness: Refining where the player is looking, with forty years of theory behind it
Ticket: R-151 (M). Records: criterion, functional, triangles, screen_space_error, screen_error_at_matched_triangles, off_screen_triangles, adjoint_ms, adjoint_share, pop_magnitude_cells, c1_holds, c2_holds, c3_holds.
Hypothesis. v1's Axis 7 named goal-oriented adaptivity and nothing has used it. The dual-weighted-residual method refines to reduce error in a chosen output functional rather than globally, and for a game the functional is screen-space error under the current camera. Yano & Darmofal (in corpus, 10.2514/6.2012-79) give the optimisation framing: "both the sizing decision and the anisotropy decision are driven directly by the behavior of the a posteriori error estimate." (C1) At matched triangle count, a goal-oriented criterion beats camera-distance LOD on screen-space error by at least 20%. (C2) The saving comes from not refining what is off-screen or back-facing, reported as an off-screen triangle count, rather than from a general improvement. (C3) The adjoint cost is under 10% of extraction, or the method is a non-starter for a frame budget and should be said so. SHARE: C1 moves the LOD selection stage; M-121 measured a level change moving the surface by up to 3.14 cells, which is the pop this criterion is meant to spend better.
Falsified by. C1 by under 20%. C2 by a saving that persists with everything on-screen, which would mean the mechanism is not visibility. C3 by above 10%. VACUITY CONTROL: the camera must be positioned so that a non-trivial fraction of the scene is off-screen, reported as a fraction, or C2 cannot fire.
Group E — multiscale flatness (harmonic analysis, quantitative rectifiability)
P-152 — registered for R-152, before the harness: The β-number is the planarity assumption the QEF never checks
Ticket: R-152 (M). Records: field, resolution, beta_infinity, beta_times_diam, qef_residual, rank_correlation, cells, beta_ms, beta_share, singular_cells, c1_holds, c2_holds, c3_holds.
Hypothesis. Dual Contouring minimises squared distance to tangent planes, which silently assumes the cell's surface patch is near-planar. Jones' β_∞(Q) — the width of the thinnest slab containing the patch, over diam Q — is the formal name for that assumption and comes with theorems; Azzam & Schul's higher-dimensional Traveling Salesman Theorem (arXiv:1609.02892, acquired and indexed this session, 79 pp.) is the surface case. β is absent from the corpus and from every file in the repo. (C1) β_∞(Q)·diam(Q) is computable per cell at under 10% of extraction cost. (C2) It rank-correlates with the QEF residual above 0.7 on at least six of eight fields. (C3) IT CARRIES SIGNAL THE RESIDUAL DOES NOT: there exist cells with low residual and high β, and the count is reported — those are the cells where the plane fit is confidently wrong. SHARE: C1 moves the vertex-placement stage, whose cost M-25 puts at 3% over Surface Nets.
Falsified by. C1 by above 10%. C2 by correlation below 0.7 on three or more fields, which would mean β and the residual measure different things and C3 becomes the whole row. C3 by an empty set, which would mean β is a reparametrisation of the residual and buys a theorem but no new signal — the most likely outcome and the reason C3 exists. VACUITY CONTROL: the residual column must have non-zero variance on every field, or the correlation is against a constant.
P-153 — registered for R-153, before the harness: β against curvature against camera distance, as a refinement criterion
Ticket: R-153 (M). Records: criterion, field, triangles, hausdorff, hausdorff_at_matched_triangles, criterion_ms, rank_correlation_with_error, worst_decile_hausdorff, c1_holds, c2_holds.
Hypothesis. Three candidate refinement criteria now exist — β, estimated curvature, and camera distance — and only the third has ever been used. (C1) At matched triangle count, β-driven refinement beats camera-distance refinement on symmetric Hausdorff error on at least five of eight fields. (C2) β beats curvature specifically on fields with sub-cell structure, where curvature estimated at the cell size is aliased and β is not, because β is defined by a slab fit rather than by a derivative — thin_plate and noise_cavity are the named predictions. SHARE: C1 moves the adaptivity stage, and the triangle counts are reported so the comparison is at a fixed budget.
Falsified by. C1 by under five fields. C2 by curvature matching β on thin_plate, which would mean the aliasing argument is wrong and M-72's mechanism does not reach the criterion. VACUITY CONTROL: the worst-decile Hausdorff column must differ across criteria, or all three are refining the same cells.
P-154 — registered for R-154, before the harness: A triangle budget computed before meshing, from a convergent sum
Ticket: R-154 (M). Records: field, resolution, beta_sum, predicted_triangles, actual_triangles, prediction_error, prediction_error_ratio, sum_converges, scales_used, c1_holds, c2_holds.
Hypothesis. The Traveling Salesman Theorem's content is that ∑_Q β(Q)²·diam(Q)^d converges precisely for rectifiable sets — which turns multiscale flatness into a number computed over the whole field before any mesh exists. That is an a-priori budget, which no criterion in the crate currently provides; M-13 gives surface cells ≈ 1.5·A/h² after the fact. (C1) The β-sum predicts final triangle count within 25% on at least five of eight fields at three resolutions. (C2) The sum converges as scales are added — reported as a convergence column — because a divergent sum would mean the field is not rectifiable at the resolutions we mesh at, which would be a more interesting finding than the budget. SHARE: none — this predicts a cost, it does not change one.
Falsified by. C1 by above 25% on four or more fields, which would leave M-13's area law the better predictor and close the row. C2 by divergence, which reframes the whole thing. VACUITY CONTROL: at least four dyadic scales must be summed, or convergence cannot be observed.
Group F — reconstruction order (approximation theory)
P-155 — registered for R-155, before the harness: Predicting M-12's fitted constant instead of fitting it
Ticket: R-155 (S). Records: field, resolution_series, fitted_constant, fitted_constant_ci, predicted_constant, ratio, within_ci, strang_fix_order, measured_order, c1_holds, c2_holds.
Hypothesis. M-12 measured Marching Cubes' error falling like h² with a fitted constant, and M-113 found the fitted constant does not survive across configurations. Strang–Fix theory says the order is a property of the filter and gives a closed form for the asymptotic constant; the trilinear's order-2 is then a derivation rather than a measurement. (C1) The Strang–Fix approximation order of the tensor-product hat is 2, derived and asserted as a test, matching M-12's measured exponent. (C2) The predicted asymptotic constant reproduces M-12's fitted constant within its confidence interval on at least four of eight fields. SHARE: none — this converts a fit into a prediction.
Falsified by. C1 by a derived order other than 2, which would mean the filter is not what we think it is. C2 by the prediction missing on five or more fields, which would mean the asymptotic regime is not reached at game resolutions — a genuinely useful negative, because it would say M-12's law is empirical rather than asymptotic and should not be extrapolated. VACUITY CONTROL: the fitted constants must differ across fields by at least 2×, or the prediction is matching a universal constant by accident.
P-156 — registered for R-156, before the harness: A compact prefilter instead of a truncated recursive one
Ticket: R-156 (M). Records: prefilter, support, field, root_position_error, hausdorff, prefilter_ms, chunk_local, seam_bit_exact, hashes_moved, vs_truncated_recursive, c1_holds, c2_holds, c3_holds.
Hypothesis. ✗42/M-359 measured shifted linear interpolation and found the recursive prefilter's non-locality bounded — truncation at k ≥ 10 moves the root under 7.15e-7 cells on all eight fields — so the chunk-locality objection is already retired empirically. Quasi-interpolation achieves full approximation order with a compactly supported prefilter, making locality exact rather than bounded (Blu & Unser, 10.1006/acha.1998.0249; the corpus holds only the landing page, so the construction must be taken from a freely available restatement and that source named in the finding). (C1) A compactly supported quasi-interpolant matches the truncated recursive prefilter's accuracy to within 5%. (C2) It is exactly chunk-local — zero dependence outside the chunk, asserted structurally rather than measured. (C3) Chunk seams remain bit-exact where M-32 says they should be, and the golden hashes that move are counted, since any reconstruction change is a re-baseline. SHARE: C1 moves the vertex-interpolation stage, the crate's single most-executed operation.
Falsified by. C1 by above 5%, which would mean compactness costs accuracy and the truncated recursive filter is the better engineering answer. C2 by any external dependence, which would mean the quasi-interpolant was mis-constructed. C3 by loss of seam bit-exactness. VACUITY CONTROL: the truncated-recursive arm must reproduce ✗42's 7.15e-7 figure as a control, or the comparison has no baseline.
P-157 — registered for R-157, before the harness: Raising the order, which is the lever ✗42 did not pull
Ticket: R-157 (M). Records: filter, approximation_order, field, resolution_series, fitted_exponent, hausdorff, samples_per_cell, eval_ms, eval_share, cases_invalidated, hashes_moved, c1_holds, c2_holds, c3_holds.
Hypothesis. ✗42 tested a knot shift at fixed order and found the gain maps to root position only as a lottery over the crossing position. The untested lever is the order itself: a filter with approximation order 4 changes the exponent, not the constant, and that is a different mechanism with a different failure mode. (C1) A higher-order reconstruction gives a fitted error exponent above 3 on at least four smooth fields, against the trilinear's 2. (C2) The cost is stated honestly in the currency that matters: field evaluations per cell, and the resulting share of extraction time, because a wider stencil is more samples and samples are this crate's dominant cost on procedural fields. (C3) THE COLLATERAL IS PRICED AT REGISTRATION: the entire A-002 apparatus — the asymptotic decider, the interior test, the body-saddle algebra, and P-127's identity — is derived from the trilinear and would need re-deriving; the count of invalidated cases is a reported column, not a discovery. SHARE: C2 moves the field-evaluation stage, which M-152 puts at 2.65 ms of an 8.40 ms upload at 129³.
Falsified by. C1 by an exponent at or below 3, which would mean the order does not materialise on our fields at our resolutions. C2 by a share that makes it unaffordable regardless of accuracy. C3 by a smaller invalidation than predicted, which would be good news and should be recorded as such. VACUITY CONTROL: the trilinear arm must reproduce exponent 2 in the same harness, or the comparison is between two different measurement setups.
P-158 — registered for R-158, before the harness: A null registered on purpose — sparse grids need a regularity our sharp fields have not got
Ticket: R-158 (M). Records: field, mixed_derivative_norm, norm_finite, sparse_grid_points, full_grid_points, point_ratio, hausdorff_sparse, hausdorff_full, fields_qualifying, c1_holds, c2_holds.
Hypothesis. Sparse grids give O(h⁻¹·|log h|^(d−1)) points instead of O(h⁻ᵈ) — but only for functions with bounded mixed second derivatives (H²_mix; Bungartz & Griebel, 10.1017/s0962492904000182). This registration exists to test the hypothesis rather than the method, because the hypothesis is where it dies. (C1) The mixed-derivative norm ‖∂⁶u/∂x²∂y²∂z²‖ is measured on all eight reference fields, and is unbounded on the CSG fields — box_exact and csg_difference — where the surface has sharp edges. (C2) On the fields where it is bounded, a sparse grid reaches matched Hausdorff error with at least 2× fewer samples. SHARE: C2 moves the field-evaluation stage on qualifying fields only, and the qualifying set is C1's output.
Falsified by. C1 by a bounded norm on the CSG fields, which would be surprising and would open the method to everything. C2 by under 2× on the smooth fields, which would say the asymptotic advantage does not materialise at game resolutions — the expected outcome, and the reason this row is M rather than L. VACUITY CONTROL: sphere must show a bounded norm, or the measurement is broken rather than the fields being rough.
Group G — the denominator (information-based complexity, nonlinear approximation)
P-159 — registered for R-159, before the harness: How far from optimal the extractor is, and the null that would be worth the most
Ticket: R-159 (M). Records: field_class, regularity, n_samples, minimal_error_rate, measured_error_rate, ratio, order_optimal, constant_gap, class_assumptions, c1_holds, c2_holds, c3_holds.
Hypothesis. EVERY NUMBER IN THIS LEDGER IS A NUMERATOR. M-12's constant, F-007's 13–15%, ✗42's ratio — each says did this help and none says how much is left. Information-based complexity answers the second, and field evaluation is this crate's dominant cost, so the bound is denominated in the currency actually spent (Krieg & Ullrich, arXiv:2602.02066, acquired and indexed this session). (C1) The n-th minimal error rate for a stated regularity class is established from the literature and written down with all its hypotheses, and the class our fields plausibly belong to is named. (C2) The measured extractor error is compared against it, and the answer is stated as a ratio. (C3) IF THE MINIMAL RATE IS ALREADY Θ(h²), MARCHING CUBES IS ORDER-OPTIMAL AND ONLY THE CONSTANT IS IN PLAY — which would cap P-157 and much of Group D's ambition at "a better constant", and is the most valuable single sentence this phase could produce. SHARE: none — this is a denominator, not a saving.
Falsified by. C1 by no rate being available for any class our fields belong to, which would say IBC does not reach this problem and should be closed out. C2 by a ratio that is not computable because the class assumptions are unverifiable on procedural fields. C3 is not falsifiable — it is a branch, and both branches are recorded. VACUITY CONTROL: the class membership must be argued from a measured property of each field — a regularity estimate, reported as a column — not assumed, or the whole comparison is against a class we merely hope applies.
P-160 — registered for R-160, before the harness: Whether adaptivity beats uniform sampling, measured because the famous theorem does not apply
Ticket: R-160 (M). Records: field, sample_budget, hausdorff_uniform, hausdorff_adaptive, gain, gain_exceeds_two, class_convex, class_symmetric, operator_linear, c1_holds, c2_holds, c3_holds.
Hypothesis. IT IS TEMPTING TO CITE A BOUND HERE AND IT WOULD BE WRONG. Gal & Micchelli and Novak (10.1006/jcom.1996.0015) prove adaption improves worst-case error by at most a factor of two — under four hypotheses: the class is convex, the class is symmetric, the error is worst-case, and the solution operator is a continuous linear mapping. Level-set extraction is not a continuous linear operator on a convex symmetric class, and the same literature records gains up to order n for nonlinear problems with restricted information. So the cap does not bind and the question is empirical. (C1) At matched sample budget, octree-adaptive sampling beats uniform on symmetric Hausdorff error, and the gain is reported per field. (C2) The gain exceeds 2 on at least one field, which is the concrete demonstration that the factor-2 result does not apply here. (C3) The four hypotheses are each checked against our setting and recorded as a row of booleans, so no future reader re-imports the bound. SHARE: C1 moves the field-evaluation stage at fixed budget.
Falsified by. C1 by adaptive losing, which would be a strong argument against the whole octree line. C2 by every gain falling under 2, which would be consistent with the theorem applying after all and would send C3 back for a harder look. C3 by any hypothesis being arguably satisfied. VACUITY CONTROL: the adaptive arm must actually vary its sample density, reported as a density ratio, or both arms are uniform.
P-161 — registered for R-161, before the harness: Which approximation class each field is in, which decides whether LOD can help it at all
Ticket: R-161 (M). Records: field, s_uniform, s_adaptive, s_difference, class_membership, n_term_decay, lod_asymptotic_gain, c1_holds, c2_holds.
Hypothesis. The corpus holds four adaptive-approximation papers at 0.62–0.64 — Karkulik & Praetorius, Gaspoz & Morin, Mommer & Stevenson, and the Bonito/Canuto/Nochetto/Veeser survey — and Stevenson is cited in this repository only for the newest-vertex-bisection closure bound, never for the approximation-class theory in the same PDFs. The class A^s is the right object: if a field's s is the same under uniform and adaptive refinement, octree LOD provably buys nothing asymptotically on that field. (C1) s is estimated for both refinement strategies on all eight fields. (C2) The fields split: at least one has s_adaptive > s_uniform and at least one does not, so the answer is field-dependent and the crate can say which fields LOD is for. SHARE: none — this predicts where a stage helps, it does not change the stage.
Falsified by. C1 by s not being estimable from the achievable resolution range, which is a real risk and should close the row honestly. C2 by every field behaving alike, which would be a simpler and still useful answer. VACUITY CONTROL: at least four resolutions per field, with the fitted s carrying a confidence interval, or the split in C2 is fitted noise.
Group H — the sampling lattice (lattice theory, information theory)
P-162 — registered for R-162, before the harness: 0.257 dB is a prediction, not a hope
Ticket: R-162 (M). Records: lattice, G, samples, field, hausdorff, hausdorff_ratio, predicted_gain_db, measured_gain_db, prediction_holds, extraction_ms, case_table_size, c1_holds, c2_holds, c3_holds.
Hypothesis. G(Z³) = 1/12 = 0.0833333 and G(A₃*) = 19/(192·∛2) = 0.078543281, both verified by direct Voronoi-cell integration this session, giving a 5.748% MSE reduction, 0.2571 dB at matched point density. Barnes & Sloane (10.1137/0604005) prove A₃* optimal among 3D lattices — not among all quantizers, where the bracketing bounds remain unproven. (C1) At matched sample count, BCC sampling improves symmetric Hausdorff error over the cubic grid on at least five of eight fields. (C2) The improvement is in the neighbourhood of the predicted 0.257 dB — within a factor of 2 — or the deviation is explained, because G predicts quantization error and Hausdorff error is not that, and the gap between them is the interesting part. (C3) The cost is stated: a BCC extractor needs a different case table, and its size is reported alongside the cubic 256. SHARE: C1 moves the whole sampling stage; C3 is a complexity cost, not a runtime one.
Falsified by. C1 by under five fields. C2 by an unexplained deviation beyond 2×, which would mean G is the wrong figure of merit for surface extraction and would be worth writing down. C3 by a case table large enough to be impractical. VACUITY CONTROL: both arms must be at genuinely matched point density, reported as counts, or the comparison is a resolution change wearing a lattice's name.
P-163 — registered for R-163, before the harness: A null registered on purpose — FCC versus BCC is 0.011 dB and should be unmeasurable
Ticket: R-163 (S). Records: lattice, G, predicted_gap_db, measured_gap_db, measurement_scatter_db, gap_below_scatter, c1_holds.
Hypothesis. G(D₃) = 2^(−11/3) = 0.078745066 against G(A₃*) = 0.078543281 — a gap of 0.011 dB, about 4% of the size of the cubic-vs-BCC gap. This registration exists so that a null is on the record before somebody spends a week distinguishing them. (C1) The measured FCC–BCC Hausdorff difference is below the measurement scatter of the harness itself, reported as a scatter column from repeated runs. SHARE: none.
Falsified by. C1 by a resolvable difference, which would mean either the harness is more precise than expected — useful — or that Hausdorff error responds to something G does not capture, which is P-162 C2's question answered from the other side. VACUITY CONTROL: the harness scatter must be estimated from at least five repeated runs of the same lattice, or "below scatter" has no denominator.
P-164 — registered for R-164, before the harness: The BCC box-spline paper this project has owned and never opened
Ticket: R-164 (M). Records: filter, lattice, approximation_order, support_size, evaluations_per_cell, hausdorff, eval_ms, vs_trilinear_on_cubic, c1_holds, c2_holds.
Hypothesis. Entezari, Van De Ville & Möller, Practical box splines on the BCC lattice (10.1109/tvcg.2007.70429), is in the corpus and the 2026-08-23 sweep recorded it as "✅ (today) | 0 files" — acquired and never cited, now for a second time. It is the reconstruction half of P-162's sampling half, and the two are only meaningful together: a better lattice sampled with the wrong filter is not obviously better at anything. (C1) A BCC box spline achieves at least the trilinear's approximation order on the BCC lattice, derived and then measured. (C2) The combination — BCC lattice plus box spline — beats cubic-plus-trilinear at matched sample count by more than the lattice change alone does in P-162, which is the test of whether the two compose. SHARE: C2 moves the sampling and reconstruction stages jointly, and P-162's C1 is the baseline it is measured against.
Falsified by. C1 by a lower order, which would mean the lattice gain is paid back at reconstruction. C2 by no improvement over P-162 alone, which would mean they do not compose and the filter is doing nothing. VACUITY CONTROL: P-162 must have completed and its per-field numbers must be the reported baseline, or C2 has nothing to exceed.
Group I — optimality of greedy (combinatorial optimisation, graph theory)
P-165 — registered for R-165, before the harness: How far greedy meshing is from the optimum, which is computable in polynomial time
Ticket: R-165 (M). Records: field, resolution, vertices_n, holes_h, good_diagonals_g, optimum_rectangles, greedy_rectangles, ratio, matching_ms, optimum_ms, c1_holds, c2_holds, c3_holds.
Hypothesis. M-56 measured greedy meshing's saving over face culling at 1.70× to 256× and called it field-dependent — but never measured it against the optimum, which for a rectilinear region is a classical polynomial-time problem. Eppstein (arXiv:0908.3916, acquired and converted this session) gives it exactly: the minimum number of rectangles is n/2 + h − g − 1, where g is the maximum number of disjoint good diagonals — axis-parallel interior segments joining two concave vertices — found as a maximum independent set in a bipartite intersection graph of horizontal against vertical chords, hence by König's theorem via maximum matching, in O(n^{3/2} log n) with range searching. Independently discovered by Lipski et al. (1979), Ohtsuki (1982), and Ferrari, Sankar & Sklansky (1984). (C1) The optimum is computed on all seven fields at three resolutions. (C2) Greedy's ratio to the optimum is reported per field, turning M-56's unbounded range into a distance. (C3) The optimum's cost is under 10× greedy's, or it is a measurement instrument rather than a shippable algorithm and is labelled one. SHARE: C2 moves the greedy-meshing stage, whose saving M-56 bounds.
Falsified by. C1 by the reduction not applying — for instance if the merged regions have holes the formula's h does not model. C2 by greedy already achieving the optimum on every field, which would close M-56's question with the best possible answer. C3 by above 10×. VACUITY CONTROL: at least one field must have g > 0 and at least one h > 0, reported as columns, or the formula is being checked in its degenerate case.
P-166 — registered for R-166, before the harness: A null registered on purpose — greedy meshing is not a matroid problem, but LOD budgeting might be
Ticket: R-166 (M). Records: problem, is_matroid, is_submodular, marginal_returns_monotone, greedy_ratio, bound_applies, violating_chunks, c1_holds, c2_holds.
Hypothesis. Greedy is provably optimal on matroids and within (1−1/e) for monotone submodular maximisation under a cardinality constraint (Nemhauser, Wolsey & Fisher; paywalled, so the statement must be sourced from a freely available restatement). Greedy meshing is a minimum-cardinality cover, not a max-weight independent set, so no matroid — that half is registered as a negative. The LOD chunk budget is the other half: choose which chunks to refine under a fixed frame budget to minimise screen-space error. (C1) Greedy meshing is shown not to be a matroid problem, by exhibiting a counterexample to the exchange property. (C2) The LOD budget's marginal screen-space-error reduction is measured per chunk and shown to be diminishing — or a chunk with increasing marginal returns is exhibited, which would kill the (1−1/e) guarantee outright and is the falsifier that matters. SHARE: C2 governs the LOD selection stage, whose amortised cost M-124 tracks to within one chunk.
Falsified by. C1 by the exchange property holding, which would be a much stronger result. C2 by increasing marginal returns, which closes the guarantee — and finding one such chunk is cheaper than proving none exists, so the experiment is designed to look for it. VACUITY CONTROL: the marginal-return curve must be computed over at least 50 chunks spanning at least two LOD levels, or "diminishing" is a claim about a handful of points.
Group J — the case table as a Boolean function (Fourier analysis on the hypercube)
P-167 — registered for R-167, before the harness: The Fourier spectrum of the 256-case table, and whether it is low-degree
Ticket: R-167 (M). Records: output_bit, fourier_weight_by_degree, spectral_concentration, anf_terms, max_degree, sparse, branchless_feasible, eval_ms_table, eval_ms_spectral, c1_holds, c2_holds, c3_holds.
Hypothesis. Marching Cubes is a lookup on a Boolean function of 8 variables, and the analysis of Boolean functions has exact machinery for such objects — Walsh–Hadamard expansion, degree, spectral concentration, algebraic normal form (O'Donnell, arXiv:2105.10386, acquired and indexed this session). Absent from the corpus at 0.584 and from every file in the repo. (C1) The Walsh–Hadamard spectrum of the table, treated as a vector-valued Boolean function, is computed and its weight distribution by degree reported. (C2) The spectrum is not concentrated on low degrees — the honest prediction, since a case table encoding topology should need high-degree terms — and the ANF term count is reported so the negative is quantitative. (C3) If C2 is falsified and the spectrum is sparse, a branchless spectral evaluation is benchmarked against the table lookup. SHARE: C3 moves the classification stage, which the work-graphs result put at a 2.8–3.4× loss when moved to irregular GPU dispatch.
Falsified by. C1 by the transform not being well-defined for the vector-valued output, which would mean the framing needs per-bit treatment and should say so. C2 by concentration on low degrees, which is the good outcome and triggers C3. C3 by the spectral evaluation losing to a lookup, which is likely — a 256-entry table is already in L1. VACUITY CONTROL: a known low-degree function (parity, majority) must be run through the same transform and reproduce its known spectrum, or the instrument is unvalidated.
P-168 — registered for R-168, before the harness: A null registered on purpose — noise stability as a robustness number, and whether it predicts anything measured
Ticket: R-168 (M). Records: noise_rate, noise_stability, predicted_flip_rate, measured_flip_rate_f32, agreement, ulp_perturbation, topology_changes, field, c1_holds, c2_holds.
Hypothesis. Noise stability — the probability that a Boolean function's output survives independently flipping each input with probability ρ — is a principled measure of how robust the extracted topology is to perturbing sample values, and it is computable directly from P-167's spectrum. The question is whether it describes the perturbations this crate actually suffers. (C1) Noise stability is computed for the case table and its predicted case-flip rate at a given ρ is stated. (C2) THE PREDICTION IS TESTED AGAINST THE WRONG NOISE MODEL ON PURPOSE, AND SAID SO: f32 rounding is not independent per-corner bit flips — it is a deterministic, spatially correlated perturbation — so the predicted and measured flip rates are expected to disagree, and the size of the disagreement measures how far the independent-noise model is from this crate's reality. SHARE: none — this is a modelling check.
Falsified by. C1 by stability not being computable from the spectrum, which would send P-167 back. C2 by agreement, which would mean the independent-flip model describes f32 behaviour after all — surprising, and it would make noise stability a genuinely usable robustness number rather than a mismatched one. VACUITY CONTROL: the measured flip rate must be non-zero at some perturbation magnitude, reported as a sweep, or C2 compares two zeros.
P-169 — registered for R-169, before the harness: Which corner matters, as an influence rather than an intuition
Ticket: R-169 (S). Records: corner_index, influence, total_influence, symmetry_class, influence_equal_within_class, refinement_priority_correlation, c1_holds, c2_holds.
Hypothesis. The influence of a variable is the probability that flipping it changes the output — a per-corner number the crate could use to decide which sample to refine first, and a sanity check on the table's symmetry. (C1) All eight corner influences are computed and are equal within each octahedral symmetry class, which they must be if the table is octahedrally correct — making this a cheap independent check on validate_table(). (C2) Total influence is reported and compared against the average sensitivity a refinement heuristic would need. SHARE: none.
Falsified by. C1 by unequal influences within a symmetry class, which would be a table defect and worth the whole ticket by itself. C2 by total influence being uninformative, which is the expected outcome for a symmetric table. VACUITY CONTROL: a deliberately corrupted table must produce unequal within-class influences, or C1 cannot detect the defect it is designed for.
Group K — foundations and their hypotheses (numerical continuation, differential topology, dynamical systems)
P-170 — registered for R-170, before the harness: Marching Cubes has a 1985 ancestor, and it proves less than it is tempting to claim
Ticket: R-170 (S). Records: source, year, doi, doi_verified, claim_type, hypothesis, guarantee, is_homeomorphism, descendant_citations_in_repo, root_citations_in_repo, c1_holds, c2_holds, c3_holds.
Hypothesis. This repository cites Plantinga–Vegter in 18 files and Freudenthal/Kuhn in 6 including marching_tetrahedra/table.rs, and cites the parent theory in none. (C1) Allgower & Schmidt, An algorithm for piecewise linear approximation of an implicitly defined manifold, SIAM J. Numer. Anal. 22(2):322–346, 1985, DOI 10.1137/0722020, predates Lorensen & Cline (1987) and describes PL approximation of H⁻¹(0) by simplicial subdivision — recorded with the DOI verified, because 10.1137/0722019 is a different paper (Nanda on the QR algorithm, same volume and issue) and is the trap. (C2) THE LIMIT IS RECORDED WITH THE PRIORITY: AS85 proves ‖H(x)‖_∞ < ε along the constructed manifold under a full-rank hypothesis at the seed — a residual bound with a regularity condition, not a homeomorphism; the isotopy result for isomanifolds is Boissonnat & Wintraecken, SoCG 2020, whose own text says the earlier result holds "without a homeomorphism with the zero set of f". (C3) Dobkin, Levy, Thurston & Wilks (ACM TOG 9(4), 1990, 10.1145/88560.88575) brought PL continuation into graphics — and traces curves, not surfaces, claiming robustness and loop detection rather than topological correctness. SHARE: none — this is a citation repair and a scope statement.
Falsified by. C1 by the citation not resolving as stated. C2 by AS85 in fact proving a homeomorphism, which would make the precedence far stronger and should be checked before being claimed. C3 by DLTW covering surfaces, same. VACUITY CONTROL: each DOI must be resolved and its title recorded in the finding, not merely quoted from this document.
P-171 — registered for R-171, before the harness: How often the hypothesis every correctness theorem needs actually fails
Ticket: R-171 (M). Records: field, resolution, cells, non_transverse_cells, non_transverse_fraction, gradient_norm_min, regular_value_violations, overlap_with_ambiguous, overlap_with_defects, c1_holds, c2_holds, c3_holds.
Hypothesis. Every PL-correctness theorem — AS85's, Plantinga–Vegter's, Boissonnat–Wintraecken's — needs the isovalue to be a regular value and the surface to meet each simplex transversally. This crate has never measured how often that fails, which means it has never known which of its cells are inside the theory and which are outside it. (C1) The non-transverse fraction is measured per field per resolution and is non-zero on at least two fields. (C2) The non-transverse cells overlap the ambiguous cells substantially — rank correlation or set overlap reported — which would say the ambiguity problem and the transversality failure are the same problem seen twice. (C3) They also overlap T-001's defect cells, or they do not, and which is stated. SHARE: none — this partitions the cells into in-theory and out-of-theory, which nothing currently does.
Falsified by. C1 by zero non-transverse cells everywhere, which would mean every theorem applies everywhere and is a strong and welcome result. C2 by no overlap, which would mean they are genuinely different populations and both need handling. C3 by no overlap with defects, which would say transversality failure is harmless in practice. VACUITY CONTROL: box_exact, whose faces have exactly-equal samples, must be included, or the field most likely to violate transversality has been excluded from the census.
P-172 — registered for R-172, before the harness: A null registered on purpose — Conley index dies on plateaus, and the census says how big they are
Ticket: R-172 (M). Records: field, resolution, plateau_cells, plateau_fraction, isolating_neighbourhood_exists, conley_applicable_fraction, vs_discrete_morse_applicable, c1_holds, c2_holds.
Hypothesis. Conley index theory is a robust, computer-assisted alternative to Morse theory that tolerates degenerate critical points, and the corpus holds Dey, Haas & Lipiński on Conley–Morse persistence barcodes at 0.662. It requires an isolating neighbourhood around the invariant set, and box_exact has exactly-equal samples across whole faces, so ∇f = 0 on a set of positive measure and no isolating neighbourhood exists — the method is undefined precisely where it would be needed. (C1) The plateau fraction is measured per field, quantifying the obstruction rather than asserting it. (C2) The fraction of cells where an isolating neighbourhood exists is reported, and compared against the fraction where discrete Morse theory — already registered — applies, so the two are ranked on the same data rather than on argument. SHARE: none — this closes a candidate.
Falsified by. C1 by negligible plateaus on every field, which would revive the method and make this row a false alarm worth having raised. C2 by Conley applying more widely than discrete Morse, which would reverse the ranking. VACUITY CONTROL: box_exact must report a non-zero plateau fraction, or the obstruction this row is built on does not exist in the fixture.
Group L — is the input consistent, and is the output well shaped (discrete exterior calculus, geometric measure theory, discrete differential geometry)
P-173 — registered for R-173, before the harness: The curl of the Hermite data is the inconsistency λ = 0.01 is guessing about
Ticket: R-173 (M). Records: field, resolution, curl_residual, curl_residual_normalised, cells, second_vertex_cells, separation_auc, lambda_global, lambda_per_cell, qef_residual_delta, sharpness_delta, self_intersections_delta, curl_ms, curl_share, c1_holds, c2_holds, c3_holds.
Hypothesis. Hodge, Helmholtz, integrability and irrotational are zero across every file in this repository, and the corpus holds the machinery only as flow visualisation. A HermiteCell's ≤12 edge normals are samples of ∇f, and a true gradient field is curl-free — so the curl residual over those edges is a direct, per-cell measure of "these normals cannot come from one smooth sheet", computable in a few dozen flops on a struct the crate already builds. It has a reason to fire where the crate already hurts: CSG min/max makes the gradient discontinuous. (C1) The curl residual costs under 2% of extraction. (C2) It separates the cells M-60 says need a second vertex from those that do not — AUC above 0.8 — on gyroid and fbm_terrain, the only two fields where M-60's rate is non-zero, with the other five as a zero control. (C3) A per-cell λ derived from the residual beats the global λ = 0.01 on at least one of sharpness or self-intersection count, without losing on the other. SHARE: C1 moves the vertex-placement stage; C3 moves the same stage's quality, not its cost.
Falsified by. C1 by above 2%. C2 by AUC below 0.8, which would mean inconsistency and multi-sheet-ness are different phenomena and the residual predicts nothing M-60 cares about. C3 by the per-cell λ losing on either axis, which would vindicate the global constant and is a perfectly good result. VACUITY CONTROL: the five fields with zero second-vertex cells must be included and must report near-zero residual, or C2's separation is measured on a population with no negatives.
P-174 — registered for R-174, before the harness: A null registered on purpose — varifolds against the normal cycles already benched
Ticket: R-174 (M). Records: estimator, field, resolution, mean_curvature_error, gaussian_curvature_error, error_ratio, estimator_ms, cost_ratio, convergence_exponent, c1_holds, c2_holds.
Hypothesis. The crate's curvature estimation is the normal-cycles line — Sun & Morvan, cited in benches/experiment_p42.rs and p45.rs. Discrete varifolds (Buet, Leonardi & Masnou, 10.1007/s00205-017-1141-0, acquired and converted this session) are the rival, with quantitative convergence bounds. This is registered as a head-to-head expecting a null, because a mature estimator is rarely beaten by a newer formalism on the same data. (C1) Varifold mean curvature is compared against the normal-cycle estimator at matched cost on the analytic fields, where exact curvature is known. (C2) The convergence exponent is fitted for both, since a method that is worse at our resolutions but converges faster is a different recommendation from one that is simply worse. SHARE: C1 moves the curvature stage only, whose share must be reported.
Falsified by. C1 by varifolds winning, which would be a real result and would redirect the P-42/P-45 line. C2 by indistinguishable exponents, which would make the choice purely about constants. VACUITY CONTROL: both estimators must be run against the analytic curvature on sphere and torus and reproduce it, or neither is calibrated.
P-175 — registered for R-175, before the harness: Fixing sliver triangles without moving a single vertex
Ticket: R-175 (M). Records: field, resolution, slivers_before, slivers_after, min_angle_before, min_angle_after, flips, vertex_positions_moved, hashes_moved, extrinsic_geometry_identical, flip_ms, c1_holds, c2_holds, c3_holds.
Hypothesis. Intrinsic triangulations improve connectivity quality while leaving every vertex where it is — the corpus holds Gillespie, Sharp & Crane on integer coordinates at 0.677 and the intrinsic-parameterisation paper at 0.676, and intrinsic Delaunay, signpost and Soliman are zero in the repo. That property is unusually valuable here specifically: this crate commits 216 golden hashes on vertex positions, and a method that cannot move a position cannot move a hash. (C1) Intrinsic Delaunay flipping raises the minimum triangle angle materially — at least 10° on the worst decile — on at least four fields. (C2) Zero vertex positions move and zero position hashes move, asserted rather than assumed. (C3) THE HONEST FALSIFIER IS STATED AT REGISTRATION: intrinsic flips leave the extrinsic surface bit-identical, so if every downstream consumer reads extrinsic triangles, nothing measurable changes — and whether any consumer benefits is C3's question, answered by naming one or reporting none. SHARE: C1 moves mesh quality, not cost; C3 decides whether that quality reaches anything.
Falsified by. C1 by under 10°. C2 by any hash movement, which would mean the implementation is not intrinsic. C3 by no consumer benefiting, which closes the row and is a likely outcome worth reaching cheaply. VACUITY CONTROL: the worst-decile angle before flipping must be below 15° on at least one field, or there are no slivers to fix.
Group M — connectivity of the sign grid (probability, random fields)
P-176 — registered for R-176, before the harness: Caves connect in three dimensions in a way they cannot in two, and it is a theorem
Ticket: R-176 (M). Records: field, isovalue, components, largest_component_fraction, component_size_distribution, giant_component_exists, percolation_isovalue, two_d_slice_comparison, air_union_find_agreement, c1_holds, c2_holds, c3_holds.
Hypothesis. Duminil-Copin, Rivera, Rodriguez & Vanneuville (arXiv:2108.08008 / 10.1214/22-aop1594, acquired and converted this session, 61 pp.) prove that for smooth Gaussian fields in dimension d ≥ 3 the critical level ℓ_c(d) is strictly positive — the nodal set percolates in 3D in a regime where the 2D analogue does not. For a voxel game that is a statement about caves: at isovalue 0 the excavated region should have one giant component rather than many isolated pockets. (C1) Sweeping the isovalue on fbm_terrain and noise_cavity, a giant component appears — one component holding above 50% of the air volume — and the isovalue at which it appears is reported. (C2) The 3D behaviour differs qualitatively from a 2D slice of the same field, which is the theorem's actual content and the control that says the effect is dimensional. (C3) The measured components agree with the crate's existing Air union-find connectivity, which is an independent check on both. SHARE: none — this predicts a property of generated worlds, and M-311's union-find is the instrument.
Falsified by. C1 by no giant component at any isovalue, which for a cave generator would be a design-relevant negative — it would mean the field produces isolated pockets and connectivity must be authored rather than emergent. C2 by 2D and 3D behaving alike, which would mean our fields are too far from the theorem's Gaussian hypothesis for it to describe them — and fbm_terrain is hash-based lattice noise, not a Gaussian field, so this is a real risk and is registered as one. C3 by disagreement with the union-find. VACUITY CONTROL: the isovalue sweep must include values producing both many-small-components and one-large-component regimes, reported as a distribution, or the transition is outside the swept range.
Discovery loop — registrations minted one at a time
Not a numbered phase. docs/research/2026-09-12-discovery-loop-prompt.md mints these; the question that
produced each one, the field it came from and its corpus probe are in docs/research/questions.md, and the
belief each one is aimed at is a paragraph in docs/research/what-governs.md.
P-177 — registered for R-182, before the harness: this crate's reach has never been a number, and Theorem 3.4 says it can be one without a medial axis
Ticket: R-182 (M). Records: field, resolution, tau_local, tau_global, tau, binding_half, tau_analytic, calibration_gap_h, bottleneck_pairs, max_abs_curvature, h_star, h_star_over_tau, h_star_reachable, topology_components, euler_characteristic, second_vertex_cells, bottleneck_distance_auc, c1_holds, c2_holds, c3_holds.
Hypothesis. Aamari, Kim, Chazal, Michel, Rinaldo & Wasserman (10.1214/19-ejs1551, in the corpus and converted, 43 pp.), Theorem 3.4: for a compact submanifold with reach τ > 0, at least one of (Global Case) a bottleneck — a reach-attaining pair with ‖q₁ − q₂‖ = 2τ — and (Local Case) a point q₀ with an arc-length geodesic satisfying ‖γ₀″(0)‖ = 1/τ holds, and "the global case and the local case of Theorem 3.4 are not mutually exclusive". That theorem licenses computing this crate's reach without a medial axis, which is the only route left open: ✗27 falsified "an exactly-zero SDF gradient detects the medial axis", and M-325's discrete medial score converges only O(h). No entry in this file states the reach of a single reference field, so every resolution rung in this repository is chosen by convenience, and the sampling hypothesis V-51 sorted out — Boissonnat & Wintraecken 2020 being the corpus's only is_homeomorphism true — has never been checked against a number. (C1) The decomposition is not decorative on this roster: at least two of the eight reference fields are bottleneck-bound (tau_global < tau_local) and at least two curvature-bound (tau_local < tau_global). (C2) Reach is the denominator for resolution: over the fields with τ > 0, h_star / tau — h_star being the coarsest spacing whose extracted topology (component count and Euler characteristic) matches the finest rung's and keeps matching at every finer rung — spans a factor below 2, max / min ≤ 2. (C3) The global half locates what M-486's curl residual could not: on gyroid and fbm_terrain the cells M-60 says need a second vertex sit nearer a bottleneck axis than the other surface cells, Mann–Whitney AUC ≥ 0.8 on the statistic P-173's harness already computes. SHARE: none — τ is an offline grading instrument and nothing in the extraction path calls it.
Falsified by. C1 by all eight fields binding on the same half, which is a statement about the roster rather than about the theorem — the same defect M-459 recorded when it found this roster adversarial to global anisotropy. C2 by a spread of 2× or more, which would say the reach is not what sets resolution here and obliges the entry to name the field at each end; a spread inside 2× gives Axis 7 the denominator this ledger has never had, every accuracy number in this file being a numerator. C3 by an AUC below 0.8, which taken with M-486's 0.270443196 on fbm_terrain at 25³ would say the second-vertex cells are a local combinatorial fact of the trilinear that no geometric predictor — neither local (curl) nor global (bottleneck) — will find, and would retire that search rather than extend it. VACUITY CONTROL: the estimator is calibrated against four closed forms before any of the eight numbers is read — sphere τ = R, torus τ = min(minor radius, major − minor), capsule τ = its radius, and box_exact τ = 0 because a sharp edge has no reach. tau_analytic and tau_measured are both columns; the four must agree within 2h at the finest rung and box_exact must report tau_measured ≤ 2h, or the row is vacuous and the other four fields' numbers mean nothing. C2's h_star is recorded as unreachable rather than scored on any field whose topology never stabilises inside the ladder.
P-178 — registered for R-183, before the harness: the Gaussian kinematic formula gives an excursion set an expected χ, which is the oracle M-458 had to do without
Ticket: R-183 (M). Records: arm, field, resolution, isovalue, realisations, lambda_spectral, lambda_source, chi_digital_mean, chi_digital_sem, chi_gkf_predicted, gkf_within_band, relative_departure, band_rejects_wrong_lambda, chi_fixed_realisation, chi_convergence_gap, rungs_within_band, calibration_chi_sphere, calibration_chi_torus, c1_holds, c2_holds, c3_holds.
Hypothesis. Taylor's Gaussian kinematic formula (10.1214/009117905000000594, in the corpus and converted) gives, for a real-valued zero-mean unit-variance Gaussian field, E[χ(M ∩ f⁻¹[u, ∞))] = Σ_j L_j(M)·ρ̃_j(Id, u) with ρ̃_j(Id, u) = (2π)^(−(j+1)/2) ∫_u^∞ H_j(x) e^(−x²/2) dx, H_j the jth Hermite polynomial and L_j computed "with respect to … the metric induced by f" — so for an isotropic field on a box the Lipschitz–Killing curvatures are the box's Euclidean ones scaled by λ^(j/2), λ being the paper's μ₂, "just the variance of the first-order partial derivatives of f". That is an analytic expectation for χ of an excursion set, which is exactly the oracle M-458 did not have: it reports noise_cavity's χ as 82 at 33³ and −152 at 65³ and calls both ground truth, and CLAUDE.md's validity gate records χ rather than asserting it on every field whose expected_euler() is None. The four ρ̃_j are derived in the harness from the Hermite integrals and checked against the j = 0 case (the Gaussian tail), not transcribed. (C1) On an exactly-Gaussian fixture — random-phase Fourier synthesis with i.i.d. normal coefficients, whose λ is a closed-form sum over the mode set — the mesh-free digital-topology χ of M-458's oracle, averaged over ≥ 32 independent realisations, agrees with the prediction within two standard errors on at least 4 of 5 isovalue rungs. (C2) The shipped noise fields obey the same formula with λ estimated from their own sampled derivatives: noise_cavity and fbm_terrain at the finest rung land inside the 2σ band. (C3) χ of a fixed realisation has converged by the finest rung: between the two finest rungs the relative change is at most 0.10 on noise_cavity. SHARE: none — this is an oracle for the validity gate, not a stage of extraction.
Falsified by. C1 by the fixture missing its own prediction, which means the harness's Hermite derivation or the induced-metric scaling is wrong and nothing else in the row may be read. C2 by a band miss, which is the interesting direction: it would say this crate's hash-based lattice noise is far enough from Gaussian that the formula cannot grade it, and the entry must carry relative_departure as the number saying how far — P-176's C2 already found fbm_terrain's 2D slices percolating at 7.272575 where the Gaussian theorem says they should not, so this is a real risk and is registered as one. A band hit is equally informative and is the whole point: it hands the validity gate an analytic expected χ for two of the four fields M-459 found ungradeable. C3 by a relative change above 0.10, which would re-tier M-458: its noise_cavity numbers 82 and −152 would be two samplings of an unconverged quantity rather than two ground truths, and the 234 between them would be the evidence. VACUITY CONTROL: the band must be able to reject something. The same run predicts with a deliberately wrong spectral moment, 4λ, and records band_rejects_wrong_lambda; if the wrong prediction also lands inside the band the comparison cannot discriminate and the row is vacuous whatever the clauses say. M-458's calibration is re-taken in the same run — χ 2 on sphere and 0 on torus from the same oracle — or the oracle is not the one that entry measured.
P-179 — registered for R-184, before the harness: a transport distance needs no exact oracle, so it can grade the four fields M-459 found ungradeable
Ticket: R-184 (S). Records: field, bound_kind, resolution, h, arm, projections, sample_points, sw, sw_self, sw_displaced, displacement_ratio, hausdorff_mesh_to_field, rank_agreement, fitted_exponent, monotone, c1_holds, c2_holds, c3_holds.
Hypothesis. FORCED-EXPLORE move — the field was named before a hook was looked for, per the loop's §1, and it is optimal transport: the mathematics of comparing two measures by the cheapest way to move one onto the other. Peyré & Cuturi (10.48550/arXiv.1803.00567, in the corpus and converted) §10.4 defines the sliced Wasserstein distance SW(α,β)² = ∫_{S^d} W₂(P_θ#α, P_θ#β)² dθ, and for two equal-weight n-point clouds "this is achieved by simply sorting points". The assumption it tests is this crate's: that accuracy needs an exact distance oracle. M-459 records validate::accuracy as unmeasurable on 20 of its 40 rows, because the instrument is meaningless where field.bound() is not Exact — which leaves four of the eight reference fields with no numeric accuracy grade at all. A transport distance needs no oracle, only samples from each measure, and a dense root-set on the true zero level is samplable on every field. (C1) On the four Exact fields, SW between the area-weighted surface measure of the extracted mesh and the reference root-set falls monotonically across the whole ladder and ranks the rungs exactly as validate::accuracy's mesh-to-field mean does — rank_agreement 4 of 4. (C2) It measures geometry rather than the triangle-area distribution: the fitted exponent in SW ∝ h^p lies in [1.5, 2.5], M-12 having measured this crate's order as 2. (C3) It grades what nothing else can: on gyroid, capped_gyroid, fbm_terrain and noise_cavity, SW decreases across every rung and exceeds the self-noise floor by at least 4× on every one. SHARE: none — this is a grader, not a stage.
Falsified by. C1 by non-monotonicity or by a ranking that disagrees with the incumbent, which would say SW and Hausdorff measure different things and obliges the entry to say which one the game cares about rather than declaring a winner. C2 by an exponent near 1, which is the specific way this instrument can lie: SW is sensitive to how mass is distributed over the surface, so a mesh whose triangle areas are badly non-uniform can score badly while sitting in exactly the right place — an exponent near 1 means the number is dominated by area distribution and must not be reported as an accuracy. C3 by SW failing to separate rungs on the ungradeable four, which would close the only route this ledger has to grading them and send the question back to landing an exact bound. VACUITY CONTROL: two of them, because a distance that cannot say wrong cannot say right. First, a displaced arm — the same mesh translated by h/2 — must read at least 2× the undisplaced SW on every row. Second, sw_self, the SW between two independent reference samplings of the same surface, is the noise floor and must be at most a quarter of the smallest measured SW; if it is not, the metric cannot resolve what it is asked to rank and the row is vacuous whatever the clauses say.
P-180 — registered for R-185, before the harness: the formula's other hypothesis is stationarity, and noise_cavity is a noise field wearing a sphere
Ticket: R-185 (S). Records: field, region, resolution, isovalue, realisations, lambda_spectral, chi_digital, chi_gkf_predicted, band_sigma, gkf_within_band, sigma_distance, skewness, excess_kurtosis, cap_dominated_share, band_rejects_wrong_lambda, c1_holds, c2_holds, c3_holds.
Hypothesis. M-490 measured fbm_terrain inside the Gaussian kinematic formula's matched 2σ band at 0.25σ and noise_cavity outside it at 6.77σ, with the sign of χ wrong — 15.000000000 measured against −6.602285203 predicted. Both are hash noise, so Gaussianity alone does not separate them. The formula's hypothesis has a second half: it is stated for a field that is stationary over the set it is integrated over, and noise_cavity is Intersection(NoiseVolume, Sphere(radius 1.5)) on cube_domain(2.0) (fields/mod.rs:1237) — so outside radius 1.5 the sampled field is the sphere's distance function and not noise at all. The inscribed cube of that sphere has half-side 1.5/√3 = 0.866025404, and inside it the cap term is at most −0.633974596 and is dominated by the noise. (C1) Censused on that inscribed cap-free sub-box, with the sub-box's own λ and Lipschitz–Killing curvatures and a matched Gaussian ensemble on the same sub-box, noise_cavity lands inside its 2σ band. (C2) The same samples are Gaussian to third and fourth order: |skewness| ≤ 0.1 and |excess kurtosis| ≤ 0.2. C1 and C2 are separate instruments on one question and are allowed to disagree, which is the informative case. (C3) The restriction does not manufacture agreement: fbm_terrain, already inside on the full box, is still inside on its own inscribed sub-box, and the full-box noise_cavity row reproduces M-490's miss. SHARE: none — this decides what the validity gate may assert and on which region, not what the extractor does.
Falsified by. C1 by the sub-box missing the band too, which moves the blame from stationarity to Gaussianity: the crate's hash noise would then be non-Gaussian in a way the formula cannot grade anywhere, and C2's two moments are the measurement that says how. C2 by skewness or kurtosis outside the bars while C1 holds, which would be the more interesting failure — the formula surviving a field that is measurably not Gaussian would say the Euler characteristic is insensitive to the moments the bars are written on, and the bars would be the wrong instrument rather than the field the wrong shape. C3 by fbm_terrain falling out on its sub-box, which would mean the restriction changes the answer by itself and C1's hold, if any, proves nothing. VACUITY CONTROL: the sub-box band must reject a prediction built from 4λ at u = 0, and only at u = 0. M-490 is why the rung is named: at u = ±1 the formula's (u² − 1) factor is zero for every λ, so a control asserted over a ladder including those rungs is unsatisfiable by construction, which is exactly how M-490 came out vacuous. If the 4λ prediction at u = 0 also lands inside the band, the comparison cannot discriminate and this row is vacuous whatever the clauses say.
P-181 — registered for R-186, before the harness: nothing in this repository can certify a reach of zero, and the gradient's direction can
Ticket: R-186 (S). Records: field, probe_radius, surface_samples, max_angular_spread_deg, spread_ratio, limiting_spread_deg, flagged_sharp, tau_known, verdict_agrees, fillet_curvature_measured, fillet_curvature_expected, control_separates, c1_holds, c2_holds, c3_holds.
Hypothesis. M-491 read tau 1.000000000 on box_exact, whose reach is 0, and the failure was not arithmetic: a sharp edge is a one-dimensional subset of the surface, no marching-cubes vertex is obliged to land on one, and both halves of Theorem 3.4 answered correctly for a manifold the theorem's own hypothesis (reach > 0) excludes. Three reference fields carry sharp features — box_exact, thin_plate, and csg_difference at its cut — so every sampling theorem in this family is inapplicable to them, and the instrument that says so does not exist. It can: at a crease the field's gradient direction is discontinuous while its magnitude is not, so the angular spread of the unit gradient over a ball of radius r about a surface point converges to the dihedral angle as r falls, whereas on a C² surface it falls like r. The detector is that convergence, over a ladder of radii, with no mesh and no medial axis. (C1) The two behaviours separate: on box_exact and thin_plate the largest limiting spread is ≥ 80° and spread(r)/spread(2r) stays above 0.8 down the ladder, while on sphere, torus and capsule the spread falls with ratio ≤ 0.6 at every rung. (C2) The verdict agrees with the closed forms on all four fields whose reach is known: flagged on box_exact (τ = 0), unflagged on sphere, torus, capsule (τ > 0). (C3) The three fields M-491 measured a minute but non-zero τ on — gyroid 0.000709069, fbm_terrain 0.092099998, noise_cavity 0.000145884 — come back unflagged, which would say those numbers are real small reaches rather than zeros the estimator failed to see. SHARE: none.
Falsified by. C1 by the two families not separating, which would mean the angular spread is not the signal and a crease detector needs the mesh after all — a worse instrument, because the mesh is what the theorem is supposed to be grading. C2 by a disagreement with a closed form, which closes the route: an instrument that miscalls a known case cannot certify an unknown one. C3 by a flag on any of the three rough fields, which is the most consequential outcome available here — it would say those fields have reach exactly zero rather than merely small, that M-491's C2 spread of 2468.025804 was measuring a floor rather than a quantity, and that no positive-reach theorem applies to five of this crate's eight reference fields. VACUITY CONTROL: a synthetic pair with a known answer, built in the same harness and scored before any reference field is read — two half-planes meeting at exactly 90°, and the same wedge filleted with a blend radius of 0.05. The detector must flag the first, must not flag the second, and must recover the fillet's curvature 1/0.05 = 20 to within 10%. A detector that cannot tell a crease from a 0.05 fillet cannot certify anything, and the row is vacuous whatever the clauses say.
P-182 — registered for R-177, before the code: six prescribed-genus solids become reference fields, and the 162-hash ripple is paid in the open
Ticket: R-177 (L). Records: field, prescribed_genus, prescribed_chi, measured_chi_17, measured_chi_25, measured_chi_33, golden_entries_before, golden_entries_after, existing_hashes_changed, g5_triangles_9, c1_holds, c2_holds, c3_holds.
Hypothesis. P-140 built six closed solids whose boundary genus is fixed by their construction and derived twice — ball_drilled_g1 (genus 1, χ 0), graph_theta_g2 (2, −2), ball_drilled_g2 (2, −2), ball_drilled_g3 (3, −4), graph_k4_g3 (3, −4), graph_cube_g5 (5, −8) — and M-453 recorded them as bench-local on purpose, priced at a 162-hash ripple. This row pays it: the six fields move from benches/experiment_p140.rs into crates/isomesh/src/fields/ as no_std code generic over Real, join for_each_reference_field! as its 9th to 14th entries, and their χ is asserted by expected_euler() rather than recorded. The ripple is named in advance: golden_hashes.json grows from 216 to 378 entries (8 × 27 → 14 × 27, nine algorithm labels by three resolutions per field); scripts/doc_facts.sh's FIELDS count moves 8 → 14 and its HASHES count 216 → 378; and ten prose sites across the twelve documents that script reads change with them — README.md at three sites, CLAUDE.md, bevy_isomesh/DEMOS.md, docs/demos/algorithms.md at two, docs/demos/correctness.md, docs/experiments.md at two. (C1) expected_euler() returns Some(2 − 2g) on all six, and validate_indexed on a MarchingCubes extraction at 17, 25 and 33 samples per axis over each field's own domain reports exactly that χ, asserted in the shipped test suite. (C2) golden_hashes.json grows from 216 to exactly 378 entries with no existing line changed: the diff is additions only. (C3) graph_cube_g5's adequacy is non-monotone and pinned by a shipped test: χ −8 at 7³ and at 11³, and 0 triangles at 9³ — the values docs/experiments/p-140.csv records as measured_chi −8 / 0 / −8 with chi_agreement true / false / true. SHARE: none — this changes what the validity gate asserts, not what the extractor does.
Falsified by. C1 by any field whose extracted χ disagrees with its construction, which would mean P-140's bench-local fixtures do not survive the move to no_std generic code — a transcription defect in the port, since the derivations are one line each and were checked three ways in P-140. C2 by any pre-existing hash moving, which would mean the six additions perturbed an existing field's extraction; that is impossible by construction, since the macro appends and touches nothing above, and so would be a bug in the port and not a property of the fields. C3 by 9³ meshing something, which would say docs/experiments/p-140.csv is wrong about the one row this ticket exists to pin. VACUITY CONTROL: sphere and torus keep asserting 2 and 0 through the same suite — a chi_at helper that returned the prescribed value regardless of the field would pass C1 and fail them — and scripts/doc_facts.sh fails at the parent of the landing commit and passes at it, run once each way, so the prose counts are shown to be gated and not merely edited.
🔬 M-440 — C1, C2 and C3 all HELD: b*b - 4*a*c at marching_cubes/trilinear.rs:246 is Cayley's 2×2×2 hyperdeterminant of the eight corner values, symbolic_difference_is_zero true with symbolic_residual_terms 0 over terms_disc 12 against terms_cayley 12 at total_degree 4, all 3 axis pairings agreeing (pencil_matches 3, pencil_residual_terms 0), and max_abs_ratio_deviation exactly 0/1 over random_rational_trials 3,481 — while f32_sign_disagreements reads 14, which is what keeps R-134 alive (P-127, R-127)
M. cargo bench --bench experiment_p127, docs/experiments/p-127.csv, 3 rows across 58
columns — four # comment lines plus one column header plus 3 data rows, counted from the file.
f64/f32/i128, amd-ryzen-9-5900x-12-core (Zen 3), one thread, seed 0x01275ad1e0c4a1e9,
wall_ns 90,341,851. The header line reads # commit 8c63041 on amd-ryzen-9-5900x-12-core at
2026-08-30T09:25:19Z with no (WORKING TREE DIRTY); the dataset landed in 845c7a8
(p-127.csv - re-run on a clean tree) and git merge-base --is-ancestor 845c7a8 HEAD passes. The three
rows are the three axis pairings and nothing else varies: pencil_axis_pairing and pencil_matches are
the only registered columns that move, every other value is a global quantity carried identically on
all three rows, and the harness header says so in advance so that three identical
f32_sign_disagreements are not read as three measurements.
The expression, byte-for-byte from the expression column, and expression_cayley is byte-identical
with expression_matches true:
f3^2*f4^2-2*f2*f3*f4*f5+f2^2*f5^2-2*f1*f3*f4*f6-2*f1*f2*f5*f6+4*f1*f2*f4*f7+f1^2*f6^2
+4*f0*f3*f5*f6-2*f0*f3*f4*f7-2*f0*f2*f5*f7-2*f0*f1*f6*f7+f0^2*f7^2
Twelve monomials: four with coefficient +1 (the squares f0²f7², f1²f6², f2²f5², f3²f4²),
six with -2, two with +4. That is Cayley's canonical 4 / 6 / 2 shape exactly, in the
normalisation c1² - 4·c0·c2 with no leading minus and no sign flip — the normalisation de Silva &
Lim use, so their §6 applies to the crate's own sign convention rather than to a mirrored one.
disc_is_multi_affine is false with degree_per_corner 2|2|2|2|2|2|2|2: this is a quadratic
invariant, degree 2 in every corner, which is why Poly::eval_ratio clears denominators over degree 2
and why the exact ratio is an integer pair rather than a float.
| clause | registered | measured |
|---|---|---|
C1 b*b - 4*a*c from BodySaddles::coefficients is identically Cayley's 2×2×2 hyperdeterminant under f[u + 2v + 4w]: same 12 terms, total degree 4, symbolic difference exactly zero, asserted by a committed symbolic check |
zero residual, 12 = 12, degree 4 | HELD — symbolic_difference_is_zero true, symbolic_residual_terms 0, terms_disc 12 = terms_cayley 12, total_degree 4 = total_degree_cayley 4, coefficient_f0sq_f7sq 1. c1_holds true on 3 of 3 |
C2 the same polynomial equals disc(det(A₀ + λA₁)) for the two opposite-face 2×2 corner matrices, for all three axis pairings — the mechanism behind M-206 |
3 of 3 pairings | HELD — pencil_matches runs 1, 2, 3 over the rows with pencil_matches_here true on each, pencil_matches_total 3 = pencil_pairings_checked 3, pencil_residual_terms 0 on all three, and each pencil is itself a live object: pencil_terms 12, pencil_total_degree 4. pencil_split_axis names them w-slices (0123|4567), v-slices (0145|2367), u-slices (0246|1357). c2_holds true on 3 of 3 |
C3 in exact rational arithmetic over at least 3,000 random 8-tuples the two expressions agree with ratio exactly 1 and zero sign disagreements; in f32 they do not |
≥ 3,000 trials, ratio 1, f32 count > 0 |
HELD both ways — random_rational_trials 3,481, ratio_pairs_equal_trials 3,481 (every trial decided), ratio_exactly_one true, max_abs_ratio_deviation 0/1 as an exact reduced pair with max_abs_ratio_deviation_f64 0.000000e0, undefined_ratio_trials 0, f64_sign_disagreements 0 (_disc 0 and _cayley 0), nonfinite_evaluations 0 over exact_evals 82,663 — and f32_sign_disagreements 14, non-zero, so the falsifier "zero f32 disagreements, which would retire P-134 before it is written" misses. c3_holds true on 3 of 3 |
The
f32count is 14 and every one of them is in the constructed near-zero stratum, which is why the number means something.f32_disagreements_generalis 0 overgeneral_trials3,000 andf32_disagreements_near_zerois 14 overnear_zero_trials481 — 2.91% of the stratum, 0% of the rest.f32_sign_disagreements_discandf32_sign_disagreements_cayleyboth read 14 andf32_cross_disagreementsreads 0, which is not an independent measurement: C1 makes the two polynomials the sameBTreeMap, soPoly::eval_f32on them is bit-identical and the zero is a witness that C1 held all the way down to the float path. The sharp subset isf32_flush_to_zero_trials= 10 of the 14: anf32evaluation returning±0.0against a non-zero exact value, andtrilinear.rs:250branches ondiscriminant == R::ZEROand takes the double-root path, so on those ten tuples a cell with two real body saddles is silently re-classified as a tangency. That isP-134's subject, handed over as a count rather than as a worry.Six vacuity controls, every one of them a live number rather than a hoped-for zero (
M-44). (1) Both signs are present:positive_trials2,680,negative_trials789,zero_trials12, summing torandom_rational_trials3,481 exactly — a claim about signs over a population that had signs to get wrong. (2) The registration's own bar, "at least 50 within1e-6of zero":near_zero_trials481 againstnear_zero_floor50 atnear_zero_threshold1e-6, and 481 is alsonear_zero_constructed, so not one general-stratum draw landed in that band — a random 8-tuple with corners of size10³has|Δ|of order10¹², and had the harness relied on luck C3 would have read 0 for a reason with nothing to do with the arithmetic. (3) The stratum is constructed exactly and the construction reports its own failures:Δis a quadratic inf7alone, sonear_zero_attempts800 draws yieldednear_zero_brackets_found481 sign changes in[-4, 4]and 319 draws had none, which for a quadratic with complex roots is a real and uninteresting outcome rather than a bisection failure; every bisection step evaluates the exact rational discriminant, so the bracket is never lost to rounding. (4)bisection_max_depth22 is derived, not chosen: halving stops when one more step would push|numerator|pastf32_mantissa_limit16,777,216 and take the trial off the gridf32represents exactly. (5)inexact_f32_inputs0 — every corner value is a dyadic rational that round-tripsf32 → f64exactly, checked on every trial, so a sign disagreement is the evaluation and not the input; without it the 14 would be a restatement off32's mantissa width andP-134would inherit a number about representation. (6) The predicate itself was shown able to readfalse:corrupted_control_residual_terms1 — Cayley with itsf0²f7²coefficient bumped1 → 2differs from the repo discriminant by exactly one monomial.Poly::sub(..).is_zero()carries C1 and all of C2, so a predicate that answeredtrueunconditionally would have passed every clause in the row; this control is deliberately an assert and not a CSV row, because a row would invite being quoted as a result.
What it means that this shipped for the crate's whole life without anyone knowing. The expression at
trilinear.rs:246 is built from three coefficients assembled at :199-214 out of face twists and edge
differences, and every id the crate has ever attached to it treats it as a transcription of Grosso's
quadratic. M-207 defends the root extraction around it and says nothing about what the discriminant
is. M-214, M-215, M-216 and M-217 all build on BodySaddles::inside_count without once
asking what the sign of that discriminant is invariant under. And M-206 is the one that could not be
left alone: two independently derived constructions locate the same body saddles, to 1.1e-12 —
interior::SweptFaces solving a quadratic in the sweep height, trilinear::BodySaddles solving one
in the face coordinate, sharing no arithmetic, no coefficient and no parametrisation, and agreeing to
twelve digits. C2 is the explanation: they are two of the three slicings of one pencil, and
pencil_matches 3 with pencil_residual_terms 0 says all three slicings compute the same
degree-4 form. An unexplained correct number has become a theorem, and M-206's twelve digits are now
the f64 shadow of an exact identity rather than a coincidence.
The identity was already known and was worth nothing, which is the part worth copying. The one
artefact that proved it before this row is
docs/research/2026-08-29-phase-27-hyperdeterminant-identity.py:45-67, which writes Cayley's canonical
form out in a(i,j,k) notation and sp.expands it. It needs sympy; scripts/preflight.sh:98-101
installs markdown and pymdown-extensions into ~/.venvs/isomesh and nothing else, and no gate in the
repository names that file. So the identity had been known for exactly as long as it had been
unenforced, which is zero coverage in the only sense that matters. What replaced it is
crates/isomesh/benches/common/poly.rs — a degree-4 form in eight variables has at most 330 monomials,
so exact expansion over i128 is a hundred lines and no dependency — and this CSV is the committed
reading of it. expression is byte-identical across runs because every polynomial is a BTreeMap, every
exact comparison is on i128 integers, and every float sign goes through a helper that maps both +0.0
and -0.0 to 0 because trilinear.rs:250 does.
SHARE: zero, and zero by construction rather than by measurement. This harness reads no field,
extracts no mesh and proposes no change to crates/isomesh/src/**. Across the whole phase — from
bd4f8c4, the merge that landed the fifty registrations, to HEAD — the only change under
crates/isomesh/src/ is experiment.rs itself (+1,710 lines, the registrations), no
golden_hashes.json moved, and trilinear.rs:246 computes the same twelve-term form after this row as
before it. wall_ns is recorded because it is interesting and is read by
nothing, which is the only safe status for a nanosecond on a host whose governor swings the same binary
1.45× (M-280). What stands in a share's place is what the two exact clauses license downstream, each
over an exact denominator: symbolic_residual_terms 0 of 12, pencil_matches 3 of 3, and
random_rational_trials - ratio_pairs_equal_trials 0 of 3,481. Concretely they are what let R-128
assert the GL(2)³ weight is a square and therefore that the body-saddle count cannot depend on cell
aspect ratio; what let R-130 read real tensor rank off a sign the crate already computes, via de Silva
& Lim §6; what let R-131 treat discriminant == 0 as Det₂,₂,₂(A) = 0 and apply Prop 7.3 verbatim
rather than by analogy; and what gives R-133's exact sign something to be exact about. A consumer
of this crate should change nothing. The finding is that a shipped expression has a name, a literature,
and three equivalent derivations — and now a committed exact check standing between it and a future edit.
🔬 M-441 — C1 and C2 both HELD on 48 of 48 rows: count_disagreements, sign_disagreements and corner_value_mismatches are 0 over 7,077,888 cells at cell aspect ratios 1, 4 and 8, and the GL(2)³ weight is (det g₁ det g₂ det g₃)² as an exact i128 equality — gl2_weight_check exact_500of500|f64max_0.000e0 — so sign(Δ) is an absolute invariant, the body-saddle count is a property of the eight corner values alone, and Group D may vary cell aspect ratio without re-asking whether interior ambiguity moved under it (P-128, R-128)
M. cargo bench --bench experiment_p128, docs/experiments/p-128.csv, 48 rows across 37
columns — four # comment lines plus one column header plus 48 data rows, counted from the file.
f64 with an exact i128 arm, amd-ryzen-9-5900x-12-core (Zen 3), seed 0x0128a15ca1e50f87,
wall_ns 1,583,274,538. Header line # commit ca5c3bd on amd-ryzen-9-5900x-12-core at
2026-08-30T14:08:27Z, no (WORKING TREE DIRTY); the dataset landed in 08ce8bd
(p-128.csv - re-run on a clean tree) and git merge-base --is-ancestor 08ce8bd HEAD passes. The
fixture is eight reference fields × {33³, 65³} × three axis-scale triples — 1x1x1, 1x2x4,
1x1x8, at cell_aspect_ratio 1.000000 / 4.000000 / 8.000000 — so cells = 32,768 or 262,144 per row
and 7,077,888 over the file, of which cells_with_saddles sums to 481,035 and
saddle_count_isotropic to 605,895. The 1x1x1 rows carry is_control true, sixteen of them.
The construction is the load-bearing part, because the shipped API cannot express the registered
fixture. Extractor::extract takes a single scalar cell_size: R
(crates/isomesh/src/marching_cubes/mod.rs:193-200) — there is no per-axis cell size anywhere in the
public surface — so "meshing with per-axis cell scales (1, 2, 4)" is not an argument that exists. The
anisotropy is instead a domain reparametrisation: a bench-local AxisScaled Sdf samples the field
at (sx·x, sy·y, sz·z), which presents a cell of physical extent (h·sx, h·sy, h·sz) on a uniform
integer grid, and the anisotropic arm reads cell (i, j, k)'s eight corner values back at the
reciprocal grid point P/s. Every reference-field domain is symmetric about the origin and every
scale in the fixture is a power of two, so s·(P/s) == P bit-exactly in f64 and the two arms carry
byte-identical tensors while describing cells of different aspect ratio. That round trip is measured
rather than trusted — corner_value_mismatches 0 on 48 of 48 — which is what stops
count_disagreements = 0 from meaning "the resampling silently returned the same numbers for the wrong
reason".
| clause | registered | measured |
|---|---|---|
C1 on all eight fields at 33³ and 65³, per-axis cell scales of (1,1,1), (1,2,4) and (1,1,8) produce bit-identical body-saddle counts per cell, zero disagreements |
0 everywhere | HELD — count_disagreements 0, sign_disagreements 0 and corner_value_mismatches 0 on 48 of 48. saddle_count_isotropic equals saddle_count_anisotropic on every row (gyroid 65³ 37,653, fbm_terrain 65³ 59,521, noise_cavity 65³ 49,458, torus 65³ 15,816), and sign_delta_isotropic equals sign_delta_anisotropic as a neg|zero|pos histogram on every row — csg_difference 65³ 371|216678|45095, box_exact 65³ 0|229256|32888, gyroid 65³ 16021|0|246123. c1_holds true on 48 of 48 |
C2 for 500 random invertible g triples, Δ(g·A)/Δ(A) equals (det g₁ det g₂ det g₃)² to f64 rounding |
500 trials, ratio = weight | HELD, and stronger than registered — gl2_exact_matches 500 of 500 as an equality of two i128 products, never a quotient, so "equals" means identical integers; gl2_f64_max_deviation 0.000e0 is the registered f64 reading recorded beside it. gl2_weight_check carries both halves as exact_500of500|f64max_0.000e0, identical on all 48 rows because C2 is a property of the algebra and not of a field. c2_holds true on 48 of 48 |
The clause that actually risked something is the
GL(2)³sign census, and it is the half that is not blind by signature. C1's census compares two readings of the same tensor, so a disagreement there would be a resampling bug; the sign census applies an explicit unimodularGL(2)³triple (each determinant1, so the weight is exactly1and any drift is rounding rather than scale) to every cell's tensor throughcommon::poly::act_gl2_cubed_f64and asks whethersign(Δ)survives twelve monomials of genuine cancellation.gl2_sign_invariant_cellsreads the whole signed population on 42 of 48 rows —sphere,torus,gyroid,fbm_terrainandnoise_cavityat 32,768 and 262,144,box_exactat 4,152 and 32,888,thin_plateat 8,200 and 65,544 — withgl2_sign_variant_cells0. It is non-zero on 6 of 48, all six ofcsg_difference's rows: 2 of 5,934 at 33³ withgl2_variant_max_rel_delta1.316e-16 on each of its three scale triples, and 10 of 45,466 at 65³ with 3.424e-16 on each of its three. Those are relative magnitudes|Δ| / max|f_i|⁴, i.e. cells whose exact discriminant is already inside onef64epsilon of the vanishing locus, and the exact arithmetic that would settle them is C2's — 500 of 500 ini128.p-130.csvreads the same two counts on the same two grids from a completely different comparison (cayley_sign_disagreements2 at 33 samples and 10 at 65, bothcayley_zero_only_cells, overcells1,388 and 6,014 that equal this file'ssurface_cells), which is independent corroboration thatcsg_differencehas a handful of cells sitting on the hypersurface to within rounding and nothing else does.Five vacuity controls, and one column doing two jobs (
M-44). (1)vertex_positions_movedis 0 on all sixteen1x1x1control rows and non-zero on all thirty-two anisotropic rows, spanning 30 (thin_plate33³ at1x1x8) to 16,465 (fbm_terrain65³ at1x1x8), 77,563 over the file. Both arms are extracted withMarchingCubesunderInteriorAmbiguity::Trilinear, so the extraction really does consumeBodySaddles, and the column is the count of anisotropic vertex positions with no bit-identical counterpart in the isotropic mesh, compared as a multiset off64::to_bitstriples so the answer does not depend on emission order. A zero on the anisotropic rows would have meant the fixture never exercised anisotropy and everycount_disagreements = 0in the file was a comparison of a thing with itself; a non-zero on the identity rows would have meant the comparison was reporting noise. One column reads both ways and it reads correctly both ways. (2)cells_with_saddlesis non-zero over the fixture — 481,035 cells actually have a body saddle,gyroid65³ alone contributing 28,768 — so "bit-identical saddle counts" is not0 == 0over seven million cells. (3) Both discriminant signs are present:sign_delta_*carries non-zeronegand non-zeroposontorus65³,csg_difference,gyroidandnoise_cavity, sosign_disagreementsis a claim about signs over a population that had both. (4)gl2_singular_draws144 — singulargdraws were rejected and counted, never repaired, againstgl2_trials500, and the trial set is not degenerate in the other direction either:gl2_positive_base_trials378,gl2_negative_base_trials120,gl2_zero_base_trials2, summing to 500, withgl2_nontrivial_weight_trials500 andgl2_max_abs_weight77,440,000. (5)corner_value_mismatches0 on every row, above.
Δ = 0is not a small stratum and the census says so rather than assuming otherwise.delta_zero_cellssums to 2,167,656 of 7,077,888 — 30.6% of the fixture — and it is concentrated exactly where the field is piecewise linear:box_exact28,616 of 32,768 at 33³ and 229,256 of 262,144 at 65³,thin_plate24,568 and 196,600,csg_difference26,834 and 216,678, against 0 onsphere,torus,gyroid,fbm_terrainandnoise_cavity. A linear function has no body saddle and no twist, soa,bandcare all hard zeros there andbox_exact'ssaddle_count_isotropicis 0 at both resolutions. The sign census is deliberately taken over the cells that have a sign, and the excluded ones are counted rather than dropped:gl2_zero_delta_perturbed_cellsis 5,440 / 44,352 onbox_exact, 4,864 / 39,484 onthin_plateand 5,433 / 44,300 oncsg_difference, i.e. cells whose exact image is also zero and which any rounding at all moves off zero. Counting those as invariance failures would have reported a falsification of an invariance the cell cannot state.
One place where the CSV and the harness's own header disagree, reported rather than smoothed over.
The header at experiment_p128.rs:132-134 says c1_holds is "zero count disagreements, zero sign
disagreements, zero corner-value mismatches, and zero GL(2)³ sign variants". The code at
experiment_p128.rs:601-603 computes only the first three, and :588-600 states why in advance: the
registered falsifier is "any disagreement, which would mean the extractor's saddle path depends on
geometry the invariant says it cannot — i.e. a bug", and a unimodular image whose f64 discriminant
lands on the other side of zero on a cell already within rounding of the locus is not that. The judgement
is right and it is documented at the call site; the doc-comment four hundred lines above it is stale. The
observable consequence is that csg_difference's four rows read c1_holds true while carrying
gl2_sign_variant_cells 2 and 10, so the entry has to quote both — which this one does — rather than
letting a reader infer a clean zero from the verdict column.
SHARE: exactly zero nanoseconds, and it is a signature rather than a measurement. cell_size is not
an argument of BodySaddles::of, BodySaddles::coefficients or BodySaddles::roots, so there is no
cost for cell geometry to move, and no change to crates/isomesh/src/** is proposed. Across Phase 27 the
only change under that directory is experiment.rs's registrations and no golden_hashes.json moved.
wall_ns is in the file and is read by nothing (M-280: this host's governor swings the same binary
1.45×). What stands in a share's place is the denominator: 7,077,888 cells, each with its saddle
count and its discriminant sign compared across two cell aspect ratios and one unimodular tensor change.
What a consumer should do differently: nothing — and that is the point. The untested assumption that
Group D (R-146 … R-151) was about to lean on has been tested. sign(Δ) is an absolute invariant of
the GL(2)³ action because the relative-invariant weight is a perfect square, measured here as an
integer identity on 500 of 500 trials, and sign(Δ) is what trilinear.rs:246-250 branches on to decide
whether a cell has two real body saddles or none. So InteriorAmbiguity::Trilinear resolves the same way
at aspect ratio 8 as at aspect ratio 1, and M-206's near miss — two constructions agreeing to 1.1e-12
without anyone asking what the agreement was invariant under — now has its answer in a column.
💥 ✗99 / M-442 — C1 FALSIFIED on every conjunct at once — speedup 0.329 against a registered 10× bar, so the Δ arm is 3.04× slower, and agreement false with sweep_disagreements 251,011 of 291,592 cells — C2 HELD with negation_violations 0, C3 FALSIFIED because neither of its two registered outcomes was available; and the row's real content is that the registration assumed a Δ check costs a constant number of polynomial evaluations per cell when Δ-invariance under the cube group costs one evaluation per element, so relabellings_per_delta reads 0.980 and the bar was dead on an integer count before any clock ran (P-129, R-129)
M. cargo bench --bench experiment_p129, docs/experiments/p-129.csv, 1 row across 23
columns — four # comment lines plus one column header plus 1 data row. f64 and i128,
amd-ryzen-9-5900x-12-core (Zen 3). Header line # commit 3a1b69a on amd-ryzen-9-5900x-12-core at
2026-08-30T13:08:18Z, no (WORKING TREE DIRTY); the dataset landed in 74409e7
(p-129.csv - re-run on a clean tree) and git merge-base --is-ancestor 74409e7 HEAD passes. One row on
purpose: element reads all-48-aggregate, because both instruments are swept over all 48 octahedral
elements per cell and the registered columns are run-level totals, not per-element readings. The
population is cells_checked 291,592 — eight reference fields at CELLS = 33 cells per axis
(8 × 33³ = 287,496) plus population_synthetic 4,096 uniform draws — of which
nonzero_delta_cells is 279,570, 95.88%.
| clause | registered | measured |
|---|---|---|
C1 a Δ-based check agrees with the 48-element sweep on every cell of every reference field — zero disagreements — while costing at least 10× less |
0 disagreements and ≥ 10× | FALSIFIED on all four conjuncts. speedup 0.329 (sweep_ms 490.565315 median against invariant_ms 1491.677278 — the algebraic arm is 3.0407× slower, 30.4× short of the bar); agreement false with sweep_disagreements 251,011 of 291,592 cells, 86.08%; sweep_violations 575,076; invariant_violations 11,083,184. c1_holds false |
C2 Δ is invariant under field negation on every cell, which M-177 says reordering cannot buy for vertex placement |
0 negation violations | HELD — negation_violations 0 over 291,592 cells, bit-exactly. c2_holds true |
| C3 the invariant check catches at least one configuration class the sweep is structurally blind to, or reports honestly that it catches none | either branch of the disjunction | FALSIFIED — neither branch was available. The harness scores C3 as disagreements == 0, which is the registered "none" outcome; with 251,011 disagreements c3_token reads 251011-cells-sweep-invariant-verdict-disagree instead of none-registered-outcome. c3_holds false |
The most valuable sentence in this row is about the harness's first draft, not about the shipped code.
experiment_p129.rs:166-171records it in place: "The first condition alone is a tautology (case_of(relabel(f))andrelabel_case(case_of(f))are the same function by construction, which the first draft of this harness discovered by measuring zero violations on an asymmetric tuple)". The mechanism is exact.common::poly::relabelis a gather —out[i] = f[perm[i]](poly.rs:641-643) — so bitiofcase_of(relabel(perm, f))isf[perm[i]] < 0, which is bitperm[i]ofcase_of(f), which is exactly whatrelabel_casecomputes at:112-119. The sweep's whole subject was a function being compared against itself, and the thing that caught it was the vacuity control: a deliberately asymmetric corner tuple fed to the sweep returned zero violations, and a control that cannot report bad news is the finding. That control survives in the shipped harness at:252-263as anassert!(violations > 0)on[-1, 1, 2, 4, 8, 16, 32, 64], and it now passes. This is theM-44rule catching a harness rather than a hypothesis, which is the cheapest place it can ever fire.The correction did not go far enough, and the artefact says so if you follow the same argument one step further. The shipped sweep at
:172-189keeps two conditions: the cut-edge set comparison at:182and, at:183,CASES[moved_case].count != CASES[expected_case].count. Butmoved_caseandexpected_caseare the same integer — that is precisely what the tautology paragraph establishes — so the twoCASESlookups are the same lookup and the triangulation-count comparison cannot fire either. Every one of the 575,076sweep_violationstherefore comes from the cut-set half, and that half compares an action against its own inverse:cut_edges(relabel(perm, f))contains edge(a, b)exactly when edge(perm[a], perm[b])was cut, i.e. it isg⁻¹·cut, whilerelabel_edge(cut, perm)at:124-143maps each cut edge(a, b)forward to(perm[a], perm[b]), i.e.g·cut. Those two sets differ on any element that is not an involution on that cell's cut set, which is why the count is large (575,076 ofrelabellings13,996,416, 4.109%) and why it is not a statement about the shipped Marching Cubes table.✗49's bit-exact octahedral equivariance is not contradicted by this file and this file does not re-establish it either.The verdict is unchanged by that, and it is worth saying why rather than leaving it implied. With the direction corrected,
sweep_violationswould read 0, andsweep_disagreementscounts cells where(sweep == 0) != (invariant == 0)— so it would become the count of cells with a non-zero invariant violation, which is larger, not smaller. C1'sagreementconjunct fails harder. And thespeedupconjunct is untouched by any of it: 0.329 against 10.0.
invariant_violations11,083,184 isf64summation order and nothing else, and P-127 is why that is knowable. The count is out of 291,592 × 49 = 14,288,008 evaluations (48 relabellings plus one negation per cell); withnegation_violations0, all of it lands in the 13,996,416 relabellings — 79.19% of them. Δ is exactly invariant under all 48:p-127.csvreadssymbolic_difference_is_zerotrue withsymbolic_residual_terms0, and this harness's own first vacuity control (:231-250) re-establishes it overi128on[3, -1, 4, 1, -5, 9, -2, 6]withΔ != 0asserted first. What moves is the arithmetic:Poly::eval_f64sums twelve monomials inBTreeMapkey order, and a relabelling permutes which corner value enters which product, so the same exact integer arrives by a different rounding path. The negation arm is the controlled contrast, and it is the sharpest pair of numbers in the file. Every monomial of Cayley's form has total degree 4, sof → -fmultiplies each product by(-1)⁴ = 1exactly, magnitudes are unchanged, the summation order is unchanged, and the result is bit-identical: 0 violations. Two symmetries, one theorem, and only one of them survivesf64— the difference is entirely whether the summation order moves.So C2's zero is honest but structural, and this entry will not oversell it. The registered falsifier was "a negation violation, which would contradict the symbolic proof and send
P-127back", and that falsifier misses. But by the argument above a non-zero reading was not reachable in thef64arm, so the number is a confirmation rather than a discovery. The vacuity control that does carry weight isnonzero_delta_cells279,570: on aΔ = 0population, negation invariance would be a comparison of zeros. The other two controls held as registered — the population carries several distinct case indices (asserted>= 2at:315-320), and the broken-table control fires.
The registration's cost model was wrong, and the machine-independent column is what proves it rather
than the clock. C1's premise, verbatim from the harness header: "A Δ-based check costs a constant
number of polynomial evaluations per cell where the sweep costs 48 relabellings and case recomputations
per cell." Δ-invariance under all 48 elements is 48 evaluations per cell, one per element, plus one
for negation. relabellings_per_delta — the sweep's relabellings divided by the invariant arm's Δ
evaluations — reads 0.980: the algebraic check does more work per cell than the sweep it was to
replace. A ratio below 1 cannot become 10× on any host, and it is an integer count over a deterministic
fixture, so no governor can move it. The registration's SHARE — "C1 moves the equivariance-test stage of
CI, currently the 48-element sweep in full" — is retired, and R-129 closes on its own falsifier.
The clock corroborates rather than deciding, and it is unusually clean for this host. REPEATS
7 interleaved repeats with the warm-up excluded: sweep_ms_min 489.954371 / median 490.565315 /
sweep_ms_max 491.019299 — a 0.217% spread — against invariant_ms_min 1491.000295 / median
1491.677278 / invariant_ms_max 1500.297046, a 0.624% spread. M-280's 1.45× governor swing does
not bite here, so the 3.04× is real and not an artefact of when the two arms were sampled. Even a
best-case reading (sweep_ms_max over invariant_ms_min, 491.019 / 1491.000) is 0.329, so the bar is
missed by the same factor at either end of the band.
What a consumer should do: nothing changes, and CI keeps the sweep. Nothing in
crates/isomesh/src/** was touched by this row — across Phase 27 the only change under that directory is
experiment.rs's registrations, and no golden_hashes.json moved. What the row retires is a proposal,
not a behaviour. The scope caveat the harness header stated in advance is the reason the proposal was
always thin: Δ-invariance is a necessary condition for what the sweep tests, not the same condition —
the sweep tests the extractor's classification output while Δ tests the input's own invariant — and a
necessary condition that costs 48 polynomial evaluations per cell buys nothing over 48 table lookups.
P-127 remains exactly as strong as it was; what fails here is the attempt to spend it.
💥 ✗100 / M-443 — C1 FALSIFIED with delta_zero_share reaching 1.000000 on box_exact — every one of its surface cells sits exactly on the hyperdeterminant hypersurface — against a registered bar of 0.001, c1_zero_bar_holds false on 9 of 24 rows and c1_stability_holds false on 6 of 24 at 0.105511 against 0.05; C2 FALSIFIED and arithmetically unreachable on 24 of 24 because ambiguous = g(case) makes I(R;A) ≤ I(R;K) a data-processing inequality, with mi_gap_bits 0 to 0.988699 and never negative; C3 HELD on sphere at rank_two_share 1.000000; and rank is genuinely not a function of the case index on 9 of 24 rows, so C2's own falsifier missed too (P-130, R-130)
M. cargo bench --bench experiment_p130, docs/experiments/p-130.csv, 24 rows across 56
columns — four # comment lines plus one column header plus 24 data rows. f64,
amd-ryzen-9-5900x-12-core (Zen 3); nothing in the file is timed and there is no Instant in the
harness. Header line # commit 08ce8bd on amd-ryzen-9-5900x-12-core at 2026-08-30T14:08:32Z, no
(WORKING TREE DIRTY); the dataset landed in 277ce7b (p-130.csv - re-run on a clean tree) and
git merge-base --is-ancestor 277ce7b HEAD passes. Fixture: eight reference fields × 17 / 33 / 65
samples per axis, so grid_cells 4,096 / 32,768 / 262,144; cells is the surface-cell
population and surface_share runs 0.007812 (thin_plate at 65) to 0.296387 (gyroid at 17), summing to
104,059 surface cells over the sweep.
Which Δ this measures, because there are two f64 routes to one polynomial. Route 1 is the crate's:
BodySaddles::coefficients(&corner) at trilinear.rs:199-214, then b*b - 4.0*a*c associated exactly
as trilinear.rs:246 associates it. Route 2 is common::poly::cayley_2x2x2().eval_f64, twelve terms over
the expanded form. P-127 proved these are the same polynomial — p-127.csv,
symbolic_difference_is_zero true — and they are emphatically not the same f64 computation.
Route 1 is the measurement, because C1's subject is "a sign the crate already computes"; route 2 is a
cross-check whose disagreements can only be rounding, and it disagrees in both directions:
crate_zero_only_cells 96 / 252 / 1,800 on thin_plate (the crate returns a hard 0.0 where the
expanded sum does not) and cayley_zero_only_cells 1 / 2 / 10 on csg_difference (the other way
round), with cayley_sign_disagreements 0 on the other eighteen rows.
| clause | registered | measured |
|---|---|---|
C1 across eight fields at three resolutions the (Δ > 0, Δ < 0, Δ = 0) partition is stable and Δ = 0 is rare — under 0.1% of surface cells at f64 |
delta_zero_share < 0.001 per row, partition_share_range ≤ 0.05 per field |
FALSIFIED on both halves. c1_zero_bar_holds false on 9 of 24 rows against c1_zero_bar 0.001000: box_exact 1.000000 at 17, 33 and 65; thin_plate 0.937500 / 0.984375 / 0.996094; csg_difference 0.831081 / 0.835735 / 0.835052. It holds on the other 15, where delta_zero_share is 0.000000 exactly. c1_stability_holds false on 6 of 24 against c1_stability_bar 0.050000: gyroid partition_share_range 0.105511 and thin_plate 0.058594. c1_holds is a global verdict and is false on all 24 rows |
| C2 mutual information between rank and "this cell is ambiguous" exceeds that between rank and the 8-bit case index by a stated margin | I(R;A) - I(R;K) ≥ 0.01 bits |
FALSIFIED and UNREACHABLE on 24 of 24. c2_unreachable true, c2_holds false, c2_margin_required_bits 0.010000. mutual_information = I(R;A) is exactly 0.000000 on 18 of 24 rows and non-zero only on gyroid (0.000087 / 0.000011 / 0.000443) and noise_cavity (0.007763 / 0.003361 / 0.002834) — its maximum, 0.007763, is below the required margin on its own. mi_rank_case_index_bits = I(R;K) reaches 0.988699, mi_gap_bits = I(R;K) - I(R;A) spans 0.000000 to 0.988699 and is asserted >= 0 numerically on every row, mi_units bits_log2 |
C3 on sphere, where no cell is ambiguous, rank is 2 on essentially every surface cell |
ambiguous_cells 0 and rank_two_share ≥ 0.99 on every sphere row |
HELD at the ceiling — c3_scope sphere on 3 rows, ambiguous_cells 0, rank_two_cells 272 / 1,160 / 4,760 = cells, rank_two_share 1.000000 against c3_rank_two_bar 0.990000, rank_three_cells 0, rank_classes_present 1. c3_holds true on 24 of 24 |
C2 could not have held on any fixture, and the arithmetic is one line. In this crate ambiguity is a lookup on the case index:
AMBIGUOUS_FACES[case] != 0,marching_cubes/table.rs:202-238, derived from the case and from nothing else. WriteA = g(K). The data-processing inequality then givesI(R; A) = I(R; g(K)) <= I(R; K)for every field, every resolution and every margin, with equality exactly whengis a sufficient statistic ofKforR. No measurement could have made C2 hold, and the harness says so before it records a row (experiment_p130.rs:789-791setsc2 = falseunconditionally). What it does measure is the inequality itself, as a check on its own code rather than as a claim about the theorem:mi_gap_bitsis asserted>= -1e-9on every row with a panic message naming the mutual-information code as the thing that would be wrong. It never fired. This is recorded as unreachable with its arithmetic rather than quietly narrowed, which is the ruleP-70's C1 set.C2's own falsifier missed, and that is the salvageable result in the row. The falsifier read "rank being a function of the case index, which would make it a renaming with no new signal — the most likely outcome". It is not:
rank_is_a_function_of_case_indexis false on 9 of 24 rows —csg_difference,gyroidandnoise_cavityat all three resolutions — withrank_vs_case_index_agreement(the accuracy of the best predictor of rank from the case index,Σ_k max_r N(k,r) / cells, which reads exactly 1.0 iff rank is a function of the case index) falling to 0.820920 onnoise_cavityat 33 and 0.864086 ongyroidat 17.case_index_liftover the constant predictor reaches 0.437500 (thin_plateat 17) againstrank_majority_share0.562500 there. So real tensor rank is information the 8-bit case index does not carry; it simply is not information about ambiguity, which is a different question and the one the inequality forbids.The registered vacuity control is half unsatisfiable, and the CSV carries the failure rather than the run aborting. The control reads "
gyroidandcsg_differencemust contribute a non-zero ambiguous-cell count, or C2's mutual information is computed against a constant."csg_differencecannot contribute one.vacuity_csg_difference_ambiguous_cellsis 0,vacuity_gyroid_ambiguous_cellsis 211 (52 + 27 + 132, the half that is satisfiable),vacuity_rows_with_ambiguityis 9, andvacuity_control_as_registered_holdsis false on all 24 rows. The harness header censuses it at seven resolutions — 17, 25, 33, 49, 65, 97, 129 — andcsg_differencereads 0 at every one, as dosphere,torus,box_exactandthin_plate. The mechanism is geometric and permanent, not a resolution artefact: an ambiguous face needs two diagonal inside corners on one cell face, so the surface must cut that face into two components;csg_difference = BoxExact - Sphereis planar on the box faces, convex on the spherical bite, and joins them along a single monotone concave seam, and a curve crossing a square cuts it into two adjacent pieces, never a diagonal pair. The three fields that carry ambiguity —gyroid52 / 27 / 132,fbm_terrain16 / 30 / 58,noise_cavity193 / 502 / 567 — are exactly the three whose surfaces are not built from planes and spheres. Aborting would have discarded 24 rows of C1 and C3 over a control whose only subject, C2, is separately and structurally unreachable.What the harness enforces instead, and it is strictly sharper than the registered form (
M-44). (1) Some row must have a non-constant ambiguity variable,0 < ambiguous_cells < cells— the registered control's stated purpose, asserted directly:vacuity_rows_with_ambiguity9, andmi_against_a_constantmarks the other 15 rows per row, so a zeromutual_informationbesideentropy_ambiguous_bits0.000000 is never read as a fact about rank.entropy_ambiguous_bitsreaches 0.661945 onnoise_cavityat 17, so where the variable exists it is far from degenerate. (2) At least two distinct ranks must occur:rank_classes_presentreads 1 onsphere,torus,box_exactandfbm_terrain, 2 ongyroid,noise_cavityandthin_plate, and 3 oncsg_difference, withentropy_rank_bitsup to 0.988699. (3) Every row has at least one surface cell —cells128 at the minimum (thin_plateat 17). (4)common::poly's identity is re-asserted before any row is written, which is what makes the three Cayley cross-check columns interpretable as precision rather than as an algebra difference. (5)non_finite_samples0 on every row: aNaNcorner would make every sign comparison meaningless in a way no count would reveal. (6)degenerate_pairing_disagreements0 on 24 of 24 — the double-root test that decides theΔ = 0stratum is taken in pairing0(w-slices) and re-decided in pairings 1 and 2 on every such cell, and rank is a tensor invariant, so a disagreement would bef64incoherence and nothing else.
The falsifier named the consequence in advance and it is the finding: Δ = 0 is not a thin wall, and
on a piecewise-linear field it is the whole surface. C1's falsifier read "Δ = 0 above 0.1%, the
latter meaning the degenerate stratum is common enough that P-131 becomes urgent rather than
optional." box_exact reads max_abs_delta 0.000000e0 and min_abs_nonzero_delta inf at all
three resolutions — there is no non-zero Δ on its surface at all — and all 296 / 1,352 / 5,768 of
its surface cells classify as rank 1. thin_plate is nearly the same story from the other side: its
entire non-zero population is 8 cells at every resolution, at a single magnitude
(min_abs_nonzero_delta = max_abs_delta = 8.813477e-6 / 1.977539e-6 / 3.906250e-7), so
delta_zero_share rises with refinement, 0.937500 → 0.984375 → 0.996094, which is also why its
partition_share_range 0.058594 breaks the stability half. 16,508 of 104,059 surface cells over
the sweep are exactly on the hypersurface, 15.9%, against a registered "under 0.1%". P-131 was
registered as optional and is not.
Rank was computed, not renamed, and the theorem's two inequalities are visible as counts. Δ != 0
fixes rank by de Silva & Lim §6 — rank 2 on {Det > 0}, rank 3 on {Det < 0} — but Δ = 0 does not, so
the harness decides the stratum with exact f64 comparisons: all corners zero → rank 0; all three
flattenings of rank ≤ 1 → rank 1; the pencil quadratic identically zero → rank 2; otherwise the double
root's singular slice is zero (rank 2) or not (rank 3, the tangential orbit). Over the sweep:
0 rank-0, 15,881 rank-1, 79,939 rank-2, 8,239 rank-3, summing to cells 104,059
exactly. Against delta_positive 79,314 and delta_negative 8,237, that makes
rank_two_cells >= delta_positive and rank_three_cells >= delta_negative — the inequalities the theorem
actually gives, asserted on every row — with 625 rank-2 cells and 2 rank-3 cells found inside
the Δ = 0 wall by the classifier rather than by the sign. The two rank-3-on-the-wall cells are
csg_difference at 17 samples (rank_three_cells 9 against delta_negative 7), which is Prop
7.3's population and P-131's subject arriving unbidden in a census that was not looking for it.
SHARE: zero, discharged as registered. "C1 and C2 are counts, not timings, and move nothing." No
Instant, no shipped path changed, and across Phase 27 the only change under crates/isomesh/src/ is
experiment.rs's registrations with no golden_hashes.json moved. What a consumer should do
differently: nothing in the extractor — but anyone who was about to read tensor rank as a cheap proxy
for ambiguity should stop. The census says rank carries signal the case index does not (9 of 24 rows),
and says the case index already dominates rank at predicting ambiguity on every row by the inequality. A
rank stratification is not worth a stage for that purpose. What it is worth is a warning about the
degenerate stratum, and P-131 is where that gets spent.
🔬 M-444 — C1, C2 and C3 all HELD on 29 of 29 arms: the discriminant == 0 branch at marching_cubes/trilinear.rs:250 does fire on a reference field — csg_difference at 17 / 41 / 85 hits, c1_reference_field_hits_total 143 — and it is not the tangency the comment describes: of 3,858 branch hits, 2,222 are true rank 3 with border rank 2, two of them on csg_difference at 129³, branch_rank_one_total is 0 because rank 1 is arithmetically unreachable on that exit, and the registered W-state fixture reaches the branch with w_state_rank 3 against w_state_border_rank 2 (P-131, R-131)
M. cargo bench --bench experiment_p131, docs/experiments/p-131.csv, 29 rows across 89
columns — four # comment lines plus one column header plus 29 data rows. f64 on the reference
arms and exact f64-plus-i128 on the synthetic arms, amd-ryzen-9-5900x-12-core (Zen 3), seed
0x0000000000000131, wall_ns 2,438,302,141. Header line # commit 277ce7b on
amd-ryzen-9-5900x-12-core at 2026-08-30T14:08:40Z, no (WORKING TREE DIRTY); the dataset landed in
88a16c2 (p-131.csv - re-run on a clean tree) and git merge-base --is-ancestor 88a16c2 HEAD
passes. Fixture: eight reference fields × resolutions 33|65|129 = 24 rows at cells 32,768 /
262,144 / 2,097,152, plus five synthetic arms carrying resolution 2 — synthetic_w_state
(1 cell), synthetic_w_orbit (w_orbit_cells 2,816, an exhaustive GL(2, ℤ)³ orbit from
gl2_generators 40), synthetic_rank_one (2,048), synthetic_biseparable (6,144) and
synthetic_generic (2,048), at sampled_cells_per_stratum 2,048. Nothing here is a stopwatch;
wall_ns is read by nothing.
The subject is four lines and a comment. trilinear.rs:250-257 tests discriminant == R::ZERO and
returns one root at -b / (2a), on the grounds that "the two hyperbolas touch rather than cross".
Because of P-127 — p-127.csv, symbolic_difference_is_zero true, terms_disc 12, pencil_matches
3 — that test is exactly Det₂,₂,₂(A) = 0, so de Silva & Lim's Prop 7.3 applies verbatim rather than by
analogy: a tensor on Det = 0 is generically rank 3 with border rank 2, the W-state being the
canonical witness. A rank-3 tensor that is a limit of rank-2 tensors is not two branches touching; it is
a Jordan block in the pencil, and the comment describes the wrong object. Nothing in the repository had
ever counted how often the branch runs. This row is the count. symbolic_identity_holds true with
cayley_terms 12 and cayley_total_degree 4 is carried on every row, because if that were false
the whole framing would collapse.
| clause | registered | measured |
|---|---|---|
C1 the discriminant == 0 branch fires on at least one reference field at f64, counted per field rather than assumed zero |
≥ 1 hit on some reference field | HELD — c1_any_reference_field true, c1_reference_field_hits_total 143, entirely csg_difference: discriminant_zero_hits 17 at 33³, 41 at 65³, 85 at 129³. Every other reference field reads 0 at every resolution. c1_holds true on 29 of 29 (global by construction) |
| C2 on the cells where it fires the true configuration is classified — rank 1, 2 or 3 — and at least one is not the tangential-touch case the comment describes | ≥ 1 non-tangency | HELD — c2_global true. branch_hits_total 3,858 = border_rank_two_total 3,858, split branch_rank_two_total 1,636 + true_rank_three_total 2,222; branch_rank_one_total 0 and branch_rank_zero_total 0. On a reference field: csg_difference at 129³ carries true_rank_three 2 and w_state_like 2 among its 85 hits, while its 33³ and 65³ hits are all rank-2 biseparable (branch_rank_two_hits 17 and 41, true_rank_three 0). c2_holds true on 29 of 29 |
| C3 correcting the classification changes at least one triangle on at least one field, or provably changes none — and which is stated as the result | either limb, established | HELD on both limbs — c3_any_arm_changed true, and c3_holds (which is m2_separate_disks == 0, i.e. the mesh consequence is established) is true on 29 of 29 with m2_separate_disks 0 on every arm. The stricter falsifier reading is carried separately and is mixed: c3_mesh_changed true on 3 of 29 and c3_provably_none true on the other 26 |
mesh_delta_trianglesis non-zero on exactly three arms and zero on every reference field, and the zero is proved rather than merely observed.synthetic_w_orbit48 (m1_triangles4,936 →m2_triangles4,984,hexagon_gained24),synthetic_biseparable88 (2,619 → 2,707,hexagon_gained30),synthetic_generic4 (92 → 96,hexagon_gained1). All 24 reference-field rows readmesh_delta_triangles0 withc3_provably_nonetrue, and the derivation is in the harness header rather than in the numbers: under M2 (the double root reported with multiplicity) the six mask bits arrive in pairs, sointerior_vertex'stotalis 0, 2 or 6 and only 6 is a hexagon; under M1 (shipped) only thek = 0bits exist, sototalis at most 2 andSomeneeds all three coordinates inside. The two models therefore differ only where the double root and both its crossings lie in(0, 1)— columnhits_all_coords_inside, which reads 32 / 30 / 1 on those three synthetic arms and 0 on all 24 reference rows.hits_trilinear_eligibleis 0 on the reference rows too, so none of the 143 hits was even routed through the trilinear path (AMBIGUOUS_FACES[case] != 0and a non-empty contour set), which means those cells could not have contributed a triangle under either model. This is a documentation-level defect on the shipped reference fields and a real one on theDet = 0stratum, and both halves are in the file rather than one being chosen.The registered vacuity fixture reached the branch, and the numbers around it are the reason C2 can distinguish "no such cells exist" from "the fixture has none".
w_state_corner0|1|1|0|1|0|0|0— underf[u + 2v + 4w]that is|001⟩ + |010⟩ + |100⟩, the canonical W-state. It givesw_state_a1,w_state_b-2,w_state_c1, sob² - 4ac = 4 - 4andw_state_disc_f64is 0 witha != 0;w_state_branchreadsDiscZero, the branch at:250firing. ItsDetis exactly zero twice over, ini128and by two independent transcriptions:w_state_delta_i1280 andw_state_repo_delta_i1280. And it is really rank 3:w_state_rank3,w_state_border_rank2,w_state_local_ranks2|2|2(no flattening of rank 1),w_state_regular_pairings3. One detail worth having:w_state_double_rootis 1, the reported root'sucoordinate, which sits exactly on the boundary of(0, 1)— sodouble_root_hitsandhits_all_coords_insideare both 0 on that arm. The canonical W-state reaches the branch and sets no mask bit; it takes the orbit to move a triangle, which is whysynthetic_w_orbitis a row and not a control.Rank 1 on this branch is arithmetically unreachable, recorded with the arithmetic rather than the clause being narrowed. C2 asks for a classification into rank 1, 2 or 3. A rank-1 tensor is
f[i + 2j + 4k] = x_i·y_j·z_k, so every flattening has rank 1; in particularf4..f7 = t·(f0..f3), hencetwist_hi = t·twist_loanddu_hi = t·du_lo, hencea = du_hi·twist_lo - du_lo·twist_hiis identically zero — andtrilinear.rs:238wins before:250is ever reached.branch_rank_one_totalis 0,rank_one_reachable_on_branchis false, andsynthetic_rank_oneis the demonstration rather than the assertion: 2,048 cells,a_zero_hits2,048,discriminant_zero_hits0. The same algebra predicts a sharper asymmetry and the extras measure it:ais built fromu-direction differences, so of the three biseparable strata only the one whoseuflattening is rank 1 reaches the branch —bisep_u_branch_hits1,493 againstbisep_v_branch_hits0 andbisep_w_branch_hits0.The
a == 0exit dwarfs the discriminant exit, and the two partition the hypersurface exactly.a_zero_hitsreads 28,672 / 229,376 / 1,835,008 onbox_exact, 24,576 / 196,608 / 1,572,864 onthin_plate, 27,206 / 218,120 / 1,746,291 oncsg_differenceand 2,028,864 onfbm_terrainat 129³, against 143 discriminant hits in the whole file — so a cell witha == 0never reaches the discriminant test at all, and the registered columns are pinned to exits rather than to predicates for that reason. The identitydelta_zero_cells == discriminant_zero_hits + a_zero_no_root_hitsis asserted per arm and closes everywhere:csg_difference33³ 26,834 = 17 + 26,817, 129³ 1,740,527 = 85 + 1,740,442,box_exact33³ 28,616 = 0 + 28,616 — and that 28,616 is the same numberp-128.csvreads fordelta_zero_cellson the same grid, from a different harness. Witha == 0the discriminant isb*b, zero exactly whenbis, so the two exits cover the hypersurface and nothing falls between them.Which vacuity controls fired, and the two that keep the zeros honest (
M-44). (1) The registered one, above. (2) The strata are populated and distinct, soborder_rank_twoandtrue_rank_threeare not one column wearing two names: 3,858 against 2,222. (3) The generic arm mostly misses —synthetic_generictakes the branch on 45 of 2,048 cells, so the branch test is not a tautology, and those 45 split 2 rank-2 / 43 rank-3 withw_state_like43. (4) The classifier is two independent routes and their agreement is the check: route A reads the three2×4flattenings' exact-sign minors, route B counts regular pencil pairings over the three axis pairings, and they share no arithmetic —class_disagreements0,local_rank_anomalies0,regular_anomalies0, and on theDet = 0branchw_state_likeequalstrue_rank_threeon every arm, which is the check. (5)exact_sign_disagreements0 andentry_bound_violations0: every synthetic corner is an integer with|f_i| <= 32, soa,b,cand every2×2minor are integers below2^28and exact inf64, and Cayley's form is independently evaluated overi128by bothcayley_2x2x2andrepo_discriminantwith the sign compared against thef64discriminant on every cell. (6) The reference-field zeros are zeros that could have been non-zero where it matters and are structurally far from the branch where it does not:disc_within_one_ulpreads 2 / 6 / 11 oncsg_differenceand 0 everywhere else, andclosest_nonzero_disc_rel— the smallest|disc| / max(|b*b|, |4*a*c|)over cells witha != 0— is 1.282738e-16 / 1.288519e-16 / 1.121993e-16 oncsg_difference, about onef64epsilon, against 1.203212e0 onbox_exact, 1.158087e0–1.197131e0 onthin_plateand 4.801743e-1–6.113797e-1 onsphere. A field reading 0 hits withdisc_within_one_ulp0 is a different fact from one reading 0 hits with eleven near misses, and the file states which is which.
roots() is private, so it is mirrored — and the mirror is not trusted because it was copied
carefully. The bench transcribes BodySaddles::roots (trilinear.rs:236-267), level_crossing
(:275-280), the inside-mask loop (:180-187), inner_hexagon (:338-351), interior_vertex's
is_some() decision (:815-897), detached_ring (:1072-1105) and fan_tunnel's emission count
(:1120-1259), and on every cell of every arm compares the mirror against the shipped public surface on
raw bits (f64::to_bits) rather than with ==, because level_crossing divides by a difference that
can vanish and NaN == NaN is false — an == comparison would pass silently over exactly the cells this
row is about. All five counters read 0: mirror_u_disagreements, mirror_coordinate_disagreements,
mirror_mask_disagreements, mirror_interior_disagreements, mirror_hexagon_disagreements, plus
fan_tunnel_disagreements 0 over fan_tunnel_cross_checks_total 71. The fan_tunnel mirror C3
leans on was exercised on real six-saddle cells rather than on synthetic ones:
hexagon_control_attempts 112,290 random f64 cells yielded hexagon_control_cells 64 with six
inside saddles and hexagon_control_cross_checks 64. max_patch_triangles_seen reaches 20,
which is how a hexagon-bearing cell shows up in a triangle count.
exact_arithmetic is the disclosure column and it reads false on all twenty-four reference-field
rows. Cayley's degree-4 form in arbitrary doubles needs about 212 bits and i128 cannot hold it, so the
hit test on those rows is the crate's own f64 expression — which is correct, because C1 asks whether
the shipped branch fires at f64, not whether an exact hypersurface is met. What stays exact there is
the classification's linear algebra: every 2×2 minor goes through Kahan's error-free a*d - b*c via
f64::mul_add, one rounding of the exact value, so each minor's sign is exact.
SHARE: zero, and structurally so. mesh_delta_triangles is accumulated inside the DiscZero arm and
nowhere else, so a cell that is not one of discriminant_zero_hits cannot contribute to it — the
registration's "C3 moves only the cells C1 counts" discharged by construction rather than by argument.
No shipped path changed; across Phase 27 the only change under crates/isomesh/src/ is experiment.rs's
registrations, and no golden_hashes.json moved. What a consumer should do differently: on the eight
reference fields, nothing — the branch fires 143 times, none of those cells reaches the trilinear
emission path, and no triangle in any shipped mesh is affected. What must change is the comment. A
Det = 0 cell is generically rank 3 with border rank 2, and this file measures 2,222 of 3,858 branch
hits to be exactly that; the four-line comment at trilinear.rs:251-254 describes a tangency, which the
census finds on 1,636 hits and not on the rest. The arithmetic of the branch is right — M-207's
point stands, and reporting two roots there would let a zero-area hexagon claim six saddles — but the
justification given for it is a statement about the wrong object, and the third model the harness names
and prices (M3, refusal, the position SeparateDisks already occupies at mod.rs:429-435) is the one
the geometry actually argues for. That is a documentation fix with a measured population behind it, which
is a better thing to own than an unexamined comment.
💥 ✗101 / M-445 — C1 FALSIFIED at three of six orbit labels populated (unpopulated_orbits = zero|rank1|zero-rank2), C2 HELD hard — chi_square 445.967205 on dof 2 against critical_value_0.05 5.991, with the decomposable zero-rank1.1 stratum's defect_rate_per_orbit exactly 0.000000000 over 58,737 cells and contributing 327.649 of the 445.967 by itself — C3 HELD both ways, and the row's most reusable output is what T-001's defect population on these fields actually is: zero non-manifold edges, zero non-manifold vertices, zero self-intersecting pairs, and nothing but degenerate triangles (P-132, R-132)
M. cargo bench --bench experiment_p132, docs/experiments/p-132.csv, 3 rows across 20 columns — four # comment lines plus one column header plus three data rows, eight lines in the file, counted from it rather than from the brief; 14 of the 20 columns are P-132's registered records and the other 6 are M-273 extras. The census is eight reference fields × three resolutions (RESOLUTIONS = [17, 25, 33], experiment_p132.rs:84) over every cell, not only surface cells: cells_in_orbit sums to 405,504, which is 8 × (16³ + 24³ + 32³) exactly. f64 throughout, amd-ryzen-9-5900x-12-core. # commit 356358e on amd-ryzen-9-5900x-12-core at 2026-08-30T14:05:43Z, with no (WORKING TREE DIRTY) on that line, and landed as 767febe, "p-132.csv - re-run on a clean tree", for which git merge-base --is-ancestor 767febe HEAD passes. The three verdict columns are global, identical on all three rows: c1_holds false, c2_holds true, c3_holds true.
| clause | registered | measured |
|---|---|---|
| C1 all eight real orbits are populated across the reference fields, or the unpopulated ones are named | every orbit label populated | FALSIFIED — c1_holds false. Three labels populated: neg 71,608 cells, pos 275,159, zero-rank1.1 58,737. unpopulated_orbits names the other three verbatim: zero (Δ = 0, sorted rank (0,0,0) — the all-zero tensor), rank1 (sorted rank (0,0,1), any sign) and zero-rank2 (Δ = 0, sorted rank (0,0,2)). The clause's registered escape hatch — "or the unpopulated ones are named" — is discharged in the same column, so the falsification is the narrowing it was registered to be and not a gap |
| C2 T-001 defect rates differ significantly across orbits — chi-square against the null that defects are orbit-independent | χ² > the 0.05 critical value at the table's dof | HELD, and not marginally — chi_square 445.967205 on dof 2 against critical_value_0.05 5.991, a factor of 74.4. Rates: neg 0.004552564 (326 / 71,608), pos 0.007035932 (1,936 / 275,159), zero-rank1.1 0.000000000 (0 / 58,737). The registration's SHARE clause is satisfied by construction: each is a rate with its own denominator in the same row, never a share of a total |
| C3 the orbit partition is not a relabelling of the 256-case index: at least one case index spans two orbits and at least one orbit spans two case indices | both directions | HELD in both directions — case_spans_two_orbits true and orbit_spans_two_cases true on all three rows, so neither map is a function of the other and the orbit apparatus is not a renaming of the case table |
C2's verdict is carried almost entirely by one cell of the table, and that is the finding rather than a caveat. Under the null the expected defect counts are
cells_in_orbit× 2,262 / 405,504 — 399.447 forneg, 1,534.904 forpos, 327.649 forzero-rank1.1— and the three χ² contributions are 13.505, 104.813 and 327.649, summing to the recorded 445.967205 to all six digits. So 73.5% of the statistic is thezero-rank1.1stratum observing zero defects where the null expects 328, and the remaining 26.5% isposrunning high againstnegrunning low.zero-rank1.1isorbit_of's label for(sign Δ = 0, sorted multilinear rank (1,1,1))(experiment_p132.rs:159) — the decomposable stratum, where all three 2×4 flattenings have proportional rows, and where Cayley's form is identically zero. 58,737 cells, 14.5% of the census, and not one of them touches a defect. That is an orbit class predicting the absence of defects, which is a stronger and more useful reading than "rates differ".All three registered vacuity controls fired as assertions before the first row was written, and each of them could have aborted the run. (1) Non-zero defects in total (
experiment_p132.rs:453-459):total_defect_cells > 0, recorded asdefect_cells_in_orbit2,262 on every row — this is the run-wide figure, not a per-orbit one, and the three per-orbit counts 326 + 1,936 + 0 = 2,262 reconcile against it exactly. Without it C2 would be a chi-square on a table of zeros, which the registration names as its own failure mode. (2) Classifier self-check (:214-260): the 2×4-flattening rank function is scored against four hand-derived integer tensors before any field is sampled —zero→[0,0,0], a single entry →[1,1,1], the corner pairf0/f7→[2,2,2], and face-oppositesf0/f5→[1,2,2]— pluscayley.eval_i128on the corner pair asserted to be exactly 1, thef0·f7diagonal term of the twelve-term form. A rank function that returned a constant would pass a census and fail here. (3) Two-or-more orbits populated (:460-466):populations.len() >= 2, or the chi-square has a one-row table anddofis 0. It read three, sodofis 2 and the statistic can fire.The
negandposlabels are coarser than the harness's own header table, and that is a real limitation on what C1 falsified. The//!header (experiment_p132.rs:33-40) tabulates nine signatures —zero,rank1,rank2-sub1,mixed-12,rank2-pos/rank2-neg,rank3-pos/rank3-neg.orbit_of(:147-208) emits none of those four sign-split names: every signature with a non-zero Δ from(0,1,1)upward collapses to plainposorneg, andlet all = [...]at:471— the list C1 is scored against — has six entries, not eight or nine. So the measured statement is three of six labels reached, and the registration's "all eight real orbits" was answered against a coarser partition than the header describes. Reported, not amended (crates/isomesh/src/experiment.rs:27-31), and it is the direction that matters: a finer partition could only have left more labels unpopulated, so C1's falsification is conservative and C3's two-way spanning is unaffected.
T-001's defect population on the eight reference fields is degenerate triangles and nothing else, and this row is where that was measured. validate_features and self_intersections were run on every one of the 24 extractions here and returned zero non-manifold edges, zero non-manifold vertices and zero self-intersecting pairs on all eight fields at all three resolutions. The defect set the chi-square is taken over is therefore built from the degenerate-triangle population, detected with the crate's own rule — 2 · ValidateConfig::AREA_EPSILON_REL · h² on the cross-product magnitude, so the bench calls a triangle degenerate by exactly the predicate validate.rs:81-88 does, not by a second opinion. This is cross-confirmed by a wave-1 row that shares no code with it: docs/experiments/p-171.csv (R-171), 24 rows over 17/33/65, sums to non_manifold_edges 0, non_manifold_vertices 0, self_intersecting_pairs 0, inconsistent_edges 0 and degenerate_triangles 208 — all 208 on gyroid (4 at each of 17/33/65) and noise_cavity (54 / 68 / 74), with defect_cells 227 dilating to defect_cells_dilated 1,263. Two harnesses, two resolution ladders, one answer. Any future row that quotes a T-001 defect rate on these fields is quoting a degenerate-triangle rate, and P-132's 2,262 is that population dilated over the finer 17/25/33 ladder.
The first run of this harness measured zero defect cells on all eight fields at all three resolutions, and the vacuity control caught the instrument rather than the crate. A Marching Cubes vertex lies on a grid edge, and an interior grid edge is shared by up to four cells, so floor((p − lo) / h) per axis attributes the vertex to one of those four arbitrarily — and the one it picks is, in general, not the cell whose classification produced the defect. Attributing to the single floor cell therefore intersected the surface-cell census at an empty set while validate_features was reporting real defects one call earlier. The fix is the 2×2×2 neighbourhood of the floor cell, clamped at the lattice boundary (experiment_p132.rs:377-397) — the same up-to-four-cell sharing R-171 works with, and the reason its own file carries both defect_cells and defect_cells_dilated as separate columns. The dilation is why 2,262 cells carry a defect population whose triangle count is two orders of magnitude smaller, and it is an honest map, not an inflation: a defect is ambiguous between the cells sharing its edge, and picking one of four silently is the error the first run made.
One column in this CSV does not carry what its name says, and a reader must know it before quoting the file. nonmanifold_edges_in_orbit reads 326 / 1,936 / 0. Those are defect cells per orbit, not non-manifold edges: run.record writes the orbit's defect-cell count d into that registered slot (experiment_p132.rs:521), the three values sum to defect_cells_in_orbit 2,262, and each divided by its cells_in_orbit reproduces defect_rate_per_orbit exactly. The harness's own comment at :305-325 states the intent that the registered columns be "reported at their real values -- zero", and the code does not do that. The true non-manifold-edge count for every row of this file is 0, from the same validate_features call and independently from p-171.csv. self_intersections_in_orbit and orphaned_vertices_in_orbit read the string see column defect_cells on all three rows, which is at least self-describing. The registration is not amended; the column is reported as mislabelled and the number is reported as what it is. Related and smaller: multilinear_rank reads 0-1-1 on the zero-rank1.1 row, from a lookup table at :559, while the signature orbit_of actually matched is (0, [1,1,1]) at :159. The label is the authority; the token is wrong.
What a consumer of this crate should do differently: nothing, and the row is explicit about that. No file under crates/isomesh/src/ was touched by R-132, no golden hash moved, and the orbit classifier is bench-local — flattening_rank and multilinear_rank exist only in experiment_p132.rs. The orbit class is not computable at extraction time for free either: it needs three 2×4 rank decisions in exact i128 over the eight corner values, which is 48 minors per cell against the four operations the shipped b*b - 4*a*c costs. What the row does change is what may be claimed. sign(Δ) alone does not determine the orbit — the census confirms de Silva & Lim §7.2's correction on real data by populating a Δ = 0 label with 58,737 cells that a sign-only reading would have to fold into one of pos/neg — and orbit class is now known to be statistically related to defect rate on these fields while P-136 records, in the same phase, that sign(Δ) carries zero information about the interior verdict. Those two results are not in tension: one is about where defects concentrate, the other about which side a tunnel opens on.
SHARE, recomputed. None, and the registration asked only that C2's rates carry their denominators. Discharged literally: every row carries cells_in_orbit beside defect_rate_per_orbit, so no rate in the file is a share of a total and the three do not sum to anything. Nothing here is timed — the file contains no nanosecond, no cycle and no ratio of two clocks — so M-280's 1.45× governor swing and ✗24 cannot reach a verdict in it, and the clean-tree re-run could not have moved one. The exact i128 arithmetic is machine-independent by construction: corner values are scaled by SCALE = 2^24 and rounded to i64, and the worst |Δ| is 12 terms of max|f|⁴ ≈ 2^111.6 against i128's 2^127, an arithmetic bound rather than a margin — the first draft used 2^30 and overflowed on the gyroid's scale-8 domain, which is recorded in the constant's own doc comment (experiment_p132.rs:86-97). Every count in this file is an integer over an exactly enumerated population and is identical on any host.
Would be shown wrong by: a reference field that populates zero, rank1 or zero-rank2, which would restore C1 without touching C2 or C3 and would tell us which geometry reaches the higher-codimension strata; a finer orbit partition — the header's nine labels rather than orbit_of's six — reading a chi-square below 5.991 once pos and neg are split by rank, which would say the significance lives in the sign and not in the orbit; a resolution ladder on which zero-rank1.1 acquires a defect, which would remove three quarters of the statistic; a change to validate's degeneracy rule or to AREA_EPSILON_REL that moved the 208-triangle population, which would move the defect set both this row and p-171.csv are built on; and an extraction change that made the shipped Marching Cubes emit a single non-manifold edge on any reference field, which would falsify the sentence this entry asks every later row to quote.
💥 ✗102 / M-446 — C2 FALSIFIED, and it is falsified on an integer before any clock is read: naive_ops 27 against filter_ops 65 is op_count_ratio 2.407407, already past the registered 1.5×, and the clocks then read c2_aggregate_ratio 54.435863 because a static filter cannot certify an exactly zero Δ and three of eight fields put 84–100% of their surface cells there; C1 HELD on exactly 2 fields (fields_disagreeing_names = csg_difference|fbm_terrain) and C3 HELD on fbm_terrain alone with c3_reached_output_via_sign false on 48 of 48 (P-133, R-133)
M. cargo bench --bench experiment_p133, docs/experiments/p-133.csv, 48 rows across 71 columns — four # comment lines plus one column header plus 48 data rows, 53 lines in the file; 16 of the 71 columns are P-133's registered records and the other 55 are M-273 extras. The fixture is eight reference fields × three resolutions (33, 65, 129 samples per axis) × two scalars, and each (field, resolution) is sampled once in f64 and then rounded to f32 and widened back, so both arms see a bit-identical corner set and case_index_disagreements is 0 on all 48 rows by construction rather than by luck. The oracle is Shewchuk's expansion arithmetic (10.1007/pl00009321, the DOI real.rs:94 has cited for the crate's entire life) over the twelve monomials of common::poly::repo_discriminant(); exact_terms reads 12 on every row. # commit a7cf04b on amd-ryzen-9-5900x-12-core at 2026-08-30T14:29:39Z, no (WORKING TREE DIRTY), landed as 049714c, "p-133.csv - re-run on a clean tree", an ancestor of HEAD. All three clauses are quantified over the fixture rather than over a row — "on at least two reference fields", "in aggregate", "on at least one field" — so c1_holds/c2_holds/c3_holds carry the global verdict identically on all 48 rows and each row's own answer sits beside it as c1_row/c2_row/c3_row.
| clause | registered | measured |
|---|---|---|
C1 at f32 the sign of Δ disagrees with the exact sign on a non-zero fraction of surface cells, on at least two reference fields |
≥ 2 fields | HELD, at exactly the bar — fields_disagreeing_f32 2, fields_disagreeing_names csg_difference|fbm_terrain. csg_difference reads sign_disagreements_f32 4 / 14 / 33 at 33 / 65 / 129 over cells 1,388 / 6,014 / 24,920 (disagreement_rate 0.002881844 / 0.002327902 / 0.001324238 on the f32 rows); fbm_terrain reads 0 / 0 / 10 over 1,958 / 8,413 / 34,540, rate 0.000289519 at 129 — which is why the ladder had to reach 129 at all, since the stratum is codimension-1 and its count grows with the surface-cell count and nothing else. sign_disagreements_f64 is 0 on 46 of 48 rows and 1 on the two csg_difference 65³ rows |
C2 a filtered exact predicate costs under 1.5× the naive float evaluation in aggregate |
< 1.5× | FALSIFIED, twice over. On the op count: the naive predicate is 23 operations in coefficients (trilinear.rs:202-213) plus 4 in b*b - 4*a*c (:246) = naive_ops 27; the permanent is 8 abs plus 27 arithmetic = 35, so the filtered predicate is filter_ops 65 and op_count_ratio is 2.407407 — a property of two expression trees on any machine, already 1.6× past the bar with no clock involved. On the clocks: c2_aggregate_ratio 54.435863 = Σexact_ms 101.980201 / Σfloat_ms 1.873401 over all 48 rows, decomposing as c2_aggregate_f32 74.114977 and c2_aggregate_f64 31.998546. c2_row is false on 48 of 48; the friendliest row in the file is sphere 129³ f64 at overhead_ratio 3.691340 and the worst is thin_plate 129³ f64 at 300.878031 |
| C3 correcting the sign changes the mesh — a non-zero triangle delta or a non-zero change in T-001's non-manifold-edge count — on at least one field | ≥ 1 field | HELD on one field, fbm_terrain, and on the triangle half only — triangles_changed 6 / 10 / 12 at 33 / 65 / 129 (triangles_f32 3,970 / 16,932 / 69,172 against triangles_f64 3,976 / 16,942 / 69,184). c3_row is true on the six fbm_terrain rows and false on the other 42. nonmanifold_delta is 0 on all 48, as are nonmanifold_edges_f32 and nonmanifold_edges_f64 — the shipped Marching Cubes emits no non-manifold edge on any reference field, so that half of the clause could not have carried it |
C3 held and its mechanism did not, and the harness recorded the difference rather than letting the verdict stand for both.
c3_reached_output_via_signreads false on 48 of 48. The clause asks whether "the mesh changed"; the falsifier's interesting case is whether "the mesh changed and a Δ sign flip on a cell the trilinear path visits is why", and those are separate booleans in the file (experiment_p133.rs:1435-1449).sign_disagreements_f32_ambiguousis 0 on all 48 rows: not one of C1's 61f32sign disagreements lands on a cell that reaches the body-saddle stage.hexagon_cells_changedandjoined_mask_cells_changedare 0 on all 48. What is non-zero isinside_mask_cells_changed— 361 / 1,199 / 3,235 onfbm_terrain, 16 / 29 / 64 oncsg_difference, 1 / 4 / 8 onnoise_cavity, 2 onthin_plateat 33 — so the two precisions do disagree aboutBodySaddles::inside_mask, and they disagree through the root values rather than through the discriminant's sign. The honest reading of C3 is therefore: the mesh moves atf32, and correctingΔ's sign is not what would move it. That is the case C3's own falsifier anticipated ("the sign errors fall on cells whose classification does not reach the output") arriving as atrueverdict on the letter of the clause and afalseon its spirit, and both are in the file.The registration's vacuity control fired and every one of the harness's own controls read the way a sound instrument must. (1) The registered control — "at least one field must produce cells with
|Δ|below thef32error bound, reported as a count" — isbelow_f32_error_bound, and it is non-zero on all eight fields at all three resolutions: at 129³ it reads 8,010 / 1,798 / 23,816 / 22,324 / 8,184 / 17,060 / 1,773 / 18,314 acrosssphere,torus,box_exact,csg_difference,thin_plate,gyroid,fbm_terrain,noise_cavity. C1 is not measuring a problem the fixture excludes. (2)filter_certified_wrongis 0 on all 48 rows — the filter never certified a sign the exact expansion contradicts, over every cell of every field at both precisions, so the26ubound is measured sound and not merely derived.filter_depth_u26.0 against the derived depth-12 bound(1+u)¹² − 1 < 12.01u, givingfilter_relative_bound1.549721e-6 atf32and 2.886580e-15 atf64. (3)case_index_disagreements0 on all 48, so the two extraction arms provably saw one corner set and every triangle difference has to come from a decision downstream of the case index. (4)nonfinite_deltas0 on all 48, withmax_abs_cornerspanning 1.732051 to 9.621357 andmin_abs_nonzero_cornerdown to 1.471193e-6 — decades away from the2^±969window the Dekker–Veltkamp splits need, asserted rather than assumed.The
f64filter fails on exactly the exact-zero set and on nothing else, on all 48 rows.below_f64_error_bound == exact_zeroholds row for row: 1,352 / 5,768 / 23,816 onbox_exact, 1,162 / 5,032 / 20,875 oncsg_difference, 504 / 2,040 / 8,184 onthin_plate, and 0 on the other five fields at every resolution. This is the sharp form of the question the header sets up, and it answers cleanly: atf64the filter never gives up on cancellation, only on exact degeneracy —|Δ̂| > K·u·P̂is unsatisfiable when Δ is exactly0, no matter how cheap the filter is.filtered_fallback_rateatf64is therefore 0.000000000 onsphere,torus,gyroid,fbm_terrainandnoise_cavity, and on the other three it is exactly the exact-zero share: 1.000000000 onbox_exactat all three resolutions, 0.837175793 / 0.836714333 / 0.837680578 oncsg_difference, 0.984375000 / 0.996093750 / 0.999023438 onthin_plate.
C2's 54× is two different failures added together, and separating them is the row's most useful output. On the five fields whose Δ never vanishes, the f64 filter succeeds on 100% of cells and overhead_ratio sits in a tight band of 3.69–4.84× — sphere 3.869565 / 3.791598 / 3.691340, torus 3.932273 / 3.776620 / 3.880032, gyroid 4.178988 / 3.889140 / 3.975433, fbm_terrain 3.898701 / 3.784531 / 3.841809, noise_cavity 4.385844 / 4.737671 / 4.836655. That is the cost of a filter that always wins, and it is still 2.5× the registered bar. The other three fields are planar or polyhedral — box_exact, csg_difference and thin_plate are built from planes, so a surface cell's trilinear discriminant is identically zero — and their f64 overheads are 159.5–159.9×, 131.3–135.4× and 287.5–300.9×, because every one of those cells takes the 192-component expansion path. exact_zero is 100% of box_exact's cells, 83.7% of csg_difference's and 98.4–99.9% of thin_plate's. So the aggregate is not a measurement of Shewchuk's arithmetic being slow; it is a measurement of a static filter having nothing to certify on a plane, which is a structural fact about the predicate and not about the implementation.
The op count is what makes C2's verdict survive this machine, and that is why it is in the file. M-280 records this host's governor swinging the identical binary by 1.45×, so a clock ratio near a threshold is not a gate. Here it is not near one — 54.4 against 1.5 is not a 1.45× question — but the registration named exact_ms, float_ms and overhead_ratio and a registration is not amended to suit the instrument (crates/isomesh/src/experiment.rs:27-31), so the clocks are recorded with exact_min_ms/exact_max_ms, float_min_ms/float_max_ms, repeats 9 and overhead_ratio_scatter (0.011336 to 0.322153) beside them. The integer beside them is the durable statement: naive_ops 27, filter_ops 65, op_count_ratio 2.407407 ≥ 1.5 on every machine at every clock, forever. There is nothing to share between Δ and its permanent — twist_lo is (f0+f3) − (f1+f2) while P_tlo is |f0|+|f1|+|f2|+|f3|, and the same is true of every interior node — so unlike Shewchuk's orient2d, whose permanent is two products the value already formed, this filter is a second tree rather than an annotation on the first. A cheaper filter is conceivable; a filter that costs under 0.5× the naive predicate is not, and that is what 1.5× demanded.
SHARE, recomputed. The registration's SHARE is "C2 moves the body-saddle stage only, whose share of extraction must be reported alongside", and it is discharged as a column on every row: saddle_share = saddle_stage_ms / extract_ms, spanning 4.2e-05 to 0.006853 with a median of 0.000346. The stage this change can reach is therefore at most 0.6853% of an extraction — noise_cavity at 33³ f64, saddle_stage_ms 0.013240 against extract_ms 1.931914 — and the Amdahl arithmetic runs the wrong way from both ends: multiplying 0.6853% by the measured 54.435863 adds 36.6% to that extraction, while on the median row it adds 1.85%. So ✗51's bar bites in both directions at once — the mechanism is far too expensive to adopt unconditionally and far too small a share to be worth adopting even if it were free. extract_ms itself is recorded with extract_repeats 3 and its own min/max, and no clause reads it. What the row licenses is a narrow, correct use: an exact-sign path is affordable per cell on demand — 27 versus 65 operations on one cell is nothing — and unaffordable as a blanket replacement, and filter_certified_wrong 0 says the cheap filter is sound whenever it answers.
Two places where the file disagrees with its own header, reported and not amended. The //! header at :251-257 names a column disc_sign_cells_changed_ambiguous, "the subset of the two arms' sign disagreements that [reaches a cell the trilinear path visits]"; the CSV has disc_sign_cells_changed and sign_disagreements_f32_ambiguous and no third column, so c3_reached_output_via_sign's input is computed and recorded only as the boolean. And the header at :161-165 names f64_fallback_is_exactly_the_zero_set as a recorded column; it is not in the file, though the identity it asserts is verifiable directly — below_f64_error_bound == exact_zero on all 48 rows, which is the stronger form since a reader can check it rather than trust a boolean.
Would be shown wrong by: a filter whose permanent shares subexpressions with Δ, dropping filter_ops below 40 and making the op-count half of C2's falsification recoverable — the current tree makes that impossible, but a different discriminant expression need not; a reference field on which f64's filtered_fallback_rate is non-zero while exact_zero is zero, which would break the exact-degeneracy-only reading and mean the filter can lose to cancellation after all; any f32 sign disagreement landing on an ambiguous cell (sign_disagreements_f32_ambiguous > 0), which would let c3_reached_output_via_sign read true and turn C3 from a letter-of-the-clause pass into a mechanism; a third field acquiring sign_disagreements_f32 > 0 at a resolution above 129, which would strengthen C1 past its bar and say the stratum is denser than this ladder can see; and an extraction change that made nonmanifold_edges_f32 or nonmanifold_edges_f64 non-zero, which would give C3's second half a population it currently does not have on any reference field.
💥 ✗103 / M-447 — C2 FALSIFIED at 3 of 8 fields above the 0.50 bar against a registered 4 (c2_fields_above_bar 3, c2_min_fields 4, decided at c2_resolution 65), and box_exact is arithmetically excluded rather than counted as a miss — delta_magnitude_variance 0.000000000e0 over its 1,352 surface cells because a polyhedron's |Δ| / (max|fᵢ|)⁴ is identically 0, so correlation_population is 7; C1 HELD exactly, scale_error_dyadic 0.000000000e0 on 16 of 16 with the non-dyadic and octahedral arms at worst 0.156802 of their rounding envelope (P-134, R-134)
M. cargo bench --bench experiment_p134, docs/experiments/p-134.csv, 16 rows across 74 columns — four # comment lines plus one column header plus 16 data rows, 21 lines in the file; 11 of the 74 columns are P-134's registered records and the other 63 are M-273 extras. Eight reference fields × two resolutions, resolution counting samples so cells is (n − 1)³ = 32,768 and 262,144 exactly; 129³ is deliberately absent because the per-cell Hausdorff spends about 340 field samples per surface cell against a surface-cell count quadratic in the resolution, and the clause turns on a rank correlation rather than on a rate. f64 throughout, amd-ryzen-9-5900x-12-core. # commit 1eb925d on amd-ryzen-9-5900x-12-core at 2026-08-30T14:10:25Z, no (WORKING TREE DIRTY), landed as 520b57b, "p-134.csv - re-run on a clean tree", an ancestor of HEAD. C1 is per-row and reads true on all 16; C2 is global — the clause counts fields — and reads false on all 16, decided at the finer grid with the coarser one settled beside it.
| clause | registered | measured |
|---|---|---|
C1 the normalised magnitude is invariant under scaling all eight corner values, to f64 rounding, and under the 48 octahedral elements |
scale_error_dyadic exactly 0 and scale_error_rounding_units ≤ 1, per row, over all 60 transforms |
HELD on 16 of 16, and the two halves answer different questions. Dyadic: scale_error_dyadic is 0.000000000e0 on every row — rescaling a binary float by an exact power of two does not touch its mantissa, so a non-zero there would have been genuine scale dependence and the registered falsifier. Non-dyadic and octahedral: scale_invariance_error peaks at 2.664535259e-15 (gyroid 33, noise_cavity 33 and 65) and scale_error_rounding_units — that worst disagreement divided by ROUNDING_ENVELOPE · u · S with ROUNDING_ENVELOPE 64 — peaks at 0.156802 on fbm_terrain at 65, i.e. 6.4× inside a bound that is itself 1.6× of headroom over a worst case. transforms_per_cell 60 (4 dyadic + 8 non-dyadic spanning six decades + octahedral_elements 48) on every row |
| C2 the magnitude rank-correlates with per-cell symmetric Hausdorff error above 0.5 on at least four of eight fields | ≥ 4 fields at the bar 0.50 |
FALSIFIED — c2_fields_above_bar 3 against c2_min_fields 4, at c2_resolution 65. Above the bar: gyroid 0.742686, csg_difference 0.674217, noise_cavity 0.599755. Below it: fbm_terrain 0.249949, torus 0.211601, sphere 0.186149, and thin_plate at −0.926920. box_exact reads 0.000000 and is not in the population at all. The coarser grid settles the same way and by a wider margin: at 33 only gyroid 0.689276 clears the bar, with csg_difference 0.491836 and noise_cavity 0.475842 just under it |
box_exact's clause is not failed, it is arithmetically unreachable, and the row records that with its arithmetic —P-70's C1 precedent.box_exactis a polyhedron, so every surface cell's eight corner values are samples of a piecewise-linear function whose trilinear discriminant vanishes identically; the measured column is not merely small but exactly constant.delta_magnitude(the median) 0.000000000e0,delta_magnitude_mean0.000000000e0,delta_magnitude_min0.000000000e0,delta_magnitude_max0.000000000e0, anddelta_magnitude_variance0.000000000e0 — oversurface_cells1,352 at 33 and 5,768 at 65, withpaired_cells764 and 3,068 carrying triangles. A rank correlation against a constant is not a low correlation; it is not a number. Every one of the 1,352 cells ties, so the Spearman ranks are all equal and any value the arithmetic produces is an artefact of the tie-breaking rule. So the field is excluded, and the exclusion is columns rather than prose:in_correlation_populationfalse,exclusion_reasonconstant-normalised-magnitude-polyhedral-field,correlation_population7 on every row of the file. Three consequences worth stating. (i) The exclusion does not rescue or change C2's verdict — 3 of 8 and 3 of 7 both fall short of 4, so the falsification is a property of the six non-degenerate fields that scored under the bar and not of the degenerate one. (ii) The registration's own vacuity control passes onbox_exact— it demands non-zero variance in the Hausdorff column, andhausdorff_variancethere is 1.497206345e-3 at 33 and 2.138711097e-4 at 65 — so the degeneracy is on the side the registration did not anticipate, which is exactly why a second control had to be added rather than the first one reused. (iii) The guard is written as a population assertion, not a per-field one (experiment_p134.rs:1336-1348):correlation_population >= C2_MIN_FIELDS, 7 ≥ 4. A per-field assert would have refused the whole run over a property of one polyhedron.Six vacuity controls fired, every one of them an assertion ahead of the first
run.record. (1) Per-row Hausdorff variance — the registration's own words — non-zero on all 16, minimum 2.594543450e-7 (sphereat 65). (2) Per-rowmin_denominator > 0, so(max|fᵢ|)⁴is never a zero denominator: minimum 2.968002523e-2 (noise_cavityat 65). (3)cells_without_true_surface_points0 on all 16 — a cube's 12 edges connect all 8 corners, so a cell with a sign change always has a straddling segment and direction B is never empty; asserted rather than assumed. (4) Direction B must win somewhere or the symmetric Hausdorff is direction A wearing a longer name —cells_where_b_dominatessums to 49,709 run-wide and is non-zero on all 16 rows (400 to 13,420). (5) Some transform must actually move the magnitude, or C1's zeros areM-44zeros —nonzero_transform_deviationssums to 4,186,521, and it reads 0 on bothbox_exactrows precisely because their magnitude is the constant0, which is why the control is global. (6) Some cell must carry a validity feature, or everyrank_correlation_with_defectsis against a constant —defect_cellstotals 571 run-wide, all of it onfbm_terrain(185 at 33, 386 at 65).The defect column is live on exactly one field and it is not measuring a defect.
nonmanifold_featuresandmisoriented_featuresare 0 on all 16 rows — the shipped Marching Cubes emits no non-manifold edge, no non-manifold vertex and no inconsistently-oriented edge on any reference field, whichdocs/experiments/p-171.csvreports independently over 17/33/65.fbm_terrain's entire feature population isboundary_features190 and 390, andfbm_terrainhasclosed_in_domain() == false: those are the field leaving the box, not a defect. Sorank_correlation_with_defectsreads 0.000000 on 14 rows and 0.058808 / 0.045591 on the twofbm_terrainrows, and the correct reading of the whole column is "there was almost nothing to correlate against" rather than "the magnitude does not predict defects". This is why the harness carries two further correlations beside it:rank_correlation_with_ambiguous_facesagainst the popcount ofAMBIGUOUS_FACES[case]— a pure function of the sign pattern and therefore not a function of|Δ|— reading at most 0.216377 (noise_cavityat 33), andrank_correlation_with_uncertifiedagainst the negation of Plantinga–Vegter'svalidate::cell_is_certified, reading 0.511743 / 0.421040 onnoise_cavity, 0.330743 / 0.284509 ongyroid, and −0.066258 / −0.067052 oncsg_difference.
thin_plate's −0.926920 is the number in this file most likely to be mis-quoted, and it needs one column beside it. thin_plate is a pair of planes, so its magnitude column is a hair off constant rather than constant: delta_magnitude (median) 4.235164736e-17 at 65, threshold_sweep 1e-8:8|1e-6:8|1e-4:8|1e-2:8|1e-1:0 — eight of 2,048 surface cells above 1e-8, and the same eight all the way up to 1e-2. Its delta_magnitude_variance is 1.519918442e-5, non-zero, so it survives the exclusion test and stays in the population, and its strong negative correlation is 2,040 tied cells at machine-zero against eight outliers. Read as "ambiguity magnitude anti-predicts error on thin plates" it is nonsense; read with cells_above_threshold 8 beside it, it is the same statement box_exact makes, one epsilon short of triggering the exclusion. The other planar field behaves the same way and clears the bar for the same non-reason: csg_difference's median magnitude is 0.000000000e0 at both resolutions with cells_above_threshold 181 and 616, and its 0.674217 is a correlation carried by a small minority of live cells.
C1's threshold prediction was registered as arithmetic and came back exactly as predicted, on all 16 rows. f32_rounding_floor is re-derived per row as 30 · (f32::EPSILON / 2) · cayley_l1_norm and reads 4.291534e-5, with cayley_l1_norm 24, cayley_terms 12 and cayley_total_degree 4 read off common::poly::cayley_2x2x2() on every run rather than quoted. headline_threshold is that floor rounded up to the decade, 1e-4, and the prediction is that above it the f32 sign of Δ is determined by its inputs: f32_disagreements_above_threshold is 0 on 16 of 16. So P-127's fourteen f32 sign disagreements over 3,481 dyadic trials are confirmed on real field data to be entirely a small-magnitude phenomenon, and the magnitude is the thing that makes that legible. The shipped evaluation route is checked in the same pass: shipped_route_sign_disagreements — b*b - 4*a*c from BodySaddles::coefficients against Poly::eval_f64 — is 0 on 14 of the 16 rows, 5 on csg_difference at 65 and 1,800 on thin_plate at 65, and shipped_max_normalised_gap on those two rows is 4.915533e-16 and 4.235165e-17. Those are not two answers; they are two spellings of zero disagreeing about which side of zero they are on, which is precisely the stratum this row exists to make visible.
Direction A's caveat is a column per field rather than a sentence, and the calibration reads clean. Only direction A (mesh → true surface) reads field values as a length, via the first-order distance |f(p)| / ‖∇f(p)‖, and gotcha 15 says |sample| is meaningless where field.bound() is not Exact. So field_bound and distance_reading_is_exact ride on every row — exact on sphere, torus, box_exact and thin_plate; underestimate on csg_difference; lipschitz on gyroid; unbounded on fbm_terrain and noise_cavity — and gradient_norm_median is the size of the caveat as a number: 1.000000000 on all four Exact fields and on csg_difference, 1.475206736 / 1.476544118 on gyroid, 1.343343369 / 1.368711846 on fbm_terrain, 3.067584055 / 3.448662357 on noise_cavity. gradient_floor_points is 0 on all 16, so no point was dropped for a vanishing gradient. Direction B carries no caveat at all: segments_per_cell 28 (12 cube edges, 12 face diagonals, 4 body diagonals), bisections_per_segment 16, so a crossing is pinned to h / 65536 and its distance to the mesh is exact point-triangle geometry.
What a consumer should do differently: nothing yet, and the row narrows the next attempt rather than closing it. No file under crates/isomesh/src/ moved, no golden hash moved, and the magnitude itself costs no field samples at all — normalised_magnitude_flops 46 from eight corner values already in hand, which is why it was worth registering as a refinement criterion. What C2 measured is that ambiguity magnitude and geometric error are different phenomena on five of the seven fields that can host the question, exactly as the registration's own falsifier said was likely ("which would say ambiguity magnitude and geometric error are different phenomena — likely, and it would close the row cleanly"). The three fields that clear the bar — gyroid, noise_cavity, csg_difference — are the three with genuine sub-cell structure, and the correlation with Plantinga–Vegter's uncertified set on two of them is the more interesting surviving thread: |Δ|'s normalisation looks more like a certificate proxy than an error predictor. A refinement criterion built on this magnitude alone would refine the wrong cells on sphere, torus, thin_plate and fbm_terrain, and would refine nothing at all on a polyhedron.
SHARE, recomputed. The registration says "C2 offers a criterion for the adaptivity stage; it does not by itself move any cost", and C2 is falsified, so there is no criterion to offer and no cost to move. The arithmetic behind "none" is still worth the line: the magnitude is 46 flops on data already in the extractor's registers, so had C2 held it would have been free at the point of use — the cost would have been the refinement it triggered, not the criterion. Nothing in this file is timed: there is no nanosecond, no cycle and no ratio of two clocks, so M-280's 1.45× governor swing and ✗24 cannot reach any verdict here and the clean-tree re-run could not have moved one. Every scored quantity is a rank correlation over an integer-indexed population or an exact float comparison against zero, and both are identical on any host.
Would be shown wrong by: a fourth field clearing 0.50 at a resolution this row did not run — 129³ is the obvious one, and the two fields nearest the bar at 33 rose by 0.18 and 0.12 between 33 and 65, so the trend is not obviously flat; a normalisation other than (max|fᵢ|)⁴ — the registered one is scale-free by Cayley's degree-4 homogeneity, but scale-free is not the same as well-conditioned, and a denominator built from the corner spread rather than the corner maximum would not collapse to zero on a plane; any transform reading scale_error_dyadic non-zero, which would falsify C1 outright and mean the normalisation is wrong rather than merely unhelpful; a reference field on which f32_disagreements_above_threshold exceeds zero, which would put 1e-4 in the wrong place and undo the threshold's arithmetic derivation; and a field with a genuinely live defect column — every non-fbm_terrain rank_correlation_with_defects in this file is a zero over an empty population, and the registered clause about defects has still not been tested on data that could answer it.
🔬 M-448 — C1 and C2 both HELD, and Group A's boundary is now a number: the identity survives the trilinear control and fails structurally on a tricubic with symbolic_residual_terms 56 named non-zero terms, and under smooth_min(k) the deviation from the multi-affine Δ tracks k so closely that the six committed values are exactly k − (7/16)k² — 9.995625000e-4 at k = 0.001 rising to 3.906250000e-1 at k = 0.5, deviation_monotone and deviation_grows both true — which is the O(k) seam shell the 2026-08-23 memo measured and is what joins Group A's scope statement to M-38 (P-135, R-135)
M. cargo bench --bench experiment_p135, docs/experiments/p-135.csv, 10 rows across 24 columns — four # comment lines plus one column header plus ten data rows, 15 lines in the file; 10 of the 24 columns are P-135's registered records and the other 14 are M-273 extras. The ten rows are four arms: trilinear (arm_role control), tricubic (counterexample), seven smooth_min rows — k = 0 as a second control plus the six-rung sweep — and one smooth_min-summary. Exact i128 symbolic algebra for C1, f64 for the k sweep, seed 0x1350135 on every row and no other randomness. # commit 88955ec on amd-ryzen-9-5900x-12-core at 2026-08-30T14:31:59Z, no (WORKING TREE DIRTY), landed as dd1f221, "p-135.csv - re-run on a clean tree", an ancestor of HEAD. c1_holds and c2_holds are true on all ten rows.
| clause | registered | measured |
|---|---|---|
C1 the identity holds for the trilinear and fails for any reconstruction that is not multi-affine — demonstrated symbolically for a tricubic and for smooth_min(k) with k > 0, with the residual reported rather than merely asserted non-zero |
a reported residual, not a non-zero assertion | HELD. The control: trilinear, is_multi_affine true, identity_holds true, symbolic_residual_terms 0, degree_x/degree_y/degree_z 1/1/1, interpolant_terms 8, cases_touched 256. The counterexample: tricubic, is_multi_affine false, identity_holds false, symbolic_residual_terms 56, tricubic_degree 3 with degree_x/degree_y/degree_z 3/3/3, interpolant_terms 58, cases_touched 2^64, delta_from_corners −3.990000e2. residual_named_terms carries the leading six of the 56 verbatim: -3x^2y^3z^3 | 3x^3y^2z^3 | x^3y^3z^2 | 2xy^3z^3 | -3x^2y^2z^3 | -x^2y^3z^2. The smooth_min arms carry the same verdict numerically — identity_holds false on all six k > 0 rows — and say so about themselves: symbolic_residual_terms reads the token n/a-numeric-arm there, so C1's structural half is unambiguously the tricubic's and is not being double-counted |
C2 under smooth_min(k) the deviation from the multi-affine Δ grows with k and is bounded in the O(k) seam shell the 2026-08-23 memo measured |
monotone and growing across the sweep | HELD, and far more tightly than "grows" — deviation_monotone true and deviation_grows true on the summary row, over k_values 0|0.001|0.01|0.05|0.1|0.25|0.5. deviation_at_k is 0.000000000e0 at k = 0 and then 9.995625000e-4, 9.956250000e-3, 4.890625000e-2, 9.562500000e-2, 2.226562500e-1, 3.906250000e-1; delta_base is 2.500000000e-1 and delta_at_k falls 2.497501094e-1 → 2.475109375e-1 → 2.377734375e-1 → 2.260937500e-1 → 1.943359375e-1 → 1.523437500e-1. The summary row carries the same six as a token: deviation_at_k 9.996e-4|9.956e-3|4.891e-2|9.563e-2|2.227e-1|3.906e-1 |
The six committed deviations are not merely
O(k); they arek − (7/16)k²exactly, to all nine recorded digits.deviation_at_kis the relative displacement|Δ(k) − Δ(0)| / |Δ(0)|(experiment_p135.rs:483-487), and dividing each by its ownkgives 0.9995625, 0.9956250, 0.9781250, 0.9562500, 0.8906250, 0.7812500 — which is1 − 7k/16on every rung. Check the ends:0.001 − 7·10⁻⁶/16 = 0.0009995625, the recorded value;0.5 − 7·0.25/16 = 0.390625, the recorded value. So the leading coefficient is exactly 1 and the first correction is exactly−7/16 k², which is a considerably stronger statement than the registered clause asked for: the deviation is not just bounded inside anO(k)shell, it iskto first order with a computable quadratic term. That is the sharpest available form of "connecting Group A's boundary toM-38's smoothing result rather than leaving it a separate fact", and it means a caller can price the error of treating aSmoothUnioncell as multi-affine: at blend parameterk,Δis wrong by a relativekand no more.All three registered vacuity controls fired as assertions before the first
run.record, and each could have aborted the run. (1) The trilinear control must reproduce the identity in this harness (:349-355):repo_discriminant().sub(&cayley_2x2x2()).is_zero()asserted, or the tricubic and smooth-min arms have no baseline to fail against and the comparison is between two different measurement setups. It is the same identityP-127/M-440proved, re-run here rather than cited. Alongside it,trilinear_formof a symbolic corner tuple is assertedis_multi_affine()(:362-371), because a harness whose "trilinear" is not multi-affine is not measuring the object the crate reconstructs. (2) The tricubic residual must have NAMED non-zero terms, not a numeric difference — the registration's own words. Three assertions carry it (:411-427): the residual is not the zero polynomial,namedis not empty, and the tricubic is not multi-affine. Without the third, a draw that happened to land multi-affine would have produced a zero residual and a passing run for the wrong reason;tricubic_formforces the[3,3,3]corner term present (:281-283) so the arm is genuinely degree 3 in every variable regardless of the draw. (3) Theksweep must span at least a decade and includek = 0, whose deviation must be exactly zero.K_SWEEPspans 0.001 to 0.5 — two and a half decades — and thek = 0row readsdeviation_at_k0.000000000e0 withis_multi_affinetrue, which is correct rather than convenient:smooth_min(0)ismin, multi-affine on each side of the seam, so an exact zero there is the prediction and a non-zero would have indicted the arithmetic.What the 56 terms mean, and why the count matters more than the residual's size. The construction is: take an exact tricubic in
x,y,z; restrict it to the cell's eight corners; rebuild the trilinear that interpolates those corners; subtract. The difference is the part of the cell the corner values cannot see, and it is a polynomial rather than a number. That is the whole of C1's structural claim:BodySaddles::coefficientsreads coefficients off eight corner values, and the moment the reconstruction carries a quadratic-or-higher term in any single variable those are the wrong coefficients, so the discriminant of the resulting quadratic is a different polynomial. 56 non-zero terms is the size of "wrong" — the tricubic hasinterpolant_terms58 and the rebuilt trilinear has 8, so the residual is nearly the whole interpolant.SpatialPolyis a bench-local polynomial in the three spatial variables and is deliberately a different object fromcommon::poly::Poly, which is a polynomial in the eight corner values: the corner-value polynomial cannot express a statement about degrees inx,y,zat all, which is why a second exact type had to exist here and is not a duplicate of the shared module.
The smooth_min fixture is two planes crossing inside the cell, so the seam shell is actually sampled rather than assumed. smooth_min_corners (experiment_p135.rs:303-314) evaluates a = x − 0.5 + 0.25z and b = 0.5 − y − 0.25z at the eight corners of the unit cube and blends them with the crate's polynomial smooth-min, min(a, b) − h²k/4 with h = max(0, 1 − |a − b| / k). Inside the shell |a − b| < k that expression is quadratic in a − b, which is exactly and only why it is not multi-affine — the deviation is not a rounding artefact but the shell's own curvature, and a − b spans the seam over the corner set by construction. Δ is then read through delta_f64 (:317-328), which is trilinear.rs:202-213 plus :246 transcribed line for line — twist_lo, du_lo, dv_lo, a, b, c, b*b − 4ac — so the number being deviated is the number the crate computes, not a textbook discriminant.
This is a scope statement, and the scope it states is Group A's. P-127 proved b*b - 4*a*c at crates/isomesh/src/marching_cubes/trilinear.rs:246 is identically Cayley's 2×2×2 hyperdeterminant; P-128 through P-134 all lean on that, and every one of them silently assumes the reconstruction is multi-affine. That is a hypothesis about the filter, not a fact about the crate, and until this row it was nowhere in the ledger. It now is, with two boundaries and a rate: the identity is exact on the trilinear, structurally false on anything with a quadratic-or-higher term in a single variable (56 named terms), and false by a relative k on the crate's own SmoothUnion. The practical consequence for a consumer is narrow and precise. MarchingCubes reconstructs trilinearly, so nothing on the shipped extraction path is affected and nothing changes. A caller who builds an SDF with SmoothUnion and then reasons about Δ — orbit class (R-132), ambiguity magnitude (R-134), tensor rank (R-130) — is reasoning about a quantity that is wrong by k near the blend seam and exact away from it, and the k − (7/16)k² form is what lets that be priced instead of feared. The case-space number says the same thing from the other side: cases_touched is 256 on every multi-affine arm and 2^64 on the tricubic, because a tricubic's sign pattern lives on 64 control values rather than 8, so a case-table approach does not merely lose the identity — it loses the table.
Three column readings that are tokens rather than measurements, reported and not amended (crates/isomesh/src/experiment.rs:27-31). (a) centre_residual_value reads 0, and it is an M-44 zero. It is residual.eval(1, 1, 1) (:438), and (1,1,1) is a corner of the unit cell, not its centre — the rebuilt trilinear interpolates the corners by construction, so that residual is forced to be exactly zero and could not have read otherwise. The doc comment above it calls it "the tricubic's own value at the cell centre"; SpatialPoly::eval takes i128, so the true centre (½,½,½) cannot be passed to it. The residual's non-zero-ness is established by symbolic_residual_terms 56 and by the named terms, both of which are real, so C1 does not depend on this column. (b) tricubic_degree reads 1 on the trilinear, smooth_min and summary rows, hard-coded at :380, :519 and :589 — there is no tricubic in those arms and the column is a placeholder, not a degree. Only the tricubic row's 3 is a measurement. (c) deviation_grows and deviation_monotone are populated on the summary row alone and are empty on the six sweep rows, which is correct — they are properties of the sweep — but a reader filtering the file to the sweep rows will find C2's two deciding booleans absent.
SHARE, recomputed. The registration says none — "this is a scope statement and moves nothing" — and it is discharged as written rather than left blank. The arithmetic behind "none": zero bytes changed under crates/isomesh/src/**, zero golden hashes moved, zero field samples taken, zero meshes extracted. Every mechanism in this row is common::poly plus one bench-local exact polynomial type. Nothing is timed — the file contains no nanosecond, no cycle and no ratio of two clocks — so M-280's 1.45× governor swing and ✗24 have nothing to move, and the clean-tree re-run could not have changed a verdict: C1 is exact i128 polynomial algebra and C2's six deviations are f64 values of a closed form that reproduces to nine digits on any host. What the row buys is a fence rather than a speedup, and it is the fence P-136 puts on the other axis: P-136 records that Δ does not resolve the interior test even where the reconstruction is multi-affine; P-135 records where the reconstruction stops being multi-affine at all.
Would be shown wrong by: a non-multi-affine reconstruction on which the identity survives — the registration names this as the strictly better outcome, and it would widen Group A rather than narrow it; a smooth_min fixture whose deviation does not track k, which would mean the smoothing and the invariant are unrelated and M-38 gains nothing here — the k − (7/16)k² fit makes that very unlikely on this fixture but the coefficient is a property of the two-plane construction and a different seam geometry will have a different one; a k beyond 0.5, where the shell is wide enough to cover the whole cell and the linear term should stop dominating — the sweep's top rung already shows the quadratic correction taking 22% off, so the linear reading has a stated ceiling; a SpatialPoly bug making symbolic_residual_terms an overcount, which the named-terms column exists to let a reader check by hand; and any change to trilinear.rs:202-213 or :246 that made delta_f64 here stop being a transcription of the shipped expression, which would silently move both clauses' subject.
🧊 M-449 — the registered null came back exactly as registered: sign(Δ) is worth nothing on the interior test. Over M-165's 15,625 configurations the best of all eight sign-only rules scores population_agreement_rate 0.985600 against population_base_rate 0.985600 for a rule that never looks — delta_information_gain 0.000000, population_delta_insufficient 225 — and the reason is a group action rather than a fitted number: delta_blind_to_face_negation true while that same negation moves the separated count from 225 to 4,113 (P-136, R-136)
M. cargo bench --bench experiment_p136, docs/experiments/p-136.csv, 20 rows across 42 columns — four # comment lines plus one column header plus 20 data rows, 25 lines in the file; 8 of the 42 columns are P-136's registered records and the other 34 are M-273 extras. No RNG and no field sampling: the population is a complete 5^6 product over the five magnitudes M-165's own loop sweeps, enumerated in its loop order, so every count is identical on every host and every re-run. Two taxonomies share the configuration_class column and every row names its own in a partition extra — 14 decider_mask rows (case150/dm00 … case150/dm63, summing to configurations 15,625 and separated_count 225 exactly), 3 delta_sign rows, 1 population row (case150/all), and 2 control rows. # commit e9bf133 on amd-ryzen-9-5900x-12-core at 2026-08-30T14:09:08Z, no (WORKING TREE DIRTY), landed as 54e1b6f, "p-136.csv - re-run on a clean tree", an ancestor of HEAD. c1_holds and c2_holds are true on all 20 rows: this row's finding is a null and the null is what was registered.
| clause | registered | measured |
|---|---|---|
C1 over the configurations M-165 identifies, sign(Δ) alone agrees with the correct interior verdict on strictly fewer than all of them, and the disagreement set is characterised |
agreement < 1 and a non-empty, described disagreement set | HELD — case150/all reads agreement_rate 0.985600 over configurations 15,625, with population_delta_insufficient 225. The clause is scored on the best of all eight functions from {neg, zero, pos} to {Joined, Separated}, fitted on the row's own data by majority vote with ties to joined, so a value below 1 says no sign-only rule can succeed — the most generous reading available and the only honest one. The disagreement set is described in three ways in the same file: by delta_sign class, by decider mask, and by its overlap with Chernyaev's errors (overlap_of_delta_wrong 198/225, overlap_of_chernyaev_wrong 198/1966) |
C2 the classes where Δ is insufficient are named explicitly, so the boundary is in the ledger rather than in somebody's head |
named, a strict subset, and the closed-form containment holds | HELD — cases_where_delta_insufficient reads 0|31|47|63 on all 20 rows: four decider masks out of decider_classes_observed 14, so delta_insufficient_classes 4 is a boundary rather than "everywhere". The containment half: separated_inside_endpoint_condition 225 equals separated_count 225 over endpoint_condition_population 4,489, so every Separated verdict provably satisfies saddle(0) ≤ 0 and saddle(1) ≤ 0 — margin() is a maximum over candidate points that includes the endpoints — which is what makes the set characterised rather than merely listed |
The number that carries the whole row is a difference of two identical figures.
population_agreement_rate0.985600 is the best sign-only rule;population_base_rate0.985600 is a rule that reads nothing at all and predicts the majority verdict;delta_information_gainandpopulation_information_gainare both 0.000000. And the fitted rule says why in one line:best_sign_ruleoncase150/allisneg->joined|zero->joined|pos->joined— the best use ofsign(Δ)is to ignore it. The base rate is exactlyjoined_count15,400 / 15,625. The geometrically natural reading is worse than ignoring it:natural_rule_rate0.893504, nine points below the base rate, because "Δ > 0 means two realuroots, so the hyperbolas cross, so call it Joined" gets the entiredelta_negclass wrong — 1,308 configurations,natural_rule_rate0.000000 on that row, every one of them actuallyJoined. Recording both readings is what stops C1 from being a statement about a badly chosen mapping.The mechanism is a proof, and the aligned control is that proof measured. Negating the four corner values of the far face is the
GL(2)³elementg₃ = diag(1, −1)withg₁ = g₂ = I.P-127records the weight of that action as(det g₁ · det g₂ · det g₃)²=(−1)²= 1, soΔis exactly invariant under it. The interior verdict is not:SweptFaces::numerator(1)is a product of two negations and does not move,SweptFaces::denominator(1)negates, sosaddle(1)flips sign — andmargin()is a maximum that includessaddle(1). One operation leavesΔfixed and moves the answer.control/aligned_no_poleis the same 15,625-configuration sweep with exactly that negation applied, and the file asserts the two families'Δvalues agree row for row and bit for bit:delta_blind_to_face_negationtrue on all 20 rows, withdelta_neg1,308,delta_pos14,132 anddelta_zero185 identical on both families. Their verdicts are not:separated_count225 on the opposed family against 4,113 on the aligned one, an eighteen-fold move under an operationΔcannot see. That is a reason rather than evidence about a fixture, and it is why this null is registered as permanent rather than as "not on this population".Seven vacuity controls fired, every one before the first
run.record, and each panic message opensVOID:. (1) The registration's own control, both halves. "The configuration set must reproduceM-165's 12.6% disagreement rate as a control column, or the fixture is not the populationM-165measured."chernyaev_wrong1,966 — the exact integermarching_cubes/interior/tests.rs:230pins — andm165_rate_reproduced0.125824 againstm165_rate_registered0.126000,m165_rate_error0.000176, inside a5e-4tolerance that is half of the last place the claim was quoted to. (2)configurations15,625 with no degenerate rejection — an opposed face pair cannot have a zero bilinear denominator, soSweptFaces::newmust accept every draw, and a rejection would silently shrink the population under a pinned disagreement count. (3)poled15,625 —M-165's structural claim that every configuration has a pole inside the sweep; without a pole the corrected and numerator-only tests are provably equal (interior.rs:392-394) and the comparison is empty. (4) Every configuration hascase == 150withAMBIGUOUS_FACES[150] == 63— inside corners{1,2,4,7}are one of the cube's two tetrahedra, so all six faces are ambiguous and this is Chernyaev's case 13, not some easier neighbourhood. (5) Both verdicts occur —joined_count15,400 andseparated_count225, or every rule scores 1 and C1 could not have held for any reason but the fixture. (6) All threeΔsigns occur — 1,308 / 185 / 14,132, or "sign(Δ) alone" has no sign to be wrong about. (7) The instrument is shown able to read zero.control/aligned_no_polereadschernyaev_wrong0 andpoled0 while its verdict is not constant (11,512 joined against 4,113 separated), so 1,966 is a property of the opposed family rather than of the comparison, and the zero is not an artefact of there being only one verdict to agree about.
The one place Δ carries information is a rounding error, and it is in the file rather than in a footnote. Of the 14 decider-mask classes, exactly one has a non-zero delta_information_gain: case150/dm00, 0.006350, over 3,937 configurations — agreement_rate 0.999492 against base_rate 0.993142, and its best_sign_rule is the only non-constant one in the whole population partition, zero->separated|pos->joined. That is 0.635 percentage points, it applies inside one class out of fourteen, and it does not survive pooling: population_information_gain is 0.000000. The other three insufficient classes buy nothing at all — dm31 (825 configurations, 50 separated, agreement_rate 0.939394), dm47 (825, 49, 0.940606) and dm63 (2,828, 99, 0.964993) each read delta_information_gain 0.000000 because their delta_sign is the constant pos and there is no bit to read. The ten remaining classes reach agreement_rate 1.000000 for the uninteresting reason that their verdict is constant joined (verdict_is_constant true), which the file marks rather than counting as ten successes.
The delta_sign partition shows the failure is not concentrated where a reader would guess. case150/delta_neg: 1,308 configurations, all Joined, agreement_rate 1.000000 — and chernyaev_disagreement_rate 1.000000, so Chernyaev's numerator-only test is wrong on every single one of them while Δ's sign is uniform across the whole class. case150/delta_zero: 185 configurations, 158 joined against 27 separated, agreement_rate 0.854054, the worst class in the file. case150/delta_pos: 14,132, 13,934 against 198, 0.985989. Two consequences. First, the 225 mistakes split 198 in delta_pos + 27 in delta_zero + 0 in delta_neg, so the exactly-degenerate Δ = 0 stratum is where the sign rule is worst per capita — 14.6% wrong against 1.4%. Second, overlap_of_delta_wrong 198/225 says 27 of the sign rule's mistakes are outside Chernyaev's 1,966 entirely: those are configurations both published tests handle and a Δ-only rule does not. The two error sets are not nested and neither contains the other — overlap_of_chernyaev_wrong 198/1966 is 10.07% — which is the "characterised" that C2 asks for.
What a consumer of this crate should do differently: nothing, and that is the entire point of registering the row. crates/isomesh/src/** is unchanged by R-136 — zero bytes, zero golden hashes, no field sampled, no mesh extracted — and every mechanism here is public API (ambiguity::joined_mask, interior::{SweptFaces, chernyaev_numerator_test}, table::{AMBIGUOUS_FACES, face_bit}, trilinear::BodySaddles) plus this one bench file. What the row buys is a fence around three of its own siblings. P-127/M-440 proved b*b - 4*a*c at trilinear.rs:246 is identically Cayley's 2×2×2 hyperdeterminant, and that identity invites a false corollary — that the 730-subcase table becomes a corollary of an invariant. R-130 reads tensor rank off sign(Δ), R-132/M-445 reads orbit class off it, and R-134/M-447 normalises |Δ| into a continuous ambiguity magnitude. None of those three may be read as resolving the interior test, and after this row the ledger says so with a number and a group-theoretic reason instead of a caveat somebody has to remember. M-214 had already recorded that the saddle count under-determines a topological question; this is the same shape of result one level down, for the saddle discriminant's sign.
The decider mask is the right granularity and the row argues that rather than assuming it. The whole M-165 sweep has a single Marching Cubes case index — 150 — so the case index is a constant column and could not characterise anything. ambiguity::joined_mask(&corner, AMBIGUOUS_FACES[150]) is the shipped per-face resolution and table::segment_links(case, joined) keys the 730 subcases off exactly that mask, so the mask is the granularity at which "does Δ make the subcase table a corollary" is a well-posed question. The rows are named by the mask's numeric value and deliberately not by Chernyaev's 13.1/13.2/13.5.1 labels: transcribing a published classification from memory is guessing, and the mask needs no transcription because it comes out of the function the extractor itself calls. One reading rule rides with the file: the delta_insufficient counts are not additive across partitions and must not be summed — each row fits its own upper-bound rule, so a class that resolves internally can still contribute to the pooled mistake count, and population_delta_insufficient 225 is the one canonical figure, carried on every row for exactly that reason.
SHARE, recomputed. None, and the registration says so — "this is a negative result registered before its positive twin can be believed". A null still has a cost ledger and it is worth the three lines: change to crates/isomesh/src/** zero bytes; extraction cost moved zero, since no field is sampled and no mesh extracted; golden hashes moved zero, since nothing this harness touches is on an extraction path. No clause is timed. wall_ns reads 2,265,297 on every row and is read by nothing, which is the only safe status for a nanosecond on a host whose governor swings the same binary 1.45× (M-280) — so ✗24 has nothing to bite on and the clean-tree re-run could not have moved a verdict. Every ordering in the file is on integer keys, every rate is {:.6}, and the only float equalities are the two intended exact ones: Δ's sign against exactly zero, which is what trilinear.rs:247-250 branches on, and the family-to-family Δ comparison, which is a bit-identity claim and not a tolerance.
Would be shown wrong by: agreement_rate reading exactly 1.000000 on the whole population under some sign-only rule, which the registration names as "a major and unexpected win" that would justify reopening the A-002 interior line entirely — the GL(2)³ argument says it cannot happen, so a 1.0 would mean the weight computation or the negation's action on saddle(1) is wrong; delta_blind_to_face_negation reading false, which would break the same argument at its root and force the null to be re-explained; a configuration family in which the four insufficient masks 0|31|47|63 are no longer a strict subset of the observed classes, which would turn C2's boundary into "everywhere" and mean the instrument is too coarse; a Separated verdict outside the endpoint condition (separated_inside_endpoint_condition < separated_count), which would break the closed-form containment and make C2 a correlation rather than a proof; and a population whose chernyaev_wrong drifts from 1,966, which would say this is not the fixture M-165 measured and would void the comparison before any clause is read.
🔬 M-450 — C1, C2 and C3 all HELD on 25 of 25 rows: the trilinear's "at most 2" is the mixed volume 8 − 6 + 0 = 2 of three unit squares the harness read off the partials' own supports, reproduced independently as an eliminant of degree exactly 2 in w, with cells_with_three_or_more 0 on every row — and SADDLE_COUNT's 2 is a different theorem, grad_disc_degree 6 against repo_disc_degree 4, root sets differing on 31,883 census cells and agreeing on 7 (P-137, R-137)
M. cargo bench --bench experiment_p137, docs/experiments/p-137.csv, 25 rows across 60
columns — four # comment lines plus one column header plus 25 data rows, counted from the file rather
than from the brief. The shape, also counted from the file: the eight reference fields ×
{17, 33, 65} samples per axis = 24 census rows with is_control = false, plus one
random_corners row with is_control = true, resolution 0, control_trials 200,000 and
control_seed 0x0137013701370137. total_cells sums to 2,392,064 over the census and
surface_cells to 104,059; the control's total_cells is 0 because it has no grid. Roots are f64
from an exact rational formula, every symbolic quantity is exact i128, and census_ns (100,531,628 ns
over the census, 23,038,236 on the control) is recorded and read by nothing. Run on a clean tree —
# commit 00291e5 on amd-ryzen-9-5900x-12-core at 2026-08-30T09:28:13Z, with no (WORKING TREE DIRTY) on
that line.
| clause | registered | measured |
|---|---|---|
| C1 the mixed volume is committed as a check, and a census reports how many cells have 0, 1 or 2 real critical points inside the unit cell | MV = 2; falsified by any cell with three or more |
HELD — mixed_volume 2 and bernstein_bound 2 on all 25 rows, cells_with_three_or_more 0 on all 25. The census: cells_with_zero 100,672, cells_with_one 650, cells_with_two 4, cells_positive_dimensional 2,733, summing to surface_cells 104,059 exactly on every row |
| C2 at least one cell on at least one field has a critical point on a coordinate hyperplane, which Bernstein's count excludes by construction | falsified by no hyperplane cases | HELD — on_hyperplane_count 22 over the census on three fields: csg_difference 2 / 4 / 9, thin_plate 1 at 65³, noise_cavity 3 at 33³ and 3 at 65³. on_cell_face_count is 39 and roots_at_infinity 186 beside them. The control reports 0, which is the right answer for 200,000 random octuples |
C3 the relationship to SADDLE_COUNT is stated as a non-identity, exhibited by a cell where the root sets differ |
falsified by the two root sets coinciding | HELD — saddle_count_relationship distinct-root-sets on all 25 rows. grad_disc_degree 6 against repo_disc_degree 4, grad_disc_terms 336 against repo_disc_terms 12, grad_disc_minus_repo_disc_terms 348. cells_root_sets_differ 31,883 against cells_root_sets_agree 7, with a named witness |
Two derivations, one number, and neither is Grosso's sentence.
crates/isomesh/src/marching_cubes/trilinear.rs:128declarespub const SADDLE_COUNT: usize = 2and nothing in the tree said why. Route one: the harness buildsfsymbolically overcommon::poly, differentiates it, and reads each partial's support off the result —newton_polytope_extentsis0x1x1|1x0x1|1x1x0, i.e. exactly the three unit squares in(v,w),(u,w)and(u,v). A support that is exactly the four vertices of an axis-aligned unit square is its own hull, so no floating-point hull predicate is run at all. Then inclusion–exclusion over boxes in integers:minkowski_volume_singletons_sum0,minkowski_volume_pairs_sum6,minkowski_volume_all_three8, giving8 − 6 + 0 = 2. Route two touches no polytope:∂f/∂u = 0and∂f/∂v = 0are each linear in one unknown with the same coefficientA(w), sou = −P/A,v = −R/A, and substituting into∂f/∂w = 0gives an eliminant inwalone witheliminant_degree_in_w2. Its factorisation is checked as an exacti128identity in the eight corner values and holds:eliminant_q2_is_c111_times_ktrue,eliminant_q1_is_two_c110_times_ktrue,grad_disc_is_minus_four_k_du_dvtrue.Six vacuity controls fired, all before the first
run.record, all panicking withVOID:. (1)surface_cells > 0on every row — a field with no cut cell would report zeros about nothing; the smallest isthin_plateat 17³ with 128. (2)cells_with_zero > 0over the census — 100,672; a bucket that never fired is not a distribution. (3)cells_with_one > 0— 650, and it is non-zero on exactly two fields (gyroid19 / 25 / 60,noise_cavity122 / 219 / 205), so the middle of the distribution is carried by the two fields rough at the cell scale rather than by all eight. (4)cells_with_twois the bucket at risk and the control arm exists for it alone — the control reportscells_with_zero161,927,cells_with_one35,141 andcells_with_two1,355 oversurface_cells198,423, through the same solver, so the census's own 4 is a measurement rather than an instrument limit. (5)repo_roots150,297 over the census, so the root-set comparison is not against an empty set. (6)mirror_mismatches0 on all 25 rows: the compared repo coordinates come from the shippedBodySaddles::of, and the mirror only supplies a count the crate does not expose.
The BKK bound of 2 is attained inside a grid cell on exactly one field, at exactly one rung, and
refinement destroys it. All four of the census's cells_with_two are noise_cavity at 17³
(cells_with_zero 997, cells_with_one 122, cells_with_two 4 over surface_cells 1,123); at 33³ and
65³ the same field reports 0, and every other field reports 0 at every rung. That is the direction the
harness predicted in advance — the quantity counted is a finite point set per cell, so refinement shrinks
the cell around it — and it is why 17³ is the coarsest rung rather than 129³. Six of the eight
fields report zero interior real critical points at every resolution (critical_points_in_cell 0 on
sphere, torus, box_exact, csg_difference, thin_plate and fbm_terrain), so the census's whole
interior population — 658 points = 650 singletons + 2 × 4 — lives on gyroid and noise_cavity.
C3's symbolic half is a proof and its sample half is an exhibit, and the two answer different halves of
the same question. The repo's discriminant is b*b - 4*a*c at trilinear.rs:246, which P-127
identified as Cayley's 2×2×2 hyperdeterminant — recomputed here as repo_disc_is_cayley true,
repo_disc_terms 12, repo_disc_degree 4. The eliminant's discriminant Q₁² − 4Q₂Q₀ has
grad_disc_degree 6 and grad_disc_terms 336: a different total degree, so no scaling makes
them equal, and grad_disc_minus_repo_disc_terms 348 is the size of the difference. They are not
unrelated — repo_a_is_minus_du true says the repo quadratic's own leading coefficient
a = du_hi*twist_lo - du_lo*twist_hi (trilinear.rs:209) is identically −Dᵤ, one of the three quadratic
factors of Q₁² − 4Q₂Q₀ — which is exactly why cells_root_sets_agree is 7 rather than 0 (all seven
on csg_difference: 1 / 1 / 5).
The exhibit, with the cell named. c3_witness_field gyroid, c3_witness_cell 8x6x1,
c3_witness_resolution 17. c3_witness_grad_roots is
-1.498092:1.148434:-0.287369 | 0.561174:0.462230:0.281783 — the second of the two is strictly inside the
open unit cell — and c3_witness_repo_roots is
-3.247308:0.932460:-0.108235 | -0.849964:1.731322:-0.770827, with c3_witness_separation
1.749216212. The sharpest single pair of numbers in the row is on that same gyroid 17³ row and
needs no witness cell at all: max_abs_f_at_repo_saddle is 8.326673e-16 while
min_abs_f_at_grad_critical is 1.915778e-2. The repo's roots lie on the zero level set to within a
rounding error, because that is the system they solve — face-hyperbola intersections on f = 0; the
gradient's critical points are, at their closest anywhere on that field, two hundredths of the field's
value away from it. Two "at most 2"s, two theorems, one number. cells_both_in_cell 43 over the
census (all noise_cavity: 11 / 19 / 13) and 6,037 on the control is how strong the disagreement gets
where both sets actually put a point inside the open cell.
Which numbers are trustworthy is stated by the file rather than assumed.
max_in_cell_gradient_residual — max|∇f| over critical points inside the open cell — tops out at
2.857957e-14 on noise_cavity at 33³ and is asserted below 1e-9; every bucket in the census depends on
that column and nothing else. max_scaled_gradient_residual reaches 1.297222e-1 on csg_difference at
17³ and is deliberately not asserted: near a stratum boundary A is tiny but not zero, u and v
come out at 10¹⁵ (max_root_separation peaks at the file's own
40055465777643982268368913694720.000000000 on fbm_terrain at 33³), and such a root is
a real root the f64 interpolant genuinely has, nowhere near the cell, entering no bucket.
Nothing changes for a consumer of this crate. crates/isomesh/src/ is untouched, no golden hash moved,
SADDLE_COUNT is right and is now derivable rather than transcribed. The one thing a reader must not do
is carry SADDLE_COUNT across to ∇f = 0: the two 2s are different theorems, and P-137 is the row that
says so with an exhibited cell. The two degenerate strata are the other transferable fact —
cells_positive_dimensional 2,733 and cells_stratum_degenerate 22,456 are not rare corners but
structural: fbm_terrain is exactly linear in y by construction, which forces c₁₁₀ = c₁₁₁ = 0 and puts
every one of its cut cells in the degenerate stratum at 65³ (cells_stratum_degenerate 6,603 of
surface_cells 8,413 at 65³, and cells_with_zero = surface_cells on all three of its rungs, with
repo_non_finite_cells 179 / 796 / 3,672); box_exact has critical_points_complex 0 at every
resolution, so its interpolant has no isolated critical point anywhere in the sweep. A census that solved
the eliminant and stopped would have reported a curve of critical points on 2,733 cells and silence on
22,456 more.
One place the CSV disagrees with the harness's own header. The header's stratum table
(experiment_p137.rs:164-168) lists cells_stratum_degenerate beside cells_with_zero as the
degenerate-empty bucket. The column is not that: experiment_p137.rs:1100-1102 defines it as "surface
cells with A(w) ≡ 0", counted independently of the four buckets, and the CSV proves the code right —
box_exact at 17³ reads cells_stratum_degenerate 264 against cells_with_zero 216 over
surface_cells 296, which is impossible for a subset. The five-way sum the harness actually asserts is
cells_with_zero + one + two + three_or_more + positive_dimensional == surface_cells, and that holds on
all 25 rows.
🔬 M-451 — C1 and C2 both HELD, and the price is in the table rather than in the bound: tricubic mixed_volume 116 against the trilinear's 2 (mv_vs_trilinear 58.000000, two disjoint routes agreeing on all three arms) while the case space goes 2^8 → 2^64 and case_space_tractable flips to false — the memo's "alive at degree ≥ 2" prediction is confirmed on all four arguments, and the unregistered triquadratic arm is the only rung that has both order and a tabulable table, mixed_volume 29 over 2^27 = 134,217,728 (P-138, R-138)
M. cargo bench --bench experiment_p138, docs/experiments/p-138.csv, 3 rows across 38
columns — four # comment lines plus one column header plus three data rows, eight lines in the file,
counted from it. One row per reconstruction: trilinear with is_control = true, triquadratic and
tricubic with is_control = false. instances 2,048 on every row, drawn from
common::poly::Rng (SplitMix64) seeded SEED ^ degree — seed 5778456113849643833 /
…834 / …835 — with non-zero integer control-net entries in [−9, 9]. Every arithmetic path is i128
and max_exact_magnitude (576 / 2,359,296 / 46,438,023,168) is asserted below 2^100, so
"exactly" below is checked rather than asserted by prose. No wall clock is read anywhere in the file.
# commit f72384f on amd-ryzen-9-5900x-12-core at 2026-08-30T09:28:17Z, no (WORKING TREE DIRTY).
| clause | registered | measured |
|---|---|---|
C1 the mixed volume for ∇f = 0 with a tricubic reconstruction is computed and reported, giving the bound that would replace the trilinear's 2 |
falsified by a mixed volume that makes the tricubic case space computationally hopeless | HELD — mixed_volume = critical_points_bound = mv_permanent 2 / 29 / 116, mv_routes_agree true on all three rows, newton_boxes 0x1x1|1x0x1|1x1x0 → 1x2x2|2x1x2|2x2x1 → 2x3x3|3x2x3|3x3x2. c1_holds true, global, identical on all three rows |
| C2 the Bernstein-form arguments the memo killed are re-checked at degree 3 and reported alive or dead, with the specific reason | falsified by the arguments staying dead at degree 3, contradicting the memo's own prediction | HELD — bernstein_route_alive dead on the trilinear and alive on both higher degrees, with bernstein_reason spelling the four out: alive|control_net_is_not_the_samples|subdivision_strictly_refines|signs_finer_than_the_case_index|sharpness_theorems_bite. c2_holds true, global |
The calibration is the registration's own vacuity control and it came back on the nose. "The trilinear must be run through the same pipeline and reproduce
MV = 2, or the tricubic number has no calibration" —mixed_volume2 on thetrilinearrow,estimated_case_countthe token2^8andcase_count_decimalexactly 256. Four more controls fired before the firstrun.record, each panicking withVOID:. (1) Two disjoint routes must agree on every arm. Route A is a signed sum over the2³−1non-empty subsets of the three Newton boxes; route B is the permanent of their side-length matrix, an unsigned sum over the3!column permutations. They share no line of code, andmv_permanentequalsmixed_volumeon all three rows — a tricubic 116 from one route is a number, from two it is a measurement. (2)bernstein_route_alivemust readdeadon the trilinear arm, and it does: the same four checks, the same code, the same instance generator, reaching the opposite verdict one degree down. Without that control analiveat degree 3 would be a property of the pipeline rather than of the degree. (3) All four arguments must reproduce the memo on the trilinear arm —control_points_matching_samples16,384 ofcontrol_points_total16,384,subdivision_sites_matching131,072 of 131,072,hidden_edge_sign_changes0,enclosure_narrowed_instances0. (4)corner_sites_matchingmust be8 × instanceson every arm — it is 16,384 on all three, which is what licenses reading a mismatch at the interior sites as a fact about the degree rather than a bug in the Bernstein→monomial conversion.degenerate_netsis 0 everywhere, so no arm is measured on a fixture whose parent enclosure has zero width, andcase_classes_lower_bound3 on the trilinear sits under the enumeratedtrilinear_case_classes14 under the order-trilinear_case_group_order96 quotient, so the group used for the tricubic floor is the one being claimed.
The hopelessness is in the table and not in the bound, and the registration did not anticipate that
split. The bound rises 2 → 116, mv_vs_trilinear 58.000000 — a 58× rise in the root-isolation
budget of a Plantinga–Vegter-style subdivision solver, which is expensive and is not hopeless. The case
space is the other quantity, and it is the one that dies: the sign pattern is over the (d+1)³ control
values, so net_sign_bits is 8 / 27 / 64 and estimated_case_count is the token 2^8 / 2^27 /
2^64. 2^64 is recorded as a token and never as a float; case_count_decimal carries the exact
u128 256 / 134,217,728 / 18,446,744,073,709,551,616. The bar is a column too:
case_space_tractable is net_sign_bits <= ram_bytes_log2 with ram_bytes_log2 35 — this machine's
32 GiB at one byte per case — so the verdict is auditable from the file alone and reads true / true /
false. case_classes_lower_bound = ⌈2^((d+1)³) / 96⌉ is 3 / 1,398,102 / 192,153,584,101,141,163,
labelled a floor because it is one.
The sharpest sentence this row has to give the roadmap is about the rung nobody registered. The
registration names two degrees; the memo's sentence is "at degree ≥ 2 per variable", and degree 2 is the
cheapest place that sentence can be tested. The triquadratic arm is an addition, is marked
is_control = false, decides neither verdict, and it is the only rung of the three that gives both order
and a tabulable case space: mixed_volume 29 with case_count_decimal 134,217,728 — 128 MiB at
one byte per case, or case_classes_lower_bound 1,398,102 classes after the order-96 quotient, which
fits on a laptop — against the tricubic's 2^64 = 18.4 EB. So if P-157 wants order without abandoning a
tabulated case analysis, triquadratic is the rung, and this file is the arithmetic that says so.
The Bernstein verdict, by measured integers rather than by re-reading the memo. All four arguments the
2026-08-23 memo killed for the trilinear are alive at both higher degrees, and bernstein_route_alive is
derived from the four booleans so it cannot disagree with the columns beside it.
(1) The net is not the samples: control_points_matching_samples falls from 16,384 of 16,384 to
17,052 of 55,296 and 16,555 of 131,072. (2) Subdivision is not resampling:
subdivision_sites_matching falls from 131,072 of 131,072 to 133,732 of 442,368 and 131,747 of
1,048,576, and subdivision_exactness goes exact_resampling → inexact_strict_overestimate on both.
(2′) The enclosure narrows, which is the certificate that the parent enclosure was a strict
over-estimate: enclosure_narrowed_instances 0 / 1,623 / 1,764 of 2,048, with
enclosure_shrink_ppm_max 0 / 500,000 / 444,444 — the sharpest single narrowing takes the child union
to 50.0% of the parent's width at degree 2 and 44.4% at degree 3, and enclosure_shrink_ppm_min is
0 on all three rows because most instances do not narrow at all.
(3) The signs are finer than the case index: hidden_edge_sign_changes 0 / 6,060 / 9,223 —
cell-edge lines whose two endpoints agree in sign but which carry a sign change between adjacent control
values in their interior, information an 8-corner case index structurally cannot hold. net_is_the_samples
and signs_are_the_case_index are both true on the trilinear and false on both higher degrees.
(4) The sharpness theorems bite: sharpness_theorems_vacuous true / false / false, derived from
2′ rather than measured separately, because Rivlin's linear-in-1/degree and Stahl's quadratic-in-box-width
rates both bound overestimation — a measured overestimation of zero makes both vacuous and a measured
non-zero one makes both bite.
Two places the CSV is more honest than the harness's own header table, and both are worth reading before
quoting that table. experiment_p138.rs's summary table predicts enclosure_narrowed_instances as
"none | all" for trilinear | tricubic; the measurement is 1,764 of 2,048 on the tricubic, i.e. 86.1%
and not all — the remaining 284 instances have a parent enclosure the eight half-nets happen to reproduce
exactly, which is a fact about [−9, 9] integer nets rather than about degree 3. The same table predicts
the matching sites as "corners only" at degree 3; the measurement is 16,555 against a corners-only
floor of 8 × 2,048 = 16,384, so 171 interior control points coincide with their sample by arithmetic
accident, and 675 sub-net coefficients likewise (131,747 against 131,072). Neither moves a verdict —
net_is_the_samples is an equality over the whole net and is false — but "corners only" is a
prediction and "corners plus 171" is the number.
Nothing changes for a consumer of this crate, and that is the row's design. "SHARE: none — this prices
a decision, it does not make one." This harness calls no extractor, samples no field, touches no
crates/isomesh/src/** path and proposes no filter; TriPoly is bench-local and is not a second copy of
common::poly::Poly — that module's variables are the eight corner values and this row's are the three
spatial variables, where a tricubic has 64 coefficients and the corners are not variables at all. What
ships is the price tag: P-157 now argues against 116, 2^64 and case_space_tractable = false instead
of against a memory of a memo.
🔬 M-452 — C1 and C3 HELD, C2's c2_holds true on 4 rows of 16 and false on 12: Kuhn's six tetrahedra are regular, exhibited by the lifting the LP's own back-substitution returned — w(S) = −|S|(|S|−1)/2, heights 0|0|0|−1|0|−1|−1|−3 — verified against all 24 inequalities and a 70-subset lower-hull enumeration, so Viro's T-construction transfers to marching tetrahedra; and the registered PW/PV comparison disagrees on 22,841 of 99,932 active cells in both directions, pw_yes_pv_no 9,923 against pw_no_pv_yes 12,918 (P-139, R-139)
M. cargo bench --bench experiment_p139, docs/experiments/p-139.csv, 16 rows across 60
columns — four # comment lines plus one column header plus 16 data rows, counted from the file. The
shape, also from the file: the eight reference fields × {33, 65} samples per axis, cells_checked
32,768 / 262,144 and 2,359,296 summed, active_cells 99,932 summed. C1 and C3 are one
algebraic decision each and are therefore global — every C1 and C3 column carries the same value on all 16
rows — while C2 is per row. C1 and C3 are exact integer arithmetic throughout (i64 geometry, i128
elimination, exact rationals only in back-substitution); the sweep is f64 with a three-way </> sign
test, so an exact zero is its own class and no float equality is compared anywhere. wall_ms 0.479 to
50.098 is recorded and gates nothing. # commit 695933f on amd-ryzen-9-5900x-12-core at
2026-08-30T09:28:22Z, no (WORKING TREE DIRTY).
| clause | registered | measured |
|---|---|---|
| C1 the Kuhn triangulation of the unit cube is regular, demonstrated by exhibiting an explicit convex lifting function, or shown not to be — "this single fact decides the whole transfer" | falsified by non-regularity | HELD — is_regular true, fm_feasible true, lifting_function neg_pairs_of_set_bits, lifting_closed_form w(S)=-|S|*(|S|-1)/2, lifting_heights 0|0|0|-1|0|-1|-1|-3, hull_facets 6, secondary_polytope_vertex 6|2|2|2|2|2|2|6. witness_verified true and witness_matches_exhibited true on all 16 rows |
| C2 if regular, the patchworked surface's isotopy claim agrees with T-015's Plantinga–Vegter checker on every cell of every reference field | falsified by disagreement with T-015 | c2_holds true on 4 rows of 16 — torus and fbm_terrain at both resolutions, where pv_disagreements is 0 and isotopy_agreement 1.000000. False on the other 12, isotopy_agreement 0.063800 (box_exact 65³) to 0.994958 (sphere 65³), pv_disagreements 22,841 summed |
| C3 the connection to the Lovász-extension framing is made explicit: the Lovász extension is PL interpolation over exactly this triangulation | falsified by the two framings differing, "which would be genuinely surprising" | HELD — lovasz_mismatches 0 over lovasz_probes 15,379 (7 candidates × 13³ = 2,197 exact rational probes), by two routes sharing no code. weak_submodular_iff_convex 7of7 and strict_submodular_iff_kuhn 7of7, farkas_certificates 9 with farkas_total_weight 12, submodular_diamonds 6, diamonds_are_regularity_rows true |
C1 is decided by a linear program in exact integers, and the reason it can be is worth one line: every Kuhn tetrahedron is unimodular.
kuhn_unimodulartrue withkuhn_normalised_volume6 — the six tetrahedra are taken from the crate, not re-derived, through the publicisomesh::marching_tetrahedra::table::{TETS, TET_EDGES}(table.rs:87,:121), so they are bit-for-bit the sixMarchingTetrahedramarches.|det| = 1makes every barycentric coordinate an integer, so the6 × 4 = 24strict inequalities in 8 unknowns (regularity_inequalities24) have coefficients in{−1, 0, 1}. They reduce todistinct_inequalities9, Fourier–Motzkin eliminatesw₇ … w₀withfm_stage_rows9|3|2|1|1|0|0|0|0—fm_max_stage_rows9,fm_max_coefficient1, no blow-up at all — and back-substitution constructs the witness rather than being handed it.What the back-substitution returned is the interesting part. It is told nothing about set functions and comes back with
0|0|0|-1|0|-1|-1|-3, which read as a function of the corner's popcount isw(S) = −|S|(|S|−1)/2: minus the number of unordered pairs inS, the negated edge count of the complete graph induced onS. The geometry is the picture — the main diagonal0–7is pushed lowest and the six tetrahedra, all of which contain that diagonal, fan around it.secondary_polytope_vertex6|2|2|2|2|2|2|6sums to4 × 6 = 24, and by Gel'fand–Kapranov–Zelevinsky the regular triangulations are exactly the vertices of the secondary polytope, sois_regular = trueis what makes that vector a vertex.Eight vacuity controls fired, all before the first
run.record, all panicking withVOID:. (1) The solver can say no: the same Fourier–Motzkin onw₀ > 0 && −w₀ > 0reports infeasible —solver_refuses_infeasibletrue,control_first_violationt0/v2. (2) The witness is verified twice by routes sharing no code with the solver: against all 24 inequalities directly, and against a brute-force enumeration of all 70 four-subsets of the eight corners, each tested for "every other lifted corner strictly above my affine hull" —hull_facets6, and that enumeration finds simplicial lower facets only, so a subdivision with a non-simplicial cell would report fewer than six. (3)liftings_rejectedcould not have been zero:liftings_tested7,liftings_accepted3,liftings_rejected4,rejected_liftingsabs_squared|staircase_order|pos_pairs_of_set_bits|one_diamond_flipped. (4)uncertified_cells11,174 summed over the corpus — the registration's own named control, so C2's agreement is not agreement on a constant. (5)active_cells > 0on every row andcertified_cells88,758 summed. (6)–(7)fixtures_fired4 on all 16 rows: adegenerate_certifiedfixture forcedpw = false, pv = true, analternating_uncertifiedfixture forcedpw = true, pv = false, so both disagreement directions were shown reachable by construction before the sweep ran. (8)report_matches_walktrue on all 16 rows —isotopy_report's own counts equal this harness's walk, so the two are not counting different cells.kuhn_cell_local_edges19 withkuhn_edge_census12|6|1is asserted againstP-124's census exactly, andkuhn_max_cut_edges13,kuhn_max_triangles12,kuhn_max_components3.
The two liftings the brief proposed are both wrong, and the harness measures that rather than asserting
it. w(v) = |v|² and the staircase w(u,v,w) = −(u + 2v + 4w) are both affine on {0,1}³ —
|v|² = v₀² + v₁² + v₂² = v₀ + v₁ + v₂ when every coordinate is 0 or 1 — so all eight points are coplanar
in ℝ⁴, every one of the 24 inequalities evaluates to exactly 0, and the lower hull is a single
non-simplicial cell. Both are in rejected_liftings. w(v) = |v|² is the Delaunay lifting and the
eight corners of a cube are cospherical, which is precisely its degenerate case: the classical recollection
is right about the function and wrong about the point set. The control that matters is
one_diamond_flipped — heights (0,0,0,0,0,−1,−1,−3), still convex, violating exactly one of the
nine and merging two tetrahedra. A checker that only detected affineness would pass it, and this one
rejects it.
C3's identity is stated in its correct form, and the correct form is not the one usually quoted. The 9
distinct regularity inequalities turn out to be, on the nose, six local strict-submodularity diamonds
f(S+i) + f(S+j) > f(S+i+j) + f(S) — submodular_diamonds 6, diamonds_are_regularity_rows true,
so the six are literally among the nine — plus three complementary-pair conditions, each of which is found
by search to be the sum of exactly two of the six. Nine Farkas certificates over non-negative integer
coefficients (farkas_certificates 9, farkas_total_weight 12) prove the implication in both
directions with no second solver, so the two systems define the same open cone. Hence:
w submodular weakly ⟺ its Lovász extension is convex (Lovász 1983); w strictly submodular ⟺ its
lower hull is exactly Kuhn's six tetrahedra (Viro's hypothesis). Both equivalences hold at 7of7, and
the gap between weak and strict is not pedantry — it is exactly abs_squared, staircase_order and
one_diamond_flipped, three liftings that are convex and submodular and induce a subdivision that is not
the Kuhn triangulation.
C2's split is a statement about two instruments, not about one of them being wrong, and the CSV shows the
divergence running in both directions. PW is "the transfer's hypotheses hold for this cell": regularity
(global, C1) and unimodularity (global) and the sign distribution is defined — no corner value exactly
zero, because Viro's ε_ω lives in {+1, −1}, a zero is not a sign, and the T-surface then passes through
a lattice point (M-48's degenerate crossing). PV is cell_is_certified from T-015
(validate/isotopy.rs:126). The two clean rows are clean for opposite reasons: torus at both
resolutions has exact_zero_corner_cells 0 and uncertified_cells 0, so both predicates are
constantly true; fbm_terrain likewise, pv_disagreements 0 on all four. Everything else splits.
box_exact is the extreme — exact_zero_corner_cells 1,352 and 5,768, i.e. every active cell has
a corner at exactly 0.0, so PW is false everywhere and PV certifies 1,176 / 5,400 of them:
isotopy_agreement 0.130178 and 0.063800, all disagreement in the pw_no_pv_yes direction. gyroid
and noise_cavity go the other way — pw_yes_pv_no 370 / 780 and 3,121 / 5,646 against
pw_no_pv_yes 7 / 7 and 114 / 146 — because their failure is PV declining to certify a cell whose
signs are perfectly well defined. Summed over the corpus the two directions are comparable: 9,923 one way
and 12,918 the other, so neither instrument dominates the other, and agreement_hypotheses_only
(0.485913 to 1.000000) carries the softer reading in which PW is the global constant, so a reader can
see both denominators without re-running anything.
The sharpest thing in the row is that PV's certificate does not bound the component count of the surface
marching tetrahedra actually emits. certified_multi_component — PV-certified cells whose Kuhn PL surface
has more than one connected component — is 99 summed, non-zero on gyroid (3 / 9), fbm_terrain
(15 / 29) and noise_cavity (5 / 38), and uncertified_multi_component is 623. It is not an accident of
the corpus: the harness constructed the witness before the sweep. [1, −1, −1, 1, 4, 4, 4, 4] has
z-differences 3, 5, 5, 3, so the interval inner product is 3² − 2² − 2² = +1 > 0 and PV certifies "one
component, isotopic to a disc", while the six tetrahedra emit two disjoint patches around corners 1 and 2 —
and with 4 replaced by 3 the same sign mask is not certified, which proves the certification is a
property of the values rather than of the mask. So on fbm_terrain, where C2 holds at 1.000000 on both
rungs, 15 and 29 cells are simultaneously PV-certified and two-component. Agreement of the two predicates
is not agreement about the surface.
One more price of the source document's identification, measured rather than assumed. Viro's ε_ω is the
sign of the coefficient of the monomial x^ω, not the value at the corner, and the two sign vectors are
related by the Möbius transform (c_ω = Σ_{v ≤ ω} (−1)^(|ω|−|v|) f_v). They are not equal:
coeff_signs_match is 2,164 of 99,932 active cells, i.e. the two readings of "signs at the eight lattice
points" agree on 2.2% of them, and t_components_differ 20,437 cells give T-surfaces with different
component counts under the two readings. coeff_zero_cells is 32,071. That is a fact about the phrase
"signs at the lattice points", and it belongs beside C3's identity rather than inside it.
What a consumer of this crate gains is a sentence, and it is worth exactly zero microseconds.
crates/isomesh/src/ is untouched, no golden hash moved, the whole row is one algebraic decision plus two
read-only sweeps through the public API. What C1 buys: for every non-degenerate sign configuration,
marching tetrahedra's output is isotopic to a genuine real algebraic hypersurface with the cube as Newton
polytope, by Viro's T-construction, with a citation and an exhibited lifting behind it. What C2's split
tells a caller who wanted more than that: the Viro hypothesis and T-015's certificate are different
predicates about different surfaces, they disagree on 22.9% of active cells across this corpus, and neither
one may be substituted for the other. marching_tetrahedra/table.rs:15-53 already proved the six tetrahedra
tile without alternation and P-100 / ✗78 / M-412 measured open_edges = 0 across a chunk seam; both are
about matching. This row is the first thing in the tree about convexity.
🔬 M-453 — C1 and C2 both HELD on all 560 rows: six fields with topology prescribed by construction — genus 1, 2, 3, 2, 3, 5 and prescribed_chi {0, −2, −4, −2, −4, −8} by two derivations that share no algebra — and every one of 7 extractors reproduces every prescribed χ, all 56 pairs correct at 49³; the sampling-adequacy curve is informative with distinct_first_correct_overall 5 over the rungs 5, 7, 9, 11, 13, and its sharpest finding is not about genus: graph_cube_g5, the highest-genus fixture, is perfect at 7³ and 11³ and meshes literally nothing at 9³ (P-140, R-140)
M. cargo bench --bench experiment_p140, docs/experiments/p-140.csv, 560 rows across 37
columns — four # comment lines plus one column header plus 560 data rows, counted from the file. The
shape, also from the file: 8 fixtures × 7 extractors × 10 rungs, extractors_tested 7 on every row,
resolution_ladder 5|7|9|11|13|17|21|25|33|49 samples per axis over the [−2, 2]³ domain, cells
64 … 110,592, cell_size 1.000000 … 0.083333. is_control true on the 140 sphere and torus
rows and false on the 420 prescribed ones. The seven extractors are extractor::ALL_EXTRACTORS driven
through for_each_extractor!; GreedyQuads is excluded by the crate for the reason at
extractor.rs:246-252 — its χ is that of a Minecraft surface, which would be a category error rather
than a measurement. # commit 71e5474 on amd-ryzen-9-5900x-12-core at 2026-08-30T09:28:55Z, no
(WORKING TREE DIRTY).
| clause | registered | measured |
|---|---|---|
C1 at least three patchworked fields with prescribed non-trivial genus are added as fixtures, and every extractor reproduces the prescribed χ at sufficient resolution |
falsified by any extractor failing to converge at any resolution | HELD — c1_holds true, global. Six prescribed fixtures, converged true on all 420 prescribed rows and on all 140 control rows, and chi_agreement true on all 56 fixture × extractor pairs at the finest rung |
C2 the resolution at which each extractor first reproduces the prescribed χ is reported per extractor — a sampling-adequacy curve the crate does not have for any field of known topology beyond the sphere and torus |
falsified by all extractors converging at the same resolution, "still worth one line" | HELD — c2_holds true, global. distinct_first_correct_overall 5; fixture_distinct_first_correct 3 on ball_drilled_g3, 2 on torus, ball_drilled_g2, graph_theta_g2 and graph_k4_g3, 1 on sphere, ball_drilled_g1 and graph_cube_g5 |
prescribed_chiis arithmetic andmeasured_chiis a reading, and they are computed by code that shares nothing. The instrument is the crate's own:MeshReport::euler_characteristic(validate.rs:185) isreferenced_vertices − edges + facesandMeshReport::genus(:202) is(2 − χ − boundary_loops)/2. Construction A — a ball of radiusRwithgz-parallel cylinders drilled through it,derivationmayer_vietoris: the boundary is a sphere with2gdisks removed, glued along2gcircles togannuli, soχ = (2 − 2g) + 0 − 0 = 2 − 2g. Construction B — the closedt-neighbourhood of an embedded graph,derivationgraph_thickening: a regular neighbourhood of a graph is a handlebody withχ(N) = χ(G)andχ(∂M) = 2χ(M), soχ = 2(V − E)andgenus = E − V + 1. Two families rather than one, because a single family would leaveprescribed_chiand the construction confounded:ball_drilled_g2andgraph_theta_g2both prescribe χ = −2 through arguments sharing no algebra, andball_drilled_g3andgraph_k4_g3do the same for χ = −4.Seven vacuity controls fired, all before the first
run.record, all prefixedVOID:. (1) The ladder is a ladder — ten strictly increasing rungs, so "first correct" names a well-ordered thing. (2) The registered control, "or the fixture is a sphere in disguise": at least three prescribed fixtures with genus above 1 — there are five (ball_drilled_g2,ball_drilled_g3,graph_theta_g2,graph_k4_g3at 2, 3, 2, 3 andgraph_cube_g5at 5). (3)prescribed_chiis not a constant — five distinct values{2, 0, −2, −4, −8}. (4) The prescription is sound by construction and not by measurement:separation,window,solid_width,merge_headroomanddomain_marginall strictly positive on every fixture, andgeneratorsequalsprescribed_genuson all eight, cross-checked againstE − V + 1for the graphs and against the bore count for the balls, each cycle carrying its own witness — its centroid checked to lie strictly outside the solid, so every prescribed handle demonstrably has an open window. The graphs' numbers:graph_theta_g2separation0.749307,window0.751011,merge_headroom0.249869,domain_margin0.720000;graph_k4_g30.880000 / 0.615755 / 0.458234 / 0.472923;graph_cube_g50.940000 / 0.940000 / 0.354020 / 0.420962. The balls reportseparationandmerge_headroominfbecause a single bore family has no pair to separate. (5) The instrument reads a knownχ:sphereandtorusreproduce their crate-declaredexpected_euler2 and 0 on all seven extractors,derivationcrate_expected_euler, which is what licensesmeasured_chiat all — the calibration is deliberately notcommon::tpms, whoseχis defined only afterwrap_seamsand read offcommon::tpms::euler, because a wrapped row would makemeasured_chimean two things in one column. (6)chi_agreementcould have readfalse— it does, on 97 of 560 rows. (7) The sweep meshed something: at the finest rung every fixture × extractor pair produced at least one face, andchi_agreementisfaces > 0 && measured_chi == prescribed_chiprecisely becauseχof an empty mesh is0 − 0 + 0 = 0by arithmetic and bothtorusandball_drilled_g1prescribe χ = 0.
These are bench-local fixtures. They are not added to for_each_reference_field!, and that is deliberate,
priced, and a Phase 28 ticket rather than an omission. One new reference field adds 27 rows to
crates/isomesh/golden_hashes.json (9 algorithms × 3 resolutions; the file's 216 is 8 fields × 27) and moves
scripts/doc_facts.sh's FIELDS and HASHES counts, which are gated as prose phrases across twelve
documents. Six new fields would be a repo-wide renumbering landed inside a measurement commit, and
crates/isomesh/src/** is frozen for this phase. C1's "are added as fixtures" is therefore discharged as
bench-local fixtures, which is what made the measurement possible at all: no golden hash moved, no
document's counted phrase moved, and nothing in crates/isomesh/src/ was touched.
The sampling-adequacy curve, which is the first statement anywhere in this repository of how much grid an extractor needs before its topology is right on a field whose topology is known. Every prior answer was available for genus 0 and genus 1 only.
| fixture | mc |
mc+decider |
mt |
surface_nets |
dual_contouring |
manifold_dc |
subgrid_mt |
|---|---|---|---|---|---|---|---|
sphere (control, g0) |
5 | 5 | 5 | 5 | 5 | 5 | 5 |
torus (control, g1) |
9 | 5 | 9 | 9 | 9 | 9 | 5 |
ball_drilled_g1 |
5 | 5 | 5 | 5 | 5 | 5 | 5 |
ball_drilled_g2 |
7 | 7 | 7 | 7 | 7 | 7 | 5 |
ball_drilled_g3 |
11 | 9 | 11 | 11 | 11 | 11 | 7 |
graph_theta_g2 |
11 | 11 | 11 | 11 | 11 | 11 | 9 |
graph_k4_g3 |
13 | 7 | 7 | 13 | 13 | 13 | 7 |
graph_cube_g5 |
7 | 7 | 7 | 7 | 7 | 7 | 7 |
Two orderings fall out of that table and neither is about genus. subgrid_marching_tetrahedra is
earliest or tied on all eight fixtures, which is what a 576-evaluation-per-cell extractor should buy and
had never been demonstrated against a known χ. And marching_cubes+decider converges strictly earlier than
bare marching_cubes on three fixtures (torus 5 against 9, ball_drilled_g3 9 against 11,
graph_k4_g3 7 against 13) and never later — the asymptotic decider is buying topological correctness at
coarse resolutions, not just a different triangulation. On graph_k4_g3 the two tetrahedral extractors
reach χ = −4 at 7³ while the entire dual family needs 13³, which is the widest per-fixture spread in the
sweep after ball_drilled_g3's three distinct values.
Sampling adequacy is a commensurability property of the lattice and the feature, not a width — and the
sweep is where that is visible rather than merely arguable. feature_clearance is between 0.520000 and
0.560000 on every one of the six prescribed fixtures and feature_cells between 6.240000 and
6.720000, i.e. the predictor is nearly constant across them while their first-correct rungs spread over
5, 7, 9, 11, 13. graph_cube_g5 is the proof. Its edges lie on the lines (t, ±0.75, ±0.75) and
permutations; at 9³ the cell is h = 4/8 = 0.5, so every sample sits at a multiple of 0.5 and
min |0.5k − 0.75| = 0.25, putting every sample at least 0.25·√2 = 0.35355 from every edge axis against a
tube of 0.28. The whole genus-5 solid falls between the samples: faces reads 0 and mesh_components 0
on six of the seven extractors at 9³, and again at 5³ where h = 1.0 gives the same 0.25 residual —
12 of the 18 empty-mesh rows in the file. At 7³ and 11³ the same fixture is exactly right on all seven.
subgrid_marching_tetrahedra is the one extractor that survives 9³ (measured_chi −8, faces 1,248),
because it samples inside the cell rather than only at its corners. The other six empty rows are
graph_k4_g3 at 5³, where subgrid again finds something — and finds it wrong, measured_chi 16 on 48
faces.
The whole ladder is swept even after an extractor has converged, and that is why the file can show a
non-monotone curve rather than hiding it behind an early exit. It has 16 of them. The pilot's example
reproduces exactly in the committed run: marching_tetrahedra on graph_k4_g3 reads χ = −4 at 13³,
−16 at 17³, and −4 again at 21³ — and subgrid_marching_tetrahedra reads −16 at 17³ on the same
fixture, so it is a property of the field at that rung and not of one extractor. More: five of the seven
extractors read χ = 2 or 6 on ball_drilled_g2 at 9³ having been correct at 7³, marching_cubes+decider
reads 20 on graph_k4_g3 at 9³, and even the torus control is non-monotone twice —
marching_cubes+decider reads χ = 8 at 7³ after being correct at 5³, and subgrid_marching_tetrahedra
reads 4 at 25³ after seven correct rungs. first_correct_resolution is therefore a first, never a
threshold, and the file has to be read as a curve rather than as a bound. never would have meant "never
within [5, 49]" and is a recorded value; it does not appear.
chi_agreement deliberately does not also require mesh_components == 1 or manifoldness, and the
consequence is the one thing a consumer must take from this row. At the finest rung all 56 pairs
reproduce their prescribed χ, and yet measured_genus is none on 10 of them —
surface_nets and dual_contouring on ball_drilled_g2, ball_drilled_g3 and graph_k4_g3
(nonmanifold_edges 8 / 12 / 24, non_manifold_vertices 16 / 24 / 48), and
subgrid_marching_tetrahedra on ball_drilled_g1, ball_drilled_g2, ball_drilled_g3 and graph_k4_g3.
A correct Euler characteristic is not a manifoldness certificate, and this file is a 560-row demonstration
of it. The subgrid rows are the sharper half: nonmanifold_edges 0, non_manifold_vertices 0,
boundary_edges 0, duplicate_vertices 0, mesh_components 1 — so the term of
MeshReport::is_manifold() that fails is one of the two this CSV does not carry,
inconsistently_oriented_edges or a structural error (validate.rs:342-347, the orientation counter at
:780-783). Sweep-wide, boundary_edges is 0 on all 560 rows and the manifoldness burden is entirely
dual-and-subgrid: marching_cubes, marching_cubes+decider, marching_tetrahedra and
manifold_dual_contouring report nonmanifold_edges 0 and non_manifold_vertices 0 on all 80 of
their rows each, against surface_nets and dual_contouring at 396 non-manifold edges and 692
non-manifold vertices apiece over 33 non-manifold rows each, and subgrid_marching_tetrahedra at 90
and 110 over 39 rows. manifold_dual_contouring earning a clean sheet where its two dual siblings do
not is the clearest thing this fixture set has to say about that extractor.
What changes for a consumer of this crate: nothing yet, and that is the registration's own SHARE line
discharged rather than waved through. "SHARE: none — this adds test coverage, and its value is the
coverage", and the coverage is bench-local by the phase's own rule, so the shipped test suite gains nothing
until a Phase 28 ticket lands these as reference fields with the 27-hashes-per-field ripple priced in. What
ships now is smaller and real: six χ values that are known rather than measured, and the first
per-extractor first-correct table in the repository.
🔬 M-454 — C2 and C3 HELD and c1_holds true on 2,112 queries of 2,304, with the 192 exceptions all in one arm and all the pre-registered outcome: z3 5.1.0 re-derived AMBIGUOUS_FACES entry by entry over every real corner assignment, cases_matching_table 1,536 of 1,536 and cases_disagreeing 0 with control_unambiguous_refuted 0 over the 1,344 known-correct sub-cases; it refuted the shipped Separate default on 192 of 192 ambiguous faces in 1.185 s; and it timed out at the 2 s cap on 192 of 192 nested-quantifier witness queries, terminated=false, which is C1's registered second branch and not a defect — the whole derivation cost 399.598 s of solver time and produced 2,304 hash-stamped .smt2 certificates (P-141, R-141)
M. Z3=~/.venvs/isomesh/bin/z3 cargo bench --bench experiment_p141, docs/experiments/p-141.csv,
2,304 rows across 46 columns — four # comment lines plus one column header plus 2,304 data rows,
counted from the file. This is Phase 27's only row that needs an external binary, and it is not
optional: the solver is the executable named by the Z3 environment variable and the harness panics
without writing anything if it cannot be executed, because a CSV row for a solver that did not run is the
one artefact this row must never produce. solver z3-5.1.0 on all 2,304 rows, solver_raw
Z3_version_5.1.0_-_64_bit. The shape, from the file: five arms — ambiguity_affine 1,536 rows
(= 256 cases × 6 faces), then decider_affine, separate_affine, decider_nested, separate_nested at
192 each (the ambiguous faces only). case_index covers all 256 values and face is 384 rows
each of xlo, xhi, ylo, yhi, zlo, zhi. query_timeout_s 2 on every row, handed to the
solver as its own -T:2 so no query can hang. # commit eb205ed on amd-ryzen-9-5900x-12-core at
2026-08-30T09:38:06Z, no (WORKING TREE DIRTY).
| clause | registered | measured |
|---|---|---|
| C1 a real-quantifier-elimination engine terminates on the single-cell topology query over the 8 corner parameters within a stated budget, or is reported as not terminating, which is itself the answer | falsified by non-termination within budget, "which closes the row honestly and is a real possibility" | c1_holds = terminated, true on 2,112 rows and false on 192. query_status unsat 1,728 / sat 384 / timeout 192. Every one of the 192 is separate_nested and every one sat at the cap, wall_clock_s 2.002031–2.002637 against query_timeout_s 2. The other four arms terminated on 2,112 of 2,112, worst wall_clock_s 0.020 |
| C2 the derived taxonomy is compared against the crate's committed table, and every disagreement is adjudicated by hand against the trilinear | falsified by zero disagreements, which would instead be a strong independent validation of validate_table() |
HELD — c2_holds true, global, scored on total_disagreeing 192 > 0. Those 192 are separate_affine: cases_derived 192, cases_matching_table 0, cases_disagreeing 192. The derivation arm disagrees nowhere — ambiguity_affine cases_matching_table 1,536 of 1,536 |
| C3 any disagreement is checked against Custodio et al.'s published corrections to Chernyaev, so a machine disagreement is either a known bug or a new one | falsified by disagreements outside Custodio's set that survive adjudication | HELD — defects_outside_custodio 0, adjudicated_defects 0, custodio_corrections_known V-24|V-25|M-165|M-352. custodio_disagreement_overlap is 0_of_0 on the four arms whose refutation would be a defect and 0_of_192 on separate_affine, whose refutation is not one |
The query, verbatim from the certificate, because the whole point is that the solver was not handed the
answer. Over eight Real corner parameters with the case's eight sign constraints asserted
(fi < 0 where cube::corner_inside puts corner i inside, fi >= 0 otherwise — an exact zero is
outside, cube.rs:171-173), the topological question is stated without naming a formula:
truth <=> for all p in [0,1] there is a q in [0,1] with B(p,q) < 0
and every query in the file has one shape, (assert (not (= <claim> truth))) (check-sat), so unsat
means the claim holds for every real corner assignment in this case's sign class and sat means a
counterexample exists. There is no second assertion form and no per-arm special case. The two encodings of
truth, taken from /tmp/isomesh-p141/ambiguity_affine__case000__xlo.smt2 (992 bytes,
smt2_hash e81ffc571bcdc6fa) and separate_nested__case006__zlo.smt2:
; affine -- the inner existential discharged analytically and nothing else
(define-fun truth () Bool
(forall ((p Real))
(=> (and (<= 0.0 p) (<= p 1.0))
(or (< (+ (* f0 (- 1.0 p)) (* f4 p)) 0.0)
(< (+ (* f2 (- 1.0 p)) (* f6 p)) 0.0)))))
; nested -- `truth` verbatim
(define-fun truth () Bool
(forall ((p Real))
(=> (and (<= 0.0 p) (<= p 1.0))
(exists ((q Real))
(and (<= 0.0 q) (<= q 1.0)
(< (+ (* f0 (- 1.0 p) (- 1.0 q)) (* f2 p (- 1.0 q)) (* f3 p q) (* f1 (- 1.0 p) q)) 0.0))))))
B(p,·) is affine in q, so its minimum over [0,1] is at an endpoint and
∃q ∈ [0,1] . B(p,q) < 0 is exactly B(p,0) < 0 ∨ B(p,1) < 0 — q = 0 is the ring edge (v₀,v₁) and
q = 1 is (v₃,v₂). That is the only thing the affine encoding discharges; the residual formula is
still nonlinear in the parameters and still needs real quantifier elimination.
The 192 timeouts are one arm, one direction, and the reason the file has two encodings at all. z3 refutes the nested
∀p ∃qform and cannot produce a model of it:decider_nestedcame backunsaton 192 of 192 inarm_solver_s3.285 with a worstwall_clock_sof 0.020, whileseparate_nested— the arm whose correct answer issat, a witness — timed out on 192 of 192 and burnedarm_solver_s384.443 of the run's 399.598 s doing it. Refuting an∃∀∃prefix reduces to a universal statement nlsat handles; exhibiting a model of a quantified nonlinear formula needs the elimination itself. So a design that used only the nested form could never have returnedsat, and an instrument that can only produce one answer has not measured anything (M-44). The affine encoding decides both directions on the same 192 faces in 1.185 s —separate_affinesaton 192 of 192 — which is the same question answered 324× faster and, more to the point, answered at all. Both outcomes were registered in advance, andterminated=falseis reported as the answer it is rather than dropped or retried at a larger cap.Nine vacuity controls fired, every one before the first
run.record, every one also a column so a reader can check it without re-running. (1)control_table_mismatches0 — this harness's own alternating-sign test againstAMBIGUOUS_FACESon all 1,536 pairs, so the population being derived is the table's. (2)control_ambiguous_pairs192 andcontrol_ambiguous_cases120: 192 is6 faces × 2 alternating patterns × 2⁴ free cornersand 120 is256 − 136, the 136 beingM-41's. (3)control_decider_transcription_mismatches0 over 12,288 assignments — the decider predicate as the SMT text states it, evaluated in Rust, against the shippedambiguity::face_is_joined; without this the solver would be answering about this file's transcription instead of the crate's rule, which is exactly the failureM-219is. (4)control_forced_oracle_mismatches0 — the exact interval evaluator against an independent oracle on all 1,344 unambiguous pairs. (5)control_varying_ambiguous192 —truthmust actually vary with the magnitudes on every ambiguous face, or the constancy question is being asked of a constant and thesatanswers are a zero that could not have been non-zero. (6)control_tangency_samples6,836 ofcontrol_samples98,304: theall_unitfixture putsd_in == d_outexactly on every ambiguous face, so the tie the crate documents atambiguity.rs:45-48is reached by construction rather than by seed luck. (7)control_numeric_disagreements0 — the decider against the interval evaluator over the same 12,288 assignments; a finite counterexample there would make the solver'sunsatimpossible. (8)control_unambiguous_refuted0 — the registration's own named control: "the pipeline must first re-derive a known-correct sub-case the table already contains, or a clean run proves nothing about the solver's fidelity." All 1,344 of them re-derived, not onesat. (9) Both answers seen: 1,728 unsat and 384 sat in one run.
The derivation proper, and what it establishes that nothing in this tree established before.
table::CASES is build_cases() evaluated during compilation (marching_cubes/table.rs:180-194) and
AMBIGUOUS_FACES is build_ambiguous_faces() (:202-231), so the crate already refuses to transcribe
the 256-case triangulation — but derived at compile time is not proved, and both are built from the same
eight-corner sign convention the rest of the module assumes, so what they establish is that the module
agrees with itself. validate_table() (marching_cubes/mod.rs:836) and validate_decider_table() (:857)
check internal consistency and never evaluate the interpolant; M-40, M-165 and M-220 are censuses
over finite samples. ambiguity_affine asks the question over every real corner assignment: unsat says
truth does not depend on the magnitudes, which is the definition of a non-ambiguous face. It came back
unsat on the 1,344 unambiguous pairs and sat on the 192 ambiguous ones, spanning exactly 120
distinct case_index values — the same 120 the control asserts — in arm_solver_s 9.382, worst query
0.014 s. cases_disagreeing 0. So AMBIGUOUS_FACES is now derived by quantifier elimination as
well as by build_ambiguous_faces(), and the same holds for the asymptotic decider:
rule asymptotic_decider, agrees_with_table true on all 384 decider_* rows, both encodings,
cases_matching_table 192 of 192 each. The transcription cost M-207, M-219, M-221, ✗22,
M-228 and M-231 bill for is removable, and this row is the receipt: 399.598 s of solver time, once, for
a table entry-by-entry checked against the object it is a table of.
C2 held on the arm the registration did not have in mind, and that is the one place the file's verdict
needs reading carefully. The registered falsifier is "C2 by zero disagreements, which would be a strong
independent validation of validate_table() and worth the whole ticket", and the derivation arm produced
exactly zero — ambiguity_affine cases_disagreeing 0 over 1,536, decider_affine and
decider_nested 0 over 192 each. Read against the ambiguity table alone, C2's falsifier fires and the
prize the registration named is won. The harness scores C2 on total_disagreeing over all arms
(experiment_p141.rs:1272-1275), which is 192, from separate_affine refuting FaceAmbiguity::Separate
— the crate's shipped default, whose own documentation says it "agrees with the field's own bilinear
interpolant on the face only by luck" (ambiguity.rs:13-14). Both statements are in the file and neither
is averaged into the other: the derived taxonomy agrees with AMBIGUOUS_FACES and with the decider on
1,920 of 1,920 decided entries, and disagrees with the default pairing on 192 of 192. A reader who wants
C2's registered reading should quote cases_disagreeing 0; a reader who wants the harness's should quote
total_disagreeing 192. That is the sharpest disagreement between this CSV and its registration in the
group.
C3's zero is a zero over an empty adjudicated population, and the arithmetic that makes it empty is worth
stating rather than leaving to be inferred. defects_outside_custodio is computed as
Σ (disagreeing − custodio_covered(disagreeing)) over the arms for which refutation_is_a_defect() is true
(experiment_p141.rs:1265-1270). refutation_is_a_defect is true on ambiguity_affine,
decider_affine and decider_nested and false on both separate_* arms — the adjudication, and a
correct one: a separate_affine refutation indicts nothing, because the crate never claimed Separate
matches the interpolant. Those three arms disagreed 0 times, so adjudicated_defects is 0 and
defects_outside_custodio is 0 − 0 = 0 necessarily. C3 could only have been falsified by a disagreement
in the ambiguity or decider arms, and there were none; over the 192 disagreements that do exist it says
nothing at all, which is what custodio_disagreement_overlap 0_of_192 on that arm records. V-24,
V-25, M-165 and M-352 are the corrections the overlap would have been checked against.
The certificate is per query and it is a hash rather than a committed file.
machine_checkable_certificate is <bytes>b_<hash> — 2,304 distinct hashes over 2,304 distinct
smt2_file names, smt2_bytes 985 to 1,066 summing to 2,307,128 bytes. The .smt2 text is
written to std::env::temp_dir()/isomesh-p141 (experiment_p141.rs:1156, 2,304 files present after the
run) and is not committed to the repository; what is committed is the per-row smt2_bytes and
smt2_hash, so any reader can regenerate the query, hash it and re-run it against their own z3. TOTAL_BUDGET
is a second, whole-run bound that panics rather than truncating, on the principle that a short CSV which
looks complete is worse than no CSV.
What changes for a consumer of this crate: nothing at runtime, and that was the registration's SHARE line
before the numbers. This harness calls no extractor, allocates no grid and touches nothing on the
extraction path; CASES and AMBIGUOUS_FACES are read, never rebuilt, and crates/isomesh/src/ is
untouched. What the repository gains is a method and a price: the case table is machine-derivable in under
seven minutes of solver time on one desktop, over every real corner assignment rather than over a sample,
and the dossier's rejection of CAD as "global, doubly exponential, needs arbitrary precision" priced a
runtime cost for something that is run once in a project's lifetime. The one caveat a future user of this
route must carry is the encoding asymmetry, measured here on 2,304 queries rather than argued: state the
existential analytically or the solver will refute and never witness.
💥 ✗104 / M-455 — C1 HELD to the integer on 16 of 16 in-scope rows (chi_measured -8 / -64 / -216 against chi_predicted -8 / -64 / -216 at N = 1, 2, 3, and -8 again at 65 and 97 voxels per period), C2 HELD with genus_measured = genus_predicted = 5 / 33 / 109 = 1 + 4N³ on all 16, C3 FALSIFIED on 70 of 70 because the gate was not added — and the falsifier's own reason for that is too strong: what the gate needs is a second ValidateConfig constructor plus one fold pass, not a change to Extractor::extract_into, and this row is the measurement that says so (P-142, R-142)
M. cargo bench --bench experiment_p142, docs/experiments/p-142.csv, 70 rows across 43
columns — four # comment lines plus one column header plus 70 data rows, counted from the file
rather than from the brief; 14 of the 43 columns are P-142's registered records and the other 29 are
M-273 extras. The shape, also counted from the file: five grids × seven extractors × two wrap
modes, field = gyroid on all 70, f64, amd-ryzen-9-5900x-12-core (Zen 3). The grids are
period_sweep at periods_per_axis 1/2/3 with voxels_per_period 33 (resolution 34/67/100,
cells 35,937 / 287,496 / 970,299) and resolution_sweep at N = 1 with voxels_per_period 65 and
97 (resolution 66/98, cells 274,625 / 912,673). # commit 845c7a8 on amd-ryzen-9-5900x-12-core at
2026-08-30T09:26:52Z, with no (WORKING TREE DIRTY) on that line. crates/isomesh/src/** is
unchanged by this row and no golden hash moved; the wrap, the Euler reader and the nodal field are all
benches/common/tpms.rs.
| clause | registered | measured |
|---|---|---|
C1 extracting the gyroid over an integer number of periods with periodic wrap gives χ = -8N³ exactly for N ∈ {1,2,3}, on every extractor in the crate that produces a closed surface |
integer equality, no tolerance | HELD — chi_agreement true on 16 of 16 rows with c1_scope = in_scope. chi_measured -8 (N=1), -64 (N=2), -216 (N=3) against chi_predicted -8 / -64 / -216, and -8 again at voxels_per_period 65 and 97, i.e. stable across a 3× refinement at fixed N. boundary_edges 0 and nonmanifold_edges 0 on all 16 |
| C2 the genus is consistent, so the surface is closed and orientable and C1's arithmetic applies | genus = (2 − χ)/2, every in-scope row |
HELD — genus_measured 5 / 33 / 109 = genus_predicted 5 / 33 / 109 = 1 + 4N³, genus_agreement true on 16 of 16, and chi_from_genus equals chi_measured on all 70 rows where a genus exists. genus_measured reads none on exactly 2 of 70 rows — the open subgrid_marching_tetrahedra arms at N = 2 and N = 3, where is_manifold is false with nonmanifold_edges 0, so the failing conjunct is one of the other three in validate.rs:342-347 rather than a non-manifold edge |
C3 the oracle is added to the validity suite as a gate for gyroid |
the gate exists in crates/isomesh/src/ |
FALSIFIED — c3_holds false on 70 of 70. It is not added, and nothing under crates/isomesh/src/ moved |
The single number that decides C1 is
seam_pairs_identified, and it is why the verdict is a measurement rather than a definition. The two wrap modes come from one extraction: theopenreading is taken beforewrap_seamsand theperiodicreading after it, so the arms differ in exactly one operation. On the 16 in-scope rows the wrap identified 305 / 1,225 / 2,769 pairs atN = 1/2/3undermarching_cubes, 503 / 2,045 / 4,655 undermarching_tetrahedra, and 593 / 905 at 65 and 97 voxels per period — never zero, soperiodicis never byte-for-byteopen.Four vacuity controls, all of them assertions rather than columns. (1) The
-8is derived, not assumed:body_centring_oktrue withbody_centring_residual1.887e-15,primitive_cells_per_cubic_cell2,primitive_latticebcc,space_groupIa-3d andchi_per_cubic_cell-8 on 70 of 70 — had the(π,π,π)shift merely negatedF_Gthe prediction would have been-4and the harness would have been grading its own arithmetic. (2) The surface exists:faces > 0on 70 of 70 (9,984 to 815,508), so no χ is0by vacuity (M-44). (3) C1's scope is non-empty and the wrap put it there: 16 in-scope rows, every one withseam_pairs_identified > 0. (4) The registered control ran and failed, and it is recognised by its boundary and not by its χ: all 35openrows carryboundary_edges > 0(564 to 8,856) and 0 of 35 agree with-8N³. The open χ is extractor-independent — -3 at everyN = 1grid, -53 atN = 2, -199 atN = 3,chi_gap5 / 11 / 17 — so the box cuts the same number of tunnels whichever algorithm cuts them, and periodicity rather than the extractor is what the wrap supplies.One instrument cross-check rides on every row:
validate_chiequalschi_measuredon 70 of 70, socommon::tpms::euler(welds, then counts) andisomesh::validate::validate_indexed(counts as given) agree on every reading in the file.
Which extractors close under the wrap is itself a result, and it is recorded per row rather than
filtered. c1_scope splits 70 rows into 16 in_scope, 35 control_open_arm and 19
excluded_not_closed. wrap_seams is a primal operation — it folds a coordinate within tol of
the far face onto the near one and welds — so it can only identify a vertex that lies on the domain
boundary plane. surface_nets, dual_contouring and manifold_dual_contouring place one vertex per
cell and emit a quad per interior grid edge: seam_pairs_identified is 0 on all 15 of their periodic
rows, the wrap is a no-op, and their periodic row is numerically their open row (chi_measured -3 / -53 /
-199, boundary_edges 564 to 5,280). That zero is the point of recording the column — a wrap that
identified nothing is visible as a zero instead of being inferred from a disagreeing χ.
subgrid_marching_tetrahedra is the interesting middle case: it is in scope at N = 1, v = 33 (χ -8,
boundary_edges 0) and excluded on its other four grids, where the wrap identified 503 / 2,042 / 4,649
/ 980 / 1,514 pairs and still left boundary_edges 12 / 24 / 12 / 12 with chi_gap -3 / -6 / -3 /
-3. Its extra sub-grid vertices do not all land on the boundary plane, so a periodic gate written against
it would need more than the primal fold.
C3 is false and the useful half of the answer is naming what it would take, because the registered
falsifier's reason is measurably wrong. The falsifier reads "C3 by the gate being unimplementable
within the existing suite". Two things are needed and neither is that. (1) A periodic domain on
ValidateConfig. validate_indexed counts V − E + F over the buffer it is handed and
ValidateConfig::from_cell_size (validate.rs:102) is its only constructor — it carries a cell size and
nothing about the box. The gate needs (lo, hi, wrap: [bool; 3]) and a fold in front of the weld it
already performs: a second constructor plus one pass. It is emphatically not a change to
Extractor::extract_into, whose doc states the signature "is not negotiable"
(extractor.rs:63-70), and this row is the evidence: wrap_seams is a pure post-pass over MeshBuffer
that needed no cooperation from any extractor and closed four primal extractors' output unmodified.
(2) An uncapped, period-conforming reference field. The shipped gyroid entry is capped_gyroid(),
whose expected_euler() returns None with the reason "genus depends on how many tunnels the cap
encloses" (fields/mod.rs:1078) and whose χ is not -8N³ at all. A gate needs a new field on
[0, 2πN]³ with expected_euler() = Some(-8N³), and one new entry in for_each_reference_field! adds
27 rows to golden_hashes.json (216 = 8 fields × 9 algorithms × 3 resolutions) and moves
doc_facts.sh's gated FIELDS and HASHES counts in twelve documents. So the gate is implementable in
validate; what it is not is implementable inside a measurement commit. The wave-1 summary's shorthand
"a trait-signature change" is looser than the measurement: no trait signature has to move.
voxels_per_period is odd on purpose, and nonmanifold_edges reading 0 on 70 of 70 is the positive
statement that the choice worked. The registration named "32, 64, 96 and 128 voxels per period", all
multiples of 8, and common::tpms's author measured over 168 configurations that a
multiple of 8 puts samples exactly on the π/4 lattice where a nodal function cancels to exactly
0.0 — M-48's degenerate crossing — after which one cell places coincident vertices and the weld
turns them into a pinch. In all twelve of the module's pinching runs chi_measured − chi_predicted
equalled non_manifold_edges exactly, which is why the column is on every row here. At 33, 65 and 97 it
is 0 everywhere, so no sample landed on the isosurface and no part of C1's agreement is a cancelled
pinch. P-143 runs the divisible-by-8 family as an explicit control and reproduces the failure on
Schwarz D.
What a consumer should do differently: nothing yet, and that is the honest answer. CLAUDE.md:199-203
and fields/mod.rs:23-28 both state as a standing rule that the gyroid has no derivable Euler
characteristic. Both statements are true of the box the crate samples and false of the surface, and
the correction is one line long: the boundary the rule describes is an artefact of cutting the 3-torus
open, and a periodic-conforming box plus a seam identification removes it. Until the Phase 28 fixture
ticket lands, gyroid's topology gate is still "record whatever the mesh said" — but the number to
compare against is now known, published and reproduced on four extractors at five grids.
💥 ✗105 / M-456 — C1 FALSIFIED on 1 of 10 in-scope rows, schwarz_p at N = 3 reading chi_measured -102 against chi_predicted -108 with non_manifold_edges 6 and chi_pinch_corrected -108 exactly, and falsified a second time by added_as_reference_field false on 36 of 36; C2 HELD as an exact i128 polynomial identity on 36 of 36 with the seven half-period shifts classified 1 / 0 / 6, 0 / 1 / 6 and 3 / 4 / 0 invariant/negated/neither — so Schwarz P's primitive_lattice is simple_cubic beside the space group Im-3m, and that apparent contradiction is the mechanism (P-143, R-143)
M. cargo bench --bench experiment_p143, docs/experiments/p-143.csv, 36 rows across 55
columns — four # comment lines plus one column header plus 36 data rows, counted from the file
rather than from the brief; 11 of the 55 columns are P-143's registered records and the other 44 are
M-273 extras. The shape, also counted from the file: three surfaces × six grids × two wrap modes,
extractor = marching_cubes on all 36, f64, amd-ryzen-9-5900x-12-core (Zen 3). Grids:
period_sweep at periods 1/2/3 with voxels_per_period 33, resolution_sweep at N = 1 with
voxels_per_period 65 and 97, and one degenerate_grid_control at voxels_per_period 32,
is_control = true. # commit 520b57b on amd-ryzen-9-5900x-12-core at 2026-08-30T14:10:40Z, no
(WORKING TREE DIRTY). Schwarz P and Schwarz D are bench-local common::tpms::NodalTpms fixtures;
nothing under crates/isomesh/src/ changed and no golden hash moved. The gyroid arm at N = 1,
v = 33 is directly comparable with p-142.csv and reproduces it to the integer — chi_measured -8
from vertices 5,284, edges 15,876 and faces 10,584.
| clause | registered | measured |
|---|---|---|
C1 both Schwarz P and Schwarz D are added as reference fields and both reproduce χ = N³·χ_cell under periodic wrap |
integer equality on both fields; graded by the falsifier "C1 by either field disagreeing" | FALSIFIED — c1_holds false, and the whole verdict turns on one row of the ten with in_c1_verdict = true: schwarz_p, period_sweep, N = 3, resolution 100, chi_measured -102 against -108. The other 9 of 10 agree exactly: Schwarz P -4 / -32 at N = 1, 2 and -4 at 65 and 97 voxels per period; Schwarz D -16 / -128 / -432 at N = 1, 2, 3 and -16 at 65 and 97. added_as_reference_field is false on 36 of 36, which is C1's other half answered negatively and reported in its own column |
C2 the mechanism, asserted rather than assumed: F_G is invariant under the body-centring shift (π,π,π) while F_P and F_D are negated by it, checked as a symbolic identity and not inferred from the χ values it explains |
exact identity, no tolerance | HELD — c2_holds true on 36 of 36. body_centring_invariance reads invariant on gyroid, negated on schwarz_p and negated on schwarz_d, decided by F' − F == 0 / F' + F == 0 in an eight-variable i128 polynomial ring with no floating point anywhere. All seven non-trivial half-period shifts are classified per surface: shifts_invariant/shifts_negated/shifts_neither = 1 / 0 / 6 (gyroid), 0 / 1 / 6 (Schwarz P), 3 / 4 / 0 (Schwarz D), and primitive_cells_per_cubic_cell = 1 + invariant gives 2 / 1 / 4 with chi_per_cubic_cell = -4 × that: -8 / -4 / -16 |
primitive_latticereadingsimple_cubicon a surface whose space group isIm-3mis not an inconsistency, it is the entire content of C2.Im-3mis body-centred, and its body-centring operation negatesF_P—nodal_expressionf5 + f3 + f1,nodal_terms3, one trigonometric factor per term, so(-1)¹ = -1on every term. A negating shift maps the zero set to itself but exchanges the two labyrinths: it is a symmetry of the surface and not a translation of the labelled structure, so it contributes nothing to the translation lattice and P's cubic cell holds one primitive cell. Writingbccthere besidechi_per_cubic_cell-4 would put a contradiction inside a single CSV row, becausebccmeans two primitive cells means-8. The gyroid is the other side of the same arithmetic —nodal_expressionf2*f5 + f1*f4 + f0*f3, two factors per term,(-1)² = +1, invariant, two primitive cells,-8. Schwarz D needs the face-centring half:nodal_expressionf1*f3*f4 + f1*f2*f5 + f0*f3*f5 + f0*f2*f4,nodal_terms4, three factors per term, so(π,π,π)negates while(π,π,0),(π,0,π)and(0,π,π)are invariant —shift_classesreadsnegated|negated|invariant|negated|invariant|invariant|negatedover the enumeration order(x) (y) (xy) (z) (xz) (yz) (xyz), three invariant,fcc, four primitive cells, -16.Eight vacuity controls, seven of them assertions. (1) The registered one — three different
χatN = 1:chi_at_n1_triple-8|-4|-16on 36 of 36, pairwise distinct, so the suite cannot confuse a correct oracle with a constant. (2) The three predictions were three numbers to begin with:chi_per_cubic_cell_symbolic-8 / -4 / -16, computed from the shift counts in this harness rather than transcribed. (3) The lattice index discriminates:primitive_cells_symbolic2 / 1 / 4, three different integers, so one explanation is not being offered for three different numbers, and each is asserted equal to the module's ownprimitive_cells_per_cubic_cell. (4) The classifier can say all three words: over the 21 classifications, 4 invariant, 5 negated, 12 neither. (5) The polynomial is the module's function:transcription_residual2.220e-16 (gyroid) and 4.441e-16 (P and D) over a 2,197-point offset grid — a symbolic identity about a mistyped polynomial is worth nothing, and this is the only thing standing between two transcriptions. (6) The exact algebra agrees with the numerics:body_centring_numeric_oktrue on 36 of 36 withbody_centring_residual1.887e-15 / 1.388e-15 / 1.707e-15, andshift_residualsreturns both the invariance and the negation residual so that neither is vacuous — a function that vanished on the grid would return two zeros and is refused. (7) No nodal polynomial is identically zero:nodal_terms3 / 3 / 4, sinceF = 0satisfies invariance and negation at once. (8) Every row meshed a surface:faces6,384 to 343,224.One control replaces a filter, and the swap is what makes C1 falsifiable at all. The obvious scope predicate is
MeshReport::is_closed(), whichP-142used. It isis_manifold() && boundary_edges == 0 && chi % 2 == 0(validate.rs:356) andis_manifold()requiresnon_manifold_edges == 0(validate.rs:342) — so a pinch makes a row not closed, and scoping on it silently deletes precisely the rows that can disagree withN³·χ_cell. Measured on this fixture, that filter drops the one Schwarz P row that disagrees and turns a false clause true: the failing row readsis_closedfalse andis_manifoldfalse withboundary_edges0. So closure is asserted on the property the clause actually needs,boundary_edges == 0, which a pinch does not satisfy away, andis_closed/is_manifoldare recorded as columns instead of used as filters.
The falsifying row is a statement about M-48, not about the oracle, and the two columns beside it say
so exactly. chi_pinch_corrected = chi_measured − non_manifold_edges is -102 − 6 = -108 on that
row, pinch_accounts_for_gap is true, and c1_holds_pinch_corrected is true on 36 of 36.
common::tpms's author measured that in all twelve of the module's pinching runs
chi_measured − chi_predicted == non_manifold_edges exactly — 4, 4, 7, 9, 17, 32, 135, never off by
one — because each pinch merges two sheets and costs exactly one from χ. Both pinching rows in this file
obey it: Schwarz P at N = 3 (gap 6, non_manifold_edges 6) and Schwarz D on the degenerate grid
(gap 4, non_manifold_edges 4). So the topological prediction N³·χ_cell was exact, and
marching cubes' handling of a sample that lands on the isosurface is the whole of the gap. The
registration is not amended (crates/isomesh/src/experiment.rs:27-31 forbids it): it was given the
falsifier "C1 by either field disagreeing", it is graded by that falsifier, and the corrected verdict
sits beside C1 rather than substituted for it. The grid that produced it was known to be a hard case
before the run — common::tpms recorded "Schwarz P shows the same failure once, at N = 3, v = 33, from
ordinary floating-point cancellation rather than an exact lattice" — and it was kept in scope, because
dropping the one configuration a prior measurement had already flagged as failing is choosing the
population after seeing the answer.
The divisible-by-8 family was run as a control instead of being avoided on a citation, and it
reproduced its published failure to the integer. common::tpms's author measured that Schwarz D reads
the wrong χ at every voxels_per_period divisible by 8 — -12 at 32 and 56, -9 at 64, -7 at 96,
+1 at 128, and only there — because a multiple of 8 puts samples on the π/4 lattice where F_D's four
terms are equal in magnitude and cancel to exactly 0.0 (at (π/4, π/4, 3π/4), for instance), the
crossing parameter is 0 or 1, one cell places coincident vertices, and the weld turns them into a pinch.
Those are exactly the four resolutions P-142's registration named. The degenerate_grid_control arm at
voxels_per_period = 32 reads: gyroid -8 (unaffected), Schwarz P -4 (unaffected), Schwarz D
-12 against -16 with non_manifold_edges 4, chi_pinch_corrected -16 and
genus_measured none. The -12 at 32 is the module's published number, reproduced independently on
a separate fixture in a separate binary. The mechanism is a property of the grid, not of the surface,
which is why the phase's odd choices — 33, 65, 97 — are a measurement rather than superstition.
The non-wrapped control is recognised by its boundary and deliberately not by its χ, and this file is
where that rule earns its keep. All 18 open rows carry boundary_edges > 0 (360 to 5,346), and
5 of 18 nevertheless agree with the closed-surface prediction, and all five are Schwarz P's:
chi_measured -4 at N = 1, -32 at N = 2, and -4 at 65, 97 and 32 voxels per period, every
one with chi_agreement true, hitting its own prediction by coincidence of the caps the box cuts. Its
sixth open row is the pinching one and disagrees like the rest (-102, non_manifold_edges 6).
Gyroid's six (-3 / -53 / -199 / -3 / -3 / -3) and Schwarz D's six (-11 / -117 / -415 / -11 / -11 /
-7) disagree throughout. A control that compared χ would therefore have passed the wrong arm on five
rows of eighteen, which is why what is asserted about χ is only that at least one open
row disagrees. The wrap identified 678 / 4,632 / 14,656 seam pairs on Schwarz P and 585 / 3,121 /
8,745 on Schwarz D at N = 1, 2, 3, so periodic is never byte-for-byte open.
What a consumer should do differently: nothing, and the reference-field roster does not move this
phase. added_as_reference_field is false on every row and the reason is priced rather than vague:
one new entry in for_each_reference_field! adds 27 rows to crates/isomesh/golden_hashes.json
(216 = 8 fields × 9 algorithms × 3 resolutions) and moves scripts/doc_facts.sh's gated FIELDS and
HASHES counts, which appear as prose in twelve documents — a repo-wide renumbering inside a measurement
commit. What this row does establish is that P-142's single number was not a coincidence: three
surfaces through one apparatus produce -8, -4 and -16, and all_three_agree_in_scope reads
false for exactly one reason — a degenerate crossing at N = 3 on Schwarz P — with the arithmetic of
that one reason on its own row.
💥 ✗106 / M-457 — C1 FALSIFIED by the three-octave half, where resolution_convergence reads never on 4 of 5 seeds and χ is still moving at 129³ — but the falsification runs the interesting way: at one octave χ converges on 5 of 5 seeds and oracle_exists is true on 35 of 140 rows, so a deterministic χ oracle for a periodic value-noise solid does exist, against a registration that named "no oracle available at game resolutions" as the likely outcome; C2 HELD with chi_variance_across_seeds 10.240000 and chi_span_across_seeds 8 at the converged rung, the converged χ reading -8 on three seeds, -12 on one and -16 on one, so the gate must be per-seed exactly as registered (P-144, R-144)
M. cargo bench --bench experiment_p144, docs/experiments/p-144.csv, 140 rows across 31
columns — four # comment lines plus one column header plus 140 data rows, counted from the file
rather than from the brief; 11 of the 31 columns are P-144's registered records and the other 20 are
M-273 extras. The shape, also counted from the file: 2 octave counts × 5 seeds × 7 resolutions × 2
wrap modes off 70 extractions, field = periodic_value_noise on all 140, period 4, iso
0.000, f64, amd-ryzen-9-5900x-12-core (Zen 3). The ladder is samples_per_axis 17 / 33 / 49 /
65 / 81 / 97 / 129 (cells_per_axis 16 to 128, cell_size 0.250000000 down to 0.031250000). Seeds:
0x5eed000000000001, 0x5eed000000000002, 0x0badc0ffee0dd00d, 0x123456789abcdef0,
0xf00dfacecafeb0ba. # commit ad28433 on amd-ryzen-9-5900x-12-core at 2026-08-30T09:29:17Z, no
(WORKING TREE DIRTY). Nothing under crates/isomesh/src/ changed; the field and the wrap are
bench-local.
| clause | registered | measured |
|---|---|---|
C1 with periodic wrap and a fixed seed, measured χ converges as resolution increases and is stable to at least 65³ |
falsified by "χ still moving at the highest tested resolution" | FALSIFIED — c1_holds false, a global verdict over both octave counts. At 1 octave it is met on every seed: resolution_convergence 17 / 17 / 33 / 33 / 49, chi_stable true on 5 of 5 at samples_per_axis 65, and chi_delta_from_top 0 from the convergence rung upward. At 3 octaves it fails: resolution_convergence never on 0x5eed000000000001, 0x5eed000000000002, 0x0badc0ffee0dd00d and 0x123456789abcdef0, and 97 on 0xf00dfacecafeb0ba. The three-octave ladders are still moving at the top: -4, -16, -26, -22, -26, -28, -30 and 0, 2, -2, -10, -4, -2, 0 on the two 0x5eed… seeds |
| C2 χ varies across seeds, so the gate must be per-seed rather than per-field | falsified by seed-independent χ | HELD — c2_holds true on 140 of 140. chi_variance_across_seeds is non-zero at every rung of every arm. Under periodic wrap it reads 13.760000 / 15.360000 / 10.240000 across the one-octave ladder and 160.000000 / 197.440000 / 213.760000 / 178.240000 / 207.040000 / 224.000000 / 228.160000 across the three-octave one, with chi_span_across_seeds 8 and 42 at the top rung; the control arm's own top-rung spans are 10 and 36 over variances 13.760000 and 184.960000. The converged one-octave χ is -8 on three seeds, -12 on one and -16 on one |
The two clauses together are the finding, and they are not in tension. C1 as registered is a claim about every seed at once and it fails, because a three-octave field is not resolved by a
129³grid. C2 says the number is per-seed and it holds. What survives is a narrower positive result than the registration asked for and a stronger one than its falsifier expected: at one octave, with periodic wrap, the field has a definite χ that the extraction reaches by33³on four of five seeds and by49³on the fifth, andoracle_exists— which additionally demandswrap_mode = periodic, convergence at or below 65, andboundary_edges == 0on every rung of the ladder — is true on 35 of 140 rows, i.e. on all thirty-five one-octave periodic rows and nowhere else.Why three octaves cannot converge here is an integer property of the grid, not an opinion.
finest_lattice_cells_per_axisis 4 at one octave and 16 at three, andvoxels_per_finest_lattice_celltherefore reads 4 / 8 / 12 / 16 / 20 / 24 / 32 across the one-octave ladder against 1 / 2 / 3 / 4 / 5 / 6 / 8 across the three-octave one. At129³the three-octave field is sampled at eight voxels per finest lattice cell — the resolution the one-octave field reached at33³, where it had already converged. The ladder is not too short; the field is sixteen times finer.The ladder carries three rungs above the
65³C1 names, and the file contains the row that proves one would not have been enough. At three octaves, seed0x123456789abcdef0reads χ -32 at 65, -32 at 81, then -36 at 97 and -32 at 129. A single confirming rung would have recorded that ladder as converged.chi_stableis by constructionfalseat the top rung (there is no higher rung to agree with), which is whyresolution_convergenceandchi_delta_from_toprather thanchi_stablecarry C1's evidence;chi_stablereads true on 54 of 140 rows.Seven vacuity controls, all assertions. (1) The registered one — at least three seeds, and distinct: five, checked on the de-duplicated seed set rather than the array length. (2) The seed is wired in:
min_seed_separation1.064370, strictly positive, so a seed-independent χ would have falsified C2 for the right reason rather than because the seed never reached the hash. (3) The field really is periodic:max_periodicity_residual1.332e-15 over 1,331 off-lattice probes and all three axes, against a1e-12bar — if it were not, the wrap would identify faces that do not match and every χ in the file would be an artefact. (4)octavesis not decorative: the two counts produce different fields on the same probes. (5) The two wrap modes are different measurements:boundary_edgesis 0 on all 70 periodic rows and 300 to 5,034 on all 70 control rows, andidentified_pairsis 158 to 2,540 on periodic and 0 on control. (6) Every extraction produced a surface:triangles2,860 to 319,772. (7) The ladder can falsify C1: 65 is on it and three rungs sit above it.non_manifold_edgesis 0 on 140 of 140, so no χ here is a cancelled pinch.
The shipped fbm_terrain is out of reach by arithmetic rather than by measurement, and that is the
first half of C1's answer. FbmTerrain::sample is p[1] − (base_height + amplitude · fbm(x, 0, z))
(fields/mod.rs:1352-1362) — monotone in y, so the sign at y = lo is opposite to the sign at
y = hi everywhere and no identification of the top and bottom faces exists. A heightfield therefore has
no χ on the 3-torus at any resolution, which is why closed_in_domain() returns false with the comment
"a heightfield exits through the sides" (fields/mod.rs:1384) and expected_euler() returns None
with "not closed, so there is nothing to assert" (fields/mod.rs:1387). What this row measures instead
is the volumetric sibling — the same lattice value noise thresholded as a solid, the shape noise_cavity
is and every cave generator in the wild actually meshes — made exactly periodic by taking the corner hash
modulo the lattice period. That is the most favourable case available: an oracle unreachable there is
unreachable for the terrain too.
The non-wrapped control converges as well, and reads a different number, which is why oracle_exists
demands closure rather than convergence. At one octave the control ladders converge on the same rungs —
resolution_convergence 17 / 17 / 33 / 33 / 49, identical to the periodic arm — yet oracle_exists
is false on all 70 control rows, because a χ counted over a surface with 300 to 5,034 boundary edges
is a number about the sampling box and not about the field. The two arms' converged values differ on every
seed: -8 against -2 on 0x0badc0ffee0dd00d, -8 against -4 on 0x5eed000000000002, -16 against
-12 on 0x123456789abcdef0, -12 against -4 on 0x5eed000000000001, -8 against -2 on
0xf00dfacecafeb0ba. So the wrap does not merely tidy the boundary; it changes the invariant, which is
the same conclusion p-142.csv's open arm reached on the gyroid.
What a consumer should do differently, and what nobody should write into the suite. Do not write a
single χ constant for a noise field: at one octave the five seeds give -12, -8, -8, -16, -8 and at
three octaves -30, 0, -42, -32, -40 in the seed order above, so a per-field constant is wrong by up
to 42 on the same field.
A per-seed gate is affordable and correct at one octave and is not available at three — and since the
crate's noise reference fields are multi-octave, the practical answer for noise_cavity and
fbm_terrain remains "record, do not assert", now with the reason measured rather than asserted. This
row opens no landing ticket: a positive result would open a fixture ticket for a ninth reference field
with a known χ, and the one-octave field that would carry it is not the field the crate ships.
🔬 M-458 — C1 and C2 both HELD: a digital-topology oracle reading χ off the field's own signs with no mesh involved reproduces chi_stratified_morse 2 on sphere and 0 on torus, reproduces P-142's analytic gyroid exactly (-8 / -64 / -216 against chi_predicted_p142 -8 / -64 / -216 with disagreement_cells 0), and supplies a first ground-truth χ on the two closed fields the crate declares unknowable — gyroid -24 stable across 33³ and 65³, noise_cavity 82 and -152 — at cost_ratio 0.4746 to 1.0648 of the extraction it grades; and Etiene et al. 2012's DOI, flagged unverified since Phase 23, resolves through three independent routes to 10.1109/tvcg.2011.109, Topology Verification for Isosurface Extraction, IEEE TVCG 18(6), 952–965, 2012 (P-145, R-145)
M. cargo bench --bench experiment_p145, docs/experiments/p-145.csv, 38 rows across 47
columns — four # comment lines plus one column header plus 38 data rows, counted from the file
rather than from the brief; 11 of the 47 columns are P-145's registered records and the other 36 are
M-273 extras. The shape, also counted from the file: four arms × two extractors, f64,
amd-ryzen-9-5900x-12-core (Zen 3). calibration is the five reference fields with
expected_euler() == Some(χ) at 33³ and 65³ (20 rows, is_control = true); new_ground_truth is
gyroid and noise_cavity at the same two grids (8 rows); out_of_scope is fbm_terrain (4 rows);
p142_cross_check is gyroid_nodal on the 3-torus at periods 1/2/3 with 33 voxels per period, whose
resolution column reads 34 / 67 / 100 and reproduces p-142.csv's exactly (6 rows). Every row is
meshed twice, extractor ∈ {marching_cubes, marching_cubes+trilinear} — the crate's default and its
ambiguity-resolving configuration. # commit 00631a7 on amd-ryzen-9-5900x-12-core at 2026-08-30T14:14:20Z,
no (WORKING TREE DIRTY). Nothing under crates/isomesh/src/ changed and no golden hash moved.
| clause | registered | measured |
|---|---|---|
C1 the method computes a ground-truth χ on at least two fields where the crate currently has none, and agrees with P-142's analytic prediction on gyroid |
two halves, both integer | HELD — c1_holds true on 38 of 38. Two new ground truths, gyroid and noise_cavity, both of which return expected_euler() == None today (fields/mod.rs:1078, :1256): chi_stratified_morse -24 on gyroid at both 33³ and 65³, and 82 / -152 on noise_cavity. The cross-check is exact: on all six gyroid_nodal rows chi_stratified_morse equals chi_predicted_p142 — -8 / -64 / -216 — with disagreement_cells 0 and agreement true |
| C2 the cost is reported and the set of fields where it applies is stated | falsified only by inapplicability to every field | HELD — c2_holds true on 38 of 38. applicable_fields names eight of the nine field entries run: box_exact\|csg_difference\|gyroid\|gyroid_nodal\|noise_cavity\|sphere\|thin_plate\|torus, with fbm_terrain the sole exclusion. method_cost_ms is the median of 5 repeats after a warm-up (method_repeats 5, with method_cost_ms_min/max beside it), 0.3103 to 52.6494 ms, against extract_cost_ms on the same row: cost_ratio 0.4746 (gyroid_nodal at N = 2) to 1.0648 (thin_plate at 65³). The oracle is cheaper than the extraction it grades on 34 of 38 rows and the four exceptions are all thin_plate, whose mesh is tiny (1,016 to 4,088 triangles) while the oracle still visits every block |
This is the digital-topology half of Etiene et al., not the stratified-Morse half, and the row says which. The paper gives two oracles;
oracle_methodreadsdigital_topologyon all 38 rows and the registered column namechi_stratified_morseis honoured as "the ground-truth χ of Etiene et al.'s method" rather than renamed. The weights are derived by enumeration over all 2562×2×2binary patterns from the crate's ownmarching_cubes::table::EDGE_CORNERS, not transcribed, so the oracle cannot disagree with the extractor about which corners are adjacent. χ of the digital solid is doubled to a surface χ viaχ(∂M) = 2·χ(M), and the CSV carries the arithmetic:chi_solid_26-4 / -32 / -108 on the nodal arm againstchi_stratified_morse-8 / -64 / -216. The gyroid checks that doubling independently — its labyrinth per conventional cubic cell is thesrs(Laves) net, 8 nodes and 12 edges,χ = 8 − 12 = -4, and2 · (-4) = -8is exactlyP-142's number, reached from voxel counts rather than from genus-3-per-primitive-cell.Ten vacuity controls, all assertions rather than columns. (1) The registered one —
spheremust returnχ = 2: it does, at both resolutions, onchi_surface_26andchi_surface_6. (2) The assigned second —torusmust return0: it does, and it is the stronger control, since a method that reported2for everything would pass the sphere. (3) The oracle is not a constant: eight distinctchi_stratified_morsevalues across the in-scope rows —-216, -152, -64, -24, -8, 0, 2, 82. (4) The weights are derived and checkable:w(0x00) == 0,w(0xFF) == 0, a single occupied voxel weighs exactly1/8, eight such blocks make theχ = 1of a cube. (5) The two connectivities genuinely differ: the derived tables disagree on 96 of 256 configurations —connectivity_split_configurations96 on 38 of 38 — and the corner-touching pair fixture must readχ₂₆ = 1againstχ₆ = 2. (6) The digital object is neither empty nor full:inside_samples225 to 485,162, strictly inside(0, blocks). (7) The mesh exists:mesh_triangles≥ 1,016. (8)disagreement_cellscould have been non-zero: it is 551 and 602 onnoise_cavity, 40 and 141 ongyroid, 30 and 58 onfbm_terrain, and 0 on the calibration and cross-check rows — so Theorem 4.1's hypothesis was genuinely tested. (9) The exclusion is measured from both sides and they agree:fbm_terrainalone hasboundary_inside > 0(3,047 and 12,195) andboundary_edges > 0(190 and 390), and every in-scope row has both at zero. (10) The DOI column is the registration's DOI:prereg.hypothesisis asserted to contain the string indoibefore any row is written, so what is reported is a resolution of the registered claim and not of a retyped one.
connectivity_split_blocks reading 0 on the calibration and the cross-check is the reason the
cross-check is worth anything, and 487 on noise_cavity is the reason the column exists. On all six
gyroid_nodal rows and all twenty calibration rows not a single block of the grid landed on one of the
96 configurations where foreground-26 and foreground-6 disagree, so chi_surface_6 equals
chi_stratified_morse there (-8 / -64 / -216 and 2 / 0 / 2 / 2 / 2) and P-142's number is
reproduced under both digital models rather than under a chosen one. On the noise fields the choice is
everything: noise_cavity at 33³ has 487 split blocks and reads chi_solid_6 -90 against
chi_solid_26 41 — a surface χ of -180 under one model and 82 under the other, on one
occupancy. Even the capped gyroid splits, 37 blocks at 33³ and 135 at 65³, chi_surface_6
-50 against chi_stratified_morse -24; the extraction reads -24, so foreground-26 is the model
that matches the mesh and this row is the measurement that says so rather than the convention that assumed
it.
noise_cavity disagrees with the extraction and that is a result, not a failed clause. agreement
reads true on 30 rows, false on 4 (all noise_cavity) and not_applicable on 4 (all
fbm_terrain). At 33³ the oracle says 82 while the extraction reads -96 under the default
marching_cubes and 6 under marching_cubes+trilinear; at 65³ the oracle says -152 against
-175 and -162. disagreement_cells is 551 and 602 on those rows — cells where Etiene's
own unambiguity test fails, so the digital reconstruction carries no homeomorphism guarantee and the
extractor's face and interior rules are free to choose a different topology from the trilinear
interpolant's. The two extractors disagreeing with each other by 102 at 33³ on the same field, in the
same run, is the sharper half of that observation, and C1 was never quantified over it: the clause asks
the method to produce a ground truth on two such fields and to agree with P-142 on the gyroid, and
both are met.
Two harness discoveries belong in the record because each one first read as an instrument fault.
(1) common::tpms::euler welds before counting and validate::validate_indexed does not, so they
legitimately differ by exactly the coincident-vertex count. Marching cubes caches one vertex per grid
edge, so the two agree except where two different grid edges produce the same position — M-48's
degenerate crossing. Welding merges that pair, dropping one referenced vertex and therefore χ by one:
measured -175 against -174 on the wrapped gyroid, a difference of exactly one coincident pair
(experiment_p145.rs:1112-1124). The cross-check now runs validate_indexed on a welded copy, both
readers are asked about the same mesh, and the committed file shows the consequence:
chi_extracted_validate equals chi_extracted on 38 of 38 rows. (2) The raw sample signs are not
periodic across a period, and gating on them would have refused a correct torus. sin(2πN) is
-2.4e-16 and not 0.0 in f64, so a sample lying on the surface flips sign between the two ends of one
period: wrap_sign_mismatches reads 3 on every gyroid_nodal row, at N = 1, 2 and 3 alike. The
gate is therefore on the glued occupancy, which is periodic by construction because the occupancy is
copied modularly rather than resampled, and wrap_occupancy_mismatches == 0 is what is asserted
(experiment_p145.rs:1420-1438); wrap_sign_mismatches is carried as a diagnostic column. The
harness's own vacuity-control bullet at experiment_p145.rs:251-255 still says
wrap_sign_mismatches == 0, and the CSV disagrees with it — the code is right and the comment is stale.
The wrap itself is non-vacuous on every one of those rows: seam_pairs 305 / 1,225 / 2,769, the same
three integers p-142.csv recorded for marching_cubes at the same three grids.
What a consumer should do differently. The instrument is now available and it is affordable — under
1.07× an extraction on every row, and half an extraction on the largest — so the correct treatment of
gyroid's topology in the test suite is no longer "record whatever the mesh said": the capped gyroid has
a reproducible ground truth of -24 at both 33³ and 65³, computed from the field rather than from the
mesh, and marching_cubes/tests.rs's current position that the number "is not known analytically, so it
is recorded rather than asserted" is true of the analytic route and false of this one. noise_cavity is
the opposite lesson: the oracle produces a number there, the extractors produce two different numbers, and
551 and 602 ambiguous cells per grid say the surface is under-resolved rather than that anybody is
wrong — so a gate on that field would have to be a gate on disagreement_cells, not on χ. And the
Phase 23 audit's DOI unverified flag is discharged: doi_verified true on 38 of 38, with
doi_resolved_title Topology Verification for Isosurface Extraction, doi_venue
IEEE-TVCG-18(6)-952-965-2012 and doi_handles openalex:W2086220855|pubmed:21690649 carried on the row
so the CSV is the record rather than a comment.
💥 ✗107 / M-459 — C1 FALSIFIED with c1_winners 0 of c1_population 4 against a bar of 3: at matched Hausdorff the metric-driven arm is never cheaper and is 2.298935× dearer on thin_plate, the most anisotropic measurable field; C3 FALSIFIED on 40 of 40 with metric_share 0.332862 to 8.747515 against a 0.15 bar and c3_row_decisive true on every row; C2 HELD on the 20 rows where it can be read and unmeasurable on the other 20, because validate::accuracy is meaningless where field.bound() is not Exact — and the finding is that this crate's reference-field roster is adversarial to global anisotropy: the one field where the mechanism demonstrably works, fbm_terrain at flat_axis_aligned_fraction 1.000000, is Unbounded and therefore ungradeable (P-146, R-146)
M. cargo bench --bench experiment_p146, docs/experiments/p-146.csv, 40 rows across 57
columns — four # comment lines plus one column header plus 40 data rows, counted from the file
rather than from the brief; 18 of the 57 columns are P-146's registered records and the other 39 are
M-273 extras. The shape, also counted from the file: eight reference fields × five rungs,
metric = M_Lp_hessian and p_norm = 2.0 on all 40, f64, amd-ryzen-9-5900x-12-core (Zen 3).
The ladder is resolution 17 / 25 / 33 / 49 / 65 — five rungs, a factor of 4 in h, odd throughout
because M-266 proved the canonical grids' odd counts are load-bearing (thin_plate is centred on
y = 0 and loses its surface entirely on an even count). # commit 77e71cb on
amd-ryzen-9-5900x-12-core at 2026-08-30T09:27:05Z, no (WORKING TREE DIRTY). crates/isomesh/src/ is
frozen for Phase 27 and nothing in it moved; this row owns benches/common/metric.rs and is its first
consumer.
| clause | registered | measured |
|---|---|---|
| C1 at matched symmetric Hausdorff error, a metric-driven mesh uses at least 25% fewer triangles on at least three of eight reference fields | ratio = triangles_aniso / triangles_iso ≤ 0.75 on ≥ 3 fields |
FALSIFIED — c1_winners 0 against c1_population 4. Per field: ratio 1.000000 (sphere), 1.153211 (torus), 1.000000 (box_exact), 2.298935 (thin_plate). c1_field_win is false on all 20 measurable rows and unmeasurable:bound=… on the other 20 |
| C2 the win lands on the fields with a flat direction | per field, predicted_win == observed_win, predicted before the run |
HELD where readable — c2_holds true on 20 rows and unmeasurable on 20. All four Exact fields were predicted not to win and did not. c2_global_holds is true on 40 of 40. The mechanism half, c2_mechanism_holds (predicted flat_axis against measured), reads true on 21 rows and false on 19 |
| C3 computing the metric costs under 15% of extraction | metric_share ≤ 0.15 on every row |
FALSIFIED — c3_holds false, c3_row_holds false on 40 of 40, and c3_row_decisive true on 40 of 40: the min/max band never straddles the bar, the smallest metric_share_lo in the file being 0.32888. metric_share spans 0.332862 (thin_plate at 65³) to 8.747515 (csg_difference at 17³) — the metric costs between a third of an extraction and 8.7 extractions |
C1's population is 4, not 8, and the arithmetic that narrows it is the whole reason the clause could not be reached as written.
validate::accuracyprojects by Newton along∇fand compares against|f|, andcrates/isomesh/src/fields/mod.rs:83-84states the rule onFieldBound::Exactin as many words: "Only this admits a Hausdorff measurement against the field's own values." Thefield_boundcolumn splits the roster exactly:Exactonsphere,torus,box_exact,thin_plate(20 rows,c1_skip_reasonempty);Underestimateoncsg_difference;Lipschitzongyroid;Unboundedonfbm_terrainandnoise_cavity. So the registered bar of "three of eight" is three of four — 75% of what can be measured, not the 37.5% it reads as. That is a narrowing and not an impossibility:3 ≤ 4, so C1 was reachable, was run, and came back 0 of 4. The four skipped fields still emit every metric, aspect-ratio, triangle and cost column; only the four Hausdorff-derived columns readunmeasurable:bound=…, andc1_population4 andc1_skip_reasonare on every row so the denominator travels with the verdict.On two of the four measurable fields the anisotropic arm was the isotropic arm, and the CSV says so rather than reporting a null.
grid_anisotropicequalsgrid_isotropicat 65x65x65 onsphereandbox_exactwithaxis_ratio1.000000, so theirratioof exactly 1.000000 is a construction identity and not a measured tie — the metric prescribed a uniform grid, which is precisely what the pre-registeredflat_axisprediction ofnone/mixedsaid it would do. The two fields where the grid genuinely moved both got worse:torusat 63x69x63 (axis_ratio1.095238) readsratio1.153211, andthin_plateat 21x635x21 (axis_ratio30.238095) reads 2.298935.thin_plateis the instructive one: at 65³ the anisotropic arm emits 536 triangles against the isotropic 4,088 — a 7.6× saving — but athausdorff_anisotropic0.141556797 againsthausdorff_isotropic0.045927933, a 3.1× worse error, and at matched error it loses by 2.3×.The two ratios that carry C1's falsification are read off an extrapolation, and the CSV says which. The matched error is
hausdorff_matched= the finest isotropic reading — 0.001329268 (sphere), 0.003976398 (torus), 0.072168784 (box_exact), 0.045927933 (thin_plate) — and both arms are evaluated there through their own fittedln Tagainstln Epower law.matched_interpolatedreads true onsphereandbox_exactand false ontorusandthin_plate: on those two the anisotropic arm never reached that error on any rung, so its triangle count at the matched error is an extrapolation beyond its own span. That weakens the magnitude of1.153211and2.298935and not their sign — at equal sample budget the anisotropic arm's error is worse on all fivethin_platerungs and on the fourtorusrungs above 17³, equal on the tensphere/box_exactrows whose grid did not move, and better on exactly one of the twenty measurable rows (torusat 17³,hausdorff_anisotropic0.040603651 againsthausdorff_isotropic0.051184351). That is why the extrapolation runs in the direction it does.Six vacuity controls, and the registered one needed the module author's amendment to mean anything. (1) The registered control —
aspect_ratio_max > 3on at least one field: satisfied on 40 of 40 rows, and that is exactly the problem. (2) The amendment, and it is load-bearing:benches/common/metric.rswarns that at a flat directionaspect_ratiois|λ|max / H_FLOOR ≈ 1e9, "a number of order 1e11 that is the floor talking, not a measured anisotropy", so the bar is asserted again over cells that are not at the floor —aspect_ratio_max_off_floor > 3on 35 of 40 rows. The five that fail are allfbm_terrain, whereoff_floor_cellsis 0 andat_floor_fractionis 1.000000 on every rung. (3) The anisotropic arm must be anisotropic:axis_ratio47.400000 onfbm_terrainat 65³ against a 1.5 floor. (4) The two arms must be on one budget:budget_ratiospans 0.898211 to 1.137594, inside the required[0.25, 4]. (5) The Hausdorff instrument must respond to resolution: both arms' errors must span ≥ 1.2× across the ladder orratiowould be read off a fit through a horizontal line; all fourExactfields survived, withfit_r2_isotropic0.999693 / 0.981613 / 0.999754 / 0.999965 andfit_r2_anisotropic0.999693 / 0.991829 / 0.999754 / 0.986247. (6) The band must be non-empty:band_points279 to 21,655.
aspect_ratio_max must be read with at_floor_cells beside it, and this file is the demonstration.
benches/common/metric.rs's author measured the at-floor counts box_exact 1686/1790 cells,
fbm_terrain 1156/1156 (a heightfield SDF is exactly linear in y) and gyroid 1/2945 with a
genuine 5.11e3, and all three reproduce here on an independent fixture. box_exact at 65³ carries
aspect_ratio_max 2.400000e10 beside aspect_ratio_max_off_floor 3.824847 with at_floor_cells
18,042 of band_points 18,082 (at_floor_fraction 0.997788) — two numbers ten orders of
magnitude apart on one row, and only the second one is a measurement. fbm_terrain reads
at_floor_fraction 1.000000 at every rung (578/578 through 8,450/8,450) with
aspect_ratio_max_off_floor 0.000000e0: there is no off-floor cell at all, because ∂²f/∂y² is
identically zero. And gyroid is the expected witness for the off-floor bar and delivers it —
at_floor_cells 1 of band_points 1,414 at 17³ with aspect_ratio_max =
aspect_ratio_max_off_floor = 5.110482e3, the module's "genuine 5.11e3" to three digits.
The registered aspect_ratio_mean has the same disease, and the file carries its antidote too.
box_exact at 65³ reads aspect_ratio_mean 1.555702e9 against aspect_ratio_mean_off_floor
3.119172e0, so the average is floor-dominated as thoroughly as the maximum, and neither registered
aspect-ratio column means anything read alone. complexity_target — the registration's
C(M) = ∫√det M standing in for a vertex count — is recorded on every row and falls monotonically with
resolution on seven of the eight fields (sphere 2.255462e0 → 2.487997e-1, gyroid
4.438602e2 → 1.037636e2). The exception is noise_cavity, which rises over the first three rungs —
3.510168e1 → 3.758484e1 → 3.877107e1 — before falling to 2.876359e1, i.e. its metric is still
finding structure at 33³ and the complexity integral is not yet resolved. No clause reads that column; it
is recorded because R-147 and R-150 will.
C2's per-field prediction was written into the harness before it had ever run, and the one field it
predicted would win is the one field C1 cannot grade. The prediction, on fbm_terrain: sample is
p[1] − (base + amp·n(x, 0, z)) (fields/mod.rs:1352-1362), exactly linear in y, so
∂²f/∂y² = ∂²f/∂x∂y = ∂²f/∂y∂z ≡ 0 and ŷ is an exact null eigenvector at every point. Measured:
flat_axis y, flat_axis_aligned_fraction 1.000000 on all five rungs, axes_pinned 1 (the
y axis driven down to the MIN_SAMPLES floor of 5), grid_anisotropic 31x5x31 through
237x5x233, axis_ratio 6.200000 through 47.400000, c2_predicted_win true. And the
arm visibly worked there, on the only instrument that field admits: at 65³ mesh_residual_max_aniso is
2.696938e-2 against mesh_residual_max_iso 2.910318e-1, a 10.8× reduction in max |f(v)|/h
— bought with 115,174 triangles against 16,884, so it is an accuracy win and not a budget win.
field_bound is Unbounded, hausdorff_isotropic and hausdorff_anisotropic both read
unmeasurable:bound=Unbounded, and c1_field_win therefore reads unmeasurable rather than true.
That residual is explicitly not a Hausdorff distance and grades nothing — for a non-Exact field
|f| is not a distance, which is the whole reason the field is out of C1's population — but it is a real
number about a real mesh, and it is recorded so the four skipped fields are not silent.
The 19 rows where c2_mechanism_holds is false are all the same caveat, and the harness named it before
the run rather than after. flat_axis is a two-thirds majority of the exploitable population, and a
two-thirds majority of a population of one is still a two-thirds majority. sphere and torus were
predicted none and measured mixed — over flat_axis_aligned_fraction 0.002777 and
0.005305 at 65³, i.e. 18 of 6,482 and 32 of 6,032 band points. noise_cavity was predicted
none and measured y at four rungs on a fraction of 0.000159 — 3 of 18,892 points.
thin_plate was predicted mixed and measured z at 33³, 49³ and 65³, and there the fraction is
0.493380, so that one is a real structural reading rather than a majority of nothing. The label was
not given a minimum population after its answer became visible (crates/isomesh/src/experiment.rs:26-31
— a measurement rule retuned once its answer is visible is no longer a measurement), so the correct way to
read the column is to filter on the fraction, never on the label.
C3's falsification was predicted from scaling before the clock was read, and the crossing resolution is
recorded rather than guessed — but the recorded crossings are estimates, not a law. The band is a shell,
so band ∝ N²; extraction is a volume, so extract ∝ N³; therefore metric_share ∝ 1/N and
share_times_resolution is the scale-free constant, from which the crossing is
share_times_resolution / 0.15. Read off the top rung: thin_plate ≈ 144, fbm_terrain ≈ 239,
torus ≈ 448, sphere ≈ 467, noise_cavity ≈ 647, box_exact ≈ 678, gyroid ≈ 877,
csg_difference ≈ 1,048 samples per axis. The 1/N law is only approximate in the measured data
and the file shows it: share_times_resolution rises across the ladder on sphere (47.857805 →
70.098216) and falls on thin_plate (28.723999 → 21.636050), so those crossing numbers are
order-of-magnitude statements. One band point costs nineteen field samples plus one Jacobi
eigendecomposition and one extraction cell costs about one field sample, which is the constant the shell/
volume ratio has to overcome; at the ladder's resolutions it does not. Only wall-clock columns are
machine-dependent here and only C3 reads them, which is why the median of 5 repeats is reported with
metric_share_lo/metric_share_hi beside it rather than averaged into a pass — M-280 measured this
host's amd-pstate-epp governor swinging the same binary 1.45×, and c3_row_decisive true on 40 of
40 says that swing cannot reach the bar.
The anisotropic arm is per-axis global, not per-cell, and every verdict above is a verdict about that
construction. Every inherent extract in the crate takes a single scalar cell_size
(crates/isomesh/src/marching_cubes/mod.rs:193 and the six others), so a per-cell anisotropic mesher is a
source change by construction and Phase 27's freeze forbids it. What was built instead spends the same
total sample budget N³ on per-axis counts proportional to the metric's per-axis densities, driven
through the shipped extractor by a coordinate warp with vertices mapped back to world space before
anything measures them. A field whose flat direction rotates over the surface has per-cell anisotropy
this arm structurally cannot spend, and it reads as a null here while a real anisotropic mesher would win
on it — which is exactly sphere (zero eigenvalue along the radial direction) and torus (flat
direction azimuthal). So C1's 0 of 4 retires the global route and says nothing about the per-cell one.
What a consumer should do differently: nothing, and no landing is proposed. The registration priced
this row's SHARE as "C1 moves the triangle budget, whose share of frame cost M-135 puts at 29% for the
contour and 45% for the collider check"; the Amdahl ceiling on C1's own bar is 0.25 × 0.29 = 7.25% and
0.25 × 0.45 = 11.25%, at most 18.5% of a frame, and the realised share is zero because no
measurable field won. What this row does deliver is common::metric itself — measured, with its floor
behaviour characterised — for R-147, R-148, R-149, R-150 and R-151, and one instruction to each
of them: read p-146.csv's own c1_population (4), c1_skip_reason and at_floor_cells rather than
assuming a win, and never quote an aspect_ratio_max without the at-floor count on the same row.
💥 ✗108 / M-460 — C1, C2 and C3 all FALSIFIED: the exponent moved by 0.352013 on fbm_terrain against a 0.1 bar, the fitted constant improved on 3 of 8 fields against a strict majority and its rank correlation to the AM–GM gap is −0.095238 — negative, not merely under 0.7, and under 0.7 at all three τ — and C3's csg_difference read exponent_difference 0.000000 because a permutation-symmetric field annihilates all three degrees of freedom a per-axis grid has; the one prediction that survived is the companion, companion_regularity_deficit 0.319404 against an expected 0.33 (P-147, R-147)
M. cargo bench --bench experiment_p147, docs/experiments/p-147.csv, 8 rows across 79
columns — four # comment lines plus one column header plus eight data rows, thirteen lines, counted
from the file; 13 of the 79 columns are P-147's registered records and the other 66 are extras. One
row per reference field, each carrying a five-rung ladder resolution_series 17|25|33|49|65 in its
series columns, reference_dof 274,625 = 65³, instrument field_to_mesh_max on all eight.
f64 throughout, one thread, no PRNG. Clean tree — # commit 049714c on
amd-ryzen-9-5900x-12-core at 2026-08-30T14:29:56Z, with no (WORKING TREE DIRTY). wall_seconds sums
to 2.741 s and no clause reads it. All three verdict columns are global: c1_holds, c2_holds
and c3_holds are false on all eight rows, and the per-field facts sit in c1_smooth,
c1_row_holds, c2_row_improves and exponent_difference.
| clause | registered | measured |
|---|---|---|
C1 the fitted error exponent is statistically indistinguishable between the arms, \|Δexponent\| < 0.1, on every smooth field |
< 0.1 over the smooth population |
FALSIFIED — c1_population 3 (c1_smooth true on sphere, torus, fbm_terrain), and fbm_terrain reads fitted_exponent_isotropic 0.439357 against fitted_exponent_anisotropic 0.791370, exponent_difference 0.352013 — 3.5× the bar, and resolved: exponent_difference_ci95 0.138928 with exponent_difference_resolved true. The other two could not disagree: sphere's arms_identical is true so Δ is 0.000000 exactly, and torus's 0.018566 sits inside its own exponent_difference_ci95 0.197725 (exponent_difference_resolved false). c1_row_holds false on thin_plate (0.108109) and fbm_terrain only |
| C2 the fitted constant improves, and its improvement tracks the AM–GM gap per field, rank correlation above 0.7 | strict majority of 8 fields and ρ ≥ 0.7 | FALSIFIED on both conjuncts — c2_improved_fields 3 of 8 against a strict majority of 5, and c2_rank_correlation −0.095238: not merely under 0.7 but negative. Neither τ rescues it — c2_rank_correlation_tau2 −0.119048, c2_rank_correlation_tau_inf 0.214286. constant_ratio reads 1.000000 on sphere, box_exact, csg_difference, gyroid, noise_cavity, 1.125249 on torus, 3.131972 on thin_plate and 0.114405 on fbm_terrain |
C3 a field lacking W^{2,p} regularity — csg_difference — shows an exponent difference above 0.1 |
> 0.1 on that one field |
FALSIFIED — c3_exponent_difference 0.000000, c3_arms_identical true, c3_field csg_difference, with c3_reason on every row reading arms_identical:axis_ratio_max=1.000000:per_axis_grid_cannot_grade_a_permutation_symmetric_field. Its fitted_exponent_isotropic and fitted_exponent_anisotropic are both 0.305633 and its two error series agree digit for digit at all five rungs |
C3's
falseis arithmetically unreachable rather than informative, and the harness says so in a column instead of in prose.BoxExact's half-extents are[1, 1, 1]and the subtracted sphere sits on the(0.6, 0.6, 0.6)diagonal (fields/mod.rs:917-923), socsg_differenceis permutation-symmetric in(x, y, z): its three per-axis metric weights are equal to rounding,anisotropic_gridreturns[N, N, N], and the two arms are one grid.axis_ratio_seriesis1.000000|1.000000|1.000000|1.000000|1.000000andaxes_pinned_seriesis0|0|0|0|0on that row, soexponent_difference0.000000 is a zero that could not have been non-zero (M-44) — the same shape asP-70's C1. The registration's falsifier is honoured rather than reinterpreted: it reads "C3 by no exponent difference on the CSG field, which would say our sharp fields are smoother than assumed", and the CSV recordsfalsewhilec3_reasonstates that the conclusion the falsifier offers does not follow. What does follow is the companion, and it is the row's one surviving prediction:companion_regularity_deficit0.319404 withcompanion_deficit_holdstrue— the median isotropic exponent over C1's three smooth fields (0.625037,torus's) minuscsg_difference's own 0.305633, exactly0.319404, against an expected0.33derived fromp-155.csv's1.985onsphereand1.000onbox_exact. So the CSG field is less regular; a per-axis global grid simply cannot see it.Six vacuity controls fired, all as assertions before the first
record, and two of them are what make the three falsifications readable. (1) The registered one —am_gm_gap_spread5.829144e9, assertedmax > 2·min, overam_gm_gaprunning4.214619e-10(fbm_terrain) to2.456762e0(noise_cavity) at the registeredam_gm_gap_tau0.571429; had it been flat, C2's correlation would have been a correlation against a constant. The spread is honest but lopsided, and the reason is on the row:fbm_terrain'sat_floor_fractionis 1.000000, so its1e-10gap isH_FLOORand not a curvature —am_gm_gap_tau28.170066e-9 andam_gm_gap_tau_inf3.421812e-8 are the same statement at two other exponents. (2) The anisotropic arm must be anisotropic somewhere:axis_ratio_max47.400000 onfbm_terrainand 30.238095 onthin_plate, against a floor of1.5; five of eight fields read exactly 1.000000, which is why C2 and C3 read the way they do rather than a defect in either. (3) C1's population must contain a field whose arms differ —c1_smoothtrue on three,arms_identicalfalse ontorus,thin_plate,fbm_terrain, so C1'sfalseis carried by a field that was free to hold. (4) The ladder must move the instrument by ≥ 1.2× on both arms for every field a clause reads:ladder_span_isotropic16.371182 / 12.872040 / 5.601517 on the smooth three and 3.998839 oncsg_difference,ladder_span_anisotropic16.371182 / 9.117663 / 26.467312 / 3.998839. (5) Every rung of every arm produced a mesh, a seed and a positive error —triangles_series_*,seed_coverage_series_*anderror_max_series_*are non-zero at all forty rung-arm pairs. (6) The band was non-empty everywhere:band_points_seriesruns279|533|935|1925|3399onthin_plateup to1414|3103|5449|12259|21655ongyroid.Beside them, and a correctness gate rather than a vacuity control:
reproduction_checks160 withreproduction_mismatches0. Every triangle count, everygrid_anisotropicstring and every recordedhausdorff_*indocs/experiments/p-146.csvwas re-derived here and compared exactly, so this row is measuringP-146's arm and not a lookalike. (The harness header says "120 exact comparisons"; its own table sums to 160 and the CSV agrees with the table.)
C2's c2_improved_fields 3 is really 1, and the CSV lets a reader prove it. c2_row_improves is
ratio < 1.0 and reads true on gyroid, fbm_terrain and noise_cavity — but gyroid and
noise_cavity print constant_ratio 1.000000 and carry arms_identical true, with
error_max_series_anisotropic identical to error_max_series_isotropic at all five rungs and
fitted_constant_isotropic = fitted_constant_anisotropic = 2.045145e-1 and 2.477978e-1
respectively. Their ratios are below one by less than the column's printed precision, i.e. by at most
5e-7 relative, on two fields whose two arms are the same mesh. So exactly one field of eight
improved its constant — fbm_terrain at 0.114405 — and it is the same field that broke C1. That is
the precise inverse of the registration's claim: the only real constant improvement in the file is
carried by a field whose exponent moved, so it is a change of rate wearing a constant's clothes. Of
the two fields whose arms genuinely differ and whose exponents did not resolve, both got worse:
torus 1.125249 and thin_plate 3.131972.
The theory the registration cites is not what failed; its d is. sphere's
fitted_exponent_isotropic 0.692081 with fit_r2_isotropic 0.999747 reproduces Bonito–Canuto–
Nochetto–Veeser's N^(−2/3) = 0.666667 to within 0.025 on the smoothest field in the roster, and
the quoted order is the one uniform refinement actually delivers here. What C1 assumes on top of that is
d = 3 for every field, and fbm_terrain's Hessian has an exact null direction, not a small one:
f = p_y − amp·fbm(x, 0, z) is affine in y, flat_direction_fraction reads 1.000000 and
axes_pinned_series reads 1|1|1|1|1, so P-146's grid spends the whole budget laterally —
grid_series_anisotropic runs 31x5x31 → 237x5x233. With one direction degenerate the rate is
N^(−2/2), and 0.791370 is that rate arriving, not the theory breaking. The exponent gain the
falsifier called "the more interesting result" is therefore real and is a statement about the field's
dimension.
Against a triangle count the answer is different, and that is the second half rather than a
contradiction. exponent_vs_triangles_isotropic is 0.974539 on sphere — the E ∝ T^(−1) a
surface mesh gives where dof gives 2/3 — and exponent_difference_vs_triangles is 0.216259 on
fbm_terrain, 0.079374 on thin_plate, 0.053245 on torus and 0.000000 on the five
identical-arm fields. A reader comparing this row to a paper must check which N the paper meant;
both are in the file.
What this means for Group D, on top of P-146. P-146 measured the aggregate and its C1 and C3
were both falsified — no triangle win at matched Hausdorff, metric_share never once under 15%. This
row was the decomposition that would have said which half of E = C·N^(−α) anisotropy is allowed to
move, and the answer is neither, through this construction. The exponent moved only where the
field's own dimension dropped, and the constant moved only on that same field. Both failures share one
cause and it is not the theory: a per-axis global grid has three degrees of freedom, and five of the
eight reference fields annihilate all three. Group D's mechanism has not been refuted; it has been
shown to be unreachable by any bench that spends anisotropy globally, which is the only thing the
shipped extract — one scalar cell_size at marching_cubes/mod.rs:193 and six other sites — can
express. P-149 measures the same wall from the other side and P-150 guards how the numbers may be
quoted.
SHARE, recomputed. Zero, and registered as zero — "none — this is M-12's law, decomposed."
Nothing in crates/isomesh/src/ was touched by this ticket, no golden hash moved, and the anisotropic
arm is a bench-local sampling grid the shipped extractor cannot ask for. wall_seconds is the only
machine-dependent column in the file and no clause reads it, so M-280's 1.45× governor swing has
nothing to move: every verdict here is a comparison of two least-squares slopes over exact integer
dof ladders. The number that would have justified a landing is a constant_ratio below one on a
field whose arms genuinely differ, and there is exactly one — fbm_terrain, whose grid is
237x5x233 and is a heightfield special case rather than a general mesh.
What a consumer should do differently: nothing, and one thing they must not do. No shipped path
changed. But never read a constant_ratio, a saving or a ratio from a row whose
arms_identical is true — five of the eight rows in this file are that, and on them every
comparison column is measuring the extractor's determinism. Would be shown wrong by: a per-cell
anisotropic extractor (a source change, and Phase 28's business) reproducing Δexponent < 0.1 with a
constant_ratio below one on sphere and torus; a rank correlation above 0.7 between
constant_ratio and any gap definition over a population in which more than two fields' arms differ;
or companion_regularity_deficit falling near zero at a finer ladder, which would say
csg_difference's creases cost nothing in the rate after all.
🔬 M-461 — C1 HELD with component-wise determinant swell reaching 6.841331e9 against log-Euclidean's 1.771547e-7 at a 5% bar, C2 HELD on 48 of 48 geometries so three transcendentals cost M-32 exactly nothing, and c3_holds split 84 true / 12 false — the twelve are gyroid under both schemes at both cell sizes, and the CSV names the cause: its seam correspondence is not injective (seam_vertices_a 295, seam_vertices_b 294, seam_pairs 295), which is M-48 again and not the interpolant; hashes_moved 0 on all 96 rows against a live golden control (P-148, R-148)
M. cargo bench --bench experiment_p148, docs/experiments/p-148.csv, 96 rows across 72
columns — four # comment lines plus one column header plus 96 data rows, 101 lines, counted from the
file; 12 of the 72 columns are P-148's registered records. The fixture, also counted from the file:
8 fields × 3 seam axes (x|y|z, 32 rows each) × 2 cell sizes × 2 schemes — interpolation_scheme
componentwise on 48 and log_euclidean on 48, cell_size_power_of_two true on 48 and false on 48,
p_norm 2.0 on every row. cell_size takes six values, three genuine powers of two
(5.000000000000e-1, 2.500000000000e-1, 1.250000000000e-1) and three off the dyadics
(4.705882352941e-1 = 8/17, 2.413793103448e-1 = 7/29, 1.176470588235e-1 = 2/17), over
cells_per_chunk 16|17|28|29 and seam_cells 1024|1156|3136|3364. f64 throughout, one thread, no
PRNG. Clean tree — # commit 923df1e on amd-ryzen-9-5900x-12-core at 2026-08-30T14:19:10Z, no
(WORKING TREE DIRTY). The three verdicts have three different granularities and a reader who does
not know that will misread the file: c1_holds is global (identical on all 96), c2_holds is
per geometry (both scheme rows of one (field, axis, h) carry one value), c3_holds is per row
with c3_row_decisive beside it.
| clause | registered | measured |
|---|---|---|
| C1 component-wise interpolation swells determinants above 5% on at least one field, and log-Euclidean does not | > 0.05 for one arm, ≤ 0.05 for the other |
HELD, by fourteen orders of margin — c1_componentwise_swell_max 6.841331e9 and c1_log_euclidean_swell_max 1.771547e-7 on all 96 rows. The worst component-wise row is csg_difference/x/h = 0.125 at determinant_swell_max 6.841331e9 with log_determinant_swell_max 2.264625e1 — the interpolated determinant is 6.8 billion times the determinant-monotone path's; the worst log-Euclidean row is csg_difference/x/h = 2/17 at 1.771547e-7, five orders under the bar. c1_row_swell_above_bar is true on 42 of 48 component-wise rows and false on 48 of 48 log-Euclidean rows |
C2 log-Euclidean interpolation preserves M-32's power-of-two bit-exactness, or it does not, and which is stated as the result |
either, stated | HELD, and the answer is "it preserves it" — c2_holds and c2_global_holds true on all 96 rows, i.e. 48 of 48 geometries. bit_exact_seam is true on all 48 power-of-two rows and false on 44 of 48 non-power-of-two rows, identically under both schemes on every geometry — bit_exact_pairs equals seam_cells on the whole power-of-two arm. So Sym3::log, twelve Jacobi sweeps and Sym3::exp add nothing to M-32's loss and take nothing from its guarantee |
| C3 the seam remains closed under both schemes | seam_open_edges no higher than the undisplaced baseline |
84 of 96 rows true; 12 false. c3_row_decisive is true on all 96 and seam_open_edges_baseline is 0 on all 96. The twelve are gyroid on all three axes at both cell sizes under both schemes: seam_open_edges 3 at h = 0.25 and 11 at h = 7/29, with boundary_edges_total 5 and 16/17. c3_global_holds is therefore false on every row. Every other field closed: seam_open_edges 0 on 84 rows |
The twelve
falserows are not a failure of either interpolant, and the CSV proves it rather than arguing it. Ath = 0.25ongyroid,bit_exact_pairsis 3136 of 3136seam_cells— chunk A's interpolant and chunk B's agree bit for bit at every dyadic rung on every seam cell, andcheap_directionis a pure function of those sixf64s, so the two chunks displace along an identical direction and no direction disagreement is available. Yetseam_worst_displacement_gapreads 4.280446e-3 againstweld_epsilon2.500000e-5, i.e.gap_over_weld_epsilon1.712178e2, andDISPLACE_CELLS · his0.01 × 0.25=2.5e-3, so the gap is exactly 1.712178 × one displacement step —gap_over_weld_epsilon / 100to the last digit, because the step is a hundred epsilons by construction. A vertex displaced once cannot land 1.7 steps from its partner when both use the same direction. What can is a vertex displaced twice, and the file says which one:seam_vertices_a295,seam_vertices_b294,seam_pairs295 — every one of A's seam vertices found a partner, but B has one fewer, so one of B's seam vertices is claimed by two of A's, and the census writesb.positions[vb]once per pair.seam_vertices_movedis 2 of 295 on exactly those rows, which is the two pairs sharing that partner. The non-injectivity is also what wraps a column:seam_vertices_unmatchedreads 18,446,744,073,709,551,615 =2^64 − 1on precisely these twelve rows, au64subtraction ofseam_b − seam_pairs=294 − 295. So the honest reading isc3_holds's twelve zeros locate a defect in C3's own instrument, not in the metric, the interpolant or the extractor — and the mechanism isM-48's degenerate crossing, which the harness had already measured and gated for (see below) but only on the B side of the match.Three measured threshold stories, and all three are load-bearing. (1)
SELF_SWELL_TOLERANCEmoved1e-9→1e-5because the old bound was unreachable by construction. The first draft's number was justified as "six orders above thef64round-off of a well-conditioned eigenproblem" — butcommon::metricfloors Hessian eigenvalues atH_FLOOR = 1e-9precisely so a flat direction stays representable, which puts the metric's condition number at about1e9on exactly the fields this row cares about, and alog/expround trip on a matrix of condition number κ loses aboutκ·ε=1e9 × 2.2e-16≈2e-7.1e-9was therefore gating on the eigensolver's accuracy rather than on the formula. Measured in the committed run:swell_self_max5.039778e-7 onbox_exact/xandbox_exact/yath = 2/17underlog_euclidean— that bound to within a factor of three. Component-wise reaches the low1e-14s (0.5x + 0.5xisxin IEEE).1e-5sits two orders above the measured round-off and four orders belowC1_BAR = 0.05, so the control can still fail without ever touching the clause, which is the property that made1e-9attractive and is preserved. (2) A key collision is a coincident vertex pair, not a broken key. The transverse match quantum isMATCH_QUANTUM_CELLS = 1e-6cells (M-377's choice), and every seam vertex lies in the seam plane, so two sharing a transverse key are one geometric point reached from two different grid edges —M-48exactly, the same mechanismP-145's Euler cross-check hit. Measured: exactly 1 ongyroidath = 0.25and 0 elsewhere, against aKEY_COLLISION_FRACTIONgate of0.05, so the correspondence is a bijection on points and a large collision share — which would mean the quantum is too coarse — still aborts the run. (3) C3's control needs the two chunks' landings to separate by more than the weld epsilon, and on two fields it cannot.cheap_directionreturns the metric's first eigenvector, and a heightfield's smallest eigendirection isyon both sides of any seam — different metrics, identical chosen direction. Sofbm_terrainmoves its seam vertices and still shows a zero gap: ath = 0.5itsxseam carriesseam_pairs47 withgap_over_weld_epsilon0.000000e0 andcontrol_seam_opensfalse, andbox_exactdoes not move at all. Both are named field properties, both are recorded:control_seam_opensistrueon 64 rows (sphere,torus,csg_difference,gyroid,noise_cavity, andthin_plate'syaxis) withcontrol_seam_open_edgesrunning 14 to 625, andfalseon 32 (box_exact12,fbm_terrain12,thin_plate'sxandz8).P-70's precedent applies: unreachable on part of the population is recorded, not aborted.The registered vacuity control fired on 88 rows and was unreachable on 8, and the eight are the same eight that produce C2's only surprise.
metric_distance_maxis the affine-invariant‖log A − log B‖_Fover the seam face and runs to 3.086325e1, withpairs_with_distinct_metricsreaching 3364; it reads 0 onthin_plate'sxandzseams (metric_distance_max0.000000e0,at_floor_fraction1.000000), because a slab's metric is the same on both sides of a seam cut through its plane. Those are exactly the 4 non-power-of-two rows on whichbit_exact_seamreadstrue— interpolating between two identical metrics is the same computation on the same bits at anyh, so bit-exactness there is vacuous and the vacuity column sits beside it to say so. They are also 4 of the 6 component-wise rows that stay underC1_BAR, and the other 2 are the same story to twelve decimal places — the six arethin_plate/xandthin_plate/zat both spacings (determinant_swell_max3.552714e-14 and 7.815970e-14,metric_distance_maxexactly 0.000000e0) andfbm_terrain/yat both (5.151435e-14, 7.105427e-14, withmetric_distance_max3.763863e-12 and 1.060250e-12 against 3.982857e0–5.376344e0 on that same field'sxandzseams). So every geometry where the naive scheme fails to swell is a geometry whose two metrics are equal, or equal to a part in1e12— the swell is not optional where the endpoints genuinely differ. Four more controls:seam_ghost_ulpsasserted> 0on the non-power-of-two arm and== 0on the other, measured 30 on 42 rows and 7 on 6 against 0 on all 48 (withseam_own_ulps2/7/0) — this isM-32's own fixture trap, "the non-power-of-two seam test first usedh = 4/33… it passed while proving nothing", and the six spacings were searched rather than guessed;seam_plane_ulpsis 0 on all 96 rows, independently reproducingR-004's finding that the seam plane is the wrong unit of analysis — the plane coordinate agrees bit-for-bit even on the geometries that disagree by 30 ulp about the cell centres where the metric is sampled;min_metric_eigenvalueis asserted positive and runs 1.066648e-8 to 2.592641e-3, soln detis a number on every interpolant; andweight_reversal_exactis assertedfalse, so the non-dyadic ladder really does perturb the weight andbit_exact_seam_nondyadicis not a second copy ofbit_exact_seam.
C2's second half is new, is not in M-32, and a consumer of a metric field has to meet it.
bit_exact_seam is measured on a dyadic ladder t = k/8, dyadic_ladder_steps 8, so the weight
reversal 1 − (1 − t) returns t exactly and the column measures the cell size and nothing else.
Run beside it on nondyadic_ladder_steps 10, bit_exact_seam_nondyadic is false on all 96
rows — including at h = 0.125, where M-32 grants bit-exactness. The mechanism is arithmetic and not
transcendental: 1 − (1 − 0.1) is 0.09999999999999998. So "seams are bit-exact at a power-of-two
cell size" is necessary and not sufficient once a per-vertex weight enters: the weight must be dyadic
too. That is a condition M-32 does not state.
hashes_moved is 0 on all 96 rows, and two controls stop that zero from being free. It is measured
on the fixture that defines the phrase — the 24 committed marching_cubes rows of
crates/isomesh/golden_hashes.json, golden_rows 24 on every row — by running the shipped
extractor on each fixture's own grid, running the metric-interpolation pipeline over that grid's
mid-plane seam under the row's scheme, then re-extracting and re-hashing: golden_interpolations
207,872 interpolations run in total. golden_fixture_matches_shipped is true on 96 of 96, so
the baseline is the live extractor and not a stale file, and golden_control_hash_moved is true on
96 of 96, so displacing one vertex by the metric's own step does move mesh_hash. The zero is
predicted by construction — nothing here touches crates/isomesh/src/** and a metric field is on no
shipped extraction path — and it is measured anyway.
The intrinsic scheme costs 249×, and the falsifier asked for that number. C1's falsifier reads
"C1 by no swell, which would mean the intrinsic scheme is unnecessary here and saves the transcendental
cost"; the swell is real, so the cost is what a caller trades against it.
transcendental_cost_ratio is 249.382581 on all 96 rows, over timing_repeats 5 with a median
headline: interp_ns_per_pair 3.027 ns component-wise (min 3.008, max 3.359) against
754.967 ns log-Euclidean (min 754.889, max 761.061). Per-fixture, metric_ms runs
1.095259–20.163785 and interp_ms 0.971398–178.904454, summing to 649.45 ms and
2,526.93 ms across the file. No clause reads a clock — the ratio is reported because the
falsifier names it, not because a verdict rests on it, so M-280's 1.45× governor swing cannot reach
any of the three verdicts. Context from p-146.csv, recomputed rather than remembered: metric_share
there runs 0.332862 to 8.747515 with c3_holds false on all 40 rows, so the stage C1 moves
already costs between a third of extraction and nine times it, and 249× on the interpolation inside it
is not a rounding error.
What a consumer should do differently. Interpolate metrics log-Euclidean, and do not treat
Sym3::det as the way to see the difference. Component-wise interpolation of two SPD matrices whose
anisotropies point in different directions inflates det by up to 6.841331e9 on this roster — and
benches/common/metric.rs:542-548 states what that means and named this row as its referee:
"interpolating between two metrics whose anisotropies point in different directions swells det, which
in mesh terms means the seam quietly asks for coarser elements than either side did." The
intrinsic scheme's worst deviation from the determinant-monotone path is 1.771547e-7, which is
round-off. The cost is 249× per interpolation and the metric build already dominates extraction, so the
scheme is the cheap part of an expensive stage. Two caveats travel with it: the seam is bit-exact only
when the cell size is a power of two and the interpolation weight is dyadic, and a metric-driven
displacement must match seam vertices as a bijection on points or M-48's coincident crossings will
open a seam that neither scheme opened — gyroid's 12 rows here are that, at 3 and 11 edges.
SHARE, recomputed. The registration's SHARE is "C1 moves the metric-construction stage, whose share
P-146 C3 reports", and that share is 0.332862 to 8.747515 of extraction, falsified against its own
15% bar on all 40 of p-146.csv's rows — quoted from the file, not from memory. Nothing landed:
hashes_moved 0, no golden hash moved, and crates/isomesh/src/** was not touched. Would be shown
wrong by: a log-Euclidean determinant_swell_max above 0.05 on any field, which would retire the
scheme's monotonicity in practice; a power-of-two geometry reading bit_exact_seam false under
log-Euclidean while componentwise reads true, which would put the transcendentals on M-32's wrong
side; or a seam_open_edges above baseline on a field whose seam correspondence is injective and
whose bit_exact_pairs equals seam_cells, which is the reading the twelve gyroid rows do not
supply.
💥 ✗109 / M-462 — C1 FALSIFIED where it could be read at all: torus's triangle saving is perfectly anti-monotone in the curvature ratio, Spearman −1.000000 at 65³, and C2 FALSIFIED on fbm_terrain, whose umbilic bin — the control that was supposed to show no saving — costs −6.037543; 70 of 112 rows read unmeasurable:arms_identical because five of eight fields make P-146's two arms one grid, and the only part of the mechanism that held is the closed form: am_gm_gap_measured agrees with 2√r/(1+r) on 97 of 112 rows (P-149, R-149)
M. cargo bench --bench experiment_p149, docs/experiments/p-149.csv, 112 rows across 43
columns — four # comment lines plus one column header plus 112 data rows, 117 lines, counted from the
file; 10 of the 43 columns are P-149's registered records. The shape, also from the file: 8 fields
× 2 resolutions (33, 65, 56 rows each) × 7 feature_class bins (16 rows each), one row per
(field, resolution, bin). grid_isotropic is 33x33x33 on 56 rows and 65x65x65 on 56;
grid_anisotropic is the same on 70 of them and graded on 42 — 31x35x31/63x69x63 on torus,
13x191x13/21x635x21 on thin_plate, 87x5x83/237x5x233 on fbm_terrain. f64 throughout, one
thread, no PRNG. Clean tree — # commit c909961 on amd-ryzen-9-5900x-12-core at 2026-08-30T14:30:08Z,
no (WORKING TREE DIRTY). Both verdict columns are per group (one (field, resolution)), written
identically on that group's seven bin rows, with c1_global_holds and c2_global_holds false on all
112.
The two verdict columns are four-valued, and the split is the result. Averaging either into a word would destroy the finding, so here is the whole distribution, counted from the file:
| column | value | rows | which groups |
|---|---|---|---|
c1_holds |
unmeasurable:arms_identical |
70 | sphere, box_exact, csg_difference, gyroid, noise_cavity at both rungs |
false |
14 | torus at both rungs |
|
true |
14 | fbm_terrain at both rungs |
|
unmeasurable:bins=2<3 |
14 | thin_plate at both rungs |
|
c2_holds |
unmeasurable:arms_identical |
70 | the same five fields |
unmeasurable:no_umbilic_bin |
28 | torus, thin_plate |
|
false |
14 | fbm_terrain |
|
true |
0 | — |
| clause | registered | measured |
|---|---|---|
| C1 binning surface cells by principal-curvature ratio, the anisotropic triangle saving is monotone in the ratio, correlation above 0.7 | monotone, ρ > 0.7 | FALSIFIED on torus, and the one true is worse news than the false. torus reads saving_vs_curvature_ratio_correlation −0.400000 at 33³ and −1.000000 at 65³ — at the finer rung the relationship is perfectly reversed: saving 1.000000 (near_umbilic, 16 cells, 24 → 0 triangles), −0.021203 (mild_anisotropy, 2016 cells), −0.128891 (strong_anisotropy, 2064), −0.357143 (flat_direction, 112). fbm_terrain reads 1.000000 at both rungs and so scores c1_holds true — while every one of its five ordered bins has a negative saving: at 65³, −6.037543 / −5.996029 / −5.896340 / −5.555359 / −5.315789. The correlation is monotone because the anisotropic arm is uniformly about 7× more expensive and slightly less so where the ratio is high. c1_groups_holding 2 of c1_groups_measurable 4 on all 112 rows |
| C2 cells with ratio near 1 — spherical caps — show no saving, the control that says the effect is anisotropy rather than general refinement | |saving| small on the umbilic bin |
FALSIFIED on the one group where it was measurable, and by a factor of seven. c2_umbilic_saving reads 0.000000 on the 70 identical-arm rows, undefined on the 28 rows with no populated umbilic bin, and −3.322148 (fbm_terrain at 33³) and −6.037543 (at 65³). At 65³ that bin holds 580 cells at principal_curvature_ratio 1.134998 with elliptic_fraction 0.177586, and the anisotropic arm spends 8248 triangles there against the isotropic arm's 1172. The falsifier reads "C2 by a saving on isotropic cells, same conclusion and more damning" — this is a cost on isotropic cells, which is the same conclusion again |
The 70 identical-arm rows are the phase's central Group D fact and they are recorded as
unmeasurable, not asfalse.axis_ratioreads exactly 1.000000 on 70 of 112 rows withbudget_ratioexactly 1.000000 andaxes_pinned0 —sphere,box_exact,csg_difference,gyroidandnoise_cavityreceive a metric-driven grid identical to the isotropic one at both rungs, so everysavingin those bins is1 − T/Tand could not have been anything else (M-44). Three of those five even carry a computed correlation of 0.000000 overcorrelation_bins5 — a Spearman through five tied zeros — which is exactly why the verdict column saysunmeasurable:arms_identicalrather than reporting a falsification fitted through a constant. The graded fields aretorus(axis_ratio1.129032 at 33³, 1.095238 at 65³),thin_plate(14.692308, 30.238095) andfbm_terrain(17.400000, 47.400000,axes_pinned1 —n_yheld atMIN_SAMPLES).
thin_plate'sunmeasurable:bins=2<3is unreachable with its arithmetic, not a near miss.correlation_binsis 2 on both its rungs: at 65³ onlynear_umbilic(8 cells, ratio 1.324449) andflat_direction(240 cells, ratio pegged at the reported cap 1000000.000000) are populated among the five ordered classes, withumbilic,mild_anisotropyandstrong_anisotropyall atcells0 andsavingundefined:no_isotropic_triangles. A slab is a box: it has two curvature regimes — the flat faces and the rim creases — and nothing in between, so a monotonicity over three or more bins is arithmetically undefined on it. Its two populated bins both show positive savings (planar0.886667 over 1800 cells,flat_direction0.733333 over 240) bought with error:hausdorff_delta+0.083310516 and +0.072732432, positive, so the triangles came out of the accuracy and not out of the anisotropy.torusandthin_plateboth readunmeasurable:no_umbilic_binon C2 because theirumbilicbin is empty —cells0 — so C2's control has no population on either.All five registered vacuity controls fired, and the registered one fired across the sweep rather than per group. (1) Every ordered curvature-ratio bin non-empty on at least one field:
cells_all_fieldsis 30,964 (umbilic), 13,647 (near_umbilic), 19,746 (mild_anisotropy), 17,805 (strong_anisotropy) and 3,467 (flat_direction), beside 14,303planarand 5,763unclassified— 105,695 binned cells, 19,945 at 33³ and 85,750 at 65³, so the monotonicity is not fitted through gaps in the population, only through gaps in the per-field grids. (2) The anisotropic arm is anisotropic somewhere:axis_ratio47.400000 onfbm_terrainagainst a floor of 1.5. (3) The two arms are on one budget:budget_ratioruns 0.898211–1.019700 against a[0.25, 4]window, so no "saving" is a smaller sample count in a metric's clothes. (4) At least one group reaches three populated ordered bins:correlation_binsis 5 on ten groups, 4 ontorus, 2 onbox_exactandthin_plate, 1 onsphere. (5) The band is non-empty on every group, and the surface→mesh probes converged:probe_residual_maxruns 0.000000e0 to 5.625000e-2 over the 56 rows where the projection is a projection.
The mechanism the row was built to find is in the data — it is just not connected to the saving.
The registration's whole claim is that the AM–GM gap collapses toward zero exactly where one principal
curvature vanishes, and in two surface dimensions that gap is 2√r/(1 + r) and a function of the ratio
alone. Both halves are recorded, and they agree on 97 of 112 rows exactly as printed:
am_gm_gap_measured (the median per-cell √\|κ₀κ₁\|/((\|κ₀\|+\|κ₁\|)/2) inside the bin) against
am_gm_gap_predicted (2√R/(1+R) at the bin's median ratio R). On fbm_terrain at 33³ the measured
gap falls 0.997759 → 0.972287 → 0.857911 → 0.590343 → 0.205980 across the five ordered bins, against
the closed form's 1.000000 / 0.993808 / 0.942809 / 0.745356 / 0.277297 at the bin edges — strictly
decreasing, and the collapse is real. So the physics is confirmed and the saving is not a function of
it: the gap knows the curvature ratio per cell, and a per-axis global grid has three numbers with
which to answer. Of the 15 rows where the two disagree, seven are the flat_direction bin where the
ratio is pegged at the cap 1e6 and the measured gap reads exactly 0.000000 against a predicted
0.002000, and the rest differ in the third or fourth digit (torus/65/near_umbilic
0.946860 vs 0.946690; the largest is csg_difference/33/mild_anisotropy, 0.862363 vs
0.776258).
Two orientation and definition facts a reader needs before quoting any number here. First,
principal_curvature_ratio is the reciprocal of common::metric's own convention: the module
returns curvatures ascending by magnitude and documents P-149's ratio as |κ₀|/|κ₁| ∈ (0, 1]
(benches/common/metric.rs:666), while this harness records |κ₁|/|κ₀| ≥ 1 because the registration
pairs "monotone" with "above 0.7" and only that orientation lets a confirmed mechanism read positive.
Both are on every row — curvature_ratio_reciprocal carries the module's, and
saving_vs_reciprocal_correlation its correlation, which is the sign-flipped twin (torus at 65³:
−1.000000 registered, +1.000000 reciprocal). Second, the ratio is blind to sign and gyroid
exploits that: a minimal surface has κ₁ = −κ₀ exactly, so a gyroid saddle has r = 1 and lands in
umbilic beside a sphere cap. elliptic_fraction is on every row for exactly this — 1 for a cap,
0 for a saddle — and fbm_terrain's umbilic bin at 65³ reads 0.177586, so C2's control
population there is mostly saddles rather than caps.
What this means for Group D, read together with P-146 and P-147. P-146 measured the aggregate
and got no win (c1_winners 0 over c1_population 4). P-147 decomposed the error law and found
neither the exponent nor the constant moved for the reason the theory names. This row was the third
attempt — measure the mechanism per feature class — and it lands on the same wall from a third
direction: the AM–GM gap is a per-cell quantity, and P-146's construction spends anisotropy per
axis over the whole domain. pooled_correlation over the whole sweep is 0.187131 at 33³ and
−0.060731 at 65³, i.e. it degrades toward zero as the grids get finer, which is the opposite of a
mechanism sharpening. The three failures are one failure with three witnesses, and it is a failure of
the instrument the shipped extract permits — one scalar cell_size
(marching_cubes/mod.rs:193) — not of Loseille–Alauzet. The registered clause about monotonicity is
retired for per-axis global grids only; nothing here narrows the per-cell claim, which needs a
source change to ask for.
SHARE, recomputed. The registration's SHARE is "C1 decomposes P-146's C1 saving by feature class;
the bin populations are reported so each saving has a denominator." Discharged twice: what was
decomposed is a zero (p-146.csv's c1_winners is 0 on all 40 rows), and this row's answer is that
the zero is a constant, not a cancellation — on five of eight fields it is zero cell by cell because
the two arms are one grid. Every row carries cells as its own denominator and cells_all_fields as the
class's sweep-wide one. No source change landed, no golden hash moved, no clause reads a clock —
there is no wall-clock column in the file at all (R-151 owns the cost question).
What a consumer should do differently: nothing changes, and one number must stop being quoted. No
shipped path moved. But fbm_terrain's c1_holds true is not evidence for anisotropic
refinement and must never be cited as a Group D win: it is a monotone correlation over five bins each
of which is a 6× triangle cost, and the correct one-line summary of this row is that on the two
fields whose grids actually graded, the anisotropic arm was either anti-monotone (torus) or uniformly
more expensive (fbm_terrain). Would be shown wrong by: a per-cell anisotropic extractor
reproducing a positive saving in the strong_anisotropy and flat_direction bins with
hausdorff_delta ≤ 0, and a near-zero saving in umbilic on the same field and rung — which is C1
and C2 together, and is the measurement this construction cannot make.
🧊 M-463 — the registered null came back null and then inverted: Cao's L¹ anomaly did not reproduce — anomaly_reproduced false on all 384 rows, violations_in_l1 0 of violations_total 72 — because M_L1 wins all 96 groups in every norm, so norm_dependent_winner_rungs is 0 and L¹ is the one column where the theory holds rather than the one place it fails; c1_holds true on 96 rows and false on 288, C2 HELD on 384 with every violation classified and the continuous model agreeing with Cao on all 384 (P-150, R-150)
M. cargo bench --bench experiment_p150, docs/experiments/p-150.csv, 384 rows across 53
columns — four # comment lines plus one column header plus 384 data rows, 389 lines, counted from the
file; 9 of the 53 columns are P-150's registered records. The shape, also from the file: 8 fields ×
3 resolutions (17, 33, 65) × 4 norms × 4 metrics = 384, i.e. 96 groups of four
(group_key = field|resolution|norm, group_arms 4, groups_total 96, groups_resolved
96). norm and metric each take four values 96 times; p_exponent and metric_exponent carry
1|2|3|inf. stencil_points 21 on every row, domain_extent 4.000000 / 14.000000 / 16.000000. f64
throughout, one thread, no PRNG, no wall-clock column anywhere in the file. Clean tree — # commit
5d04110 on amd-ryzen-9-5900x-12-core at 2026-08-30T14:30:15Z, no (WORKING TREE DIRTY). The verdicts
are group verdicts, identical on a group's four rows; error_measured, element_count,
quadratic_model_ratio, element_extent_*, complexity_* and metric_scale are per arm.
| clause | registered | measured |
|---|---|---|
| C1 the metric optimised for a given norm wins in that norm, every comparison inside one norm | per group | c1_holds true on 96 rows and false on 288 — true on the 24 L^1 groups and false on the 72 others, so it holds on 24 of 96 groups. winner_metric is M_L1 on all 384 rows: M_L1 is the argmin in L^1, in L^2, in L^3 and in L^inf, at every field and every rung. norm_dependent_winner_rungs is 0 — there is not one rung anywhere in the file where the winner depends on the norm. c1_global_holds false on all 384 |
| C2 any violation is characterisable, and the comparison is always reported within a norm and never across two | mechanism ≠ uncharacterised; grouping structural |
HELD on all 384 rows, c2_global_holds true. violation_mechanism reads none on the 96 L^1 rows, element_exceeds_domain on 144 and hessian_floor on 144, and never uncharacterised. The split is not ragged: hessian_floor on every non-L^1 group of box_exact, csg_difference, thin_plate, fbm_terrain; element_exceeds_domain on every non-L^1 group of sphere, torus, gyroid, noise_cavity. The "within a norm" half is structural rather than promised — group_key's third field is the norm and the winner is an argmin over that group and nothing else |
the registered null — does Cao's L¹ anomaly reproduce on our fields? |
either, reported | NO, and the file is unanimous. anomaly_reproduced and anomaly_reproduced_global false on all 384 rows; cao_table_agreement reads theory_holds on 96 rows (all 24 L^1 groups) and violation_outside_l1 on 288, never l1_anomaly_reproduced. violations_total 72, violations_outside_l1 72, violations_in_l1 0 |
The null is not "nothing happened" — it is the sharpest possible inversion of the source's own caveat, and it is worth stating in one sentence. Cao writes that his theory holds "in all the cases except the
L^1-error of quadratic interpolation", and the registration exists because building on that column is the weakest available ground. On these eight fields,L^1is the only column where the theory holds at all:loss_margin_relativeis exactly 0.000000e0 on every one of the 96L^1rows, and runs 1.296543e-1–3.929444e0 inL^2, 2.362076e-1–1.442354e1 inL^3and 3.595569e-1–5.304897e2 inL^inf. The worst single reading isgyroidat 33³ inL^inf:loss_margin_relative5.304897e2 — the metric optimised forL^infloses inL^inftoM_L1by a factor of 531, withspread_in_norm531.489721 across the group's four arms. So the registration's warning was correct in direction and wrong in location: theL^1column is not uniquely weak here, it is uniquely sound, and the honest reading of the whole file is that one metric — the most strongly graded one — minimises every norm we can measure, which is C1 falsified in the strongest form the registration admits. That outcome was anticipated: the harness's header declaresnorm_dependent_winner_rungsdeliberately not a vacuity control, because a zero there is a registered finding and aborting on it would suppress the result.C2's
hessian_floorandelement_exceeds_domainare not labels; each carries its own column and the split is explained by one number per field. The fourhessian_floorfields are exactly the four whose band is mostly atH_FLOOR:at_floor_fraction0.963303–0.997788 (box_exact), 0.788321–0.893635 (csg_difference), 0.885305–0.990585 (thin_plate) and 1.000000 at all three rungs (fbm_terrain, because a heightfield SDF is exactly linear iny). On those the determinantDthe exponent−α_qacts on is a floored1e-9and not a curvature, anddet_floored_log_variancereads 2.745404e2–6.326219e2 on those four — a handful of extremeln Dvalues rather than a distribution. The fourelement_exceeds_domainfields carryat_floor_fractionunder 0.09 and instead fail the other way:element_extent_relative— the unit-metric tetrahedron's longest edge against the domain's own extent — reaches 1.084709e3 (sphere), 1.735163e3 (torus), 1.348027e3 (gyroid) and 3.430490e3 (noise_cavity, at 17³ underM_Linf, anelement_extent_maxof 1.372196e4 in adomain_extentof 4.000000). An element three thousand times the domain is not sampling the region its Hessian describes, which is mechanism (2) of the four the header names. Neither mechanism is a defect in the shipped crate: both are properties ofcommon::metric's floored Hessian as a mesh prescription, measured here for the first time.Every registered vacuity control fired, and one of them closes a caveat in the source itself. (1) The registered control — at least three norms must be run, counted from the groups that exist and requiring
L^1,L^2andL^infby name: four norms ran, 24 groups each. (2) At least two metrics per group:group_arms4 on all 384 rows, asserted equal to the level count, so "the optimal metric wins" is never a comparison against nothing. (3) Every arm's error population contains a positive error:error_measuredis non-zero on all 384 rows, running 5.961251e-5 to 1.377310e4. (4) The budget must actually be matched — and this is where Cao's own table is beaten rather than quoted:cao_element_match_referencecarries his 0.014000 (1.4%) element-count agreement as a column, and this file'scomplexity_rel_erroris at most 4.434e-10 over all 384 arms, seven orders tighter (the harness header claims six against a1e-8target; the run beat its own target), withelement_countidentical on a group's four rows by construction. (5) At least one group's ranking is resolved pastMIN_SEPARATION = 1e-3:ranking_resolvedtrueon all 384 andgroups_resolved96 of 96, withrunner_up_margin_relativenever below 7.094655e-2. So no verdict in the file is arithmetic noise. (6) The band is non-empty on every field and rung:band_samples279–21,655.
The continuous model agrees with Cao on all 384 rows, and that is the cleanest thing in the file.
The header derives, before any measurement, that q = p minimises the continuous error Ê_p(M_q)
strictly — the derivative d(ln Ê_p)/du = E_B[ln D] − E_A[ln D] vanishes identically at u = α_p and is
increasing, so the stationary point is the unique minimum unless Var(ln D) = 0. Measured:
continuous_winner_metric is M_L1 on the 96 L^1 rows, M_L2 on the 96 L^2 rows, M_L3 on the
96 L^3 rows and M_Linf on the 96 L^inf rows — it picks the matched metric on 384 of 384,
with continuous_wins true throughout and det_floored_log_variance never zero (min 1.295172), so
the ranking could always discriminate. continuous_agrees is true on 96 rows and false on 288:
exactly the same 96/288 split as c1_holds. So the theory and the measurement agree in L^1 and
disagree in the other three, and the disagreement is entirely attributable to the four discrete effects
the header enumerates — this is the separation of theory on our data from measurement on our data,
and it is what makes C2's characterisable a claim with content rather than a shrug.
The premise the whole metric rests on fails outright on two of eight fields, and the column that says
so is not read by any clause. quadratic_model_ratio is the same 21-point maximum taken over the
cell's own quadratic model rather than over f, divided by the measured error, median over the band —
the direct test of "the cell's Hessian describes f over the element the metric prescribed". It reads
exactly 0.000000e0 on 64 rows, and all 64 are box_exact or csg_difference at 33³ and 65³: on a
grid-aligned polyhedron at those rungs the median band cell's quadratic model predicts zero error
while the measured e_K is finite, because a face has no second derivative and the error the mesh makes
there is tangential. Where it is not zero it runs 2.831506e-9 to 1.398914e0, so the quadratic
model over-predicts by up to 40% at one end and under-predicts by nine orders at the other.
The registration names no clause over this column and it is recorded anyway;
P-147's C3 and P-155's C2 are the two rows that already found the polyhedra outside W^{2,p}, and
this is the same fact arriving through the metric's own premise.
Cao's headline 5.1× is carried as a column so it cannot be quoted loose. cao_spread_reference is
5.138122 on all 384 rows — his 2.79e-6 / 5.43e-7 — and it sits beside this file's own
spread_in_norm, which is the max/min error inside one group and runs 1.301923 to 531.489721.
The point the registration was registered to make survives intact and is now measured: a spread of that
size between two metrics is routine and means nothing across two norms, because M_Linf loses to
M_L1 by spread_in_norm 5.391872 even in L^1 on gyroid at 65³ (2.299342e0 against
4.264459e-1) — a spread larger than Cao's headline, inside one norm — while being the
metric optimised for a different question entirely. element_count is identical on a group's four rows,
so there is no element-count caveat left to hide behind.
SHARE, recomputed. "None — this is a methodology guard", and the discharge is that nothing here
proposes a change to crates/isomesh/src/, and that is the finding. No source file was touched, no
golden hash moved, and no clause reads a clock — there is no nanosecond, cycle or wall-clock column in
the file, so M-280's 1.45× governor swing has nothing to swing and this row's verdicts are unmovable
by a re-run: every one is an argmin over four f64 errors computed from a fixed deterministic sweep.
What the row produces is a constraint on how Group D may be quoted, plus the two columns that let a
reader check it — det_floored_log_variance and continuous_agrees.
What a consumer should do differently. Nothing in the crate changes. The rule this row exists to
ship is: an error comparison between two metrics is meaningless unless both are read in the same norm at
the same complexity, and on our fields not even that is enough — because the same metric, M_L1, wins
every norm at every rung, so a reader who picks a metric by matching it to a norm will be beaten by the
most graded one on 72 of 96 comparisons. And never carry Cao's L¹ caveat forward as though it had
been confirmed here: it was tested on eight fields at three resolutions and came back false 384
times. Would be shown wrong by: a field on which M_L1 is not the winner in some norm, which would
put norm_dependent_winner_rungs above zero and restore the theory's discriminating power on real data;
an L^1 group reading cao_table_agreement l1_anomaly_reproduced, which would be Cao's own exception
arriving on different data and a genuine contribution; or a violation returning
violation_mechanism uncharacterised, which is the single way C2 can fall.
💥 ✗110 / M-464 — C1 and C2 split 16 true / 48 false: they hold on torus alone, where gain_near 0.244932 collapses to gain_wide −0.010015 and so is the visibility mechanism C2 asks for, and fail on the other three — sphere's goal arm is 10.655× worse at matched triangles (gain_near −9.655511) because it saturates at 1,280 triangles, while box_exact's and thin_plate's near-camera clause is arithmetically unreachable at the 1e-4 px error floor; C3 FALSIFIED at adjoint_share 0.144361 against a 10% bar, and the whole criterion costs 0.371498–3.055830 of extraction (P-151, R-151)
M. cargo bench --bench experiment_p151, docs/experiments/p-151.csv, 64 rows across 61
columns — four # comment lines plus one column header plus 64 data rows, 69 lines, counted from the
file; 12 of the 61 columns are P-151's registered records. The shape, also from the file: 4 fields
× 2 cameras × 2 criteria × 4 budget rungs. The population is the four FieldBound::Exact fields —
sphere, torus, box_exact, thin_plate, 16 rows each — because probe generation Newton-projects
along ∇f and only an exact distance field makes that a one-step projection worth asserting. functional
is rms_visible_pixel_displacement on all 64, pixels 1920x1080, fov_y_deg 38.0, c1_bar 0.20,
repeats 7 interleaved. blocks_occupied 32 on 48 rows and 64 on box_exact's 16;
level_histogram is four counts over LEVEL_CELLS = 2, 4, 8, 16 cells per block axis. f64 throughout,
one thread, no PRNG. Clean tree — # commit 1acfb94 on amd-ryzen-9-5900x-12-core at
2026-08-30T14:30:21Z, no (WORKING TREE DIRTY). c1_holds and c2_holds are per field (the
near-camera verdict, written on all sixteen of that field's rows); c3_holds is global and false
on all 64, with the per-row fact in c3_row_holds.
The screen-space error, quoted because two readings were available and the file uses one.
screen_space_error is a world error weighted by projected pixel size, taken surface → mesh:
E = sqrt( (1/|V|) · Σ_{q ∈ V} ( f_px · d(q, M) / z(q) )² ), f_px = (1080/2)/tan(19°)
with V a fixed set of points on the true surface, generated once per field from a 33³ seed
lattice by Newton projection and filtered to the visible ones (in frustum and front-facing), so V
is identical for both arms and every budget; d(q, M) the exact point-to-triangle distance; z(q) the
view-axis depth. probes reads 1442 / 1344 / 1538 / 289 and visible_probes 26 / 285 / 8 / 175
on the near camera against 686 / 657 / 769 / 257 on the wide one. The direction is surface → mesh
on purpose: |f(v)| over mesh vertices is blind to a feature the mesh omits, and omission is exactly
what a saturating criterion produces.
| clause | registered | measured |
|---|---|---|
| C1 at matched triangle count, a goal-oriented criterion beats camera-distance LOD on screen-space error by at least 20% | gain_near ≥ 0.20 |
c1_holds true on 16 rows, false on 48 — c1_fields_held 1 of 4 on every row. torus: gain_near 0.244932, over the bar. sphere: −9.655511 — at matched_triangles 3212, screen_error_at_matched_triangles is 3.431338e1 for the goal arm against 3.220247e0 for camera-distance, a factor of 10.655 the wrong way. box_exact and thin_plate: 0.000000 exactly, and unreachable — see below. The four fields' matched_triangles are 3212 / 2920 / 3800 / 1016, each the camera-distance arm's own count at REFERENCE_RUNG = 2 (budget_fraction 0.3500) on the near camera |
| C2 the saving comes from not refining what is off-screen or back-facing, rather than from a general improvement | gain_near ≥ 0.20 and gain_wide < 0.5 · gain_near |
c2_holds true on 16 rows, false on 48, c2_fields_held 1. On torus it holds cleanly and in the registered direction: gain_near 0.244932 against gain_wide −0.010015 — move the camera back until nothing is outside the frustum and the entire advantage vanishes and turns slightly negative. On the other three the first conjunct fails, so C2 is not reached; and on two of them the second conjunct would have failed too, which is worth naming — thin_plate reads gain_near 0.000000 with gain_wide +0.320501 and sphere −9.655511 with +0.200163, i.e. the goal arm's advantage is larger with everything on-screen. Where it wins on those fields it wins on curvature, not visibility |
| C3 the adjoint cost is under 10% of extraction | adjoint_share < 0.10 |
FALSIFIED. c3_holds false on all 64 rows with c3_row_decisive true on all 64; c3_row_holds true on 56 and false on 8. The eight are box_exact/near, where adjoint_share is 0.144361 — 14.44% — with adjoint_share_lo 0.137235 and adjoint_share_hi 0.145944, so the whole seven-repeat interval sits above the bar. Elsewhere the share runs 0.013032–0.039679 |
box_exact's andthin_plate's C1 is arithmetically unreachable, and the arithmetic is one line.ERROR_FLOOR_PX = 1e-4, and on the near camera both fields'screen_space_erroris at or below it:box_exactreads 0.000000e0 on all eight near rows (an axis-aligned box's faces are reproduced exactly by marching cubes, and only 8 of its 1538 probes are visible from an eye inside the domain at[0.30, 0.62, 1.30]), andthin_platereads 2.123138e0 → 2.018027e0 → 3.744388e-15 → 3.744388e-15 across the rungs, i.e. the plate is resolved exactly once the level is fine enough.screen_error_at_matched_trianglesis therefore 1.000000e-4 for both arms on both fields, andgain_nearis1 − 1e-4/1e-4= 0.000000 — a zero that could not have been anything else (M-44), on half the population. C1's registered content is carried entirely bysphereandtorus, and it is carried without vacuity there because both arms produce a real, resolved error curve on both.P-70's C1 is the precedent for recording that rather than scoring two more failures.
sphere's −9.655511 is the goal criterion saturating, and the clamp that produced it is conservative against the hypothesis by design. The goal arm's ranking isZ_K · (κ_K h_L²/8)², so a block whose surface is flat hasκ_K = 0, an honest zero gain, and the greedy declines to spend triangles on it. Onsphere/nearthat leavesblocks_promoted3 of 32 at every rung against camera-distance's 31/32/32/32,trianglespinned at 1280 on rungs 1, 2 and 3 (budget_boundfalseon those three rows,matched_clampedtrueon all four), andlevel_histogram29|0|0|3— twenty-nine blocks left at the coarsest level because only 26 of 1442 probes are visible. The read-off is then clamped to the curve's endpoint, charging the goal arm the error it had at fewer triangles, which is larger;matched_clampedflags every such row (trueon 8 of 64). So the number is a genuine loss and the clamp makes it a lower bound on the loss, not an artefact.All five vacuity controls fired, and the registered one is the reason the two cameras exist. (1) The registered control — "a non-trivial fraction of the scene must be off-screen" — asserted above
OFF_SCREEN_FLOOR = 0.20on the near camera and measuredoff_screen_fraction0.663662 (sphere), 0.474702 (torus), 0.732120 (box_exact), 0.301038 (thin_plate); it is asserted on the frustum fraction (frustum_off_fraction0.715768 / 0.488854 / 0.722603 / 0.258065) and not on the registeredoff_screen_trianglesunion, because back-facing alone puts about half of any closed surface off-screen for free —back_facing_fraction0.817427 / 0.609873 / 0.856164 / 0.500000 near, and still 0.473029 / 0.501592 / 0.500000 / 0.500000 wide. (2) The C2 control must be a control: the wide camera'soff_screen_fractionis 0.000000 on all 32 wide rows, against aWIDE_ON_SCREEN_CEILof 0.02 — so "everything on-screen" is literally what was run, and C2's falsifier had a real instrument. Moving the camera back removes frustum invisibility and cannot remove back-facing, so C2's verdict is a statement about the frustum half of the mechanism and the row carries the residual rather than implying it. (3) The functional has a population:visible_probes8–769, non-zero on every (field, camera) — the8onbox_exact/nearis the tightest and is why that field's error is at the floor. (4) The two criteria disagree:levels_differtrueon all 64 rows, so nogainin the file is a measurement of the extractor's determinism. (5) Something is promoted:blocks_promotedruns 2–64, sopop_magnitude_cellsis not a zero that could not have been non-zero.
The registered column shows C2's mechanism directly, and it is the strongest single reading in the
file. off_screen_triangles — the count of extracted triangles whose centroid is outside the frustum
or whose normal faces away from the eye — on torus/near at the matched rung 2:
camera-distance emits 2920 triangles of which 2444 are off-screen (83.7%, with
frustum_off_triangles 1727), while the goal arm emits 3154 triangles of which 1807 are
off-screen (57.3%, frustum_off_triangles 923). So at a larger total the goal arm leaves 47%
fewer triangles outside the frustum — 1727 against 923 — and that is where its 24.5% win comes from.
The two halves
are recorded separately because they behave differently: over the four rungs
frustum_off_triangles falls 307/858/1727/3883 → 211/401/923/1203 between the arms while
back_facing_triangles falls only 383/862/1860/4099 → 272/742/1181/2005 — moving the camera back
removes frustum invisibility and cannot remove back-facing, which is exactly why the wide control
isolates one half of the mechanism and gain_wide −0.010015 is a statement about the frustum half
alone.
M-121's pop, measured again on this ladder, and the comparison must be against the right half of
M-121 — but the SHARE's own falsifiable prediction did not come out. M-121 recorded "a level
change moves the surface by up to 3.14 cells, which is the pop nobody measures" — worst 3.136
cells, typically 0.6–1.6, over a full LOD flight. That 3.136 is a two-level switch, and R-091
established it: restricted to adjacent level pairs the same fixture reads 1.6177 cells, a 1.94×
disagreement, because game_lod_flyover::level_for lets a block cross two LEVEL_RANGE boundaries
between frames while h divides by the coarser cell (FINDINGS.md:19167-19173). A promotion here is
one level — it halves h — so 1.6177 is the figure this row is commensurable with, not 3.136, and
quoting the larger one would repeat exactly the trap m121_reproduced_adjacent_only exists to keep
visible. On this block ladder pop_magnitude_cells — the two-sided nearest-vertex Hausdorff distance
between a promoted block extracted at its old and its new level, in units of the coarse level's cell size
— runs 0.707107 to 0.752866 over all 64 rows: inside M-121's "typically 0.6–1.6" band and
44–47% of the adjacent-pair worst. The SHARE, however, is registered as a claim that a goal-oriented
criterion "has a comparable pop_magnitude_cells and a smaller pop_magnitude_pixels: the same pops,
moved off the screen." It does not. pop_magnitude_pixels = pop_world · f_px / z_K is
identical on the two criteria at every (field, camera) — 632.149486 / 29.328897 on sphere
near/wide, 625.188963 / 29.234561 on torus, 615.986568 / 29.078625 on box_exact,
515.071192 / 28.495007 on thin_plate — so the goal arm's much smaller promotion set (3 blocks
against 31 on sphere/near) still contains a block whose worst pop sits at the same depth as the
distance arm's. The column is a worst-over-promoted-blocks and a worst is not moved by promoting fewer;
the 21.6× near/wide ratio in it is the camera, not the criterion. That is the SHARE falsified on its
own column, which is what putting it in a column rather than in prose is for.
C3's failure is on the cheapest of three stages, and the other two are worse — which is the number a
reader should take away. What C3 times is adjoint_weights and nothing else: per proxy probe, one
Sdf::gradient, one normalisation, one back-face test, one frustum test, one f_px/z, one accumulate,
with nothing cached, because in a destructible-terrain game the field is edited between frames and a
cached normal is stale. adjoint_ms runs 0.004450–0.017790 ms against extract_ms
0.119631–0.985447 ms, seven interleaved repeats after a warm-up with a median headline, and
adjoint_scatter (max/min) 1.134557–1.261566 — so M-280's 1.45× governor swing is inside the
scatter and the interleaved schedule is what lets the ratio survive it. The bar is breached on exactly
one (field, camera) pair, box_exact/near, and the mechanism is visible on the row rather than
mysterious: that field has 64 occupied blocks against 32, so the proxy probe set is the largest in
the file, while its near-camera extraction is the cheapest (extract_ms 0.119631) — a large
numerator over a small denominator. But adjoint_share is not the cost of the method, and
criterion_share is: proxy sampling plus principal_curvatures plus the adjoint runs
0.371498–3.055830 of extraction, i.e. 37% to 306%, over criterion_ms
0.201302–0.366092 ms with proxy_ms 0.088481–0.195981 and curvature_ms
0.039051–0.152321. That is the same order as p-146.csv's metric_share,
carried here as columns p146_metric_share_min 0.332862, p146_metric_share_median 2.008345,
p146_metric_share_max 8.747515. So C3 is falsified at 14.44% on the adjoint, and the honest
verdict on the method's cost is three to thirty times worse than the clause it failed.
One quiet corroboration of a phase-wide fact. degenerate_triangles is 0 on all 64 rows, across
four fields, two cameras, two criteria and four levels of block LOD, including every cracked seam where
two neighbouring blocks sit at different levels. Read from docs/experiments/p-171.csv:
non_manifold_edges, non_manifold_vertices and self_intersecting_pairs are 0 on all 24 rows, and
degenerate_triangles is non-zero on gyroid alone (4, on three rows) and noise_cavity alone
(54 / 68 / 74) — 208 in total — and 0 on sphere, torus, box_exact, thin_plate,
csg_difference and fbm_terrain. So T-001's entire defect population on these fields is degenerate
triangles, and the two fields that carry them are not in this row's FieldBound::Exact population. This
file's zero is the complementary reading: on the four fields that carry no degenerate triangles under
uniform extraction, block LOD with mismatched neighbour levels does not create any either.
SHARE, recomputed. The registration's SHARE is "C1 moves the LOD selection stage; M-121 measured a
level change moving the surface by up to 3.14 cells, which is the pop this criterion is meant to spend
better." Discharged as two columns and falsified on the second: pop_magnitude_cells
0.707107–0.752866 (comparable, as predicted) and pop_magnitude_pixels identical between arms (not
smaller, against the prediction). No source change landed — crates/isomesh/src/ is frozen for
Phase 27 and every inherent extract takes one scalar cell_size (marching_cubes/mod.rs:193 and
six other sites), so a per-cell adaptive extractor is a source change by construction and the block-LOD
construction here is the one M-121 measured. No golden hash moved.
What a consumer should do differently. Do not adopt a goal-oriented criterion on this evidence.
It beat camera-distance LOD by the registered 20% on one field of four, and on that field the win is
demonstrably the frustum test (gain_wide −0.010015) rather than the DWR estimate — which means the
cheap half of the mechanism is doing the work, and a frustum cull in front of a distance LOD gets it for
a rounding error. Against that, the criterion's own cost is 37%–306% of extraction and its curvature
term makes it saturate: on three of four fields it stops spending the budget entirely
(budget_bound false on 12 rows), which on sphere costs a 10.655× screen error at matched
triangles. Would be shown wrong by: gain_near ≥ 0.20 with gain_wide < 0.5 · gain_near on three
or more fields, which is C1 and C2 together on a majority; a cached-normal adjoint bringing
adjoint_share under 0.10 on box_exact/near and a criterion_share under 1.0, which would make
the cost argument survivable; or a residual model that does not zero on a flat block, which is the
single mechanism behind every saturation in this file.
💥 ✗111 / M-465 — C1 FALSIFIED on 16 of 16 rows (beta_share 0.824659–1.693981 against a bar of 0.10), C2 FALSIFIED at c2_fields_above_bar 4 of eight against a bar of six, C3 HELD on 6 rows of 16: β is not a fraction of an extraction, it is one to two extractions, and the signal it carries that the residual does not is 3 to 176 cells a row (R-152)
M. cargo bench --bench experiment_p152, docs/experiments/p-152.csv, 16 rows × 61 columns — eight reference fields at resolution 33 and 65, counted from the file. # commit 98c5309 on amd-ryzen-9-5900x-12-core at 2026-08-30T09:27:15Z, no (WORKING TREE DIRTY) on that line. f64 throughout, one thread, no PRNG. The β side is common::beta (R-152's own module) consumed unchanged; the residual side is the shipped solver — isomesh::hermite::HermiteCell and isomesh::dual_contouring::solve::{LAMBDA, solve}, both already public and already used from benches (experiment_p52.rs:217-220), so the residual measured is the residual of the vertex the crate actually places (experiment_p152.rs:77-84).
| clause | registered | measured |
|---|---|---|
C1 β_∞(Q)·diam(Q) is computable per cell at under 10% of extraction cost |
beta_share ≤ 0.10 |
FALSIFIED on 16 of 16. beta_share = beta_ms / extract_ms runs 0.824659 (noise_cavity at 33) to 1.693981 (thin_plate at 33). c1_bar 0.10 is on every row; the nearest row misses it by 8.2× and the worst by 16.9×. beta_share_min/beta_share_max bracket the extreme repeat pairing and never cross the bar either (thin_plate at 33: 1.677951 / 1.921522) |
| C2 it rank-correlates with the QEF residual above 0.7 on at least six of eight fields | c2_fields_above_bar ≥ 6, decided at resolution = 65 |
FALSIFIED. c2_fields_above_bar 4 on every row, at both resolutions. Clearing c2_bar 0.70 at 65: torus 0.816543, gyroid 0.774640, noise_cavity 0.718168, fbm_terrain 0.710924. Missing: csg_difference 0.697785, sphere 0.380151, and box_exact and thin_plate at 0.000000 |
C3 there exist cells with low residual and high β — where the plane fit is confidently wrong — and the count is reported |
confidently_wrong_cells > 0, per row |
HELD on 6 rows of 16. fbm_terrain 16 and noise_cavity 11 at 33; sphere 176, fbm_terrain 48, noise_cavity 20 and gyroid 3 at 65. Empty on the other ten, including every row of box_exact, thin_plate, torus and csg_difference |
C3's surviving six rows are the only thing in this file that argues for
β, and they are worth naming precisely. Both sides are quantiles of that row's own surface-cell population, written into the CSV rather than fixed by the harness:low_residual_thresholdisp25(residual)andhigh_beta_thresholdisp75(β·diam)on the floored column (experiment_p152.rs:216-220). Aconfidently_wrongcell is therefore one whose twelve edge crossings fit a plane in the best quartile of the field while sitting in no thin slab at all —sphereat 65 has 176 of them at thresholds7.901111851e-9and0.000020132,fbm_terrainat 65 has 48 at1.915251244e-5and0.009391222. That is not a reparametrisation of the residual: the residual, by construction, cannot see a patch that is curved but consistently curved, because a saddle's tangent planes can agree beautifully about a point that lies on none of the surface. What it is good for is exactly one thing — a per-cell flag that says "do not trust this vertex, keep the Hermite data or subdivide" in the cells the QEF's own objective calls its best. What it costs is the whole row above it: to obtainsphere's 176 flags you run 347,480 slab objective evaluations (slab_fits4,760 ×slab_evaluations_per_patch73) and paybeta_share1.384397 — a whole extraction and a third — which is 1,974 objective evaluations per flagged cell. Ongyroidat 65 it is 1,564,536 evaluations for 3 flags: 521,512 per cell.noise_cavityat 65 is 103,569;fbm_terrainat 33, the cheapest, is 8,933. A diagnostic at five hundred thousand evaluations per hit is a research instrument, not a stage.Six vacuity controls fired, all as assertions before the first
run.record, so a run that could not fire aborts rather than recording a pass. (1) The registered one:qef_residual_variance > 0on all 16 rows — 8.995557389e-16 at the smallest (box_exactat 65) and 2.552673646e-4 at the largest (fbm_terrainat 33) — so norank_correlationin this file is a correlation against a constant, which is the failure the registration's own falsifier names. (2)population_mismatch0 on 16 of 16:beta_per_cell'sSomeset and this file'scut ≥ 3set are the same cells, so the two statistics are of one point set. Had it been non-zero the whole comparison would be void rather than merely wrong, and it could have been:HermiteCell::from_corners' corner order lives in a private module and a permuted guess would land the crossings on different edges. (3)three_crossing_above_floor0 on 16 of 16, overthree_crossing_cells8 to 8,310 — three points are coplanar, so this is the coplanarity theorem re-measured on every field at every resolution, and a non-zero would meanPLANAR_FLOORsits below the noise it was chosen to clear. (4) The dead band:beta_floor_gap_decades8.239 to 11.557 on the twelve rows carrying cells on both sides, withbeta_max_below_floornever above 4.511952e-16 andbeta_min_above_floornever below 2.380555e-8. The floor at1e-12is the middle of a band no cell occupies, which is what licenses it as a measurement rather than a tolerance. (5)nonplanar_cells > 0somewhere in the run — 19,958 at the largest — so arank_correlationof0.000000is that row's geometry and not a dead instrument. (6) The singular strip is monotone in its threshold on every row.The floor decides C2, and both readings are in the file so no reader has to take one on trust.
rank_correlationis computed on the floored column;rank_correlation_unflooredsits beside it. The two disagree most where it matters most:thin_plateat 65 reads 0.000000 floored and 0.995977 unfloored — over aβcolumn whosebeta_infinityandbeta_infinity_maxare both 0.000000000 and whose largest sub-floor value is 6.409876e-17, on a field whose 2,048 surface cells are planar by construction — andcsg_differenceat 65 reads 0.697785 floored against 0.834229 unfloored, i.e. below C2's bar and above it. The unfloored reading would have returned a different verdict on C2 and the difference would have been a result about Jacobi's last bits. This entry quotes the floored column throughout.
spearman_ceiling says which of C2's four failures were refused by arithmetic and which by measurement, and they split two and two. The ceiling is the exact bound over both observed tie structures — the concordant pairing's coefficient, which by the rearrangement inequality no pairing of these two multisets can exceed (experiment_p152.rs:283-297). On box_exact and thin_plate it is 0.000000 at both resolutions with spearman_ceiling_admits_bar false: planar_fraction is 1.000000, nonplanar_cells 0, so the β column is a single value and no pairing could have produced any coefficient at all. Those two fields did not fail C2, they could not take it. On csg_difference the ceiling is 0.744336 at 33 and 0.769426 at 65, both above the bar and both admits_bar true, so its 0.674180 / 0.697785 is a real shortfall — β and the residual genuinely order those cells differently. sphere's ceiling is 0.985099 at 65 against a measured 0.380151: the widest gap in the file, and the field where the two statistics agree least.
A correction to common::beta's own census, recorded in columns rather than by editing the module. beta.rs:89-91 states that 944 of 1,160 sphere cells, 888 of 1,128 torus cells, all 512 thin_plate cells and 4,101 of 6,176 noise_cavity cells "carry a patch that is planar by construction". Those four numbers are the count of cells with at most four crossings, and the census's own justification — "three points are coplanar" — licenses the three-crossing cells and no more. Measured: on sphere at 33, three_crossing_cells 312 are all below the floor (three_crossing_above_floor 0), while of four_crossing_cells 624 only 48 are (four_crossing_below_floor). On noise_cavity at 33 it is 43 of 2,126; on gyroid at 65, 90 of 8,310. On the piecewise-planar fields the whole four-crossing population is below the floor — box_exact 1,344 of 1,344 at 33 and 5,760 of 5,760 at 65 — which is the right answer for a field that is affine across every cell. So the census's phrase is correct on box_exact and thin_plate and overstates the planar population by roughly the four-crossing count everywhere else. crates/isomesh/src/** and benches/common/** were read-only for this row; the module keeps its header and this entry carries the correction.
The row also produces the first per-cell evaluation of solve's Tikhonov constant, and it is the sharpest incidental number in the file. λ = 0.01 (solve.rs:85) is documented as the regulariser that stops an under-determined cell from flying off, and ✗12 records the removal of the rank branch that used to decide the question; the constant has therefore been a fixed answer to a question the crate never evaluated. Evaluated here by Sylvester's criterion on M − t·I — exact for a symmetric matrix, no eigensolver (experiment_p152.rs:243-262) — singular_cells at t = LAMBDA reads 4,760 of 4,760 surface cells on sphere at 65, 5,760 of 5,768 on box_exact, 6,001 of 6,014 on csg_difference, 16,263 of 28,375 on noise_cavity. On a smooth sphere at 65³ the regulariser dominates M along some direction in every single surface cell, so λ is not a rare rescue, it is the vertex-placement rule almost everywhere. singular_cells_tight at t = 1e-9 is the strip that keeps that honest: 0 on sphere, and 5,760 on box_exact — genuinely rank-deficient there, marginal at λ's scale on the sphere. A count identical at both thresholds is decided by neither, and these are not.
What a consumer should do differently: nothing, and the row closes the question rather than opening a ticket. The SHARE sentence offered β the vertex-placement stage, which M-25 prices at 3% of an extraction; the measurement puts the pass at 82% to 169% of one, so there is no share to fold it into and C1's bar was more than an order of magnitude from the mechanism's own published cost before the run began. β earns its theorem — Azzam & Schul's surface TST, arXiv:1609.02892 — and its 73-evaluation upper bound is honest in the only safe direction, since every value here is ≥ the true β_∞ and can only over-report roughness. But as a per-cell statistic it costs a mesh to compute, agrees with the residual on four fields of eight, and is identically zero on the two fields where a planarity statistic would be most useful to have. M-465 is the number to cite for β's cost; C3's six rows are the residue worth a Phase 28 look, and only if someone finds a way to compute β for less than 1,974 objective evaluations per flagged cell.
💥 ✗112 / M-466 — C1 FALSIFIED at c1_fields_won 2 of eight against a bar of five, C2 FALSIFIED at 0 of 2 named fields with beta_beats_curvature false on 8 of 8: the criterion this row was built to promote loses to the derivative it was built to discredit, on every field, and noise_cavity's refinement ladder is inverted (R-153)
M. cargo bench --bench experiment_p153, docs/experiments/p-153.csv, 24 rows × 87 columns — three criteria × eight reference fields, counted from the file. # commit b0289d0 on amd-ryzen-9-5900x-12-core at 2026-08-30T12:56:38Z, clean line. One grid ladder (BASE_SAMPLES 17 → refined h/2 → REFERENCE_SAMPLES 65), one triangle budget per field, three orderings of the same cells. f64, one thread, no PRNG; grid coordinates are exact binary fractions on all eight domains, so the assembly controls are bit-level.
| clause | registered | measured |
|---|---|---|
C1 at matched triangle count, β-driven refinement beats camera-distance refinement on symmetric Hausdorff on at least five of eight fields |
c1_fields_won ≥ 5 |
FALSIFIED at 2. beta_beats_camera is true on torus (beta_vs_camera_ratio 0.800923) and gyroid (0.929633), false on the other six: csg_difference loses at 1.023005, and sphere, box_exact, thin_plate, fbm_terrain and noise_cavity read exactly 1.000000 — both arms sit on the same number, the coarse bookend. c1_holds_at_low_budget is false too, so the verdict does not turn on BUDGET_GROWTH |
C2 β beats curvature specifically on the sub-cell fields, thin_plate and noise_cavity named |
beta_beats_curvature on both named fields |
FALSIFIED at 0 of 2, and at 0 of 8. c2_thin_plate_won false, c2_noise_cavity_won false, beta_beats_curvature false on all eight. beta_vs_curvature_ratio: thin_plate 3.000000, gyroid 2.735820, box_exact 2.598076, csg_difference 1.831611, noise_cavity 1.262138, fbm_terrain 1.128548, sphere 1.065154, torus 1.024600 — every one above 1 |
The sharper result is the one no clause asked for: curvature beats camera distance on 8 of 8. Reading
hausdorff_at_matched_trianglesacross the three arms, curvature is strictly better than the shipped incumbent on every field —sphere0.019777825 vs 0.021066438,torus0.043960594 vs 0.056237683,box_exact0.083333333 vs 0.216506351,csg_difference0.120924796 vs 0.216506351,thin_plate0.044194174 vs 0.132582521,gyroid0.381445370 vs 1.122556500,fbm_terrain0.591709749 vs 0.667773082,noise_cavity0.512673132 vs 0.647064302. Two of those land the arm exactly on the all-refined bookend:thin_plate's 0.044194174 andbox_exact's 0.083333333 arehausdorff_uniform_fine, i.e. at half the fine budget curvature bought the whole fine result. So the row's registered content is falsified and its incidental content is a clean win for the criterion it used as a foil. What that costs is incriterion_ms: camera distance is 0.0129 ms on every row — it is an arithmetic expression — while curvature runs 0.6669 to 18.9701 (fbm_terrain), a factor of 1,470 at the worst field, andβruns 0.1602 to 1.7292. A criterion that wins on eight of eight and costs 19 ms per 16³ score pass is a chunk-build-time precomputation, not a per-frame LOD decision, and that is the Phase 28 ticket this row leaves rather than claims.
thin_plateis C2's headline prediction and it failed for the opposite reason to the one registered. The clause rests on curvature being aliased at cell scale where a slab fit is not. Measured:score_distinct_values1 andscore_all_tiedtrue forβonthin_plateand onbox_exact—βis not aliased there, it is blind, because a slab fit through a planar patch cannot report anything but zero, andThinPlate::canonical()is two planar sheets and a0.025-tall rim (fields/mod.rs:617-637). With one distinct scoreβ's ordering degenerates to the index tie-break walkingz-slabs, so itsrank_correlation_with_erroris 0.000000 and its Hausdorff stays at the coarse bookend 0.132582521; curvature is zero on the sheets and large at the rim, which is exactly where the error is, and reaches 0.044194174 — the ratio 3.000000 in the table is the coarse bookend over the fine one. The harness wrote this prediction down before the run:predicted_beta_beats_curvatureis true on the two named fields and false on the other six, andc2_prediction_heldrecords the disagreement.Six vacuity controls fired, every one as an assertion with a
VOID:message. (1) The registered one: per field the threeworst_decile_hausdorffvalues must differ, andworst_decile_spreadruns 0.000972008 (sphere) to 0.222623767 (gyroid) — non-zero on all eight, so the three criteria are not refining the same cells. (2)refined_overlap_with_betais the Jaccard index of each arm's refined set withβ's: 0.153153–0.284994 for camera and 0.244048–0.439759 for curvature, never 1.0, so no two criteria are one criterion. (3)0 < refined_cells < surface_cellson all 24 rows, so no arm is a bookend wearing a criterion's name. (4)population_mismatch0 on 24 of 24. (5) The coarse assembly is the whole-grid extraction:whole_grid_triangles_coarseequals the assembled count byassert_eq!on all eight fields andwhole_grid_hausdorff_gap_coarseis 0.000000000e0 on all 24 rows, againstASSEMBLY_TOLERANCE = 1e-12and a first-run worst of4.5e-16(experiment_p153.rs:431,:1997-2008). (6) Each criterion discriminates somewhere — global, not per field, becauseβ's single distinct value on the two planar fields is the measured answer and a per-field form would abort on the finding.
Four thresholds and claims in this harness were re-derived mid-run against a measurement, and each is a result rather than bookkeeping.
(1) LADDER_SPAN_FLOOR went 1.2 → 1.01 and became bidirectional, because noise_cavity's ladder is INVERTED. The control requires the two uniform bookends to separate, or there is no error for a criterion to redistribute. The first version demanded coarse ≥ 1.2 × fine on the guess that refinement always helps. Measured ladder_span over the eight fields: torus 3.959681, sphere 3.741626, thin_plate 3.000000, gyroid 2.942902, box_exact 2.598076, csg_difference 2.313171, fbm_terrain 1.128548 and noise_cavity 0.964442 — hausdorff_uniform_coarse 0.624056160 against hausdorff_uniform_fine 0.647064302, the error going up under refinement. That is not a fixture defect: noise_cavity carries noise at the h/2 scale, so halving every cell exposes octave detail the coarse grid smooths over. The inversion is C2's own premise — sub-cell structure a derivative estimated at cell size cannot see — arriving as a measurement of the premise rather than as a verdict on the clause. The floor is therefore symmetric (ladder_span ≥ 1.01 or 1/ladder_span ≥ 1.01, experiment_p153.rs:2025) and set from the noise below it, not from the fields above it: the assembly identities run at 1e-12 relative, so 1% of span is decisive by eleven orders. The per-field spans stay columns; a floor tuned to the fields it flatters would be tuning.
(2) The fine-rung Hausdorff identity was DROPPED to a column, and the measurement is why. The coarse bookend's per-cell assembly is the whole-grid extraction exactly — same h, shared samples. The fine bookend is not, and cannot be: the whole 33³ grid's cell walls sit at h/2 while the per-cell assembly's sit at h, so on a field with sub-cell detail the two place surface differently. whole_grid_hausdorff_gap_fine is 0.000000000e0 on seven fields and 1.156280978 on fbm_terrain — 1.16 relative, a real geometric gap and not an instrument error. The claim was removed rather than loosened, the gap is a column, and every arm is compared against the assembled bookends so the comparison stays inside one instrument family. The same rung's triangle gap is assembly_triangle_gap: 0 on five fields, 0.009029 on gyroid (0.90%, the 10,536-against-10,632 the header names) and 0.055153 on noise_cavity.
(3) project gained a residual gate and a per-step band, mirroring accuracy.rs, and the cause was not the symptom. The first run read projection_step_cells_max 1.4e-6 on sphere and 1.38 cells on noise_cavity — a reference vertex sliding most of a base cell, which means the measured Hausdorff was the distance between two wrong points. The step cap was the symptom: project declared convergence on a small step alone, and on a field with vanishing-gradient plateaus (noise_cavity's octave creases, exactly M-48's class) a near-zero gradient makes the step tiny at an |f| far from zero, so the walk creeps sheet to sheet and stops without ever reaching the surface. The fix is the crate's own residual discipline: require both the step within PROJECT_TOLERANCE_REL of the cell size and |f| within AccuracyConfig::RESIDUAL_TOLERANCE_REL of zero (experiment_p153.rs:404-421). Reference vertices still displaced past PROJECT_MAX_STEP_CELLS = 0.5 are now rejected and counted, with the share gated at PROJECT_MAX_UNCONVERGED = 0.01 (:2058-2070). The residue is visible in the committed columns: projection_step_cells_max still reads 1.381890117 on noise_cavity — the walk that motivated the gate — while projection_unconverged is 0 on all 24 rows and mesh_projection_unconverged is 0 on seven fields and 38–52 on noise_cavity, under 1% of its 14,440 reference samples.
(4) The population is scoped to the cells beta_per_cell can score, and the exclusion is a column. meshable_cells is {c : fine_triangles(c) > 0}; base_sign_change_cells is the subset visible at base resolution; beta_unscored_meshable is the difference. It is 0 on five fields and 30 on gyroid (1,214 of meshable_cells 1,244), 21 on fbm_terrain (470 of 491) and 91 on noise_cavity (1,123 of 1,214). Those are cells whose surface flips no base corner sign, so beta_per_cell returns None and there is no patch to fit — β cannot rank them at all. population_unscored is 0 on every row, meaning the three arms score one identical population; the excluded cells are meshed by every arm and ranked by none of them, and on the three noisy fields they are between 2% and 7.5% of the meshable set. Sub-cell structure that flips no corner sign produces no patch, so the criterion C2 promotes is structurally unable to see the phenomenon C2 says it sees. That, and not the aliasing argument, is why C2 failed.
What a consumer should do differently: leave isomesh::lod alone, and do not add a β pass anywhere. The shipped criterion is camera distance and it stays, on this evidence, until someone prices curvature at chunk-build time — it wins 8 of 8 at matched budget but costs up to 19 ms to score a 16³ grid, against 0.0129 ms for a distance. β costs 0.1603–1.7292 ms here and 0.82×–1.69× a whole extraction in P-152's own measurement (p-152.csv, beta_share), loses to curvature on every field, and is identically zero on the two piecewise-planar fields. The SHARE sentence imagined a β win moving the adaptivity stage; there is no win to move, and the transition-face gap every graded assembly carries (transition_faces 16 to 1,212 per row) is a separate, unwired problem — isomesh::transvoxel::cell ships the primitive and nothing connects it to a graded grid.
💥 ✗113 / M-467 — C1 FALSIFIED at c1_fields_within_bar 1 of eight against a bar of five, and unreachable at 4 — max_fields_any_constant 4, so no single k could ever have passed — while C2 HELD on 21 rows of 24 with thin_plate divergent at all three resolutions; M-13's area law, with zero fitted parameters, gets 5 fields where the β-sum gets one (R-154)
M. cargo bench --bench experiment_p154, docs/experiments/p-154.csv, 24 rows × 59 columns — eight reference fields at resolution 17, 33 and 65, counted from the file. # commit 3975077 on amd-ryzen-9-5900x-12-core at 2026-08-30T14:19:55Z, clean line. Nothing is timed: no clause here is a cost clause and this host's amd-pstate-epp governor swings the same binary 1.45× between runs (M-280), so cost is recorded as machine-independent counts — samples_ratio 64.361 / 68.534 / 70.778, slab_fits 176 to 36,869, at slab_evaluations_per_patch 73.
| clause | registered | measured |
|---|---|---|
C1 the β-sum predicts final triangle count within 25% on at least five of eight fields at three resolutions |
c1_fields_within_bar ≥ 5, a field passing only when one k puts all three of its resolutions inside 0.25 |
FALSIFIED at 1. Only fbm_terrain has all three rows inside the bar (prediction_error_ratio 0.027197 / 0.165737 / 0.182066).row_within_baris true on **6 of 24** rows. The extremes:noise_cavityat 17 overpredicts at **2.950391** (10,113 predicted against 2,560 actual) andthin_plate` at 17 underpredicts at 0.991935 (2** predicted triangles against 248 actual) |
| C2 the sum converges as scales are added | increment_ratio_last < 1, per row |
HELD on 21 rows of 24. The three failures are thin_plate at all three resolutions, increment_ratio_last 2.050775 / 1.851035 / 1.968992 — a ratio approaching 2, i.e. contribution ∝ n, i.e. the truncated sum grows without bound as scales are added |
C1 was refused by arithmetic before it was refused by the fit, and the file says so exactly rather than leaving it to inference.
kis fitted once, globally, over all 24 rows as the geometric mean ofactual / (β-sum / h²)— the exact minimiser of squared log error, which is the right loss for a clause phrased as a ratio bound:fitted_constant35.457497,dof_spent1,fit_rows24,dof_residual23. That is one degree of freedom and it is stated as one; the prediction is not parameter-free and this entry does not claim it is. Butkwas deliberately not tuned to the verdict, and the question "would a luckier constant have passed?" is then answered exactly instead of dodged. Rowiis inside the bar iffk ∈ [0.75·r_i, 1.25·r_i]; a field passes iff its three intervals intersect (field_constant_lo,field_constant_hi,field_feasible_any_constant); andmax_fields_any_constantis the largest number of fields any singlekcan satisfy at once, found by evaluating the count at every interval endpoint, which is where a closed-interval stabbing optimum is attained. It reads 4, in the windowk ∈ [9.161527, 11.219131](max_fields_constant_lo/_hi, a span of only 1.22×). Four is below C1's five, so no constant whatsoever — not the honest fit, not the luckiest one — could have carried this clause.thin_plateis the field that cannot be stabbed at all: its interval isfield_constant_lo3834.165400 againstfield_constant_hi1745.834089, lo above hi,field_feasible_any_constantfalse, so its three resolutions demand mutually exclusive constants.The mechanism behind that is dimensional and was stated before the run.
S = Σ β(Q)²·diam(Q)²is a bending functional — on a smooth patchβ_∞(Q) ~ curvature·diam(Q), soβ²·diam² ~ curvature²·diam⁴— while a uniform extractor's triangle count is an area functional. Two functionals that disagree on the sphere-versus-plane axis cannot be related by one constant, and the size of that disagreement is the column:beta_sum_per_arearuns 0.000390999 (thin_plateat 17) to 0.352619618 (noise_cavityat 17), withbeta_sum_spread901.843081 on every row. A conversion factor varying by nine hundred times is not a constant, andrequired_constant— thekeach row would need — makes it concrete: 5112.220533 onthin_plateat 17 against 8.975305 onnoise_cavityat 17.Seven vacuity controls fired as assertions before the first
run.record. (1) The registered one:scales_used4 / 5 / 6 at the three resolutions,≥ 4on all 24 rows, so convergence is read off at least four dyadic increments. (2) Every scale carried a patch — eachper_scaleentry's sub-box count and contribution strictly positive — orincrement_ratio_lastwould be a ratio over a zero. (3)beta_sum > 0on all 24 rows (0.003031951 at the smallest, 182.588903859 at the largest), so a falsified C1 is a wrong prediction and not an undefined one. (4)actual_triangles > 0on all 24. (5)mesh_area > 0on all 24 (7.754372 to 664.289692). (6)beta_sum_spread901.843081 > 2 — this is theM-44control for a negative result: a falsification that could not have been a pass is not a falsification, and here the conversion factor genuinely varies. (7)surface_cellscomputed from this file's own grid pass agrees exactly withp-152.csv's independentHermiteCell/beta_per_cellcount on all sixteen shared(field, resolution)pairs — 1,160 / 1,128 / 1,352 / 1,388 / 512 / 5,240 / 1,958 / 6,176 at 33³ and 4,760 / 4,208 / 5,768 / 6,014 / 2,048 / 21,432 / 8,413 / 28,375 at 65³ — which is what licenses theM-13cells-level column below.
The incumbent was measured on the same 24 rows rather than cited, and C1's own falsifier is confirmed by the numbers it predicted. The falsifier says a miss "would leave M-13's area law the better predictor and close the row". Priced four ways:
| predictor | form | fitted parameters | fields inside 25% |
|---|---|---|---|
the β-sum |
k·β_sum/h² |
1 | 1 (c1_fields_within_bar) |
M-13 as published |
2·1.5·A/h² |
0 | 5 (m13_fields_within_bar) |
M-13 refitted |
k₁₃·A/h², k₁₃ = 2.579116 |
1 | 4 (m13_fitted_fields_within_bar) |
M-13 anisotropic |
2·mean_l1_normal·A/h² |
0 | 6 (m13_anisotropic_fields_within_bar) |
M-13 as written, with no fitted parameter at all, reaches 5 of 8 where the one-parameter β-sum reaches 1 — m13_error_ratio is 0.002216 on torus at 33, 0.011151 on fbm_terrain at 33, 0.013352 on sphere at 65. And M-13 sharpened is better still: the 1.5 is M-13's own derivation of E[Σ|nᵢ|] under an isotropic normal distribution, and an axis-aligned plane has Σ|nᵢ| = 1, so on box_exact and thin_plate the assumed constant is 50% high by construction. Replacing it with the measured area-weighted mean_l1_normal — computed as Σ|cross|₁ / Σ|cross|₂, which needs no normalisation because the cross product's L1 over its L2 is the unit normal's L1 norm — reads 1.021812 on thin_plate and 1.036503 on box_exact against 1.556108 on noise_cavity, and lifts the count to 6 of 8. Refitting M-13's constant globally makes it worse (4), which is the expected signature of a law whose published constant is already near-optimal. triangles_per_surface_cell re-measures M-13's own cells-to-triangles conversion on every row and reads 1.937500 to 2.279608, so the 2.0 is M-13's and it is very nearly right.
thin_plate's divergence was named in advance, and its content is narrower than "not rectifiable". The plate is a slab of half-thickness 0.4·(4/64)/2 = 0.0125 (fields/mod.rs:617-627), so its two faces are 0.025 apart while the finest sub-box in this ladder is 4/64 = 0.0625 across. Every sub-box in the ladder therefore contains both faces, and the thinnest slab containing both has a half-width set by the plate rather than by the sub-box: β(Q)²·diam(Q)² = (w/diam)²·diam² = w², a constant per box, while the number of boxes carrying that patch grows with n. Hence contribution ∝ n and increment_ratio_last → 2, measured at 2.050775 / 1.851035 / 1.968992. Contrast box_exact, whose β also comes from a non-smooth feature but whose dihedral edge gives w ∝ diam: its increments halve, increment_ratio_last 0.514706 / 0.507143 / 0.503521. The plate is of course a smooth compact rectifiable surface; what diverges is the sum truncated above the field's own smallest length scale, which is the honest content of the registration's phrase "not rectifiable at the resolutions we mesh at" — and this crate meshes thin_plate at a cell size 2.5× its thickness on purpose (M-266).
One distinction inside C2 must not be averaged away: two convergence readings disagree on 9 rows and both are in the file. c2_holds is the divergence test (increment_ratio_last < 1) and is false on 3 rows. sum_converges is common::beta::BetaSum::converges(rel_tol)'s stricter reading at convergence_tolerance 0.10 and is false on 9 of 24 — box_exact, csg_difference, thin_plate, fbm_terrain and noise_cavity at 17, thin_plate, fbm_terrain and noise_cavity at 33, and thin_plate at 65. The clean example is box_exact at 17: increment_ratio_last 0.514706, so the increments are halving and the sum plainly converges, but the last increment is 0.410156250 of a total 3.373697917 — 12.2% — so the module says false. A row where the two disagree has not diverged, it has been cut short, and scales, increment_last and scales_used are on the row so a reader can see which. At 33 and 65 the same field reads true on both.
What a consumer should do differently: nothing, and this row closes S-as-a-budget rather than parking it. The gap it was aimed at is real — MeshSink::reserve (crates/isomesh/src/mesh.rs:225-232) exists and no extractor in the crate ever calls it, GreedyQuads reserves a cell count (greedy_quads.rs:181) and DualMesher reserves against work already done (dual.rs:638), while the only budget the crate owns is denominated in time (DirtySet::mesh_within_budget, chunk/dirty.rs:121). The TST sum does not fill it: it is a bending functional priced against an area, no single constant reaches more than four of eight fields, and it costs 64× to 71× the extraction's own sample count (samples_ratio) to compute. A caller who wants a triangle count before meshing should use 2·1.5·A/h² when an area estimate exists — 5 of 8 within 25%, zero parameters — and nothing otherwise. SHARE is discharged as registered: no stage moves, crates/isomesh/src/** is untouched.
💥 ✗114 / M-468 — C1 HELD with strang_fix_order 2 and measured_order 2 on 8 of 8, both derived and not quoted, C2 FALSIFIED at c2_hits 0 against a bar of four over c2_measurable_fields 4: the bar equalled the entire measurable population, so it was arithmetically unreachable — and two of those four fields are polyhedra whose creases have no second derivative (R-155)
S. cargo bench --bench experiment_p155, docs/experiments/p-155.csv, 8 rows × 44 columns — one row per reference field, each over the resolution series 19 | 27 | 35 | 47 | 63. # commit 076943b on amd-ryzen-9-5900x-12-core at 2026-08-30T09:27:21Z, clean line. Both clauses are global: C1 because the filter is one object, C2 because it counts fields, so the same c1_holds / c2_holds is written on every row and the per-field half of C2 is c2_hit.
| clause | registered | measured |
|---|---|---|
C1 the Strang–Fix approximation order of the tensor-product hat is 2, derived and asserted as a test, matching M-12's measured exponent |
strang_fix_order == 2 == measured_order |
HELD on 8 of 8. strang_fix_order 2 from the dual-lattice zero order, measured_order 2 from exact polynomial reproduction. M-12's own exponent is re-measured in the same harness as m12_ratio 4.178656 (mean error 2.716769e-3 at 32³ against 6.501537e-4 at 64³), against the ideal ((4/31)/(4/63))² = 4.13 |
C2 the predicted asymptotic constant reproduces M-12's fitted constant within its confidence interval on at least four of eight fields |
c2_hits ≥ 4 |
FALSIFIED at 0. c2_hit false on 8 of 8, within_ci false on 8 of 8, c2_hits 0, c2_measurable_fields 4. ratio = fitted / predicted: sphere 2.776811, torus 2.163685, thin_plate 2.060398, box_exact inf; the other four carry nan with skip_reason bound_not_exact |
C2's bar was unreachable arithmetic and the file records it with the arithmetic, not as a near miss. The clause asks for four of eight fields.
hausdorff_validis true on exactly four —sphere,torus,box_exact,thin_plate— and false on four, whoseskip_reasonnames the reason per field:csg_differencebound_not_exact (Underestimate { q: 0.5 }),gyroidbound_not_exact (Lipschitz { l: 3.464… }),fbm_terrainandnoise_cavitybound_not_exact (Unbounded).validate::accuracyis meaningless wherefield.bound()is notExact, so those four have no Hausdorff number at all and therefore no fitted constant — theirfitted_constant,fitted_constant_ci,ratioandci_relative_halfwidthare allnan. So C2's bar of four equals the entire measurable population: it needed 4 of 4, with zero slack, on a clause whose falsifier speaks of "missing on five or more fields" — a count the population cannot even reach. And of those four, two are polyhedra:box_exactandthin_plateboth carryanalytic_constant0.000000, because the closed form on the smooth part of a polyhedron is zero — flat faces, and the trilinear reproduces a linear field exactly — with no second derivative at all at the creases, which is where their entire error lives. A prediction of the formC = (1/8)·sup|∂²f/∂xᵢ²|has nothing to predict on those two. The fields on which C2 could have been a fair question aresphereandtorus, i.e. two, and it misses on both by 2.78× and 2.16×.P-70's C1 is the precedent for recording this shape.Nothing here is an instrument failure, and the interval widths say so.
sphere's fit is tight —fitted_constant3.393342e-1 withfitted_constant_ci[3.354011e-1, 3.433134e-1],ci_relative_halfwidth1.166%,fitted_exponent1.985214 — and the prediction 1.222029e-1 sits 2.78× below it, nowhere near the interval.torusis looser (ci_relative_halfwidth19.08%,fitted_exponent1.712362) and still misses: fitted 8.930169e-1 against predicted 4.127297e-1. The fitted exponents landing at 1.99 and 1.71 while the derived order is exactly 2 is itself the content of the negative:M-12'sh²law is empirical at game resolutions, not asymptotic, and its constant must not be extrapolated. That was registered as "a genuinely useful negative" and it is the one this row returns.M-113had already found the same constant reading 4.0000 in one grid alignment and 5.8564 in another; C2 now adds that it is also not the theory's constant on the two fields where the theory has one.Six vacuity controls fired. (1) The registered one: the fitted constants must differ across fields by at least 2×, or the prediction would be matching a universal constant by accident —
fitted_spread14.458612, seven times the requirement, over fitted constants 3.393342e-1 to 4.906302e0. (2) The degree-2 row must fail, or the order test cannot fire:c1_residual_deg20.250000 andc1_residual_deg30.380859 againstc1_residual_deg0andc1_residual_deg1at exactly 0.000000. (3)zero_valued_samples0 on all four measurable fields — an exactly-zero sample isM-48's degenerate crossing and would put anO(h)term into a fit about anO(h²)one — and 5 ongyroid, 1 onnoise_cavity, both skipped rows, which is precisely the boundary of the ladder argument rather than a claim quietly false on half the table. (4)edges_dropped_finest0 on all eight, overcrossing_edges_finest2,046 to 27,190. (5)grad_norm_rangeis 1.000000|1.000000 on the four exact fields, so the|grad f|denominator in the predicted constant is 1 by definition there and not by luck; it is 0.047665|10.005683 onnoise_cavity, which is the same fact from the other side. (6)fourier_quadrature_max_deviation1.930950e-11: the Fourier arm is cross-checked against a 262,144-point trapezoid quadrature of its own defining integral.
C1's order 2 was derived constructively, in two independent instruments, and neither of them quotes Strang–Fix — that is the whole point of the row. The theory statement is that a filter reproduces every polynomial of total degree ≤ m − 1 iff its Fourier transform has a zero of order m at every non-zero dual-lattice point. The harness measures both halves:
- The reproduction half, exactly and symbolically, in
common::poly'si128arithmetic. Variables 0–2 are the local cell coordinates(u,v,w)and variables 3–5 are the integer cell origin(i,j,k), so the residualT_h p − pis a polynomial in six variables andPoly::is_zero()on it is a statement about every cell of the lattice at once, not about one sampled cell. Overc1_monomials_tested20 monomials:c1_residual_deg00.000000,c1_residual_deg10.000000,c1_residual_deg20.250000,c1_residual_deg30.380859.measured_orderis1 +the largest fully reproduced degree, hence 2 — the hat reproduces constants and linears and fails onx². - The Fourier half numerically.
β̂₁(ω) = sinc²(ω/2) = 2(1 − cos ω)/ω²;sin(ω/2)vanishes at everyω = 2πkand it is squared, so every non-zero dual point carries a zero of order exactly 2, and the tensor product's zero at a dual point withrnon-zero components has order2r, minimised atr = 1. Measured over all 26 dual pointsk ∈ {−1,0,1}³ \ {0}:fourier_dual_lattice_max_value1.519574e-33 — the transform is numerically zero on every one of them — andfourier_zero_order_min2, read off a log-log slope atε = 1e-2and1e-3.
Two instruments agreeing on 2 is a cross-check rather than a restatement, and one real property is recorded beside it so no reader has to rediscover it: c1_multiaffine_reproduced true on 8 of 8. The trilinear reproduces the whole multi-affine space exactly — including xy, xz, yz and xyz, total degree 3 — but Strang–Fix order is about the total-degree space, where x² is the first failure, so the order is 2 and not 4. That is why c1_residual_deg3 is non-zero while the multi-affine flag is true.
box_exact's inf is the sharpest sentence this experiment produces, and it is a division by a measured zero rather than a defect. Along any axis edge that crosses the box's surface the SDF is exactly linear — near the +x face with the other two q components negative, f is identically x − 1 — so the hat's residual on that edge is not small, it is zero; and every crossing edge is such an edge, because the regions where two q components are positive lie strictly outside the solid and produce no sign change. predicted_series carries the round-off floor so the zero reads as a zero and not as a missing measurement: 4.496403e-15 | 4.690692e-15 | 8.021361e-15 | 1.468270e-14 | 0.000000e0. predicted_constant is therefore 0.000000e0, analytic_constant agrees at 0.000000, and ratio and predicted_stability_ratio are both inf by division. Meanwhile fitted_constant on that field is 4.906302e0 over a Hausdorff series of 1.283001e-1 … 3.724840e-2 with fitted_exponent exactly 1.000000. Filter theory predicts no reconstruction error at all on a polyhedron, the extractor has plenty, and it falls like h¹ — so whatever that error is, it is not reconstruction error. What licenses the zero as a measured zero rather than an instrument that cannot report one (M-44) is thin_plate: same code path, same family of field, and it returns a non-zero supremum 2.373437e0 from its rim.
What a consumer should do differently. Cite M-12 as an empirical h² law with a field-specific constant measured on the field in hand, never as an asymptotic law with a transferable constant — M-113 showed the constant moves with grid phase, and this row shows it is also 2.06×–2.78× away from the theory's value on the only two fields where the theory has one. The derived order 2 is now a fact of the filter rather than a fit, which is what P-157 needs: its own vacuity control is "the trilinear arm must reproduce exponent 2 in the same harness", and M-468 is that baseline. SHARE is none, as registered — this row converts a fit into a prediction and the prediction lost.
💥 ✗115 / M-469 — C1 FALSIFIED at c1_fields_within_5pct 5 of a c1_population of 6 (csg_difference at +6.80%), C2 HELD structurally with footprint_probe_outside 0 on all 80 rows, C3 FALSIFIED at one ulp — and the shipped standard_trilinear arm loses seam bit-exactness on the same six fields with the same worst delta, so C3's failure is not the quasi-interpolant's (R-156)
M. cargo bench --bench experiment_p156, docs/experiments/p-156.csv, 80 rows × 60 columns — five prefilter arms × eight reference fields × two resolutions (33 and 65 samples), counted from the file. # commit 2181f83 on amd-ryzen-9-5900x-12-core at 2026-08-30T14:24:01Z, clean line. tau 2.000000e-1 on every row. Every mechanism is bench-local: crates/isomesh/src/** is untouched and hashes_moved is 0 on 80 of 80 over a golden fixture asserted at 216 rows × 8 fields × 9 algorithms × 3 resolutions before anything is recorded.
| clause | registered | measured |
|---|---|---|
| C1 a compactly supported quasi-interpolant matches the truncated recursive prefilter's accuracy to within 5% | |vs_truncated_recursive − 1| ≤ 0.05 for quasi_fir3 at the finer resolution, over every field whose baseline is above the floor |
FALSIFIED at 5 of 6. c1_population 6, c1_fields_within_5pct 5, c1_decided_at_resolution 65. Inside: sphere 9.992880e-1, torus 9.957635e-1, gyroid 9.980282e-1, noise_cavity 1.008319, fbm_terrain 1.011222. Outside: csg_difference 1.068013 — +6.80% |
| C2 it is exactly chunk-local — zero dependence outside the chunk, asserted structurally rather than measured | chunk_local structural; footprint_probe_outside = 0 |
HELD. chunk_local true on all four FIR arms and false on recursive_whole_line, from the tap list rather than from any measurement; footprint_probe_outside 0 on 80 of 80. read_depth_samples 5 for quasi_fir3 against 11 for recursive_truncated_k10 and 33/65 for the whole-line recursion |
C3 chunk seams remain bit-exact where M-32 says they should be, and the golden hashes that move are counted |
seam_bit_exact and seam_local_bit_exact true at dyadic h; hashes_moved counted |
FALSIFIED. quasi_fir3's seam_bit_exact is false on six fields of eight at both resolutions — sphere, torus, csg_difference, gyroid, fbm_terrain, noise_cavity — with seam_worst_delta_cells 1.776357e-15 at 33 and 7.105427e-15 at 65 and seam_sign_disagreements 0. True only on box_exact and thin_plate. hashes_moved 0 |
C3's falsification is real and it is not about compactness, because the shipped prefilter fails it identically.
standard_trilinearis the identity prefilter atτ = 0— the crate's ownt = a/(a − b)— and itsseam_bit_exactis false on exactly the same six fields, withseam_worst_delta_cells1.776357e-15 at 33 samples and 3.552714e-15 at 65, andseam_sign_disagreements0 throughout. The seam arm isM-32's mechanism and not a simulation of it: each chunk samples from its own origin with its own local indices (experiment_p156.rs:1016-1084), and the comparison islo[0] + cell·u_globalagainstorigin_b + cell·u_local.M-32measured 16 of 16 shared-plane vertices agreeing ath = 0.125, and those vertices sit at integer local indices, where the two expressions are equal by IEEE as well as by algebra. A crossing does not:ucarries a fraction, andh·ureassociated across the chunk origin rounds. So C3's result narrowsM-32rather than retiring anything about the quasi-interpolant — a dyadic cell size buys bit-exact seams at lattice positions and does not buy them at interpolated crossings. The two fields where it holds prove the mechanism rather than contradicting it:box_exactandthin_plateare polyhedra whose x-crossings land on exact binary fractions, so there is no fraction to round, andseam_worst_delta_cellsis 0.000000e0 on every arm. The instrument is shown able to fail loudly as well as quietly —m32_control_seam_bit_exactis false on 80 of 80 at the non-dyadich = 4/34(m32_control_cell_size1.176471e-1), withm32_control_worst_delta_cellsup to 1.451509e-5, four orders above the dyadic residue.Nine vacuity controls fired, all before the first
run.recordwithVOID:messages. (1) The registered one:✗42's baseline is reproduced on✗42's own fixture —x42_torus_k10_delta7.152528e-7 atx42_torus_relative_error5.353398e-8, andx42_gyroid_k10_delta1.927142e-7 at 2.220179e-7. Without it the comparison has no baseline. (2) The moment identities, asserted so the two FIR arms are provably different filters and not two spellings of one:moment_01.000000e0 on both,moment_1−2.000000e-1 =−τon both, andmoment_2−1.200000e-1 =2τ² − τon the three-tap against −2.000000e-1 =−τon the two-tap. (3) Positive control on an exactly linear ramp:ramp_root_error0.000000e0 on every arm exceptrecursive_truncated_k10, whose 6.008154e-7 is its startup transient. (4) Negative control proving the moment conditions load-bearing: the exact filter's first three impulse taps(1.25, −0.3125, 0.078125)sum to1.015625and failM₀ = 1; fed through the identical code path they miss the ramp's root bysabotage_ramp_root_error4.615385e-2 cells — five orders worse thanquasi_fir3's 0.000000e0. (5) The mesh detour is faithful:standard_mesh_bit_identicaltrue on every row of the fourExactfields, sohausdorffmeasures a prefilter and not the detour. (6)edges_measured > 0and the baselineroot_position_errorabove the floor, on the fields that carry a population. (7) The truncation residue is non-zero:residual_vs_whole_line_cells0.000000e0 for the whole-line arm by definition, 4.017437e-7 to 8.272421e-7 forrecursive_truncated_k10on the fields carrying a population —✗42's bound re-measured over thousands of edges rather than eight — and genuinely different for the FIR arms, up to 3.189860e-2, because they are different filters and not approximations of that one. (8) The locality probe can see a long-range dependence (below). (9) The golden fixture is the real one, 216 rows.
Four instrument findings, each measured and each recorded rather than papered over.
(1) box_exact is excluded from C1's ratio population, with the reason and the arithmetic. Its truncated-recursive baseline root_position_error is 3.552714e-15 cells at 33 samples and 7.105427e-15 at 65 — four orders below the 1e-9 floor — because its x-crossings are exact binary fractions and both filters reproduce them to the last bit. A ratio over that baseline is not a ratio: quasi_fir3's vs_truncated_recursive on that field reads 1.250074e12 at 33 and 4.279959e11 at 65, which is 3.041093e-3 / 7.105427e-15 and nothing about accuracy. The clause is arithmetically unreachable on that field, so the field leaves the population and c1_excluded_exact_baseline names it on all 80 rows (P-70's precedent). Two things ride on the same measurement and are worth stating: the three-tap does not reproduce box_exact's crossings exactly (root_position_error 3.041093e-3) even though it reproduces a linear ramp exactly, because a five-sample footprint on a box straddles the kink that a two-sample bracket does not see; and crossings_lost reads 1,081 for quasi_fir2 and quasi_fir3 on that field at 65 samples, against 0 for the shipped two-sample arm. That is compactness's real price, and it is not in the ratio.
(2) thin_plate has no cut x edge carrying a full footprint, at either resolution. edges_measured is 0 on all ten of its rows and root_position_error is 0.000000e0 with vs_truncated_recursive NaN. The field is 0.4 cells thick (THICKNESS_IN_CELLS = 0.4, fields/mod.rs:617-637), so the footprint the wider taps need runs off the slab before it brackets a crossing — a property of the field's own thickness and not of the filters. The row is recorded with edges = 0 and excluded from every ratio (experiment_p156.rs:1436-1448). This is the one place where the CSV disagrees with itself and the disagreement should be read the harness's way: in_c1_population is computed as !exact_baseline_fields.contains(field) (:1691-1694) and reads true on thin_plate, while the C1 verdict loop skips it for a sub-floor baseline, so c1_population 6 = eight fields minus box_exact and minus thin_plate, whereas c1_excluded_exact_baseline names only box_exact. The population that decided C1 is six and both exclusions are named here.
(3) box_exact at 65 samples has no cut bracket in the chunk overlap. seam_pairs is 0 on all five arms of that row, because its faces are axis-aligned and the ten-sample overlap window can sit entirely inside a face. Its seam_bit_exact is therefore a no-bracket reading rather than a vacuous true, and the global control requires the mechanism to be exercised somewhere — it is, on 2,354 seam pairs on noise_cavity at 65 and 1,462 on gyroid. The same shape appears on thin_plate, whose seam_pairs is 0 for quasi_fir3 at both resolutions.
(4) footprint_probe_outside is zero BY CONSTRUCTION for the whole-line arm, so it cannot be the locality control's quantity, and the control now uses the measured dependence SPAN. locality_probe computes floor = depth.map_or(0, |d| n.saturating_sub(d)) (experiment_p156.rs:1095), and the whole-line recursion declares no depth — it has no footprint — so "outside its footprint" is the empty set and the count is zero however far the dependence actually reaches. The first draft asserted that zero was positive, which no run could ever satisfy. The quantity that does say the probe can see a long-range dependence is footprint_probe_span: 12 to 30 samples for recursive_whole_line (30 on gyroid at 65, 29 on sphere at 65) against the widest declared FIR footprint of 11, so the control is now "the whole-line arm's dependence must reach wider than any FIR's declared footprint" (:1509-1521). The FIR arms read footprint_probe_span 2 / 3 / 4 / 5 — their declared depth, measured — and footprint_probe_outside 0, which is now a zero that could have been non-zero. C2's assertion stays structural for the reason the header gives: on an exactly linear restriction the recursion's startup transient cancels (✗42's own note, experiment_p60.rs:157-164), so a purely measured locality check can pass for a non-local filter.
The quasi-interpolant's source: the primary was read, in full, from the first author's own institutional copy, and a graphics-facing restatement is named beside it — but the three-tap construction itself was derived here, in this crate's notation. The corpus holds only the landing page for Blu & Unser, Approximation Error for Quasi-Interpolators and (Multi-)Wavelet Expansions, ACHA 6, 219–251 (1999), 10.1006/acha.1998.0249; the paper is freely available from Thierry Blu's CUHK page and was read there (https://www.ee.cuhk.edu.hk/~tblu/monsite/pdfs/blu9801.pdf). Three items are used and no others: Definition 2 eq. (15), the moment conditions on the sampling distributions; Theorem 3 eq. (30), order-L quasi-biorthonormality ⟺ O(T^L) error, so the order is bought by the moments alone and exact interpolation is not required; and §III-C's paragraph after Theorem 4, which states P-156's hypothesis in the source's own words — "it is now possible to consider compactly supported sampling functions associated with any kind of synthesis function", one extra moment buying the asymptotic constant as well as the order. The restatement named for a graphics reader is Nehab & Hoppe, Generalized Sampling in Computer Graphics, MSR-TR-2011-16 / IMPA E022/2011, whose §2.1 gives the mechanism in one sentence and records that a FIR design for q exists (Dalai, Leonardi & Migliorati 2005) beside Blu & Unser's IIR one. What is not taken from either is the filter. Writing δ = z⁻¹ − 1 so the exact prefilter is 1/H = 1/(1 + τδ) = 1 − τδ + τ²δ² − …, truncating that series is the quasi-interpolant and each term fixes one more moment; the three-tap (1+τ+τ², −(τ+2τ²), τ²) = (1.24, −0.28, 0.04) is the truncation that matches the exact filter's M₂ = 2τ² − τ, and the two-tap (1.2, −0.2) is the minimal order-2 one, carried beside it so the 5% bar is decided against a filter and not against a family. The derivation and its closed form f_T(u) − g(u) = (g″/2)·[s(1−s) + M₂ − τ²], which reduces to ✗42's own (g″/2)·[s(1−s) − τ(1−τ)] at M₂ = 2τ² − τ, are written out at experiment_p156.rs:97-140. The taps are not a truncation of the impulse response, and that distinction is load-bearing: 1/H's first three taps (1.25, −0.3125, 0.078125) sum to 1.015625, fail M₀ = 1, and do not even reproduce a constant — which is why they are the harness's negative control.
What a consumer should do differently: nothing. Keep t = a/(a − b), and the registered falsifier says why in advance. C1's miss is small but it is a miss on a real field — csg_difference at +6.80% against a 5% bar, at the resolution the clause was to be decided at, and the ratio's distance from 1 was supposed to fall like h between the two rungs (it goes 1.069615 at 33 to 1.068013 at 65, i.e. it does not). The falsifier's reading therefore stands: "compactness costs accuracy and the truncated recursive filter is the better engineering answer." The compact filter's advantages are real and measured — read_depth_samples 5 against 11, chunk_local true structurally, prefilter_ms 2.53–2.55 against the truncated recursion's 4.65–4.67 at 65 samples, and no sequential dependence per vertex — and they are not worth a 6.8% root-position regression on a CSG field plus 1,081 lost brackets on a polyhedron. SHARE is discharged against C1 rather than with it: the vertex-interpolation stage does not move. The two findings that outlive the row are C3's narrowing of M-32 to integer lattice positions, and ✗42's 7.152528e-7 reproduced over thousands of edges instead of eight.
💥 ✗116 / M-470 — C1 FALSIFIED with c1_hits 0 of c1_population 4: the tricubic Lagrange 4x4x4 filter is genuinely order-4 on its own zero set (recon_fitted_exponent 3.842076 / 3.091828 / 3.741280 / 4.037091 against the trilinear's 1.837459 / 1.769023 / 1.895204 / 1.896907) and the mesh's fitted_exponent still reads 1.906661 / 1.980732 / 1.766603 / 1.924567, with an infinite-order exact_oracle arm pinned at 1.912218 / 1.985443 / 1.754517 / 1.942273 — the second order belongs to the piecewise-linear mesh and no filter can reach it; C2 HELD at samples_per_cell_ratio 1.383534 for +0.254234 ms on M-150's 15.01 ms path, C3 HELD at cases_invalidated 256 against a registered prediction of 256 (P-157, R-157)
M. cargo bench --bench experiment_p157, docs/experiments/p-157.csv, 27 rows across 85
columns — four # comment lines plus one column header plus 27 data rows, counted from the file
rather than from the brief; 14 of the 85 columns are P-157's registered records and the other 71 are
M-273 extras. The shape, also counted from the file: nine fields × three arms, filter reading
trilinear / tricubic_lagrange_4x4x4 / exact_oracle with approximation_order 2 / 4 / inf,
is_control true on the first and third and false on the tricubic, every row carrying the same
resolution_series 17|25|35|49. f64 throughout, amd-ryzen-9-5900x-12-core (Zen 3),
# commit 38b1de0 on amd-ryzen-9-5900x-12-core at 2026-08-30T14:25:55Z with no (WORKING TREE DIRTY) on
that line. Cost columns are one rung — timing_resolution 35, cells_at_timing 39,304,
timing_repeats 7 — and the crossing search is bisections 30 on both non-trilinear arms.
| clause | registered | measured |
|---|---|---|
| C1 a higher-order reconstruction gives a fitted error exponent above 3 on at least four smooth fields, against the trilinear's 2 | fitted_exponent > 3.0 on ≥ 4 smooth fields |
FALSIFIED — c1_hits 0 against c1_population 4. The tricubic arm's fitted_exponent is 1.906661 (sphere), 1.980732 (sphere_r060), 1.766603 (torus), 1.924567 (torus_fat); the trilinear control on the same four reads 2.023133 / 2.028781 / 1.854380 / 1.998152. Not one row of 27 exceeds 3, and the largest tricubic exponent in the file is sphere_r060's 1.980732 |
| C2 the cost is stated in field evaluations per cell and the resulting share of extraction time | both currencies on every row, and the tricubic within 2.0x the trilinear's samples_per_cell on every field |
HELD — samples_per_cell 1.090856 trilinear against 1.509236 tricubic on all nine fields, samples_per_cell_ratio 1.383534, well inside the 2.0 bar. eval_ms and eval_share are on all 27 rows: eval_ms 0.092461–7.781730 trilinear, 0.127850–10.805982 tricubic; eval_share 0.227700–0.895177 trilinear, 0.026679–0.620328 tricubic |
| C3 the count of A-002 cases a higher-order filter invalidates, priced at registration rather than discovered | cases_invalidated >= 256 |
HELD — cases_invalidated 256 = cases_total 256, decomposed as cases_with_geometry 254 + cases_empty 2, with cases_decider_dependent 120, cases_tunnel_capable 152 and cases_centroid_bearing 0. hashes_moved 0 over hashes_checked 24 and fixture_rows 216: nothing in crates/isomesh/src/** moved, as predicted |
C1 is falsified, and the file contains its own derivation of why — which is the difference between a negative result and a shrug. Three arms, one grid, and the exponents line up in a way that leaves no room for the filter: the tricubic's reconstruction error falls at 3.842076 / 3.091828 / 3.741280 / 4.037091 on the four smooth exact fields (
recon_fitted_exponent), which is order 4 arriving exactly as advertised — and the mesh built on that reconstruction still converges at 1.906661 / 1.980732 / 1.766603 / 1.924567. Theexact_oraclearm settles it: it places every crossing on the field's own zero to within2^-30of a cell, so it has no reconstruction error at all — itsrecon_zero_errorat the finest rung is3.880529e-11 / 3.485401e-11 / 3.690609e-11 / 3.872636e-11and itsrecon_fitted_exponentreads a flat0.999998 / 0.780120 / 0.992178 / 0.825710because it is fitting arithmetic noise — and itsfitted_exponentis still1.912218 / 1.985443 / 1.754517 / 1.942273. A filter of infinite order buys the same exponent 2 that a filter of order 2 buys. The second order is the chord error of a flat triangle spanning a curved cell,sup max_i |d2f/dxi^2| h^2 / 8, and that term contains no reference to the reconstruction whatsoever. So C1 could not have held on this functional, and the row establishes that rather than reporting a disappointment.C1's population is 4 because the arithmetic makes it 4, and the bar was registered at 4.
smoothis true on six fields — the two spheres, the two tori,gyroidandfbm_terrain— buthausdorff_validis false ongyroid(boundlipschitz),fbm_terrainandnoise_cavity(boundunbounded), sofitted_exponentisnanon nine of the 27 rows and the four smooth fields with anexactbound are the whole of C1's scope.box_exactandthin_plateareexactand are not smooth: their creases have no second derivative, and the file shows exactly what that does to an approximation-order measurement —recon_fitted_exponent-4.311810 for the tricubic onbox_exactand -11.028321 for the trilinear onthin_plate, fits through ladders that are at thef64cancellation floor on three rungs and not on the fourth. Those two are reported and excluded, not averaged in.Nine vacuity controls, all of them assertions that abort with
VOID:rather than columns that record a pass. (1) The trilinear arm reproduces exponent 2 in this harness — the registration's own control —fitted_exponent2.023133 / 2.028781 / 1.854380 / 1.998152 inside a band of 0.75 about 2.0, the band taken fromp-155.csv's committed 1.985214 and 1.712362 rather than chosen here. Had the trilinear read something other than 2, C1's comparison would have been between two measurement setups. (2) The filter really is higher order — the tricubic'srecon_fitted_exponentmust exceed the trilinear's by at least 1.0 on the smooth population, and does: +2.004617 / +1.322805 / +1.846076 / +2.140184. Without this, "higher-order reconstruction" would be a name and C1 would measure nothing. (3) The oracle really is exact —recon_zero_errorbelow1e-6 * hat the finest rung, i.e. below8.333e-8ath = 4/48; measured 3.485401e-11 to 1.546312e-10 across all nine fields. (4) The stencil never extrapolated —stencil_clamped0 on all 27 rows, withhalo_layers2 coveringstencil_samples64 against the trilinear's 8; a clamp would mean the reconstruction measured is not the one the header describes. (5) Every population is non-empty —crossings_finest966–15,792 withcrossings_dropped0 on all 27 rows, andhausdorff_coveragetrue on all 27, so no supremum is taken over an empty set (M-44). (6) The empty case is genuinely invalidated — a4x4x4block whose middle cell hasempty_case_index0, all eight corners strictly outside, and whose tricubic interpolant readsempty_case_centre_value-2.814453 at the cell centre whileCASES[0]emitsempty_case_triangles0;empty_case_interior_componenttrue. (7) C1's population is exactly the four named fields —c1_population4, so the bar of four is not met by a roster widened after the fact. (8) The baselines are the committed artefacts —p-155.csv'sp155_strang_fix_order2,p155_measured_order2,p155_fitted_exponent_sphere1.985214 andp155_fitted_exponent_torus1.712362, andp-138.csv's three case spaces and tractability flags, are read from the files at run time and asserted. (9) The fixture was read —hashes_checked24 andfixture_rows216, sohashes_moved = 0is not a zero over an empty set.
A vacuity control was wrong at the first run and was replaced, and both readings are in the file. The
harness's own header still records the first draft's control: "Every arm must produce an identical vertex
and triangle count at every resolution on every field, or the exponents describe different meshes"
(experiment_p157.rs:230-232). That contradicts the row's purpose. A higher-order reconstruction moves
the zero set — that is the whole mechanism under test — so the tricubic arm's vertex and triangle counts
differ from the trilinear's by construction, and the difference is the effect. Measured on sphere at
the first run the counts differ, and the draft control read that as a broken comparison. The control now
asserts what actually has to be shared for the exponents to be comparable — the grid, which is
structural (every arm extracts on the same shape, origin and h at each rung, inside one loop) — and
that every arm produced a non-empty mesh at every rung, arm.triangles > 0 && !arm.recon.is_empty()
(experiment_p157.rs:1781-1805). topology_identical stays as a measured column and reads false
on four of the nine fields (sphere, box_exact, thin_plate, noise_cavity) and true on the other
five. At the finest rung the counts differ on three: box_exact 6,908 / 3,456 tricubic against
6,344 / 3,174 trilinear, thin_plate 2,312 / 1,158 against 2,296 / 1,150, noise_cavity
31,892 / 15,794 against 31,888 / 15,792. sphere agrees at the finest rung and differs at a
coarser one, which is why a per-field flag reads false where the headline counts match.
P-138 already priced the proposal this row runs into, and the numbers are read from p-138.csv at run
time rather than quoted. p138_case_space_trilinear 2^8, p138_case_space_triquadratic 2^27,
p138_case_space_tricubic 2^64, with mixed volumes 2 / 29 / 116 and
p138_tractable_triquadratic true against p138_tractable_tricubic false. The tricubic's corner
signs are not its case index — p138_signs_are_case_index_tricubic false with
p138_net_sign_bits_tricubic 64 against the trilinear's 8 — so a 256-row table is not merely
inconvenient for a tricubic, it is the wrong object. The sentence this row inherits is P-138's:
degree 2 is the only one of the three that gives both an order above the trilinear's and a case space
anyone can tabulate. This harness shipped the tricubic anyway, because C1 asks about the exponent and
degree 3 is what an exponent lift is for; C1's answer is that the exponent lift does not reach the mesh,
so the 2^27 alternative is named here and not benched — P-138 benched it.
C3's 256 is a decomposition, not a slogan, and its sharpest half is the two cases with no geometry.
The 254 cases with geometry are invalidated because their crossing positions and their linking are
derived from the trilinear's edge and face restrictions; cases_decider_dependent 120 of them also
depend on the trilinear's own face hyperbola and cases_tunnel_capable 152 on the body-saddle
algebra. Cases 0 and 255 are invalidated for a sharper reason and the harness constructs the
counterexample instead of arguing for it: a cell with all eight corners strictly outside whose tricubic
interpolant is strictly negative at the centre, empty_case_centre_value -2.814453, for which
CASES[0].count emits 0 triangles — a closed component of the reconstruction's zero set inside a cell
the shipped table calls empty. The body-saddle algebra it retires is re-measured here rather than cited:
b*b - 4*a*c at marching_cubes/trilinear.rs:246 is Cayley's 2x2x2 hyperdeterminant, and this run
reproduces P-127's identity through common::poly — p127_identity_holds true,
p127_identity_terms 12, p127_identity_degree 4, p127_identity_variables 8,
p127_pencil_matches 3 of 3, with p127_identity_multi_affine false because the discriminant is
quadratic in each corner even though the interpolant is not.
SHARE, recomputed from the constants rather than repeated. The registration's SHARE is "C2 moves the
field-evaluation stage, which M-152 puts at 2.65 ms of an 8.40 ms upload at 129^3". m152_eval_ms
2.650000 and m152_upload_ms 8.400000 are in the file, as is m150_path_ms 15.010000. The
4x4x4 stencil on a cached grid is a halo, not an eight-fold stencil: the evaluation count grows by
((129 + 2*HALO)/129)^3, and share_growth_at_129 is 1.095938, so the stage goes 2.65 ms to 2.90 ms
— share_delta_ms_at_129 0.254234 and share_delta_pct_at_129 1.693767 percent of the 15.01 ms
path. The halo is a surface cost, so it is cheaper at the resolutions that matter: 1.383534x at the
35^3 this harness times against 1.095938x at 129^3, and quoting only the 35^3 figure would
overstate the price of the proposal by a factor of four. eval_share is reported and is deliberately
not a bar: the tricubic's share falls on every field (0.227700 to 0.026679 on sphere) because
total_ms grew — total_ratio 8.729571–12.669701 on the smooth and CSG fields — and neither number
is a statement about affordability, because total_ms compares a bench-local scalar interpolant against
the shipped and tuned extractor. The exact_oracle's cost is the one figure worth carrying out of the
timing block: its samples_per_cell_ratio reaches 6.275802 on noise_cavity, 30 bisections of the
field per crossing, which is the arithmetic reason it is an oracle and not a filter.
What a consumer should do differently: nothing, and that is now measured rather than assumed. The
shipped trilinear path is unchanged — hashes_moved 0 — and the reason to leave it alone is stronger
than "the tricubic was not tried". ✗42 found the knot-shift gain was a lottery over root position; this
row finds the order lever moves the reconstruction's own zero set by a factor of 295
(recon_zero_error at the finest rung falls 7.959516e-4 to 2.700651e-6 on sphere) and moves the
extracted mesh's convergence rate by nothing at all. Anyone proposing to raise the reconstruction order
in this crate must first raise the order of the mesh, because the mesh is what the second order belongs
to — and the collateral for doing so is priced on this row at the whole 256-case table.
💥 ✗117 / M-471 — the null arrived exactly as registered: C1 HELD with mixed_derivative_norm divergent on both CSG fields (norm_growth_exponent 5.000000 on box_exact and 5.148604 on csg_difference, against a Lipschitz-kink calibration arm fitting 5.000000 and reproducing its analytic 6/h^5 to 4.329870e-15 relative), and C2 FALSIFIED on 8 of 8 rows — on the three qualifying fields the Smolyak arm is 4.19x, 4.94x and 2.26x worse than the full grid while holding 4.128317x fewer samples, and break_even_reads_per_eval 8793.8 prices the mechanism out of this crate at any accuracy (P-158, R-158)
M. cargo bench --bench experiment_p158, docs/experiments/p-158.csv, 8 rows across 39
columns — four # comment lines plus one column header plus 8 data rows, one per
for_each_reference_field! field, counted from the file rather than from the brief; 11 of the 39 columns
are P-158's registered records and the other 28 are M-273 extras. f64 throughout,
amd-ryzen-9-5900x-12-core (Zen 3), # commit 1380017 on amd-ryzen-9-5900x-12-core at
2026-08-30T09:29:48Z with no (WORKING TREE DIRTY) on that line. The norm ladder is four odd
resolutions n33/n49/n65/n97 (norm_ladder) and the Smolyak ladder four levels
L5=705|L6=1649|L7=3809|L8=8705 (sparse_points_ladder), sparse_level 8. field_wall_seconds
1.710–4.746, read by no clause.
| clause | registered | measured |
|---|---|---|
C1 the mixed-derivative norm is measured on all eight reference fields and is unbounded on the CSG fields, box_exact and csg_difference |
norm_finite false on both named fields |
HELD, and wider than registered. norm_finite false on box_exact (mixed_derivative_norm 7.962624e6 at n97, norm_growth_exponent 5.000000) and on csg_difference (1.683440e7, 5.148604) — and also on thin_plate (1.150517e7, 5.213463), gyroid (9.156357e4, 4.878970) and noise_cavity (1.424060e8, 4.872009). Five of eight, not two. c1_holds is global and reads true on all 8 rows |
C2 on the fields where the norm is bounded, a sparse grid reaches matched Hausdorff error with at least 2x fewer samples |
hausdorff_sparse <= hausdorff_full at point_ratio >= 2.0, on every qualifying field |
FALSIFIED on 8 of 8 rows, c2_global false. On fields_qualifying = sphere|torus|fbm_terrain: hausdorff_sparse 2.245119e-2 against hausdorff_full 5.361366e-3 (4.19x worse), 6.813442e-2 against 1.378826e-2 (4.94x), 6.138858e-1 against 2.717775e-1 (2.26x). Not a budget failure — point_ratio 4.128317, twice what C2 asks — and not an extraction-grid failure, since the sparse arm was meshed at 65^3 against the full arm's 33^3 |
C2 is the expected outcome and the reason this row was registered
Mrather thanL, and the file says why in a column rather than in prose. The band norm and the whole-domain norm are recorded side by side, and they disagree in exactly the way the method's hypothesis needs them not to.norm_growth_exponentis measured over the shrinking surface band|u| <= 2hand is negative on the two smooth fields — -0.772578 onsphere, -1.519635 ontorus— so their surfaces really are inH^2_mix.norm_domain_exponentis measured over the box the Smolyak interpolant is actually built on, which is the quantity Bungartz & Griebel's theorem needs, and it is5.000000onspherewithnorm_domain_finest3.117591e7. Every field in the roster diverges on the whole domain at between 5.000000 and 6.010966, because an SDF is singular on its medial axis whether or not its surface is smooth:sphere's medial axis is the single pointr = 0, two units inside its surface and squarely inside the interpolation domain. So theO(h^-1 |log h|^(d-1))point count is conditional on a regularity that no signed distance field in this crate has over the domain a tensor-product interpolant is defined on. The two columns were expected to disagree and were recorded before the Hausdorffs were looked at.The three qualifying fields qualify for reasons that have nothing to do with their surfaces, and one of them is the roughest field in the roster.
FbmTerrain::sampleis affine iny(fields/mod.rs:1352-1362: the noise never seesp[1]), sod2u/dy2is identically zero and the mixed sixth derivative is structurally zero — its measuredmixed_derivative_norm2.978418e-11 sits at the finite-difference roundoff floor withnorm_over_floor_min4.679366e-3 andnorm_regimeat_roundoff_floor, so its apparentnorm_growth_exponent6.010966 is the floor's ownh^-6and says nothing about the field.norm_regimereads resolved on the other seven withnorm_over_floor_minbetween 3.040622e6 and 2.669788e13, six to thirteen orders of headroom. The mirror case isgyroid:Gyroid::sampleis a sum of three two-variable terms (fields/mod.rs:1022-1024), each annihilated by the third second derivative, so the nodal gyroid's mixed sixth derivative is also identically zero — andcapped_gyroidreadsnorm_finitefalse anyway, because what survives is themaxagainst the bounding sphere (fields/mod.rs:744-747). Its unboundedness is its seam, not its surface.thin_platereads on this instrument exactly asbox_exactdoes, becauseThinPlateis a box (fields/mod.rs:651), and its band norm equals its domain norm to the digit (1.150517e7 both, exponent 5.213463 both) because the plate is sub-voxel and the band is the plate.Seven vacuity controls, and two of them are calibration arms with closed forms rather than fits. (1)
stencil_smoothmust reproduce the exactd^6/dx^2dy^2dz^2ofx^2 y^2 z^2, which is 8;control_smooth_valuereads 8.000024426. The stencil factorises on a separable input so 8 is a closed form, and a miss would mean every norm in the file measures the instrument. (2)stencil_kinkmust reproduce the exact constant ofmax(x+y+z, 0), whose stencil sum is15 - 12 + 3 = 6giving6/h^5:control_kink_constantis the worst relative deviation from that and reads 4.329870e-15, andcontrol_kink_exponentfits 5.000000 against the analytic 5. Together they prove the instrument returns the right number for a smooth function and detects a Lipschitz kink at the right rate — which is precisely the dynamic range C1 needs, and it is why the five divergent fields' 4.872009–5.213463 is a recognition rather than a coincidence. (3) The registered control:sphereshowsnorm_finitetrue, so the CSG verdicts are the fields being rough and not the measurement being broken. (4) The band is non-empty on every field at every resolution —band_points_finest13,095–98,028; a maximum over an empty set is not a norm (M-44). (5) The full arm extracted something and had coverage —full_triangles1,016–13,236 andhausdorff_fullstrictly positive on all 8, which is alsoc2_reachabletrue on all 8, so no row's C2 is unreachable for want of a baseline. (6) C1's qualifying set is non-empty —fields_qualifyingnames three fields, so C2 is not scored over the empty set. (7) The headline level offers at least the2xC2 registers —point_ratio4.128317, so a negative C2 is a statement about the method and not about this harness's budget.
SHARE was discharged negatively by arithmetic available before any Hausdorff was read, and that number
is the finding a reader should carry away. The sparse arm saves 35,937 - 8,705 = 27,232 field
evaluations. To spend them it evaluates a 109-term Smolyak combination (sparse_terms) at every one
of the 65^3 = 274,625 points of its extraction grid, each term one trilinear interpolation of eight
array reads — sparse_reads_per_sample 872 — so 8 * 109 * 274,625 = 239,473,000 reads against
27,232 saved evaluations. break_even_reads_per_eval is 8793.8: a single Sdf::sample would have to
cost more than eight thousand seven hundred memory reads before the trade is even neutral, and the most
expensive field in this roster is a four-octave lattice-hash fbm that evaluates no transcendental at all
(fields/mod.rs:1294-1295). Sparse grids are for problems whose function evaluation is a PDE solve. An
SDF is not one, and no accuracy target changes that ratio.
The convergence rate is the second half of the negative, and it is measured against theory rather than
against the other arm. sparse_rate_theory is -2.000000 on every row — the rate a multilinear
Smolyak reconstruction should show against its own point count. Measured sparse_rate_exponent:
-0.921708 on sphere, -0.542523 on torus, -0.497986 on fbm_terrain, and +0.113535 on
noise_cavity, where the error rises with level and sparse_unconverged reads 1,748 probes. Less
than half the theoretical rate on the best-behaved field in the roster. sparse_coverage is true on
all 8 rows, so none of these is the trap where a lost surface produces zero samples in both directions and
symmetric_hausdorff reads 0.0 — no coverage is recorded as inf, never as zero.
Two rows read hausdorff_sparse < hausdorff_full and neither is evidence, which is what
hausdorff_sparse_floor exists to establish. box_exact reads 2.083333e-2 sparse against
1.443376e-1 full and thin_plate 1.243828e-2 against 8.926786e-2 — apparent wins of 6.9x and
7.2x on two fields C1 has already excluded. The discriminator is the extraction_floor arm, the true
field extracted on the sparse arm's own 65^3 grid: hausdorff_sparse_floor 7.216878e-2 and
4.592793e-2. Both sparse readings are below their floors, so the reconstruction is beating the field
it approximates — which is a statement about validate::accuracy's mesh-to-field direction near a sharp
seam (validate/accuracy.rs:59-63, where the Newton flow can land further away than the true nearest
point), not about Smolyak. bound_exact is recorded on every row (true on sphere, torus,
box_exact, thin_plate; false on csg_difference, gyroid, fbm_terrain, noise_cavity) so that
where the number is a residual rather than a distance the reader can see it; both arms of a row use the
identical instrument on the identical grid, so C2's comparison is still the comparison C2 asks for.
What a consumer should do differently: nothing, and this row is the reason not to try. No shipped code
path was touched and none is proposed. What the row buys is a closed direction with a number attached:
Smolyak sparse grids do not reach signed distance fields, they fail on the hypothesis rather than on
the implementation, and the hypothesis fails on the whole-domain norm for every field in this roster
including the sphere. The repository previously contained no measurement of H^2_mix at all — no bench,
test or document held the words Smolyak, H^2_mix or mixed derivative — and the corpus audit had
recorded the field as "ABSENT (0.597) | 0 | Registered expecting a null" (FINDINGS.md:25051). It came
back null, with the eight norms, the two calibration constants and the break-even read count that make it
a null rather than an absence.
🧊 M-472 — the registered null came back, and it is a null with page numbers: against W_inf^2 — the class the trilinear model is second-order exact for, and the one C3 names — Marching Cubes is order-optimal, ratio 1.020157 on sphere and 0.991341 on torus, where measured_error_rate 0.680105 and 0.660894 meet a minimal_error_rate of 0.666667 (g_n ≍ n^(-s/3) at s = 2, i.e. Θ(h²), and the independent h fit reads measured_h_exponent 1.974952 and 1.919062 against minimal_h_exponent 2.000000), so only the constant is in play and constant_gap bounds it at 7.252731 and 6.263480; C1 and C3 HELD on all 18 rows, c2_holds false on 10 of 18 exactly where the ratio is not trustworthy, and three things the source does not contain are carried in every row's class_assumptions rather than glossed (P-159, R-159)
M. cargo bench --bench experiment_p159, docs/experiments/p-159.csv, 18 rows across 54
columns — four # comment lines plus one column header plus 18 data rows, counted from the file
rather than from the brief; 12 of the 54 columns are P-159's registered records and the other 42 are
M-273 extras. The shape, also counted from the file: nine fields × two arms, arm reading
pinned_w2 and measured_max, the eight for_each_reference_field! fields plus lens_control with
is_control true on its two rows and false on the other sixteen. resolutions 17|25|33|49|65
and n_samples_ladder 4913|15625|35937|117649|274625 identical on all 18, n_samples 274,625 —
five rungs rather than the house three, because measured_error_rate is a fitted exponent and a
three-point fit has no residual. extractor marching_cubes_defaults_refinement_0 on all 18: shipped
defaults, set_crossing_refinement untouched at 0, because this row denominates the shipped
configuration. f64, amd-ryzen-9-5900x-12-core (Zen 3), # commit 807ba99 on
amd-ryzen-9-5900x-12-core at 2026-08-30T09:30:00Z. wall_seconds 0.009147–0.493597, read by nothing.
| clause | registered | measured |
|---|---|---|
C1 the n-th minimal error rate for a stated regularity class is established from the literature and written down with all its hypotheses, and the class our fields plausibly belong to is named |
a rate, its hypotheses, and a named class | HELD, global on all 18 rows. field_class reads W_inf^2_unit_ball_on_bounded_convex_D_in_R3, W_inf^4_… and W_inf^1_…; minimal_error_rate 0.666667 / 1.333333 / 0.333333 = s/d at d = 3, i.e. g_n ≍ n^(-s/3) = Θ(h^s). Every hypothesis is a token in class_assumptions: s_integer=true, s_gt_d_over_q=true, d=3, p=inf, q=inf, domain=bounded_convex, information=n_function_values, adaptive=no_by_thm9.3 |
| C2 the measured extractor error is compared against it and the answer is stated as a ratio | a computable ratio per row | HELD on 8 rows, false on 10, per row, and false exactly where the registration's own falsifier bites — "a ratio that is not computable because the class assumptions are unverifiable": either fit_r2 is below the 0.90 floor or the measured regularity does not reach the arm's pinned s. The eight are sphere and torus on both arms, and box_exact, csg_difference, gyroid and fbm_terrain on measured_max |
C3 IF the minimal rate is already Θ(h²), Marching Cubes is order-optimal and only the constant is in play — a branch, and both branches recorded |
not falsifiable; both legs present | HELD, global. order_optimal takes both values across the 18 rows — true on 5 (sphere/W^2, torus/W^2, box_exact/W^1, csg_difference/W^1, gyroid/W^1) and false on 13 — so neither leg is missing and a later reader can score the branch either way from the file |
The single sentence this row was registered to produce, and the numbers that carry it. Against
F_inf^2— the class Marching Cubes' own trilinear model is second-order exact for — the minimal error rate isn^(-2/3), which isΘ(h²)ath ≍ n^(-1/3). Two fits are recorded, one in each currency. In evaluations,minimal_error_rate0.666667 againstmeasured_error_rate0.680105 onsphereand 0.660894 ontorus, which is theratiocolumn: 1.020157 and 0.991341, against anORDER_OPTIMAL_TOLERANCEof 0.15. In grid spacing,minimal_h_exponent2.000000 againstmeasured_h_exponent1.974952 and 1.919062, atfit_r2_h0.999743 and 0.997765. Marching Cubes is order-optimal for that class: no algorithm readingnfunction values can do better in rate, however the points and the reconstruction are chosen, and therefore the whole of Group D's ambition against aW^2target is capped at a better constant.P-157is the row that pays that cap in the same phase: it raised the reconstruction to order 4, measuredrecon_fitted_exponentup to 4.037091 on the reconstruction's own zero set, and still read a mesh exponent of 1.906661–1.980732 — with an infinite-order oracle arm pinned at the same 2. The two rows agree from opposite directions, one by theorem and one by construction.What is left is the constant, and the file bounds it — in the direction that is honest.
constant_gapis 7.252731 onsphereand 6.263480 ontorusat the finest rung (constant_gap_coarsest6.856280 and 5.358074, so it is not a fitting artefact of one resolution). It is not measured against Krieg & Ullrich's implied constant, because there is no such constant in the source; it is measured against an explicit floor built here by their own fooling-function method,f_0(x) = A·sin(pi x_1/h)·sin(pi x_2/h)·sin(pi x_3/h), which vanishes on all ofh·Z^3so that no algorithm reading only the grid can distinguishf_0from−f_0. Both sloppinesses in that floor run the same way:seminorm_pinned(9.994508e-1 onsphere, 3.301270e0 ontorus) is estimated from pure axis derivatives only while the true seminorm also ranges over mixed ones, andgrad_maxis a maximum rather than a typical value. Both shrink the floor and therefore inflate the gap. So 7.252731 is an upper bound on the room remaining, not a target — and if this column had come back small, that would have been a real result.Seven vacuity controls, every one an assertion whose panic starts
VOID:. (1) The literature is transcribed faithfully — the general-drate must reproduce Proposition 2.4's independently printedd = 1form (p. 16), thes = 1multivariate formn^(-1/d)proved from scratch on p. 121, and Theorem 6.10'sp >= qcovering-radius exponent as literally printed (p. 93), to1e-12. A general-dformula is exactly the kind of thing that gets adin the wrong place, andminimal_error_rateis the column that would carry the error. (2) Regularity exists and is finite for every field — the registration's own control, verbatim:regularity1.038326–4.049774 on all nine fields. (3) The regularity estimator discriminates —lens_controlmeasures 1.038326 against the smoothest field on the roster at 4.049774 (torus), a spread of 3.011448 against a required 0.5. Scored against the smoothest deliberately:box_exactis genuinely creased along twelve edges and measures 1.317836, about as rough as the control, so the roughest-field form of this clause would fire on a correct measurement. (4) The probes are on the surface and measurably closer to it than a random point —probe_max_distance0.000000e0–1.488369e-1 againstscatter_median_distance3.593906e0–1.182921e1, a comparative clause needing no constant chosen after seeing the data. (5) The gradient does not vanish on the band —grad_max1.000000e0–9.798867e0 withgrad_floor_vertices0 on all 18 rows, or the level-set reduction divides by zero; and the probe set is non-empty,probe_count2,046–28,882. (6) The instrument sees a falling error on at least five fields —error_fallstrue on 8 of 9, withladder_points5 and every recorded error strictly positive. (7) Both C3 branches are present —order_optimaltrue on 5 rows and false on 13, so the file cannot be written with one leg missing.
What was verified, from where, and what could NOT be — this is the entry's integrity and it is carried
in every row rather than in this paragraph. The rate comes from Krieg & Ullrich, arXiv:2602.02066,
Approximation of Functions: Optimal Sampling and Complexity — in the corpus at
10.48550/arXiv.2602.02066, downloaded, converted and embedded — and class_assumptions names the
places read, by page: gn_def_p13 (the n-th minimal error / sampling number
g_n(F, Y) = inf sup ‖f − Φ(f(x_1),…,f(x_n))‖, with Remark 2.2 that this is the non-adaptive quantity),
thm6.10_p93 (the load-bearing one, attributed to Krieg & Sonnleitner, on a bounded convex domain),
prop6.11_p94 (inf_{P_n} ‖dist(·,P_n)‖_{L_γ} ≍ n^(-1/d), which composed with Theorem 6.10 is the
rate), prop2.4_p16 (the independently stated d = 1 case, a transcription check), and
adaptive=no_by_thm9.3. A second source is named as a cross-check and as a different theorem, not as
corroboration:
crosscheck=BonitoCanutoNochettoVeeser_10.1017-s0962492924000011_p67, whose p. 67 says the maximal
convergence order under uniform refinement is capped by the polynomial degree of the reconstruction
space rather than by the function's smoothness, which is why this harness carries two class arms instead
of one. Three things could not be verified and are flagged in every row's class_assumptions with the
word UNVERIFIED in them: UNVERIFIED_implied_constants_absent_from_source — Theorem 6.10 and
Proposition 6.11 are order statements whose constants depend on d, s, p, q, D and are evaluated nowhere
in the paper, so explicit_floor=own_fooling_function_sin_product records what the gap is actually
measured against; UNVERIFIED_error_is_Lp_of_f_not_of_level_set — IBC bounds ‖f − f̃‖_{L_p} and an
extractor emits {f̃ = 0}, so level_set_reduction=derived_here_not_in_source; and
regularity_at_benched_h_only with regularity_probed_to_order=4 — no asymptotic class membership is
claimed anywhere. A fourth flag, seminorm=pure_axis_derivatives_only_so_underestimated, is the one that
makes constant_gap an over-estimate rather than an estimate.
Class membership is argued from a measured property of each field, which was the registration's own
vacuity control, and it is what splits C2. For f with s bounded derivatives the centred m-th
finite difference obeys Δ^m_t f = t^m f^(m)(ξ) exactly, so log ‖Δ^m_t f‖_inf against log t has slope
min(m, s) and probing orders 1 to 4 reads s off as the order-4 slope. On sphere the ladder is
slope_order1 1.000000, slope_order2 1.990151, slope_order3 2.984040, slope_order4
3.906886 — a consistency ladder that could not look like that by accident. regularity per field:
sphere 3.906886, torus 4.049774, csg_difference 1.387688, fbm_terrain 1.345032,
box_exact 1.317836, noise_cavity 1.259763, thin_plate 1.198559, gyroid 1.094014,
lens_control 1.038326. field_in_pinned_class then decides the arm: the two smooth fields are in
F_inf^2 and the other seven are not — so on the rough fields W^2 is the wrong class and the class
they measurably inhabit is W^1, where the minimal rate is n^(-1/3) = Θ(h) and on three of them
Marching Cubes hits it: ratio 1.033062 on box_exact and on csg_difference, 0.955441 on
gyroid. fbm_terrain overshoots at 1.181764 and thin_plate and noise_cavity are the two rows
whose ratios are not rates at all, both discussed below. Both reductions of
the difference norm are recorded because a max over probes is one probe's opinion, and the two disagree
where it matters: regularity_median reads 4.406408 on gyroid against a max of 1.094014, and
4.068110 on lens_control against 1.038326 — the seam and the crease are single features, and the
q = inf sup norm the theory needs is the max. On box_exact, csg_difference and thin_plate the
median is NaN because the median difference sits below the cancellation floor on four of the five rungs
(difference_ladder_below_floor_median [false|true|true|true|true]); the two reductions are floored
independently for exactly that reason.
Two rows are arithmetically unreachable and are recorded as unreachable with their arithmetic, which is
P-70-C1's precedent. box_exact on the pinned_w2 arm: constant_gap NaN and
constant_gap_coarsest NaN, because seminorm_pinned is 0.000000e0 — the W^2 seminorm
estimated from pure axis derivatives is exactly zero on an exact box distance, which is linear along each
axis over the probe set, slope_order2 correspondingly reads
NaN, and the fooling-function floor A = M_s (h/pi)^s has no value to be built from. There is no
W^2 floor for a field with no W^2 seminorm, so there is nothing for the gap to be a gap against; the
row's W^1 twin reads 4.188790e0 and is the number that means something. thin_plate on both arms:
errors reads 1.250000e-2 at all five rungs, error_falls false, error_span 1.000000,
fit_r2 0.000000, measured_h_exponent 0.000000 and measured_error_rate -0.000000. It is
ThinPlate::for_cell_size(4/64) at THICKNESS_IN_CELLS = 0.4, so its half-thickness is exactly 0.0125
and the plate is sub-voxel at every rung by construction (M-266, M-72): the mesh bridges its two
sheets inside one cell, an edge midpoint lands on the mid-plane where |f| is the half-thickness, and the
error is pinned independently of h. It cannot fall before h < 0.025, i.e. N >= 161, and 161^3 =
4,173,281 samples per pass against the 65^3 = 274,625 this bench can afford — a factor of 15.2, so the
exponent is unreachable rather than unmeasured. noise_cavity fails C2 for a different and weaker
reason worth separating: fit_r2 0.307752 with an errors ladder that is not monotone
(8.017133e-1|1.559421e0|4.385014e-1|5.205939e-1|5.443099e-1), below the 0.90 floor, so its ratios
0.264701 and 0.529403 are not rates.
The error functional had to be changed during development, and box_exact is the surviving proof — the
column is still in the file. error_functional is
max_abs_f_over_grad_norm_on_vertices_edge_midpoints_centroids: |f(x)| / ‖∇f(x)‖ over every vertex,
every edge midpoint and every triangle centroid. Sampling the vertices alone read identically zero
on box_exact at all five resolutions, and probe_max_abs_value 0.000000e0 with
probe_max_distance 0.000000e0 on that field is the same fact still recorded: its half-extents are 1,
every ladder spacing h = 4/(N−1) divides 3, so every box face lands on a grid plane, the field is
exactly linear along every cut grid edge and Marching Cubes finds those roots exactly. The error is not
zero — M-250 measured box_exact's symmetric Hausdorff at 1.443e-1 both before and after crossing
refinement — because the mesh truncates every box edge with a chord whose midpoint sits about h/2
inside the solid, and only a functional that looks between the vertices can see it. With the midpoints in,
box_exact reads measured_h_exponent 1.000000 at fit_r2 0.999957: the Θ(h) its own measured
regularity predicts, from an unfittable zero. csg_difference's ladder is byte-identical to it
(1.666667e-1 down to 4.166667e-2 on both, error_span 4.000000 on both), which is what a
box-cornered worst point looks like on two fields that share one. validate::accuracy is deliberately not
the instrument here: only four of the eight reference fields have bound() == Exact, and a functional
meaningless on half the roster cannot carry a rate fit across it. Two further instrument candidates were
tried and removed and are named in the harness rather than forgotten — striding the regularity probes to a
cap (whether a crease gets sampled then depends on the stride rather than on the field) and a raw |f|
bar for control 4 (capped_gyroid is Lipschitz { l: 3.464 } and noise_cavity is Unbounded, so a
field value is not a length on this roster).
The roughness control took three attempts and the two failures are why the shipped one is centred at
(0.11, 0.07, 0.13). lens_control is two unit spheres 1.0 apart, intersected, centred off-lattice
— curved faces and one circular crease, so its regularity must measure near 1 where a sphere measures near
4 and its error must still be a fittable Θ(h); it reads regularity 1.038326 and
measured_h_exponent 1.277221. The L^1 ball ‖x‖_1 − 1 measured s = 1.000000 exactly and was
useless, because Marching Cubes reproduces a piecewise-linear field exactly and its error sat at the
f64 floor with no exponent to fit. An origin-centred lens was worse: it put its crease at x = 0, a
grid plane at every ladder resolution, so no triangle spanned the kink and the control measured
Θ(h²) like a sphere. Both failures are the same failure M-266 names — a fixture whose feature is
lattice-aligned measures the lattice — and the off-lattice offset is the fix.
SHARE is none, discharged literally, and no consumer action follows from this row — which is the point
of a denominator. The registration says SHARE: none -- this is a denominator, not a saving, and this
harness configures nothing, proposes nothing and moves nothing: MarchingCubes::new() at every default,
no landing, no golden hash, nothing written into crates/isomesh/src/**. What changes is what a future
registration is allowed to claim. Every accuracy number previously in this ledger was a numerator —
M-12's h² at ratio 4.179, F-007/M-250's 13–15%, ✗42/M-359's root-position lottery — each
saying did this help and none saying how much is left. This row supplies the denominator in the
currency actually spent, and the answer on the class the extractor is built for is: the rate is already
optimal, the remaining room is a constant, and that constant is at most about 7x by a floor
constructed to over-state it.
🔬 M-473 — C1, C2 and C3 all HELD: at matched sample budget the octree-adaptive arm beats uniform on 12 of 12 measured rows with gain 1.230769–16.967407 while budget_ratio gives the uniform arm 1.009041–1.322344x more evaluations, gain_exceeds_two is true on 10 of 12, and the Gal-Micchelli/Novak factor-2 cap is measured not to apply rather than argued away — class_convex false at convex_midpoint_min_value 0.200000000 for convex_midpoint_triangles 0, class_symmetric false at symmetry_signed_volume 4.179064172 against -4.179064155, operator_linear false at linear_scaled_positions_equal true, error_worst_case true, hypotheses_satisfied 1 of 4 (P-160, R-160)
M. cargo bench --bench experiment_p160, docs/experiments/p-160.csv, 16 rows across 63
columns — four # comment lines plus one column header plus 16 data rows, counted from the file
rather than from the brief; 12 of the 63 columns are P-160's registered records and the other 51 are
M-273 extras. The shape, also counted from the file: four Exact-bound fields × three octree depths
with measured true — sphere, torus, box_exact, thin_plate at max_level 5, 6, 7 — plus
four skip rows with measured false, one per non-Exact field, bound naming which kind
(csg_difference underestimate, gyroid lipschitz, fbm_terrain and noise_cavity unbounded).
f64, amd-ryzen-9-5900x-12-core (Zen 3), # commit 7744cb0 on amd-ryzen-9-5900x-12-core at
2026-08-30T09:30:07Z. reference_cells 64 on every measured row and cells_tested
777–33,225. No RNG, no wall clock, and no clause on a timing.
| clause | registered | measured |
|---|---|---|
| C1 at matched sample budget, octree-adaptive sampling beats uniform on symmetric Hausdorff error, and the gain is reported per field | hausdorff_adaptive < hausdorff_uniform on every measured row |
HELD, global. c1_row true on all 12 measured rows and false on the four skips. gain = hausdorff_uniform / hausdorff_adaptive: sphere 6.727178 / 10.529887 / 16.967407, torus 8.920239 / 9.281417 / 16.340285, box_exact 2.000000 / 1.230769 / 3.200000, thin_plate 2.644104 / 3.087377 / 4.668109. gain_defined true on all 12 |
| C2 the gain exceeds 2 on at least one field, which is the concrete demonstration that the factor-2 result does not apply here | gain_exceeds_two on ≥ 1 measured row |
HELD, global, and not marginally: gain_exceeds_two true on 10 of 12 rows, reaching 16.967407 on sphere at depth 7 — 8.48x the theorem's cap. The two false rows are box_exact at depths 5 and 6, for a lattice-phase reason derived before the run and bounded by two |
| C3 the four hypotheses are each checked against our setting and recorded as a row of booleans, so no future reader re-imports the bound | four booleans, each decided rather than asserted | HELD — hypotheses_satisfied 1, so c3_holds (< 4) is true: the theorem needs all four and one fails. class_convex false, class_symmetric false, operator_linear false, error_worst_case true. The falsifier's strict reading is recorded separately rather than reinterpreted: c3_strict_holds (== 0) is false, and the hypothesis that does it is named |
The four hypotheses, each answered by a fixture that runs in this bench and reports its own evidence — booleans that are only asserted are prose in a numeric column.
(1)
class_convex= false. Two unit spheres at±(1.2, 0, 0); both are members, exact distance fields with a closed non-empty surface, andconvex_endpoint_triangles_min6,160 proves so (and is asserted> 0, or the midpoint's zero triangles would beM-44's vacuous zero). Their midpoint(f + g)/2is not a member, and not marginally:min(|p+c| + |p−c|) = 2·1.2 = 2.4along the segment between the centres, so the average is(2.4 − 2)/2 = 0.2there and larger everywhere else — the midpoint field has no zero set at all.convex_midpoint_min_valuereads 0.200000000 over a65^3grid whose origin is a lattice point, exactly the predicted value, andconvex_midpoint_trianglesreads 0.(2)
class_symmetric= false. Symmetric meansf ∈ F ⟹ −f ∈ F. The unit sphere and its negation are both extracted over[-2, 2]^3at65^3. The surfaces coincide; the winding does not, because the crate's convention is negative-inside with normals away from the solid (lib.rs:56-67), so−fdescribes the unbounded complement.symmetry_signed_volume4.179064172 againstsymmetry_signed_volume_negated-4.179064155 — the divergence-theorem volumes of the two meshes,±4π/3 = ±4.1887902to the discretisation — and a member of a class of bounded solids cannot enclose a negative volume.symmetry_hash_differstrue proves the two extractions are genuinely different artefacts and not one computation reported twice.(3)
operator_linear= false, decided by positive homogeneity, which is the cheapest half of linearity and fails exactly. Marching Cubes' crossing ist = a/(a − b), invariant under scaling the field by a positive constant, and doubling is exact in IEEE-754 — soS(2f)is the meshS(f)bit for bit while a linear operator would have to produce2·S(f).linear_scaled_positions_equaltrue, comparing the two position arrays by raw bit pattern, withlinear_max_abs_position1.000000000 asserted> 0becauseS(f) = 2·S(f)would otherwise be satisfiable by a mesh at the origin. The word continuous is answered beside it and does not feed the verdict, one mechanism per column: two unit spheres at±(1, 0, 0), touching at the origin, offset bycontinuity_epsilon0.080000000. At+εthe level set is the boundary of two overlapping balls, one component; at−εit is two disjoint balls, two.continuity_components_grown1 andcontinuity_components_shrunk2: two fields2ε = 0.16apart in the sup norm whose solution's component count is not the same number.(4)
error_worst_case= true, and saying so is the point. Symmetric Hausdorff is a sup-norm criterion and every number in the distance columns is a maximum, not a mean;mae_uniform0.001249024–0.044001088 andmae_adaptive0.000156266–0.004354597 sit beside them so the distinction is visible. So one of the theorem's four hypotheses is satisfied in this setting, and the registration's falsifier read literally — "C3 by any hypothesis being arguably satisfied" — is falsified by it. That is whyc3_strict_holdsis a separate column reading false: both readings are on the row, neither is hidden, and a later reader can score C3 either way without re-running anything.Seven vacuity controls, each naming the column that proves its fixture could have failed. (1) The registered control — the adaptive arm must actually vary its sample density:
density_ratiois8^(deepest leaf level − shallowest)and reads 64.000000–32768.000000 across the twelve rows (64and512and4096onbox_exact, whosecoarsest_leaf_levelis 3 against 2 on the other three fields). A ratio of 1 would mean the octree refined everything to one level and both arms are uniform grids, at which point every gain on the row measures the harness. (2) Both arms produced a surface —adaptive_triangles1,016–47,624,uniform_triangles136–4,328. (3) Both arms were measured in both directions —reverse_samples_adaptiveequalsreverse_samples_uniformon every measured row (6,482 onsphere, 6,032 ontorus, 18,082 onbox_exact, 3,399 onthin_plate), so the field→mesh direction is sampled identically for both and neither Hausdorff is a zero that could not have been non-zero (M-44). (4) At least one field was measurable at all — four were. (5) The convexity fixture's endpoints have surfaces — 6,160. (6) The homogeneity fixture's mesh is not at the origin — 1.000000000. (7) The discontinuity fixture produced two meshes — 1 and 2, not two absences.
The budget is matched in the uniform arm's favour, so a win is a win. sample_budget is the number of
distinct field-evaluation positions the adaptive arm needed — the miss count of a cache keyed on the
deepest lattice, so exact dedup with no hashing and no float comparison — and the uniform arm is then
given the smallest odd n with n^3 >= sample_budget. It therefore receives at least the adaptive
arm's information and usually more: budget_ratio 1.009041–1.322344, and a 1.32 budget advantage is at
most a 1.10 cell-size advantage against gains this row reports in the single and double digits.
evaluations_uncached 12,800–787,456 records what the harness actually spent against cache_lookups
6,993–299,025, so the difference between the information and the implementation is visible rather
than implied. Odd is load-bearing and a first run proved it: with n free to be even, thin_plate at
max_level = 6 drew a uniform arm of n = 20 whose vertical grid edges all straddle the 0.025-thick plate
without either endpoint entering it, and classic Marching Cubes correctly emitted nothing at all — 0
triangles against the adaptive arm's 4,088. That is a registered property of the field
(fields/mod.rs:579-583, M-266 at :606-617), not a discovery, and an infinite gain from it would have
been a measurement of lattice phase wearing adaptivity's clothes. Every uniform_samples_per_axis in the
file is odd: 13, 21, 33 on sphere, 13, 21, 31 on torus, 17, 27, 41 on box_exact, 13,
19, 25 on thin_plate.
The two gains under 2 are box_exact's, and both were predicted in closed form before the run — to nine
digits. When the cube's face x = 1 lands on a sample plane, f is exactly 0 at those corners,
is_inside (cube.rs:171, v < 0) calls them outside, the three crossings all interpolate to t = 1,
and the cube's own vertex sits 2h/sqrt(3) off the emitted triangle; when the face does not land on a
sample plane the truncation is half as deep, h/sqrt(3). The adaptive arm is always in the first case,
because x = 1 sits at lattice index 3·2^(L−2) of the octree's 2^L + 1 points, an integer at every
depth here — so hausdorff_adaptive on box_exact should read exactly 2·cell_adaptive/sqrt(3), and it
reads 0.144337567 / 0.072168784 / 0.036084392 against cell_adaptive 0.125 / 0.0625 / 0.03125.
The uniform arm alternates with n: at n = 17 (h = 0.25) and n = 41 (h = 0.1) it is in phase and
hausdorff_uniform reads 2h/sqrt(3) = 0.288675135 and 0.115470054; at n = 27
(h = 4/26) it is out of phase and reads h/sqrt(3) = 0.088823118. So gain reads cell_ratio
2.000000 and 3.200000 at depths 5 and 7 and cell_ratio/2 = 1.230769 at depth 6, which is also
why hausdorff_uniform is non-monotone in the budget on that field. The phase term is a property of
the fixture, it is bounded by two, and box_exact is the only one of the four fields it touches. The
other three follow the laws derived before the numbers: on a smooth field the error is the linear
interpolation error on a curved surface, O(h²), so gain ≈ cell_ratio² — sphere at cell_ratio
2.666667 / 3.200000 / 4.000000 gives 6.727178 / 10.529887 / 16.967407 against squares of 7.11 /
10.24 / 16.00; on a polyhedral field the error is in the corners and is O(h), so gain ≈ cell_ratio —
thin_plate at 2.666667 / 3.555556 / 5.333333 gives 2.644104 / 3.087377 / 4.668109.
There are no cracks at the level transitions, no dilation and no 2:1 balancing are used, and the witness
column only became one after the first run forced a correction. The refinement test is the crate's own
shipped predicate — SubgridMarchingTetrahedra::cell_is_provably_empty (subgrid/extract.rs:494-508),
negated and recursed over levels: a cell is subdivided iff its corner signs disagree or
|f(centre)| <= l_field · edge · 0.5 · sqrt(3), with l_field = field.bound().lipschitz() rather than a
tuning knob. For an l_field-Lipschitz field a pruned cell contains no zero of the field, boundary faces
included, so a coarse leaf has nothing for a finer neighbour to disagree with and no transition geometry is
needed. Two columns measure that argument instead of trusting it: active_by_sign_only is 0 on every
row — the centre term subsumes the sign term, as predicted — and corner_range_over_diagonal_max
maxes at 0.500000000 — exactly that on sphere and box_exact, 0.499024116 on torus at depths 5
and 6 and 0.499648709 at depth 7, 0.499982421 on thin_plate — asserted
<= l_field + 1e-9, which is the pruning proof's only assumption. That column is also the answer to the
registration's literal wording: a range-over-diagonal variation test is bounded above by 1 by
definition for a 1-Lipschitz field, so a slack >= 1 can never fire and a slack < 1 fires on any cell
whose diagonal lies along the gradient — neither follows a surface, and the criterion used is the crate's.
adaptive_boundary_edges is 0 on all twelve measured rows, and so is uniform_boundary_edges, so
neither is reported alone — with adaptive_components and uniform_components both 1 everywhere.
That column read 358,360 across these rows on the first run, and it was not measuring cracks:
validate_indexed keys its edges on vertex index, the per-leaf extraction emits every shared vertex once
per leaf, so on the raw buffer every triangle is an island and the number is a measurement of
unweldedness. Both arms now go through the crate's own Welder at its own epsilon_for first — one
instrument, applied identically — and adaptive_vertices_removed says what each arm had to lose:
1,530–71,442 on the adaptive arm against 0 or 48 on the uniform arm, which Marching Cubes already
welds per grid edge inside one extract. adaptive_triangles_collapsed is 0 on all twelve, so the
weld destroyed no sliver on that arm; uniform_triangles_collapsed is 96 with
uniform_vertices_removed 48 on sphere at 13³ and 21³ and 0 everywhere else — the same pair
M-48 recorded for Welder::weld on sphere.
Four rows are skipped and the skip is a row, which is the failure mode this apparatus exists to
prevent. validate::accuracy reads the SDF as a distance oracle, and only four of the eight reference
fields have bound() == Exact. On the other four a Hausdorff number would be a fiction, so
csg_difference, gyroid, fbm_terrain and noise_cavity carry measured false, gain_defined
false, c1_row false, bound naming which of the four kinds it is, and zeros in the distance
columns. They are excluded from C1 and C2 and from nothing else — the four global hypothesis booleans,
c3_holds, c3_strict_holds and hypotheses_satisfied are written identically onto all sixteen rows.
The same gate is load-bearing twice over: the octree's pruning is the Lipschitz certificate, so a field
with no declared constant has no sound octree either. The two exclusions have one cause.
One bias remains in the instrument and it runs against C1, which is why the mean columns are there.
symmetric_hausdorff is max(mesh→field, field→mesh) from the crate's own report; the forward direction
dominates and is independent of the lattice, projecting every referenced vertex and every triangle centroid
onto the zero set by Newton. The adaptive mesh has several times as many vertices as the uniform mesh at
matched budget — adaptive_vertices 510–23,814 against uniform_vertices 70–2,166 — so it has
several times as many chances to find its own worst point, and it wins anyway. mae_adaptive beats
mae_uniform by 2.36x to 17.85x across the twelve rows, in the same direction and by comparable
factors, so the maxima are not one lucky projection.
SHARE, recomputed rather than repeated, and no consumer action follows yet. The registration's SHARE is
"C1 moves the field-evaluation stage at fixed budget", and what C1 moves is not the cost of that
stage — the budget is held fixed, so the stage costs the same by construction — it is the error at that
cost. There is no 1/(1 − share/factor) ceiling to compute because the denominator is not a time. The
reachable claim is bounded instead by cell_uniform / cell_adaptive, which is a column
(2.000000–5.333333), and no error ratio can exceed that ratio raised to the extractor's order —
P-159 is the row that fixes the order, and this row records the ratio it would be raised to rather than
assuming one. Nothing in crates/isomesh/src/** was touched: isomesh::lod is a downsampling module
(lod.rs:13-15) and refines nothing, cell_is_provably_empty prunes one fixed 16³ subgrid and is never
recursed, and P-48's registration already records that this crate has no balanced octree
(experiment.rs:2386). What a consumer should do differently today: nothing. What this row licenses is a
Phase 28 ticket against the shipped extractor, with a number — up to 16.967407x less Hausdorff error for
the same field evaluations — and with the factor-2 objection permanently closed by four measured booleans
instead of re-argued.
🔬 M-474 — C1 and C2 both HELD: s is estimable for both refinement families on 8 of 8 fields over 2.03 decades of field evaluations, and the answer is field-dependent — lod_helps true on 3 (box_exact s_difference +0.322893, csg_difference +0.172500, thin_plate +0.609051, each clearing its own combined half-width) and false on 5, with fbm_terrain's s_difference_ci running -0.181268 to -0.012375, strictly negative, so greedy adaptivity is measurably worse than uniform there; the DOF are field evaluations and the adaptive family is charged for its own error estimator, dof_adaptive 4915|15629|35939|117661|274635|531449 against dof_adaptive_corners 2800|8544|19173|62101|145568|276438 (P-161, R-161)
M. cargo bench --bench experiment_p161, docs/experiments/p-161.csv, 8 rows across 53
columns — four # comment lines plus one column header plus 8 data rows, one per
for_each_reference_field! field, counted from the file rather than from the brief; 9 of the 53 columns
are P-161's registered records and the other 44 are M-273 extras. resolutions 6 and
fit_points_uniform = fit_points_adaptive = 6 on all eight rows — the three golden resolutions
17/25/33 (golden.rs:72) plus 49, 65 and 81, so dof_uniform is
4913|15625|35937|117649|274625|531441 on every row, a ln N window of 2.03 decades leaving four
degrees of freedom per fit and a 95% quantile of t = 2.776 rather than the 12.706 a two-point slope
carries. PROBES 4096 per field, drawn once and reused by every arm at every resolution. f64,
amd-ryzen-9-5900x-12-core (Zen 3), # commit cbaa53e on amd-ryzen-9-5900x-12-core at
2026-08-30T09:30:18Z. wall_ns 354,000,352–499,864,698, read by no clause.
| clause | registered | measured |
|---|---|---|
C1 s is estimated for both refinement strategies on all eight fields |
both fits exist, both intervals clear of zero, on 8 of 8 | HELD — c1_field true on all eight rows and c1_holds true globally. s_uniform 0.410671–0.694371, s_adaptive 0.365667–1.019722, every one carrying a finite confidence interval. No row reads class_membership = unfitted, which is the registered form of C1's own falsifier |
C2 the fields split: at least one has s_adaptive > s_uniform and at least one does not |
lod_helps true on ≥ 1 and false on ≥ 1 |
HELD — fields_gaining 3, fields_not_gaining 5, on every row. Gaining: box_exact (A^0.84 adaptive against A^0.52 uniform), csg_difference (A^0.68 / A^0.51), thin_plate (A^1.02 / A^0.41). Not gaining: sphere (A^0.81 / A^0.69), torus (A^0.83 / A^0.69), gyroid (A^0.50 / A^0.52), fbm_terrain (A^0.37 / A^0.46), noise_cavity (A^0.38 / A^0.45) |
The split is scored against the combined half-width, never against zero, and that single decision is what makes C2 a result rather than fitted noise.
lod_helpsiss_difference > sqrt(hw_u² + hw_a²), which iss_difference_cilying strictly above zero. Read the two smooth fields to see the clause declining rather than claiming:sphere'ss_differenceis +0.127424 and itss_difference_ciis-0.115695|0.370543, so the point estimate is positive and the interval is not —lod_helpsfalse.torusis the same shape,+0.137592over-0.005791|0.280975, missing by six thousandths. The three gainers clear it outright:box_exact+0.322893over0.185978|0.459807,csg_difference+0.172500over0.104970|0.240031,thin_plate+0.609051over0.358982|0.859120. And one field clears it in the other direction:fbm_terrain-0.096821over-0.181268|-0.012375, an interval entirely below zero, so on the roughest field in the roster the greedy octree is not merely no better but significantly worse.gyroid(-0.017396over-0.121565|0.086774) andnoise_cavity(-0.074950over-0.165442|0.015542) straddle zero and are recorded as not gaining, which is the honest reading of an interval that contains no answer.The exponents restated in the currency a caller spends, which is what
lod_asymptotic_gainis. It is10^(1/s_uniform − 1/s_adaptive)— the degrees of freedom the adaptive family saves per decade of error reduction — and is exactly 1.0 whens_differenceis 0, i.e. the registration's "octree LOD provably buys nothing asymptotically on that field". Measured: 28.469559 onthin_plate, 5.585177 onbox_exact, 3.135707 oncsg_difference; 1.730516 ontorusand 1.692382 onsphere(positive point estimates whose intervals do not exclude 1); and below one on the three rough fields — 0.859125 ongyroid, 0.365603 onnoise_cavity, 0.267601 onfbm_terrain.n_term_decayis2^(-s_adaptive), the factor the best-N-term error falls by when the evaluation budget doubles: 0.493211 onthin_plateat best and 0.776110 onfbm_terrainat worst — a doubling of the budget buys a 22% error reduction on the terrain and a 51% one on the plate.Seven vacuity controls, every panic starting
VOID:. (1) Eight fields —rows == 8, or the "all eight fields" in C1 is a claim about a subset. (2) Six resolutions per family per field, never fewer than the registered four, with aln Nwindow of at least one decade:resolutions6,fit_points_uniformandfit_points_adaptive6 on all eight. Without a window there is no slope, and C1's registered failure mode —snot estimable from the achievable range — could not be distinguished from a short sweep. (3) A confidence interval on every fit that exists —s_uniform_ciands_adaptive_cion all eight, and the split scored against the combined half-width ins_difference_ci. A missing fit is not asserted away: an unfitted field would be recorded asclass_membership = unfittedwithc1_field = false, which is C1's own falsifier, and no row is. (4) The probe set is full and fixed —probes4096 on every field, so no field is scored on a thin population;band_volume_fractionis the acceptance rate that filled it, 0.020690–0.166065. (5) The adaptive arm actually varies its density —adaptive_max_depth5, 6 or 7 against a floor of 3, i.e. somewhere at least 8x finer than its own root grid, which isP-160's density control in this row's currency, withadaptive_truncatedfalse on all eight so no series is measured against the depth cap.adaptive_leaves208,860–255,011. (6) Every probe lands in a leaf the criterion was willing to refine —probes_in_inactive_leaves0 on all eight, ors_adaptivewould be a property of the activity test rather than of the field. (7) Matched budgets — every adaptive snapshot at or just past its uniform budget and within 5%:dof_adaptive4915|15629|35939|117661|274635|531449 onsphereagainstdof_uniform4913|15625|35937|117649|274625|531441, and the worst overshoot anywhere in the file iscsg_difference's 4929 against 4913, +0.33%, or the two slopes are fitted over different windows and their difference is an artefact of the ladder.
The degrees of freedom are field evaluations and nothing else, and the adaptive family is charged for its
own error estimator — which is the choice that makes the split trustworthy. N is the number of
distinct points at which the field was evaluated to build the reconstruction: exactly n³ for the
uniform family, and for the adaptive family the size of the sample cache, every corner and every
cell-centre the refinement indicator asked for. So the adaptive arm gets no free oracle:
dof_adaptive_corners — the reconstruction corners alone — is 2800|8544|19173|62101|145568|276438 on
sphere, so roughly 43–48% of the adaptive arm's evaluations are spent on the indicator rather than on
the reconstruction, and it is charged for all of them. That costs it a constant and therefore cannot
move the slope, because a constant factor in N is an intercept shift in ln N. Triangles were the
other candidate and were rejected: thin_plate is 0.4 cells thick, so three of the eight fields have no
triangle count worth comparing at coarse h, and P-159's point is that evaluations are the currency
actually spent. M-12 is this row's exponent in the wrong currency and is re-denominated rather than
re-measured: M-12 recorded Marching Cubes' error falling like h² (mean 2.7168e-3 at 32³ against
6.5015e-4 at 64³, ratio 4.179 against an ideal 4.13); with N ~ h^(-3), h² is N^(-2/3), so
M-12's law is the statement A^(2/3) for the uniform family — a number never previously written as an
exponent in N, and whose adaptive counterpart had never been measured at all.
The smooth fields land near the theory's 2/3 and not on it, and the interval says so. With the band
held fixed as h → 0 both families are volumetric inside it, so the
Bonito–Canuto–Nochetto–Veeser sentence P-146 already quotes — for W^{2,p} regularity, uniform
refinement gives O(N^(-2/3)) in 3D and the optimal graded mesh gives O(N^(-2/3)), the same exponent,
and that order "cannot be improved upon assuming either higher regularity … or a graded mesh" — predicts
s_uniform = s_adaptive = 2/3 on a smooth field and a constant rather than a rate from adaptivity.
Measured, s_uniform is 0.685767 on sphere with s_uniform_ci 0.680730|0.690804 and 0.694371
on torus with 0.682114|0.706629: both about 3–4% above 0.666667, and both intervals exclude it.
That is recorded rather than rounded to agreement — a fixed band over a finite window is not an asymptote,
and the excess is the size of effect a 2.03-decade fit can resolve. A band shrinking with h would have
handed the adaptive family the surface's codimension for free and made every field "gain", measuring the
functional rather than the field; band_half_width is span/32 and reads 0.125000 on six fields,
0.437500 on gyroid and 0.500000 on fbm_terrain, where the span itself is larger.
Two independent controls separate the criterion from the tree and the split from the norm. The
random arm is the same octree marking a uniformly random active leaf instead of the largest
indicator, and it collapses: s_random 0.038153–0.109407 across the eight fields against
s_uniform 0.410671–0.694371 — 6.2x to 12.8x below the uniform family's exponent on the same
field — with err_random on
sphere falling only 9.2776e-2 → 6.4133e-2 over the whole 2.03 decades while err_uniform falls
1.0772e-2 → 4.3247e-4. So the adaptive gain, where it exists, is the defect × h criterion and not the
mere existence of a tree, and random_truncated false confirms the random arm was not cut short.
The sup_norm arm rescores both families in L∞ instead of the discrete L²: s_uniform_sup /
s_adaptive_sup read 0.684528 / 0.887644 on sphere, 0.706351 / 0.782220 on torus,
0.410355 / 0.632963 on box_exact, 0.350661 / 0.656578 on thin_plate, 0.363145 / 0.143959
on gyroid, 0.447688 / 0.135633 on fbm_terrain and 0.469994 / 0.184252 on noise_cavity —
the sign of the difference survives the change of norm on seven of the eight fields. The one that
flips is csg_difference, 0.401493 / 0.391143, a sup-norm difference of -0.010350 against a
primary-instrument s_difference of +0.172500: of the three gaining fields it is the only one whose
gain is norm-dependent, and a reader should treat it as the weakest of the three rather than as a fourth
pattern.
fit_r2_uniform is 0.979155–0.999972
and fit_r2_adaptive 0.955680–0.996145, and neither is consulted by a clause.
The one way this instrument can lie is named in advance, and the two columns that make it visible are
deliberately read by nothing. The adaptive family earns a constant before it earns a rate: its root
grid covers the whole domain and its refinement concentrates into the band, so at fixed N it eventually
holds a factor of roughly band_volume_fraction^(-s) over uniform — and a constant being earned across
the fitted window is indistinguishable, in a six-point log-log slope, from a higher rate. s_adaptive is
therefore an effective exponent over the achievable range and not an asymptote, which is exactly C1's
registered failure mode arriving as a widened interval rather than as an absence: sphere's
s_adaptive_ci spans 0.570125|1.056258, nearly half a unit, against a s_uniform_ci span of
0.010074. s_adaptive_tail — the slope over the last three budgets alone — is the curvature witness:
0.877565 against s_adaptive 0.813192 on sphere and 0.890058 against 0.831963 on torus, so
the adaptive slope is still steepening at the end of the window on the two fields whose intervals declined.
That is the conservative direction: a transient inflates s_adaptive and widens its interval at the same
time, so scoring against the combined half-width makes the clause decline rather than claim — which is
why sphere and torus are recorded as not gaining despite positive point estimates and gains of about
1.7x per decade.
A second, wholly independent instrument cross-checks s_uniform on the four fields where a Hausdorff
means anything, and it reproduces M-12. The mesh_uniform control is MarchingCubes plus
validate::accuracy's symmetric Hausdorff against triangle count over four resolutions:
mesh_s_uniform 0.975480 on sphere with mesh_s_uniform_ci 0.905412|1.045547 — an interval that
contains 1.0, which is h² in the mesh's own currency since T ~ h^(-2) — and 0.956925 on torus
(0.414619|1.499230, wide because a four-point fit leaves two degrees of freedom). box_exact
0.460604 and
thin_plate 0.485038 are about half that, the O(h) a polyhedral surface gives. The four non-Exact
fields are skipped and the skip is a column, not a silence: mesh_accuracy_skipped true with
mesh_accuracy_skip_reason bound=Underestimate on csg_difference, bound=Lipschitz on gyroid
and bound=Unbounded on fbm_terrain and noise_cavity, mesh_s_uniform NaN and
mesh_s_uniform_ci NaN|NaN. The primary instrument is deliberately not a mesh Hausdorff: it is the
discrete L² defect of the piecewise-trilinear reconstruction of the field itself, band-defined by field
value rather than distance, which is the only definition available on four of the eight fields
(fields/mod.rs:104-109 says plainly that for Unbounded "no accuracy figure against |sample| means
anything"). For the same reason there is no crack question in this row's primary measurement and no
boundary-edge column to answer one: the reconstruction is per-leaf trilinear on that leaf's own eight
corners, discontinuous across a level boundary exactly as an LOD octree is, and the error functional does
not care. The crack-free witness for this phase's bench-local octree is P-160's
adaptive_boundary_edges, which reads 0 on all twelve of its measured rows with no dilation, no 2:1
balancing and no transition cells.
SHARE is none and is discharged in the strong sense; what this row changes is which fields a future
octree-LOD ticket is allowed to target. The registration says "SHARE: none — this predicts where a stage
helps, it does not change the stage". This harness reads no shipped code path other than MarchingCubes
and validate::accuracy in a control arm, changes nothing in crates/isomesh/src/**, and produces no
ratio a later row could denominate a speedup in — isomesh::lod is downsampling, and its own module doc
says re-sampling "needs no API: the caller already knows how to sample a field, so adding a
Downsample::Reevaluate variant would be a second path to something that is not downsampling at all"
(lod.rs:6-16). What a consumer should do differently: on sphere, torus, gyroid, fbm_terrain and
noise_cavity, no octree scheme can beat uniform sampling asymptotically, however well implemented — the
number that says so is s_difference_ci and on fbm_terrain it says worse, not merely equal. The three
fields LOD is for are the CSG ones and the thin plate, i.e. the fields with a feature to grade toward, and
thin_plate's 28.469559 is the largest lod_asymptotic_gain in the file.
The theory this rests on was already in the corpus and had never been pointed at a field: Stevenson is
cited in this repository only for the newest-vertex-bisection closure bound
(docs/research/2026-08-13-adjacent-field-acquisition.md:91-94,
docs/research/2026-08-12-axes-and-vocabulary.md:68,75-77), never for the approximation-class theory in
the same PDFs.
💥 ✗118 / M-475 — C1 FALSIFIED at fields_improved 3 of 8 against a bar of five and C2 FALSIFIED at fields_in_neighbourhood 1 of 8, with measured_gain_db spanning −8.584787 to +0.726612 dB around a predicted_gain_db of +0.257097, C3 HELD at case_table_size 16 against 256 — and the single field that met the prediction only met it because PROJECTION_STEPS moved 64 → 1024, which at 64 aborted the run entirely and flipped csg_difference's verdict from −0.177 dB to +0.417 dB (P-162, R-162)
M. cargo bench --bench experiment_p162, docs/experiments/p-162.csv, 16 rows across 40
columns — three # comment lines plus one column header plus 16 data rows, counted from the file.
# commit 0db1c9e on amd-ryzen-9-5900x-12-core at 2026-08-30T09:27:54Z, with no (WORKING TREE DIRTY)
on that line. (field, lattice) is the primary key: eight reference fields × two arms, the cubic arm
Z3 carrying is_control true and the BCC arm A3* false. crates/isomesh/src/** is
untouched — every mechanism is in benches/common/lattice.rs, which this ticket owns.
The prediction was exact and it missed. G is recorded as 0.083333333 on every Z3 row and
0.078543281 on every A3* row, and predicted_gain_db is 0.257097 on all sixteen —
10·log₁₀(G(Z³)/G(A₃*)) with nothing fitted. Lattice::g re-asserts both decimals against their closed
forms 1/12 and 19/(192·∛2) on every call, residuals 2.17e-10 and 3.82e-10
(benches/common/lattice.rs:239-250), so a transposed digit could not have become a published
prediction. What the surface did instead, measured_gain_db per field on the A3* row:
| field | hausdorff Z3 |
hausdorff A3* |
measured_gain_db |
rms_gain_db |
prediction_holds |
|---|---|---|---|---|---|
sphere |
0.058482783 | 0.058029606 | +0.067568 | +2.321109 | false |
torus |
0.054633042 | 0.054799054 | −0.026354 | −0.337701 | false |
box_exact |
0.052354857 | 0.052354857 | 0.000000 | −53.775083 | false |
csg_difference |
0.065699639 | 0.062619113 | +0.417121 | −6.890294 | true |
thin_plate |
0.052445265 | 0.140911234 | −8.584787 | −13.914655 | false |
gyroid |
0.412209432 | 0.379129261 | +0.726612 | +1.433022 | false |
fbm_terrain |
1.023108760 | 1.052521843 | −0.246186 | +1.170820 | false |
noise_cavity |
0.277435157 | 0.647500519 | −7.361573 | +0.091786 | false |
Nine and a third decibels of spread around a prediction of a quarter of one. c1_holds false,
c2_holds false, c3_holds true on all 16 rows.
Per-clause accounting.
C1 — FALSIFIED, and by the integer the falsifier names. The clause is "improves symmetric Hausdorff error over the cubic grid on at least five of eight fields";
fields_improvedis 3 on every row —sphere,csg_differenceandgyroid, the three withhausdorff_ratioabove 1 (1.007809, 1.049195, 1.087253). The falsifier is "C1 by under five fields" and three is under five. The two losses are not marginal and are the interesting half:thin_plate'shausdorff_ratiois 0.372187 andnoise_cavity's 0.428471, i.e. BCC is 2.7× and 2.3× worse in the max norm on the two fields whose features are thinnest relative to the sample spacing.C2 — FALSIFIED, and its registered escape clause was measured rather than argued. C2 allows the deviation to be explained, and the harness fixed in advance the only reading of "explained" it would accept: Hausdorff is a maximum and
Gpredicts a mean square, so if the max form misses and the mean-square form lands, the deviation is located rather than excused (benches/experiment_p162.rs:130-146). It does not land.fields_in_neighbourhoodis 1 —csg_differencealone, the only row withprediction_holdstrue — andfields_rms_in_neighbourhoodis 0. The escape clause is therefore closed by measurement in the harder direction:rms_gain_dbranges from −53.775083 (box_exact) to +2.321109 (sphere), wider than the max form, not narrower.Gis not the figure of merit for surface extraction, and that is now a measurement rather than a suspicion.C3 — HELD, with the cost stated in full rather than flattered.
case_table_size16 against 256,distinct_up_to_symmetry5 against 22,max_triangles_per_case2 against 5,total_triangles20 against 820,reconstruction_stencil4 against 8. A case count alone would flatter BCC, so the row also carries the trade:cells_per_site6 against 1 andcorner_reads_per_site24 against 8. BCC pays three times the corner reads against a table sixteen times smaller. That is the complexity cost the registration asked to have stated, and the falsifier — "a case table large enough to be impractical" — is not met by 16 entries.Vacuity controls. (1) Matched point density, the registration's own control.
samples117,649 on the cubic arm against 114,191 on BCC,density_mismatch0.029393 against a 5% bar, on all eight fields. Without it "the comparison is a resolution change wearing a lattice's name" — and the direction matters: BCC has fewer sites, so a BCC win could not have been bought with resolution. (2) The prediction under test is the registered one,predicted_gain_db0.257097 on 16 of 16 against the0.2571inexperiment.rs. (3) Both arms measured a real surface:pointsruns 1,134–17,926 across the sixteen rows andprobesis 5,000 on every one, so no Hausdorff here is a maximum over a handful of samples (M-44). (4) The two arms differ in the lattice and its filter and in nothing else:eval_samples49,refine_steps14,probes5,000 andinsetidentical across each field's two rows. (5)extraction_ms_max/minbracket the median on all 16 rows overextraction_repeats5, becauseM-280measured this host's governor swinging one binary 1.45×.
The load-bearing story of this row is a threshold, and it is a verdict rather than a margin.
common::lattice's PROJECTION_STEPS is 1024, not 64 (benches/common/lattice.rs:1108-1127).
Gradient-Newton converges linearly, not quadratically, on a CSG crease where the field is a max of
two smooth pieces: the harness instrumented noise_cavity's cap crease at [-1.405105, 0.0, 0.523810],
|p| = 1.4996 against the r = 1.5 sphere, and measured a contraction of about 0.965 per step — 64
steps move |f| only from 4.48e-3 to 4.74e-4. Three consequences, in ascending order of how badly
they would have been missed:
- At 64 the projection aborted and no CSV was produced at all. There is no version of this row with the smaller budget; the artefact of record exists because the budget moved.
- The budget was silently under-reporting Hausdorff in the truth-to-reconstruction direction, by
dropping legitimate probes on every CSG field.
csg_difference's cubic Hausdorff moves6.135e-2to the committed 0.065699639 when the budget rises. csg_difference's lattice verdict flipped from−0.177 dBto+0.417121 dB. That single flip is worth two of this row's four integers: it is one offields_improved's 3, and it is the only member offields_in_neighbourhood's 1. At 64 steps C1 would have read 2 of 8 and C2 would have read 0 of 8 — both still falsified, but falsified by an instrument artefact instead of by the lattice.
At 1024 the stall count falls 240 → 86, and 80 of those 86 are the identical value 5.7180e-2 —
a genuine positive local minimum of the max where no zero lies along any descent path, which is the
legitimate drop the module documents rather than a budget failure. Verdicts are identical at 512 and
1024, so the numbers are insensitive to the budget once it is large enough, and the whole 49³ sweep
costs 37.0 s against 35.2 s, inside this host's governor noise. A threshold that changes a verdict is a
threshold that has to be reported with both of its numbers, and this one changed two clauses' integers.
What extraction_ms is not. BCC is the faster arm on every field — sphere 178.7981 ms against
295.3903, noise_cavity 360.7360 against 585.0305 — and none of that is evidence about
either lattice. This harness's per-evaluation cost is dominated by LatticeGrid::find, an
O(log sites) binary search per stencil tap (benches/common/lattice.rs:298-315), and the BCC arm pays
it four times per evaluation against the cubic arm's eight. A shipped extractor with a linear
index space would pay none of it. The column is recorded because the registration names it, and C3 is
scored on case_table_size and corner_reads_per_site, which are integers.
What a consumer of this crate should do differently: nothing, and now for a measured reason. The
crate samples on Z³ and has for its entire life — every extractor's extract takes the same
(sdf, shape, origin, cell_size, out) signature and Shape3's strides are [1, sx, sx·sy]
(shape.rs:11-22). Before this row, "BCC would be 0.257 dB better" was a citable prediction from Barnes
& Sloane (10.1137/0604005) with nothing in this repository able to say whether it applied. It does not
apply to this error measure: 3 of 8 fields improved and 1 of 8 landed within a factor of two, with
thin_plate and noise_cavity more than twice as bad. A BCC landing ticket is not registered by this
row, and the reason is now arithmetic rather than caution. What C1 would have needed to buy — a site
enumerator, a BCC reconstruction filter, a tetrahedral extractor over the BCC Delaunay complex, and
every consumer of Shape3's cubic index space rewritten — is priced against a win that showed up on
three fields out of eight and reversed on two.
SHARE, recomputed. The registration's SHARE is "C1 moves the whole sampling stage; C3 is a
complexity cost, not a runtime one." Discharged in both halves. The sampling stage did not move:
crates/isomesh/src/** is unchanged, no reference field was added, no golden hash can move, and
is_control true on the eight Z3 rows is the crate's own shipped geometry measured beside the
alternative rather than replaced by it. And C3 is quoted as a complexity cost — case_table_size,
cells_per_site, corner_reads_per_site, distinct_up_to_symmetry — with extraction_ms explicitly
excluded from the clause by the harness that recorded it. What this row retires is a prediction, not a
lattice: A₃* remains optimal among three-dimensional lattices for the second moment, exactly as Barnes
& Sloane prove, and this row measures that the second moment is not what an isosurface extractor's
Hausdorff error is made of. R-163 asks the same question of FCC against BCC from the other side.
💥 ✗119 / M-476 — a null registered on purpose came back not null: C1 FALSIFIED at fields_below_scatter 1 of 8, because measurement_scatter_db is exactly 0.000000 on 6 of 8 fields — a deterministic computation has no scatter, so gap_over_scatter reads inf and the clause is arithmetically false rather than narrowly missed — against measured_gap_db reaching +5.731155 dB on noise_cavity, 514× the registered predicted_gap_db of 0.011143 (P-163, R-163)
M. cargo bench --bench experiment_p163, docs/experiments/p-163.csv, 16 rows across 43
columns — three # comment lines plus one column header plus 16 data rows, counted from the file.
# commit 4b5719f on amd-ryzen-9-5900x-12-core at 2026-08-30T14:30:31Z, clean tree. (field, lattice)
is the primary key: eight fields × two arms, A3* (BCC) carrying is_control true and D3 (FCC)
false. No reconstruction filter is evaluated anywhere — each lattice is contoured on its own
Delaunay bond graph — and crates/isomesh/src/** is untouched.
This row was registered so that a null would be on the record before somebody spent a week
distinguishing FCC from BCC. The week is still not worth spending, and the reason is the opposite of the
registered one. G reads 0.078543281 on the A3* rows and 0.078745066 on the D3 rows,
predicted_gap_db 0.011143 on all sixteen. C1 claimed that gap sits below the harness's own
measurement scatter. c1_holds is false on 16 of 16, and both branches of the registration's
falsifier fired at once.
Branch one: the harness is more precise than expected — infinitely so, on three quarters of the
fields. scatter_is_zero is true on box_exact, csg_difference, thin_plate, gyroid,
fbm_terrain and noise_cavity, i.e. 6 of 8 fields, and arm_scatter_db is 0.000000 on 14 of
16 arm rows. On those rows measurement_scatter_db is 0.000000 and gap_over_scatter is
literally inf. C1 is not "close" on them; |x| < 0 is false for every real x, and the clause is
unreachable in the direction it was written, with the arithmetic naming why.
That outcome was foreseen and deliberately not asserted against. zero_set_hausdorff is a symmetric
maximum over two directions, and only the truth-to-reconstruction one depends on the probe stream; the
recon-to-truth direction is probe-independent, so "if it ever dominated the maximum the scatter would be
exactly zero" (benches/experiment_p163.rs:171-175). It dominates on six fields. The column
scatter_is_zero exists precisely so a zero there is "a registered outcome and not a broken fixture".
Per-clause accounting. There is one clause; the registration has no C2 and no C3.
C1 — FALSIFIED on the conjunction,
fields_below_scatter1 offields_measured8. The decision rule was fixed before the run: C1 claims the difference is unresolvable, so one field on which it resolves is one field on which somebody could distinguish the lattices, andc1_holdsis the conjunction (benches/experiment_p163.rs:204-210).gap_below_scatteris true onspherealone:measured_gap_db−0.102675 againstmeasurement_scatter_db0.292921,gap_over_scatter0.350522. Every other field resolves, and most of them are not close:
field measured_gap_dbmeasurement_scatter_dbgap_over_scatterscatter_is_zerobelowsphere−0.102675 0.292921 0.350522 false true torus+0.853780 0.120066 7.110924 false false box_exact+0.531513 0.000000 inf true false csg_difference+2.325768 0.000000 inf true false thin_plate−0.591560 0.000000 inf true false gyroid−0.113864 0.000000 inf true false fbm_terrain−0.035058 0.000000 inf true false noise_cavity+5.731155 0.000000 inf true false Six vacuity controls, all assertions with
VOID:messages, all fired. (1) The registration's own control — at least five repeated runs of the same lattice.repeats5 withprobe_counts2600|2800|3000|3200|3400, strictly increasing, identical schedule on both arms, andhausdorff_by_probescarries all five values per row so "below scatter" has a visible denominator. Without it the phrase has none. (2) The prediction under test is the registered one:predicted_gap_db0.011143 against the registered0.011 dBto5e-4, so C1 is not scored against a number nobody registered. (3) Matched point density:samples114,191 onA3*against 113,491 onD3from a commontarget_points117,649,density_mismatch0.006130 against P-162's own 5% bar. (4) Matched bond density, the control that stops a covering-radius comparison being won by whichever arm got more crossings: seven positive-half offsets on both lattices as an integer equality, and the realisedbonds_per_site6.766330 against 6.772079 overbonds772,654 against 768,570,bond_mismatch0.000850. (5) Both arms measured a real surface:pointsruns 3,686–45,318 over the sixteen rows, everyhausdorffandrms_errorstrictly positive and finite (M-44). (6) The lattices are the lattices they claim to be:coord_residual7.105e-15 onA3*and 3.553e-15 onD3.
Branch two: Hausdorff error responds to something G does not capture, and this row names it — the
Delaunay bond length at fixed point density. The harness wrote the alternative prediction down before
the run. At matched point density and matched bond count the two bond sets do not have matched bond
lengths: mean_bond_length is 0.094712112 on A3* against 0.096638538 on D3, from
lattice_unit 0.051282051 against 0.064516129. FCC's mean Delaunay bond is 2.03% longer on
the realised grids, and the reported Hausdorff is dominated by its truth-to-reconstruction direction —
the covering radius of the crossing set on the true surface, which scales with bond length. So
bond_length_gap_db reads 0.174897, which is 15.7× the registered 0.011143 and in the same
direction. A quantity nobody registered predicts this measurement fifteen times better than the
quantity that was registered, which is exactly what the falsifier said a resolvable difference would
mean: "P-162 C2's question answered from the other side".
The CSV disagrees with the harness header here and the CSV wins. The header derives +0.1873 dB from
the ideal mean bond lengths, (4·√3 + 3·2)/7/∛4 = 1.16355·scale against
(6·√2 + 1·2)/7/∛2 = 1.18894·scale (benches/experiment_p163.rs:240-256). The committed column is
0.174897, computed from the realised mean_bond_length pair after the box clipped the sites —
20·log₁₀(0.096638538 / 0.094712112). The ideal figure is 2.18% and the realised one 2.03%; the
difference is the clipping, and the realised number is the one this entry quotes.
The measured gaps do not even agree on a sign, which is the sharper way to say the prediction is
irrelevant. measured_gap_db is positive — BCC better, the direction both predictions are written in —
on torus, box_exact, csg_difference and noise_cavity, and negative on sphere, thin_plate,
gyroid and fbm_terrain. Four each. A 0.011 dB effect is invisible not because the instrument is
noisy but because the field-to-field variation of a max-norm geometric error is two to five hundred
times larger and does not have a consistent sign. noise_cavity's +5.731155 dB is the extreme:
hausdorff 0.224324518 on BCC against 0.433944798 on FCC, hausdorff_ratio 1.934451 — the
one axis choice the FCC arm makes, splitting each octahedron of its honeycomb along a fixed body
diagonal (benches/common/lattice.rs:638-648), is a genuine anisotropy and this is the field that
punishes it.
The mean-square form is exactly reproducible and the max form is not, and that contrast is the
instrument fact worth keeping. rms_gap_db carries no scatter column by construction, because it does
not depend on the probe stream, and it reads from −0.122351 (torus) to +11.652151
(box_exact) — wider than the max form, not narrower. So the choice of norm, not the choice of lattice,
is where this family of measurements gets its variance. Any future comparison of two sampling lattices in
this crate should be scored on a mean-square error over a fixed probe set, where the arithmetic is
deterministic, and should not expect a sub-0.02 dB prediction to survive a max-norm reading at all.
What a consumer of this crate should do differently: nothing, and the null holds even though the
clause did not. The registration's purpose was to foreclose the FCC-versus-BCC question, and the
measurement forecloses it harder than the clause did. C1 asked whether 0.011 dB is too small to see;
the answer is that the question is malformed, because on six of eight fields the harness resolves an
arbitrarily small difference exactly and still measures gaps between 0.035 and 5.731 dB driven by
bond length and axis choice rather than by G. SHARE: none is correct and remains correct:
crates/isomesh/src/** is unchanged, no reference field was added, no golden hash can move, and there is
no landing ticket from either verdict — a positive C1 lands nothing by construction, and this negative
C1 lands nothing either, because what it reports is a fact about zero_set_hausdorff and about Delaunay
bond geometry, not about the crate. Nobody should spend a week distinguishing A₃* from D₃ on this
evidence; what the evidence says is that they were never going to be distinguished by G.
💥 ✗120 / M-477 — C1 HELD on c1_fields_held 8 of 8 with order_gap spanning −0.072307 to +0.128478 against a bar of −0.15, both filters order 2 and the derivation executed to affine_residual 4.441e-16; C2 FALSIFIED and arithmetically unreachable, c2_margin_db topping out at 0.000000478 against c2_margin_required_db 0.001000, because P-162's non-control arm was already BCC plus the box spline — hausdorff reproduces p-162.csv to the last digit on all 16 rows, so the bar C2 must exceed is the measurement C2 makes, and x > x is false whatever x is (P-164, R-164)
M. cargo bench --bench experiment_p164, docs/experiments/p-164.csv, 16 rows across 70
columns — three # comment lines plus one column header plus 16 data rows, counted from the file.
# commit 3af8648 on amd-ryzen-9-5900x-12-core at 2026-08-30T14:27:36Z, clean tree. (field, filter)
is the primary key: eight fields × two arms, trilinear on Z3 with is_control true and
bcc_box_spline on A3* with false. The two crossed arms do not exist and are not faked —
bcc_reconstruct asserts a BCC grid and trilinear_reconstruct a cubic one
(benches/common/lattice.rs:980-985, :1053-1058). crates/isomesh/src/** is untouched.
C1 held with equality rather than by exceeding, which is what the derivation predicted. Entezari, Van
De Ville & Möller (10.1109/tvcg.2007.70429) gives the linear BCC box spline s − d = 1, total degree
1 on a BCC_BOX_SPLINE_STENCIL of 4 sites; the trilinear read as a box spline is
Ξ = [e₁ e₁ e₂ e₂ e₃ e₃], total degree 3 on a stencil of 8. Both reproduce affine functions
exactly and neither reproduces a quadratic, so both are order exactly 2 — same order, three times
less degree, half the stencil. order_derived is 2 and support_size is 8 on the control rows
against 4 on the BCC rows.
The derivation is not left as prose: the fifth vacuity control runs it. affine_residual is
8.882e-16 on every trilinear row and 4.441e-16 on every bcc_box_spline row — each filter's
weights summed against 1 and against an affine functional at eight generic points, exact to a rounding
unit, and required to fail against x². Then the order is measured independently by fitting
err = C·h^p over the five-rung ladder order_ladder 29|35|41|49|65:
| field | approximation_order cubic |
BCC | order_gap |
order_drop cubic / BCC |
order_r2 BCC |
|---|---|---|---|---|---|
sphere |
1.989459 | 2.001385 | +0.011926 | 4.988024 / 5.115780 | 0.999936 |
torus |
1.938142 | 1.944033 | +0.005891 | 4.689548 / 4.912465 | 0.997642 |
box_exact |
1.672027 | 1.800505 | +0.128478 | 3.922381 / 4.407020 | 0.999268 |
csg_difference |
1.475140 | 1.501436 | +0.026295 | 3.299392 / 3.548880 | 0.985985 |
thin_plate |
1.888830 | 1.816523 | −0.072307 | 4.659355 / 4.476425 | 0.996292 |
gyroid |
1.616701 | 1.564986 | −0.051715 | 3.647093 / 3.506470 | 0.997488 |
fbm_terrain |
1.434014 | 1.515663 | +0.081649 | 3.129358 / 3.435796 | 0.995688 |
noise_cavity |
1.550416 | 1.591909 | +0.041493 | 3.529171 / 3.670089 | 0.999587 |
c1_holds true on 16 of 16 with c1_fields_held 8.
Per-clause accounting.
C1 — HELD on 8 of 8, and the split inside it is reported rather than averaged. The clause is "at least the trilinear's approximation order" and the falsifier is "a lower order" — a whole integer.
c1is scored asorder_gap >= -ORDER_TOLERANCEwithORDER_TOLERANCE0.15, 15% of a genuine order loss (benches/experiment_p164.rs:346-353,:1343). The worst gap in the file isthin_plate's −0.072307, under half the tolerance and inside the fits' own scatter (order_se0.036712 and 0.063978 on that field's two arms).order_gap_nonnegativeis neverthelessfalseonthin_plateandgyroid— 2 of 8 fields where the BCC fit came out below the control's — and that column is in the file so the split can be read straight off it rather than inferred from a verdict.order_derived_agreesis a second split worth naming: true onsphereandtoruson both arms and onthin_plate's control, false on the other eleven rows, because the fitted exponent falls away from 2 on the rough fields. That is the fields, not the filters:csg_differencefits 1.475140 and 1.501436, and amaxof two smooth pieces has a codimension-1 crease where the classical order simply is not 2 for either filter.order_linfrides beside every RMS fit — from 0.967954 to 2.228334 — and the two norms disagreeing is information, since a crease givesL∞ ~ handRMS ~ h^1.5.C2 — FALSIFIED, and recorded as arithmetically UNREACHABLE with the arithmetic,
P-70C1 being the precedent.c2_reachablefalse andc2_blockerp162_arm_was_already_bcc_plus_box_splineon 16 of 16. C2 asks whether BCC-plus-box-spline beats cubic-plus-trilinear "by more than the lattice change alone does in P-162". There is no such measurement to exceed:P-162'sreconstructdispatches on the lattice and returnsbcc_reconstructforA3*(benches/experiment_p162.rs:378-386), sop-162.csv'smeasured_gain_dbis the gain of the combination. The lattice change alone was never measured by anything in this phase. The bar is therefore the identical measurement, and the file says so as an equality:vs_trilinear_on_cubicequalsc2_bar_dbon every row —+0.067568onsphere,−0.026354ontorus,0.000000onbox_exact,+0.417121oncsg_difference,−8.584787onthin_plate,+0.726612ongyroid,−0.246186onfbm_terrain,−7.361573onnoise_cavity— withc2_margin_dbreading 0.000000209, 0.000000393, 0.000000000, 0.000000387, 0.000000362, 0.000000408, −0.000000286 and 0.000000478 against a required 0.001000. Largest margin in the file: 0.000000478 dB onnoise_cavity, over two thousand times under the bar, and one field (box_exact) reads an exact 0.000000000.c2_fields_held0.The verdict fires and the registered reason is wrong, which is the part worth writing down. The falsifier reads "C2 by no improvement over P-162 alone, which would mean they do not compose and the filter is doing nothing". The filter is not doing nothing. It was already inside the baseline.
Vacuity controls. (1) The registration's own: P-162 must have completed and its per-field numbers must be the reported baseline. They are, and read from the committed CSV at run time rather than hard-coded — which is exactly what the control forbids.
p162_commitis0db1c9eon all sixteen rows, matchingp-162.csv's own# commitline;p162_hausdorffequals this row'shausdorffto the last digit on 16 of 16 (0.058482783/0.058029606,0.052445265/0.140911234,0.647500519, …), which is a measured replication rather than an inference from reading source, the harness having deliberately reproducedTARGET_POINTS = 49³,EVAL_SAMPLES49,refine_steps14,probes5,000 andINSET_SCALES2.5. (2) The baseline's verdict travels with the number:p162_c1_holdsfalse,p162_c2_holdsfalse,p162_fields_improved3, stamped on every row so nobody reads this row's C1 as an endorsement of the lattice. (3) The ladder separates order 1 from order 2:order_lever2.241379 on the cubic ladder and 2.260870 on BCC's, so an order-1 filter would drop error2.24×across the ladder and an order-2 filter2.241379² = 5.024×; measuredorder_dropruns 3.129358–5.115780, and the levers are what make the fit able to tell the two apart at all. (4) Matched point density at the headline,density_mismatch0.029393 againstDENSITY_TOLERANCE0.05, overorder_samples24389|42875|68921|117649|274625 cubic against 22815|41635|68705|114191|273259 BCC. (5) The derivation executed,affine_residualabove. (6) The ladder's probe set is shared:order_probes4,096 at one inset for all five rungs and both arms, so the error comparison is at identical points andf(p)is sampled once.
The threshold that moved, with both of its numbers. LADDER_DENSITY_TOLERANCE is 0.08, not
0.05 (benches/experiment_p164.rs:321-338), and the reason is quantisation, not
tolerance-shopping. A lattice grid holds an integer number of sites, and BCC's count moves in steps
of two per axis-pair against the cubic grid's one, so a rung's realised counts cannot be dialled to
arbitrary precision: lattice_grid solves for the scale that comes closest to the target, and at the
coarse end of the ladder — 29 sites per axis, where the step is largest relative to the total — the
residual is irreducible. Measured on the first run, sphere's worst rung is 6.454%, and the
committed file agrees: order_density_mismatch_max reads 0.064537 on seven fields and 0.050269
on gyroid, against a headline density_mismatch of 0.029393 — "well under 1%" being the
headline's own achievable match once the grid is chosen once. The reason 8% is not a loosened bar is
that it is nowhere near the factor the fit resolves: an order-1 filter drops error 2.24× across this
ladder and an order-2 filter 5.02×, so an 8% density wobble cannot be mistaken for either, and the
per-rung gap is recorded (order_density_mismatch_max) so the margin is auditable rather than asserted.
(The threshold's own doc-comment says "an order-1 filter drops error 2.51× per rung"; that figure
reconciles with neither order_lever 2.241379 nor its square, and is a slip in the comment. The
argument does not depend on it — 8% is two orders of magnitude below either reading.)
What the row can honestly say about composition, since C2 cannot. Both filters being order 2, the
combination cannot move the rate and can only move the constant — so the harness measured the
constant over five resolutions instead of guessing at one. constant_ratio_db = 20·log₁₀(C_cubic /
C_bcc) is positive on 8 of 8 fields: box_exact 3.527125, csg_difference 2.107581,
sphere 1.741309, torus 1.700542, gyroid 1.606900, thin_plate 1.332996,
fbm_terrain 0.565886, noise_cavity 0.145839. The BCC box spline has the smaller
prefactor everywhere, and order_rms_errors shows it rung by rung — on sphere,
2.1090e-3|1.4356e-3|1.0295e-3|7.4112e-4|4.1225e-4 against the trilinear's
2.6301e-3|1.8128e-3|1.3520e-3|9.3616e-4|5.2728e-4, lower at all five resolutions. That is the
composition result C2 was reaching for and could not express: same order, uniformly better constant,
between 0.15 and 3.53 dB of it, on half the stencil. It is also not a landing argument, and the
harness says so before the numbers: order 2 equal to the incumbent's is a reason to land only if the
value error is what a caller pays for, and P-162 measured that the geometric error moves the other
way on thin_plate and noise_cavity.
The cost, measured and then disqualified from the verdict. filter_evals runs 133,525–368,613
over eval_calls 20,000 and eval_cells 110,592, and the BCC arm is faster on every field:
eval_ns_per_call 1425.92–1431.92 against the trilinear's 2320.54–2333.71, eval_ms about
28.5 against 46.5, over eval_repeats 5 with eval_scatter 0.002529–0.029161. That is
the four-tap stencil against eight taps and it is a real property of the filter — but in this harness
each tap is an O(log sites) binary search, so the ratio is about LatticeGrid::find and not about a
shipped extractor's index arithmetic. No clause is scored on it.
What a consumer of this crate should do differently: nothing, and the reason is now two-sided. C1's
positive is a statement about a filter's order, not about a win: order 2 equal to the incumbent's is
what was derived and what was measured. The uniformly better constant is real and is the first thing in
this repository to say that the BCC box spline buys anything at all — but it buys it in the value
norm, on a lattice P-162 measured as not better in the geometric max norm on 5 of 8 fields — strictly
worse on four (torus, thin_plate, fbm_terrain, noise_cavity) and identical on box_exact. A shipped
BCC arm still needs a site enumerator, a BCC reconstruction filter, a tetrahedral extractor over the BCC
Delaunay complex, and every consumer of Shape3's [1, sx, sx·sy] strides (shape.rs:11-22) to stop
assuming a cubic index space, and nothing in this row or in P-162 pays for that. No golden hash
moved, no reference field was added, and the filter lives in benches/common/lattice.rs. V-45's
failure mode is a landing that happens quietly inside a measurement commit; there is none here.
🔬 M-478 — C1, C2 and C3 all HELD on 24 of 24 rows, and the sharper thing is that greedy meshing is finished: Eppstein's optimum n/2 + h − g − components reproduces exhaustive search on 33,267 components with brute_disagreements 0, and the shipped mesher's worst distance from it in the whole sweep is ratio 1.027132 — 45,620 optimal rectangles against 46,131 greedy, 1.120% over optimal, exactly optimal on 8 of the 21 rows where the ratio is defined, while cost_ratio tops out at 1.511744 against a bar of 10 and drops to 0.424099, i.e. computing the optimum is cheaper than running the mesher on 9 of 24 rows (P-165, R-165)
M. cargo bench --bench experiment_p165, docs/experiments/p-165.csv, 24 rows across 44
columns — three # comment lines plus one column header plus 24 data rows, counted from the file.
# commit 2b2a765 on amd-ryzen-9-5900x-12-core at 2026-08-30T09:30:27Z, clean tree. (field,
resolution) is the primary key: eight reference fields × 17, 33, 65 samples. repeats 5 on
every row. crates/isomesh/src/** is untouched; the shipped GreedyQuads is reached through the public
API and its output is counted, not modified.
M-56 (FINDINGS.md:1172) bracketed greedy meshing from below and nobody had ever bracketed it from
above. M-56 measured Merge::Greedy against Merge::Off — a ratio against a worse algorithm,
1.70× to 256×, and called it a property of the scene. This row asks the other direction on the very
same masks, and the answer has been polynomial-time computable since 1979. For a rectilinear region the
minimum number of rectangles in a partition is K_min = n/2 + h − g − 1, with n the boundary vertex
count, h the holes and g the maximum number of pairwise-disjoint good diagonals; Eppstein,
Graph-Theoretic Solutions to Computational Geometry Problems (arXiv:0908.3916), supplies the
reduction that makes g cheap — the intersection graph of horizontal against vertical chords is
bipartite, so a maximum independent set of chords is (#chords) − (maximum matching) by
König–Gallai.
The formula is summed over 4-connected components rather than applied to a polygon, so the committed
identity is optimum_rectangles = vertices_n/2 + holes_h − good_diagonals_g − components, and it closes
on all 24 rows. The largest instance, noise_cavity at 65: vertices_n 53,088, holes_h 13,
good_diagonals_g 2,062, components 10,234 — 26,544 + 13 − 2,062 − 10,234 = 14,261, which
is optimum_rectangles exactly, against greedy_rectangles 14,435.
| field | res | vertices_n |
holes_h |
good_diagonals_g |
components |
optimum |
greedy |
ratio |
cost_ratio |
|---|---|---|---|---|---|---|---|---|---|
sphere |
17 | 600 | 6 | 36 | 108 | 162 | 162 | 1.000000 | 1.428376 |
sphere |
33 | 2,472 | 12 | 156 | 450 | 642 | 642 | 1.000000 | 1.370735 |
sphere |
65 | 8,232 | 18 | 408 | 1,608 | 2,118 | 2,124 | 1.002833 | 1.343397 |
torus |
33 | 1,440 | 2 | 68 | 290 | 364 | 366 | 1.005495 | 1.283966 |
torus |
65 | 6,960 | 10 | 360 | 1,346 | 1,784 | 1,808 | 1.013453 | 1.351957 |
box_exact |
65 | 24 | 0 | 0 | 6 | 6 | 6 | 1.000000 | 0.872309 |
csg_difference |
65 | 1,626 | 3 | 75 | 303 | 438 | 441 | 1.006849 | 1.000178 |
thin_plate |
33 | 0 | 0 | 0 | 0 | 0 | 0 | undefined | 0.835426 |
gyroid |
33 | 11,406 | 0 | 354 | 2,304 | 3,045 | 3,093 | 1.015764 | 1.371571 |
gyroid |
65 | 44,094 | 3 | 1,446 | 9,111 | 11,493 | 11,622 | 1.011224 | 1.249934 |
fbm_terrain |
17 | 984 | 5 | 56 | 183 | 258 | 265 | 1.027132 | 0.461796 |
fbm_terrain |
65 | 16,786 | 14 | 683 | 3,268 | 4,456 | 4,517 | 1.013689 | 0.424099 |
noise_cavity |
65 | 53,088 | 13 | 2,062 | 10,234 | 14,261 | 14,435 | 1.012201 | 1.078443 |
c1_holds, c2_holds and c3_holds all true on 24 of 24.
Per-clause accounting.
C1 — HELD: the reduction applies, and it was checked against ground truth rather than cited. The falsifier is "the reduction not applying — for instance if the merged regions have holes the formula's
hdoes not model", which is the checkerboard-vertex hazard: two diagonally opposite cells set, the boundary passing through one point twice, and the region not locally a disc. It is common —pinch_verticestotals 13,698 run-wide, 1,176 ongyroidat 33 alone (the exact figure the prototype that sized this harness recorded) and 5,196 at 65 — and it is resolved by construction and then measured:identity_failuresis 0 on 24 of 24, the turning identityn/2 + h − 1 == r − h + 1closing oververtices_n,holes_hfrom the boundary walk andreflex_rfrom an independent right-turn tally (reflex_r0–6,102). Andbrute_disagreementsis 0 overbrute_checked33,267 components, of whichbrute_nonrectangular3,868 were genuinely non-rectangular — a memoised branch-and-bound that knows nothing about Eppstein, agreeing on every component small enough to enumerate.optimum_le_greedytrue on 24 of 24 is the third, cheapest consistency check: a formula returning more rectangles than an actual partition would be wrong on its face.C2 — HELD: greedy does not already achieve the optimum on every field. The falsifier is "greedy already achieving the optimum on every field, which would close
M-56's question with the best possible answer", and the measurement narrowly declines to hand that answer over. Greedy is exactly optimal on 8 of the 21 rows withratio_definedtrue —sphereat 17 and 33,torusat 17,box_exactat all three resolutions,csg_differenceat 17 and 33 — and above 1 on the other 13. The worst gap in the entire sweep isratio1.027132,fbm_terrainat 17: 265 rectangles against an optimum of 258, seven rectangles. Summed over all 24 rows the file reads 45,620 optimal against 46,131 greedy, 1.120% over optimal. So C2 held on the letter and its spirit is the opposite of a reprieve: the headroom above the shipped merge is one part in ninety, and the engineering conclusion is to stop working on it.C3 — HELD on every row, with room the falsifier never came near.
c3_holdsis per row,cost_ratio = optimum_ms / greedy_ms < 10. Worst in the file: 1.511744 (gyroidat 17), withcost_ratio_worst— the same ratio taken in the direction that makes C3 hardest — topping out at 1.568382 on the same row.total_cost_ratiotherefore never exceeds 2.511744. On 9 of 24 rows the ratio is below 1, i.e. computing the exact optimum is cheaper than running the shipped mesher:fbm_terrain0.461796 / 0.434781 / 0.424099,thin_plate0.838227 / 0.835426 / 0.830593,box_exact0.963370 / 0.921477 / 0.872309. The König reduction is not where the time goes —matching_msruns 0.000000–0.067600 againstoptimum_ms0.167161–27.940842, so Hopcroft–Karp is a rounding error on the boundary walk.Vacuity controls, five of them, every one fired. (1) At least one field with
good_diagonals_g > 0— otherwise the formula degenerates ton/2 + h − 1, the bipartite reduction that is the actual contribution is never exercised, and the matching code could be deleted without changing a number. Measured:good_diagonals_gup to 2,062, withchords_horizontal/chords_verticalup to 1,498/1,497 andmatching_pairsup to 933. (2) At least one field withholes_h > 0— the term C1's falsifier names by name — asserted separately fromgbecause a fixture can easily have chords and no holes; measured up to 18 onsphereat 65, andgyroidat 17 and 33 is the converse case,g99/354 withh0. (3) At least one field withpinch_vertices > 0, or every word of the degeneracy argument is untested and the leftmost-turn rule cannot differ from the naive one: 13,698 run-wide. (4) At least one non-rectangular component reaching the exhaustive oracle, since a brute force that only ever saw rectangles would agree with any formula returning 1 for a rectangle: 3,868. (5)culled_facesmust exceedgreedy_rectangleson at least one field, ormerge_savingis 1 everywhere and the control is not reproducingM-56: it exceeds on 21 of 24 rows, the three exceptions beingthin_plate's empty rows.
The masks analysed here are the masks the shipped extractor partitioned, and that is measured three
independent ways rather than read off the source. GreedyQuads is not an isosurface extractor: it
classifies cells by the sign at the cell centre and merges per 2D slice, 6·(n−1) masks per field
(greedy_quads.rs:178-193, :214-272), and masks reads 96 / 192 / 384 at 17 / 33 / 65 exactly.
So the optimum is computed per mask and summed, and the comparison is exact rather than analogical.
(1) The shipped mesh's own arithmetic: greedy_vertices is 2 × greedy_triangles on all 24 rows
(46,488 and 23,244 on gyroid at 65), so triangle_count()/2 is the quad count. (2) The
load-bearing one — mask_quads_agree true on 24 of 24: this file's independent re-walk of the same
masks with the same merge equals triangle_count()/2, down to the occupancy sample points. (3) The
committed golden fixture: golden_check reads match on 16 rows (17 and 33, where
golden_hashes.json carries greedy_quads rows) and absent on the 8 rows at 65, which is the only
check independent of this run.
M-56 is re-derived in the same line that measures the distance to the optimum, and it reproduces
exactly. merge_saving = culled_faces / greedy_rectangles at 33: box_exact 256.000000,
csg_difference 10.640000, fbm_terrain 4.604224, torus 2.688525, sphere 1.943925,
noise_cavity 1.798429, gyroid 1.697381 — M-56's published 256×, 10.64×, 4.60×,
2.69×, 1.94× and 1.70×, on all six fields it quoted. box_exact's saving is also the clearest
demonstration that the saving is a property of the scene: 64.000000 / 256.000000 / 1024.000000 at
17 / 33 / 65, quadrupling with resolution while optimum_rectangles and greedy_rectangles both stay
at 6. A cube's six faces need six rectangles at any resolution, and greedy finds all six.
The eighth field is the one that explains why the registration says seven, which is a better outcome
than dropping it. The registration reads "the optimum is computed on all seven fields";
for_each_reference_field! has eight (fields/mod.rs:211-256). The registration cannot be amended,
so the eighth field is surplus rather than a violation and all eight were run. The missing one is
thin_plate, and the discrepancy is inherited from M-56, whose sweep is also "seven reference
fields": thin_plate is a slab of half-thickness 0.0125 centred on y = 0
(fields/mod.rs:617-637), the grid is n odd samples over [−2, 2], and a cell centre at
−2 + h·j + h/2 equals 0 only for half-integer j. No cell centre is ever inside the plate, at any
odd resolution. The file says so in six columns at once: vertices_n 0, holes_h 0,
good_diagonals_g 0, components 0, greedy_rectangles 0, culled_faces 0 and
ratio_defined false on all three thin_plate rows — and the committed fixture agrees, reading
"vertices":0,"triangles":0 at 17, 25 and 33. It is M-266's sub-voxel aliasing seen through a
centre-sampled mesher, and the three rows are recorded as undefined rather than folded into the ratio.
What a consumer of this crate should do differently: nothing, and that is now a measured conclusion
rather than an absence of evidence. M-56 left greedy's quality bracketed only from below and
unbounded from above, so any future work on the merge could claim an arbitrary headroom. The headroom
is 1.120% over the whole sweep and 2.71% at its worst single row. The correct engineering action on
the greedy-meshing stage is to stop — which is a change to the plan for that stage, and the only kind of
change a measurement is entitled to make. This row proposes no source change; it prices one, and the
price is not worth paying.
Two deliberate non-claims, stated because the numbers invite both errors. First, this is not a
whole-volume optimum. "The minimum number of axis-aligned quads needed to represent this occupancy
grid's surface" is a different and harder problem that would let a quad span what greedy calls two
sweeps; what is measured is "the minimum number of rectangles in a partition of each of the 6·(n−1)
masks greedy actually partitions", which is greedy's problem and not an approximation of it — the
shipped mesher can never merge across two masks, because two masks are two planes with two normals and a
shared vertex there would have to average them (greedy_quads.rs:36-49). Second, optimum_ms is the
cost of the optimal count, not of an optimal partition. A shippable optimal mesher would
additionally have to construct one, which is not measured here and must not be read out of that column.
SHARE is discharged in the same direction: what C2 moves is the expectation for that stage, not the
code.
💥 ✗121 / M-479 — the registered negative HELD and the hoped-for guarantee did not: C1 HELD with is_matroid false on all 6 greedy-meshing rows, disjoint_from_small 0 and augmentation_failures 87 / 190 / 2,331 on the exhaustively scanned fixtures — the minimal counterexample being a 2×2 block, min_basis 1 against max_basis 4 — while C2 FALSIFIED on violating_chunks 92 of 221 on capped_gyroid and 155 of 186 on fbm_terrain against 0 of 152 on sphere, the worst chunk's gains reading 2.984502e1|9.237806e0|1.598680e1, marginal returns that increase at the third refinement, and submodular_scan_saw_it false on the field the constructed witness caught (P-166, R-166)
M. cargo bench --bench experiment_p166, docs/experiments/p-166.csv, 33 rows across 75
columns — three # comment lines plus one column header plus 33 data rows, counted from the file.
# commit 8968839 on amd-ryzen-9-5900x-12-core at 2026-08-30T09:30:31Z, clean tree. problem is the
primary key and arm_kind splits the file: 4 c1_fixture, 2 c1_shipped, 2 c1_control,
18 c2_budget, 3 c2_worst_chunk, 4 c2_control. c1_holds true and c2_holds
false on all 33; the per-arm reading is arm_verdict. rng_seed 179109546 run-wide.
crates/isomesh/src/** is untouched.
The (1 − 1/e) statement was sourced, and the source was found. The registration requires it from
"a freely available restatement" because Nemhauser, Wolsey & Fisher is paywalled twice over —
10.1007/BF01588971 (Mathematical Programming 14, 265–294, 1978, Part I) and
10.1007/BFb0121195 (Mathematical Programming Studies 8, 73–87, 1978, Part II) — and the local
corpus holds neither. The restatement actually read, in full, is Shamak Dutta, Bahman Gharesifard and
Stephen L. Smith, Submodular Optimization with Applications to Decision and Control,
arXiv:2606.10192v1 [math.OC], 8 June 2026 — open access, with proofs. Four of its statements are
load-bearing: Definition 3.1 (independence systems, and the augmentation property (3) that C1
hunts a counterexample to), Example 3.5 (the uniform matroid I = {A : |A| ≤ k}, "the augmentation
property is immediate", which is why is_matroid reads true on every lod_budget row),
Theorem 4.2 (f(S_G)/f(S*) ≥ 1 − 1/e; one_minus_1_over_e is recorded as 0.632121 on 26 rows)
and Proposition 2.3 (submodular iff diminishing returns). Two further statements are named and
used but decide nothing: Section 3.3's knapsack failure, reproduced verbatim as a negative control,
and Section 3.4's p-system, whose basis-size spread is recorded as p_system_lower_bound. What
the restatement does not cover is said plainly: it scopes itself to maximisation, and greedy meshing
is a minimisation of cardinality, whose classical home is Wolsey's submodular set-covering line
(10.1007/BF02579435, 1982) — named, not read, and no constant is quoted from it.
Per-clause accounting.
C1 — HELD: greedy meshing is not a matroid problem, and the counterexample is exhibited rather than argued. The set system is forced by the algorithm: ground set
Xis every axis-aligned rectangle inside a slice's face mask,Ievery family of pairwise-disjoint rectangles.empty_independentanddownward_closedare true, so(X, I)is an independence system by Definition 3.1(1)(2) — and the single observation that kills (3) is that a maximal member ofIis exactly a rectangle partition of the mask (leave a cell uncovered and its1×1rectangle is inXand disjoint from everything chosen). Different bases therefore have different cardinalities, which Definition 3.1(3) forbids. The four hand fixtures, with the CSV's ownfixture_art(/between rows, a value may not contain a newline):```text square_2x2 plus staircase ring fixture_art ##/## .#./###/.#. #../##./### ###/#.#/###
# # . # . # . . # # # # # # # # # # . # . # . # . # # # # # #fixture_cells 4 5 6 8 ground_rectangles 9 11 15 20 independent_sets 35 72 216 uncounted bases_enumerated 8 7 21 81 min_basis 1 3 3 4 max_basis 4 5 6 8 basis_size_ratio 4.000000 1.666667 2.000000 2.000000 augmentation_failures 87 190 2331 certificate axioms exhaustive exhaustive exhaustive witness disjoint_from_small 0 0 0 0 ```
square_2x2is the minimal counterexample and the CSV carries its certificate.min_basis_rectsis2x2@0+0— one2×2quad — against the all-unit-cells basis of four, so4 > 1, anddisjoint_from_smallis 0: not one of the nine rectangles inXis disjoint from the minimum partition, because that partition covers every cell. Nothing smaller than a2×2block can fail, a one-cell region having exactly one partition.ringcarries a hole — the caseR-165's formula models with itshterm — and itsground_rectangles20 exceeds the exhaustive gate, soaxiomsreadswitnessandaugmentation_failuresreadscertificaterather than a count. The file says which method certified each row rather than leaving it to prose.The shipped mesher is the fifth witness and it needs no fixture.
Merge::Offemits one quad per visible cell face — the all-unit-cells basis — andMerge::Greedyemits the merged one; both are maximal in the same system over the same occupancy in the same binary (greedy_quads.rs:98-104).quads_merge_off1,536 againstquads_merge_greedy6 onbox_exactat 33, and 1,248 against 642 onsphereat 33, are therefore measured violations of equicardinality —M-56's number re-read as an algebraic fact rather than as a saving.p_system_lower_boundon those two rows is 256.000000 and 1.943925.The sharpest thing C1 measures is that failing the exchange property costs greedy nothing here.
greedy_ratiois 1.000000 on all six greedy-meshing rows, andmin_basis_exactis true on the four fixtures. A system can fail Definition 3.1(3) while greedy still attains its minimum, and these six rows are that case.bound_appliesis false on every one of them, and the reason is structural rather than a technicality: Theorem 4.2 needs a monotone submodular objective maximised under a cardinality constraint, and greedy meshing minimises cardinality subject to covering. Two of the theorem's hypotheses fail, so the(1 − 1/e)guarantee is not weak here — it is inapplicable, which is exactly what C1 was registered to say.is_submodularis true on those rows andmarginal_returns_monotonetrue, and neither is a mistake: the objective is|S|, which is modular, hence submodular with constant marginals. Submodularity is not what greedy meshing is missing.C2 — FALSIFIED, on the falsifier the experiment was designed to hunt. The clause asks for the marginal screen-space-error reduction to be diminishing per chunk, "or a chunk with increasing marginal returns is exhibited" — and the falsifier is "C2 by increasing marginal returns, which closes the guarantee — and finding one such chunk is cheaper than proving none exists, so the experiment is designed to look for it". It found them in bulk:
field chunks_per_axischunks_visitedcurve_chunksviolating_chunks_materialarm_verdictsphere12 1,728 152 0 0 true capped_gyroid7 343 221 92 92 false fbm_terrain10 1,000 186 155 153 false
levels_spanned4 andrefinement_steps3 on everyc2row, spacingsh, 2h, 4h, 8hfromChunkLayout::at_lod(chunk.rs:137-144) withdownsample_opdecimate. So 559 surface chunks were curved across four LOD levels, and 247 of them have increasing marginal returns — the registration asked for at least 50 chunks spanning at least two levels, and each field alone clears that three times over.The extremal witness, quoted from the
c2_worst_chunkrows.worst_chunk_gainsis the chunk's three marginal gains in order:
sphere—3.164945e0|9.049330e-1|3.270063e-1atworst_chunk_coords3|3|5,worst_chunk_distance5.990734. Strictly diminishing, falling by roughly3.5×then2.8×;witness_sees_violationfalse.capped_gyroid—2.984502e1|9.237806e0|1.598680e1at 5|5|5, distance 9.526279.gain[2]15.99 exceedsgain[1]9.24 by a factor of 1.73 — an increasing marginal return, andwitness_sees_violationtrue.fbm_terrain—1.922011e0|8.965218e0|4.682462e0at 0|5|7, distance 22.328457.gain[1]8.97 exceedsgain[0]1.92 by a factor of 4.66, the worst inversion in the file;witness_sees_violationtrue.The mechanism was named before the numbers and the numbers match it. For a smooth field the trilinear error goes as
s²andsdoubles per level, so the three gains should fall as48C : 12C : 4C—sphere's ladder does exactly that. What breaks it is saturation: a chunk carrying an oscillation shorter than8his undersampled at the coarsest levels, its max residual pins near the field's own amplitude and the top gain collapses.capped_gyroid'sworst_chunk_geometric0.000000e0|1.628286e-1|2.569173e-1|5.608944e-1is that curve flattening between levels 2 and 3 wheresphere's0.000000e0|2.094507e-3|7.890689e-3|2.816246e-2keeps quadrupling. So the falsification is a statement about which fields admit the guarantee, not that none does — the fields were chosen to straddle the regime on purpose, andviolating_chunksis per field so this entry can say which.The two instruments disagreed exactly where the harness said they would, which is why the assertion was never put on the scan.
submodular_scan_saw_itis false onsphereand oncapped_gyroid, and true only onfbm_terrain. Definition 2.1 sampled on random subset pairs is a whole-world question —f(A) + f(B) − f(A∪B) − f(A∩B)sums one slack per chunk, so a minority of violating chunks is hidden by the concave majority's positive slack. Oncapped_gyroid92 of 221 chunks violate diminishing returns and the random-pair scan reported nothing. The verdict rests instead on the deterministic constructed pair at the chunk with the largestgain[j+1] − gain[j], where (2.1) collapses to2·value(j+1) ≥ value(j+2) + value(j), i.e. Proposition 2.3 and nothing else. A harness that had scored C2 on the random scan would have published "diminishing" forcapped_gyroidand been wrong about 92 chunks.Vacuity controls, six, all asserted with
VOID:messages and all written to the file. (1)is_matroid = falseon the meshing rows is licensed from above:control/uniform_matroid_U3_8reports the augmentation property holding —is_matroidtrue,augmentation_failures0 overindependent_sets93,arm_verdicttrue. Example 3.5 provesU(3,8)is a matroid, so a failure there would be a tester bug and every meshingfalsewould be worthless. (2) And from below:control/knapsack_B2_w211reproduces Section 3.3's published witness —is_matroidfalse,augmentation_failures1 overindependent_sets5,arm_verdictfalse,min_basis/max_basis1|2 and 0. The tester is right about a case it did not choose. (3)disjoint_from_small = 0is not "no larger basis exists":max_basis > min_basison every fixture —4 > 1,5 > 3,6 > 3,8 > 4— andbases_completetrue on the three exhaustive ones. (4) The shipped witness is not inert:quads_merge_off1,536 and 1,248 againstquads_merge_greedy6 and 642; had merging emitted the same count,Mergewould witness nothing. (5) Greedy is shown able to miss on alod_budget-shaped instance:control/lod_convex_synthetic,curve_chunks2 atbudget_k3, its convex chunk'sworst_chunk_gainsreading1.000000e0|1.000000e0|1.000000e1against a second chunk of(2,0,0)(benches/experiment_p166.rs, arms table), readsf_greedy4.000000e0 againstf_optimal1.200000e1,greedy_ratio0.333333 andratio_meets_nwf_boundfalse — belowone_minus_1_over_e0.632121, which is the only row in the file where that column is false. Without it,greedy_is_optimalreading true on 11 of the 18c2_budgetrows would be a zero that could not have been non-zero (M-44). (6) The measured ladders are shown able to violate: the threecontrol/lod_reversed_<field>rows reverse each chunk's gains and readgreedy_ratio0.993500, 0.877375 and 0.912685 withviolating_chunks152, 209 and 155 — every chunk, by construction.
The optimum is exact, so greedy_is_optimal is a proof and not an estimate. f(S*) under |S| ≤ k
is a bounded knapsack over the per-chunk value tables, one O(chunks · k · 4) DP pass yielding the
optimum for every budget at once. So greedy_is_optimal true means greedy attained the optimum, and
it reads that on 11 of the 18 c2_budget rows; where it does not, the shortfall is small and named —
fbm_terrain@k=279 greedy_ratio 0.979824 (f_greedy 1.724960e3 against f_optimal 1.760480e3),
fbm_terrain@k=139 0.992255, fbm_terrain@k=69 0.999922, capped_gyroid@k=331 0.997331,
capped_gyroid@k=165 0.998927. The two columns disagree on two rows and the boolean is the one to
read: sphere@k=57 and capped_gyroid@k=82 both print greedy_ratio 1.000000 with
greedy_is_optimal false, because the boolean is computed on the raw f64 (g_ratio >= 1.0,
benches/experiment_p166.rs:2085) while the column is formatted to six decimals. A ratio printed as
1.000000 in this file is therefore not by itself a proof of optimality; greedy_is_optimal is.
Every one of those shortfalls still clears 1 − 1/e: ratio_meets_nwf_bound is true on 21 of the
22 rows that carry it, the exception being the synthetic control. So the guarantee's hypotheses fail
on two of three fields and its conclusion holds anyway on every measured budget — which is the honest
shape of this result, and the reason bound_applies and ratio_meets_nwf_bound are two columns rather
than one.
fbm_terrain fails a second hypothesis outright: monotone reads false on its six c2_budget rows,
where sphere and capped_gyroid read true. normalized is true everywhere, by construction —
geometric(c, 0) = 0 exactly, level 0 being the fine grid.
The SHARE is not zero and the file carries the number. The registration's SHARE is "C2 governs the
LOD selection stage, whose amortised cost M-124 tracks to within one chunk." M-124/M-125 fix the
denominator in time — the queue lands within one chunk, ≈0.072 ms, of its budget. What C2 governs is
which chunks the budget is spent on, so the share is a fraction of error at fixed cost:
share_over_distance_order = (f_greedy − f_distance_order) / f_optimal, measured by running the
distance-only ordering a streamer's load radius already implies over the same ladders. It peaks at
0.720925 on fbm_terrain@k=1, 0.561316 on capped_gyroid@k=41 and 0.554600 on
sphere@k=28, and is 0.000000 at every field's full budget, where every ordering ends in the same
place. Ordering refinements by marginal gain instead of by distance is worth up to 72% of the most any
budget of that size could buy — distance_order_ratio bottoming out at 0.279075 — and that is the
number the SHARE sentence should be quoted from, not a fraction of a frame.
What a consumer of this crate should do differently. For meshing, nothing, and now with the
structural reason: no matroid guarantee is available for GreedyQuads and none is needed, because
greedy_ratio 1.000000 on all six rows here and R-165's 1.120% whole-sweep gap say greedy is
already at or beside the minimum. Any future claim of an approximation guarantee for the merge must
cite the submodular set-covering line and not Theorem 4.2, whose hypotheses this row measures as failing
twice. For LOD budgeting, do not rely on diminishing returns for a field with structure near 8h:
on capped_gyroid and fbm_terrain a refinement's marginal gain can be up to 4.66× the previous
one, so the (1 − 1/e) bound is not licensed even though greedy happened to clear it on every budget
measured — and a random-pair submodularity check will not tell you, having missed 92 violating chunks in
this very file. Two named simplifications remain, stated rather than hidden: each level-0 chunk picks
its own level independently (a real quadtree cut would force eight siblings to share one), and the
value residual is divided by a measured local Lipschitz constant, which is "the standard proxy and is
not a certified Hausdorff bound" — inert for C2, since a per-chunk positive constant cannot move the
sign of a second difference, and load-bearing only for greedy_ratio.
💥 ✗122 / M-480 — C1 HELD on 20 of 20 rows with the per-bit decomposition measured to recompose rather than assumed, C2 HELD on 5 rows and FALSIFIED on 15, and C3 FALSIFIED on 20 of 20 at eval_ms_ratio 953.694027 on the dense bits and 4.606356–4.736385 on the single-term ones: the two informative bits of the shipped table are dense — spectral_terms 256 of 256, spectral_concentration 0.243408203 and 0.428710938 against a 0.9 bar — while its twelve edge bits are each one degree-2 coefficient, and the registration's own guess about C3 was right, a 256-entry table is already in L1 (P-167, R-167)
M. cargo bench --bench experiment_p167, docs/experiments/p-167.csv, 20 rows across 52
columns — four # comment lines plus one column header plus 20 data rows, counted from the file
rather than from the brief. # commit 186246e on amd-ryzen-9-5900x-12-core at 2026-08-30T09:28:04Z,
with no (WORKING TREE DIRTY) on that line. One row per (reading, output bit) over the three readings
common::boolean exposes of pub static CASES: [McCase; 256]
(crates/isomesh/src/marching_cubes/table.rs:180, whose corner_inside is literally
case & (1 << corner) != 0): triangle_counts.bit0–.bit3, edge_masks.bit0–.bit12,
centroid_counts.bit0, plus the two is_control = true rows calibration.parity and
calibration.majority. Timing is std::time::Instant over workload_evaluations 1,048,576 case
indices from workload_seed 0x2545f4914f6cdd1d, timed_repeats 7, the two paths interleaved;
eval_scatter_table 1.004586–1.028855 and eval_scatter_spectral 1.000859–1.069213 say the
repeats agreed, so M-280's amd-pstate-epp swing is not hiding inside the ratio.
| clause | registered | measured |
|---|---|---|
| C1 the Walsh–Hadamard spectrum of the table is computed and its weight distribution by degree reported | Parseval, per-bit truth table reproduced, the reading's integer recomposed | HELD on 20 of 20. weight_sum 1.000000000000 on every row, bit_reconstruction_exact and reading_reconstruction_exact true on every row. C1's registered falsifier was the transform not being well defined for a vector-valued output; the answer is the output_bit column, and the claim that the per-bit family is the vector-valued function is a measurement, not a framing choice |
C2 the spectrum is not concentrated on low degrees, with anf_terms reported so the negative is quantitative |
spectral_concentration (weight at or below degree 2) below WEIGHT_TARGET 0.9 |
HELD on 5, FALSIFIED on 15. True on triangle_counts.bit0/.bit1/.bit2 and on both calibration rows; false on the thirteen edge_masks bits, on triangle_counts.bit3 and on centroid_counts.bit0. Three of the fifteen carry is_degenerate = true (the constants), so the substantive falsification is the twelve edge-mask bits, whose spectrum was known in closed form before it was computed |
| C3 if C2 is falsified and the spectrum is sparse, a branchless spectral evaluation is benchmarked against the table lookup | c3_holds = eval_ms_spectral <= eval_ms_table |
FALSIFIED on 20 of 20. c3_reachable (concentrated && sparse) is true on exactly the 15 rows C2 failed on, and the spectral path loses on every one of them at 4.606356–4.736385; on the three dense rows it loses at 953.694027, 944.158838 and 953.050146. branchless_feasible is false on 20 of 20 |
The 15 rows that falsify C2 are the calibration arriving, not a surprise about the triangulation decisions. An edge bit is
x_a xor x_b, the two-corner parity of that edge's own endpoints, so its spectrum is one coefficient at degree 2 and nothing else, and that is exactly what the file says:fourier_weight_by_degreeis0|0|1|0|0|0|0|0|0on all twelve ofedge_masks.bit0–.bit11, withmax_degree2,anf_terms2,anf_degree1,spectral_terms1 andspectral_concentration1.000000000 on every one of them. Three more rows are constants —triangle_counts.bit3(truth_table_ones0, because the maximum triangle count is 5 and bit 3 is never set) andedge_masks.bit12andcentroid_counts.bit0(both 0, twelve edges and an all-separate table that never needs an interior vertex) — and a constant's concentration is 1 by arithmetic. On the primary reading, which is the reading to quote, C2 held on every non-degenerate bit.degree_for_90pct_weightis 6 forbit1and 8 forbit2, so there is no low-degree approximation at any threshold, not merely at 0.9.Four vacuity controls, and each one could have come out the other way. (1) The instrument, on two functions with known spectra.
calibration_parity_weight_degree81.000000000000,calibration_majority_weight_degree10.598144531250 andcalibration_majority_total_influence2.187500000000 — that iscommon::boolean::self_check()'s(1.0, 0.59814453125, 2.1875), asserted against1,8·(70/256)²and8·35/128computed in the harness rather than against transcribed decimals. A transform that could not tell a degree-8 function from a degree-1-heavy one would report a plausible spectrum for both. (2) The separation is visible in the file, not only in an assert:calibration.parityreadsspectral_concentration0.000000000 andcalibration.majority0.715637207, a gap of 0.7156 against a requiredCALIBRATION_SEPARATIONof 0.5. (3)sparseis a measurement and not a constant column (M-44):control_sparse_rows17 andcontrol_dense_rows3. (4) The primary reading is non-constant, or C2's concentration would be computed against a fixture that cannot falsify it —truth_table_ones128 / 130 / 108 / 0 on the fourtriangle_countsbits.
The low bit of the shipped triangle count is exactly the parity of the eight corner signs, and that
is the sharpest thing in the file. triangle_counts.bit0 reads role parity,
fourier_weight_by_degree 0|0|0|0|0|0|0|0|1 — all of the unit mass at degree 8 —
spectral_terms 1, anf_terms 8, anf_degree 1, total_influence 8.000000000 and
influence_by_corner 1.0 on all eight corners, byte for byte the same row calibration.parity
produces. So the shipped table emits an odd number of triangles exactly when an odd number of corners
is inside, and flipping any corner changes that parity: the property is maximally high-degree and
maximally symmetric at the same time.
sparse and low-degree are different properties, and this is the row where they separate.
Parity has one non-negligible Fourier coefficient and it sits at degree 8, so it is sparse = true
with concentrated = false and spectral_concentration = 0; the edge bits are sparse and
concentrated; bit1 and bit2 are neither. The registration asked for the ANF count so the negative
would be quantitative, and it is: anf_terms 34 at anf_degree 4 for bit1 and 100 at
anf_degree 7 for bit2, against 8 at degree 1 for parity and 2 at degree 1 for an edge
bit. Note that ANF degree and Fourier degree are different numbers — an edge bit is ANF degree 1 and
Fourier degree 2 — which is why both are columns.
C3 lost by three orders of magnitude and the SHARE it discharges is negative at every density the
spectrum could have had. eval_ms_table is 0.235581–0.238111 ms for 2²⁰ evaluations on all
twenty rows — the table is in L1 and the row measures it rather than assuming it — while
eval_ms_spectral is 224.711294 ms on bit1, 224.814605 on bit2 and 224.797844 on
calibration.majority, and 1.087708–1.116328 ms on the seventeen single-term rows. Carried
through P-121's measured classification share for marching_cubes at 65³ (s between 0.018 and
0.646), a replacement k× slower makes extraction 1 − s + k·s: at k = 953.694027 that is
18.15× to 616.44× slower extraction, and even the single-coefficient best case at k = 4.736385
is 1.07× to 3.41× slower. The direction agrees with V-12's independently measured 2.8–3.4× loss
for moving classification to irregular GPU dispatch, which is worth noting precisely because the two
arrive at it from unrelated evidence. Nothing moves: a caller should keep the lookup.
One disagreement to record, and it is a citation rather than a measurement.
experiment_p168.rs's own header quotes this row as "the branchless spectral evaluation loses to the
lookup by 886× on the dense bits". The committed p-167.csv says 953.694027 on bit1,
944.158838 on bit2 and 953.050146 on calibration.majority, from the run stamped
186246e; 886 is a superseded first-run figure and the CSV is authoritative. The verdict is
unaffected — both figures falsify C3 in the same direction by the same three orders of magnitude — but
P-168's header should be read as prose about a run that is not the one in the file.
Nothing in crates/isomesh/src/** changed and nothing should. The whole mechanism is
benches/common/boolean.rs, which this ticket owns and R-168 and R-169 consume unchanged, and no
golden hash moved. What a consumer gets from this row is a negative to stop re-deriving:
validate_table() (marching_cubes/mod.rs:836) audits the table combinatorially, P-116 asked about
patterns, P-121 asked what classification costs, and this row asks what the function is — the
answer is a dense, high-degree Boolean function whose cheapest evaluation is the 256-entry table
already in the binary.
🧊 M-481 — the registered null came back registered: C1 HELD on 240 of 240 with closed_form_max_gap 0.000000000000000 and stability computable a second way to 6e-15, and C2 — "the prediction is tested against the wrong noise model on purpose, and said so" — held on 55 rows, c2_rows_disagreeing 55 of c2_rows_counted 88; the genuine artefact at ulp_perturbation 1 flips 0 corner signs on all eight fields so the whole comparison lives on amplified error, and where the model does agree it agrees for a nameable reason — measured_response_per_corner_flip 8.000000000 against total_influence 8.0 on the parity bit and 2.000000000 against 2.0 on an edge bit — while at the saturating end it over-predicts by 43.9× (response_ratio 0.022795687) (P-168, R-168)
M. cargo bench --bench experiment_p168, docs/experiments/p-168.csv, 240 rows across 55
columns — four # comment lines plus one column header plus 240 data rows, counted from the file.
# commit c96119a on amd-ryzen-9-5900x-12-core at 2026-08-30T14:21:01Z, no (WORKING TREE DIRTY).
One row per (output bit, reference field, k): 5 × 8 × 6, at resolution 65, cells 262,144,
corner_slots 2,097,152. The five bits are P-167's — triangle_counts.bit0–.bit3 and
edge_masks.bit0 — and three of them are controls with a closed-form stability the harness computes
independently: closed_form reads rho^8 on parity, rho^2 on the edge bit, rho^0 on the constant
and none on the two informative bits. This is a registered null and it returned as registered,
which is why it carries no ✗: C2's registered expectation was disagreement, and disagreement is
what the file contains.
| clause | registered | measured |
|---|---|---|
C1 noise stability is computed for the case table and its predicted case-flip rate at a given rho is stated |
Stab_rho = sum_S rho^\|S\| fhat(S)^2, and predicted_flip_rate = (1 - Stab_rho)/2 |
HELD on 240 of 240. rho_grid 0.99\|0.95\|0.90\|0.80\|0.50\|0.20\|0.00 with stability_at_rho_grid and predicted_at_rho_grid on every row, so the a-priori curve is stated independently of what the measurement did. closed_form_max_gap 0.000000000000000 and stability_gap_vs_combinatorial at most 0.000000000000006 — the spectral sum against an exact recomputation over all 65,536 input pairs that contains no transform at all, which is C1's falsifier answered rather than assumed |
| C2 the predicted and measured flip rates are expected to disagree, and the size of the disagreement measures how far the independent-noise model is from this crate's reality | relative gap agreement above agreement_relative_bar 0.25 |
HELD on 55 of 240 rows, which is 55 of the 88 where either rate is non-zero (c2_rows_counted 88, c2_rows_disagreeing 55). The other 152 rows have measured_flip_rate_f32 and predicted_flip_rate both identically 0 and are outside the population, not agreements. Of the 88 measurable rows 33 agreed, and the agreement is structural rather than lucky — see below |
agreementis a gap, not a score, and the column name is the one trap in this file. It is the relative distance betweenpredicted_flip_rateandmeasured_flip_rate_f32; C2 holds when it exceedsagreement_relative_bar0.25, and that rule reproducesc2_holdson 88 of 88 measurable rows exactly. It runs from 0.000015259 (csg_difference,k= 10⁴,edge_masks.bit0) to 1.000000000 (csg_difference,k= 10⁴,triangle_counts.bit2, where the model predicts 0.0000534026 flips and the measurement produced exactly none).Seven vacuity controls fired, and the first two are the registration's own. (1) The measured flip rate must be non-zero at some perturbation magnitude:
vacuity_max_measured_flip_rate0.424926757812, onnoise_cavityatk= 10⁷. (2) And so must the per-corner rate, orrhois identically 1 and C2 compares two zeros:noise_ratereaches 0.239023208618,rhofalls to 0.521953582764. (3) Thef32error field must be non-zero on every field, orksweeps nothing:err_nonzero_pointsis 128,456–274,625 and the upper figure is 65³ exactly, so ontorusandfbm_terrainevery single grid sample differs between the precisions. (4) The grid points must be the same real points at both precisions:grid_point_cast_exacttrue on all 240 rows, so the measured error is evaluation precision and not a relocated sample. (5) Rounding the value cannot flip its sign, measured rather than asserted:f32_roundtrip_sign_flips0 on all 240 rows — a sweep over ULP-multiples of the result would have been eight orders of magnitude of exactly zero, which is the vacuous comparison the registration forbids. (6) The cells must not be uniformly empty:empty_case_share0.891757965–0.992187500, non-trivially below 1 on all eight fields. (7)common::boolean::self_check()against1,8·(70/256)²and8·35/128computed in the harness, matchingP-167's control —1.000000000000,0.598144531250,2.187500000000.
The genuine artefact moves nothing, and that is the row's first result. ulp_perturbation 1
is the value a caller running the crate at f32 actually receives, and at k = 1 corner_sign_flips
is 0 and topology_changes is 0 on all eight fields; the same is true at k = 100. Two of
the six magnitudes in the sweep are therefore entirely inert, and noise_rate is 0.000000000000
with rho 1.000000000000 on 130 of the 240 rows — 26 of the 48 (field, k) pairs. Those 130
plus the 22 triangle_counts.bit3 rows whose constant output can never flip are exactly the 152
rows carrying is_degenerate = true, which is the complement of C2's population of 88.
The error itself is everywhere —
perturbation_max_abs at k = 1 is 5.898564281459e-8 to 1.726317120143e-6 and
err_nonzero_points is in the hundreds of thousands — it simply never reaches a sign, because a flip
needs k·|e| > |v| and err_min_abs_value_where_nonzero is 1.497041141080e-6 at the smallest.
So every non-vacuous row in this file is a row about amplified error, and the k > 1 arms are
amplifications of the real error field's shape rather than a noise model of their own. The sweep first
bites at k = 10⁴ and then on only four of eight fields (torus 128 flips, csg_difference 32,
fbm_terrain 196, noise_cavity 704); gyroid joins at 10⁵, sphere at 10⁶ and thin_plate only
at 10⁷, and box_exact never joins at all.
box_exact is immune to the entire sweep and that is a measurement, not a gap.
corner_sign_flips 0 at every k up to 10⁷, where perturbation_max_abs is already
5.898564281459e-1. Its err_nonzero_points is 128,456 — the lowest of the eight, under half
of 274,625 — and its err_min_abs_value_where_nonzero is 8.838834764832e-2, the largest of the
eight by three orders of magnitude. So where an exact polyhedral distance on a dyadic grid differs
between the precisions at all, it differs where the field is far from zero; near its own faces both
precisions return the same bits and k·e is exactly zero however large k gets.
Where the model agrees, it agrees because the response is measure-independent — and that is the
finding, not an exception to it. Seven of the 88 measurable rows land inside a relative gap of
1e-3, and every one of them is either the parity bit or the edge bit in the single-flip regime:
torus at k = 10⁴ reads measured_response_per_corner_flip 8.000000000 against
total_influence 8.0 with a gap of 0.000427142, and the five edge_masks.bit0 rows read
2.000000000 against 2.0 with gaps of 0.000015259–0.000335693. The first-order model is
predicted_flip_rate ≈ eps · I(f), so a function whose per-case response is constant — a xor of
corner signs — is predicted exactly no matter how the cases are distributed. The two informative bits
have a per-case response that varies, and they disagree at the very smallest non-zero perturbation:
at torus, k = 10⁴, bit1 measures 3.000000000 flips per corner flip against an influence of
4.0 and bit2 measures 1.000000000 against 3.5. The disagreement is present before any
saturation and it is the case measure, not the correlation.
Both causes are separated in the file, and neither correction rescues the model. Distribution:
predicted_flip_rate_case_weighted re-runs the same independent-flip model with the input drawn from
the field's measured case histogram instead of uniformly over 256 cases. It reduces the gap on 12
of the 88 measurable rows, enlarges it on 31 and leaves 45 unchanged (the rows whose response
is measure-independent), and the mean relative gap rises from 0.419829 to 0.503282 — so
removing the distributional mismatch does not leave a working model behind it. Amplitude:
eps_needed_for_measured inverts the model curve and eps_needed_ratio reports it against the
measured per-corner rate. It spans 0.023010 to 1.020505 over the 88 rows, so at the saturating end
independent noise needs only 2.3% of the flip rate correlated rounding actually delivered to
predict the same output flip rate — the linear model over-predicts by 43.5× there. response_ratio
tells the same story from the other side, 0.022795687 to 1.020408163, and it falls sharply as
noise_rate rises — gyroid on parity reads 0.956766917 at k = 10⁵, 0.344280122 at 10⁶ and
0.232160875 at 10⁷ — though not monotonically on every series: 6 of the 30 (field, bit) series
with at least two non-zero-noise points carry a local rise, so the saturation is a trend and not a law.
model_saturated is false on all 240 rows, so none of this is the instrument running out of range.
What a consumer should do differently: nothing, and the number to stop reaching for is noise
stability. The registered SHARE was none and the arithmetic is the discharge. The independent-flip
prediction is eps · I(f) with I = 4.0 on the bit that matters, and the eps the f32 path
actually delivers on a 65³ grid is 0 on all eight reference fields. A robustness number whose input
is measured at zero where the artefact lives, and which over-predicts by up to 43.5× where it is
non-zero, cannot carry a precision decision or a refinement heuristic. f32 rounding in this crate is
a deterministic, spatially correlated perturbation, exactly as the registration said before any number
existed, and the size of the gap is now on the record instead of being assumed. Nothing in
crates/isomesh/src/** changed: common::boolean is R-167's module, consumed unchanged.
💥 ✗123 / M-482 — C1 HELD in the strongest reading the clause can have, because symmetry_class_count is 1: all eight corners are a single orbit of the 48-element cube group, so "equal within each octahedral symmetry class" means all eight equal, and influence_spread is 0.000000000 on every bit of triangle_counts with octahedral_violations 0 over 12,288 (π, x) pairs; C2 FALSIFIED on 200 of 200 at refinement_priority_correlation exactly 0.000000 against an informative_correlation bar of 0.50 — C1 holding is C2 failing — and the corrupted-table control detects 2 of 4 planted corruptions by inequality while all four show influence_shift_abs 0.007812500 = 2/256, which is exactly how much of validate_table() this cheap check can and cannot replace (P-169, R-169)
M. cargo bench --bench experiment_p169, docs/experiments/p-169.csv, 200 rows across 45
columns — four # comment lines plus one column header plus 200 data rows, counted from the file.
# commit b12f121 on amd-ryzen-9-5900x-12-core at 2026-08-30T14:21:06Z, no (WORKING TREE DIRTY).
Twenty-five arms at eight rows each, one row per corner, so corner_index is the row key and every
per-corner column is a real per-row value: the four triangle_counts bits plus their aggregate, the
thirteen edge_masks bits plus their aggregate, centroid_counts.bit0 and its aggregate, and four
is_control = true corruption arms. No clock is read — the registration names no ratio on time, so
every column is an exact rational or an integer count, and there is no timing column in the file at
all. The field scans are the crate's own deterministic grids at 33³ and 65³ over all eight reference
fields: scanned_cells 2,359,296 with scanned_cut_cells 99,932.
| clause | registered | measured |
|---|---|---|
C1 all eight corner influences are computed and are equal within each octahedral symmetry class, making this a cheap independent check on validate_table() |
equality, on the primary reading's non-degenerate bits plus its aggregate | HELD. c1_holds true on 200 of 200. influence is 1.000000000 / 0.500000000 / 0.437500000 / 0.000000000 on triangle_counts.bit0–.bit3 and 1.937500000 on the aggregate, identical on all eight corners of each, with influence_spread 0.000000000 and total_influence 8.0 / 4.0 / 3.5 / 0.0 / 15.5. influence_agrees_combinatorial true on 200 of 200 — two independent computations of the same rational number |
| C2 total influence is reported and compared against the average sensitivity a refinement heuristic would need | \|refinement_priority_correlation\| >= 0.50 on the primary reading |
FALSIFIED on 200 of 200, in both of the two ways the number could have been useful. refinement_priority_correlation is 0.000000 on every primary arm, and separately the uniform-measure figure is the wrong magnitude: empirical_total_influence is 0.141688453 against 4.0 on bit1 and 0.076633453 against 3.5 on bit2, uniform_minus_empirical 3.858311547 and 3.423366547 |
The zero in C2 is exact and it is a consequence of C1, not noise.
common::beta::rank_correlationreturns0.0when either sample has no rank variance (beta.rs:854-874, a zero denominator). C1 holding means the primary reading's eight influences are equal, so that sample has no rank variance and the Spearman correlation against any priority vector whatsoever is exactly zero. The table's octahedral correctness is precisely what makes per-corner influence useless as a refinement signal. The priority side is controlled so the zero is attributable to the influence side and nothing else:refinement_priority_distinct8 against a required 3,control_correlation_self1.000000000 andcontrol_correlation_negated−1.000000000 through the same function, and the same correlation is measurably non-zero on the twelve labelled edge bits — ±0.125988, ±0.251976, ±0.503953, ±0.629941, ±0.755929 — so the instrument can produce a number and twelve arms of this run prove it.The corrupted-table control is the row's most useful negative, and it detects half of what it was built for.
common::boolean::corruptflips one case entry. Oncorrupt.bit1@case37(control_delta2) andcorrupt.bit2@case7(control_delta4) the eight influences split — 0.507812500 / 0.492187500 and 0.445312500 / 0.429687500,influence_spread0.015625000 on both — andcontrol_detectedis true. Oncorrupt.bit0@case37(control_delta1) andcorrupt.bit3@case37(control_delta8) the corruption lands and moves every corner by the same amount — all eight to 0.992187500 and all eight to 0.007812500,influence_spread0.000000000 — andcontrol_detectedis false. The blind spot is a property of the sign pattern, not of the corruption failing to apply, and that distinction is measured rather than argued:influence_shift_absis0.007812500= 2/256 on every corner of all four control arms, because a single-case flip touches exactly the pair(x₀, x₀ xor e_i)for eachi. Bit 0 is parity, so every neighbour always differed and all eight influences fall together; bit 3 is the constant zero, so none ever differed and all eight rise together. Without that column, "still equal" could have meant "corruptdid nothing".Six more vacuity controls. (1) The primary reading is octahedrally invariant:
octahedral_violations0 over all 48 × 256 = 12,288 (relabelling, input) pairs, without which an unequal influence would localise nothing and C1 would be a coincidence rather than a check. (2) The primary reading is non-degenerate —is_degeneratefalse onbit0–bit2and the aggregate — so C1's equality is not an equality of zeros (M-44). (3)influence_equal_within_classcan come out both ways over the census: true on the primary reading and its aggregates, false on 112 of 200 rows — the 96 rows ofedge_masks.bit0–.bit11plus the 16 rows of the two detected corruption arms. (4) The edge-mask aggregate reproduces a closed form through the same instrument: 3.000000000 on all eight corners fortotal_influence24.000000000 = 2 × 12 edges = 8 ×CUBE_VERTEX_DEGREE3. (5) Every scanned grid contains a cut cell,scanned_cut_cells99,932. (6) The per-bit totals reproducep-167.csv's committed 8.0 / 4.0 / 3.5 / 0.0 exactly — two Phase 27 CSVs measure the same quantity through the same module and agreeing was not optional.
c1_holds is true on rows whose own influence_equal_within_class is false, and that is correct
rather than a bookkeeping error. The 96 edge_masks.bit0–.bit11 rows read
influence_equal_within_class false with influence_spread 1.000000000 and an
influence_by_corner that is 1 on two named corners and 0 on the other six. C1's verdict is a
global one taken over the primary reading's non-degenerate bit arms plus its aggregate, so those
rows carry the per-arm equality as data and do not vote. The edge-mask inequality is not a table
defect, and reading C1 against it would have been a false positive. A cube symmetry π relabels corner
signs and maps edges to edges, so mask(x') = σ(mask(x)): the mask is equivariant, the group acts on
the twelve edge labels, and a single edge bit is x_a xor x_b attached to two named corners — its
influence vector is 1, 1, 0, 0, 0, 0, 0, 0 up to relabelling under any measure. Only the multiset
over bits is invariant. Both halves are measured, using common::poly::octahedral_relabellings() as an
independently generated copy of the same group: edge_mask_labelled_violations is 10,944 of 12,288
(89.06%) while edge_mask_equivariant_violations is 0 — the failure is exactly the edge
relabelling and nothing else — and the multiset statement holds at the level the group actually acts
on, the edge_masks.aggregate arm's 3.0 per corner.
The second half of C2's falsification is independent of the first and is the one a heuristic author
should read. Influence is defined under the uniform measure on {0,1}⁸; a refinement heuristic runs on
real cells, whose case histogram is dominated by the empty and full cases. empirical_influence
re-weights the same flip count by the measured histogram of all eight reference fields at both
resolutions, and empirical_agrees_with_uniform is true exactly on the measure-independent
functions — parity (8.000000000 both ways), every edge bit (2.000000000 both ways) and the
constants — and false on the two informative bits and the primary aggregate, the only arms C2 could
have used. The uniform figure overstates what a heuristic would actually see by 28.2× on bit1
(4.0 against 0.141688453), 45.7× on bit2 (3.5 against 0.076633453) and 1.89× on the aggregate
(15.5 against 8.218321906). So the quantity is doubly uninformative: it does not rank the corners, and
it is not even the right magnitude for the cells a caller has.
One result hiding in the control, which the harness's own header records as a first reading it had to
correct. The refinement priority is nearly corner-symmetric by construction — the same sample plays
all eight corner roles in the eight cells meeting it — and the residual looked like a boundary-layer
effect that would shrink like 1/N. It does not: the harness measures the spread as a share of the
vector's own mean at 1.52% at 33³ and 2.68% at 65³, growing, while the pooled
refinement_priority_spread in the file is 0.005782371 over per-corner priorities of
0.124649179–0.125371976 — 0.58% of the mean, the two grids' asymmetries partly cancelling. So the
near-degeneracy is a property of the eight fields rather than of the grid's edge, and a finer grid does
not buy a ranking.
What this is worth as a gate, exactly. The influence census is exhaustive over 256 cases × 8
corners — 2,048 table comparisons, no field evaluation, no clock — against validate_table()'s
combinatorial audit at crates/isomesh/src/marching_cubes/mod.rs:836, and it is a quantitative
question that audit never asks. What it would catch is a corruption that changes the flip relation
unevenly across corners, localised to a corner index; what it provably would not catch is a corruption
on a bit where every neighbour already differed or none ever did, which the two undetected control arms
demonstrate in the same run. So the honest recommendation is that it belongs beside
validate_table() and not instead of any part of it, and the influence_shift_abs column is the
piece with teeth — all four planted corruptions moved it by 2/256 while only two moved the equality.
Nothing in crates/isomesh/src/** changed, no golden hash moved, and the registered SHARE: none
stands: a passing check moves no stage, and its value is that it could have failed.
📖 V-51 / M-483 — C1, C2 and C3 all HELD on 8 of 8 rows with doi_verified true on every one, including the registered trap: 10.1137/0722019 resolves to T. Nanda, Differential Equations and the QR Algorithm, SIAM J. Numer. Anal. 22(2):310-321 — the article immediately preceding Allgower & Schmidt at 322-346, trap_gap 1 — and AS85's is_homeomorphism is false, it constructs a PL manifold along which ‖H(x)‖_∞ < ε under a full-rank hypothesis at the seed, so the file's only true is Boissonnat & Wintraecken 2020, thirty-five years later; the repository counts are re-taken every run and read descendant_citations_in_repo 21 and root_citations_in_repo 4, of which 0 survive removing the registration layer that introduced the name (P-170, R-170)
M. cargo bench --bench experiment_p170, docs/experiments/p-170.csv, 8 rows across 41
columns — four # comment lines plus one column header plus 8 data rows, counted from the file.
# commit d20dde1 on amd-ryzen-9-5900x-12-core at 2026-08-30T09:30:35Z, no (WORKING TREE DIRTY).
This is the phase's only desk-work row, and it is desk work because the gap is bibliographic
rather than numerical: it carries V-51 because its result is a reading of primary sources, and
M-483 because two of its columns are counts re-measured from the working tree on every run. Nothing
is timed. One row per source, two of them is_control = true.
| row | year | DOI | title, venue | claim_type |
is_homeomorphism |
|---|---|---|---|---|---|
allgower_schmidt_1984 |
1984 | 10.1007/978-3-642-45567-4_26 |
Piecewise Linear Approximation of Solution Manifolds for Nonlinear Systems of Equations, Lecture Notes in Econom. and Math. Systems 226, 339-347 | residual_bound |
false |
allgower_schmidt_1985 |
1985 | 10.1137/0722020 |
An Algorithm for Piecewise-Linear Approximation of an Implicitly Defined Manifold, SIAM J. Numer. Anal. 22(2), 322-346 | residual_bound |
false |
nanda_1985_trap (control) |
1985 | 10.1137/0722019 |
Differential Equations and the $QR$ Algorithm, SIAM J. Numer. Anal. 22(2), 310-321 | unrelated_work_trap |
false |
allgower_gnutzmann_1987 |
1987 | 10.1137/0724033 |
An Algorithm for Piecewise Linear Approximation of Implicitly Defined Two-Dimensional Surfaces, SIAM J. Numer. Anal. 24(2), 452-469 | residual_bound_2d_surfaces |
false |
lorensen_cline_1987 (control) |
1987 | 10.1145/37402.37422 |
Marching cubes: A high resolution 3D surface construction algorithm, SIGGRAPH Comput. Graph. 21(4), 163-169 | no_correctness_claim |
false |
dobkin_levy_thurston_wilks_1990 |
1990 | 10.1145/88560.88575 |
Contour tracing by piecewise linear approximations, ACM Trans. Graph. 9(4), 389-423 | robustness_and_loop_detection |
false |
allgower_georg_1990_ncm |
1990 | 10.1007/978-3-642-61257-2 |
Numerical Continuation Methods, Springer Series in Computational Mathematics 13 | manifoldness_under_strong_conditions |
false |
boissonnat_wintraecken_2020 |
2020 | 10.4230/LIPIcs.SoCG.2020.20 |
The Topological Correctness of PL-Approximations of Isomanifolds, LIPIcs (SoCG 2020) 164, 20:1-20:18 | isotopy |
true |
C1 held and the vacuity control is the whole point of the row: each DOI must be resolved and its title recorded in the finding, not merely quoted from this document.
doi_verifiedis true on 8 of 8, every row carries a non-emptytitleand a non-emptyresolved_via, and the eight titles are distinct — a copy-pasted title would have made the table look resolved while carrying one answer eight times. Precedence is arithmetic off theyearcolumn rather than prose: 1984 < 1985 < 1987, withpredates_marching_cubestrue on the three 1984/1985 rows. That column compares years, so Allgower & Gnutzmann's April 1987 reads false against Lorensen & Cline's August 1987; the four-month precedence is in the issue dates and not in this column, and the column should not be quoted for it.The trap is the row that makes the verification real, and it is computed rather than asserted.
trap_gap1: the two SIAM article numbers parse to integers differing by exactly one, on the same venue, volume, issue and year, with different titles —0722019is Nanda on isospectral flows and the symmetric eigenvalue problem, ending at page 321, and0722020is Allgower & Schmidt, beginning at page 322. A one-digit slip in the DOI returns a paper on the QR algorithm, and if it did not,doi_verifiedwould be measuring nothing. The trap already costs something in this repository:this_source_citations_in_reporeads 3 on the Nanda row, because the registration that named the trap put its DOI into the tree.Two more controls.
homeomorphism_column_is_not_constant— at least one rowtrueand at least onefalse, satisfied by 1 true and 7 false; eightfalserows would be a column that could not have been true, which is not a measurement (M-44). Andscanner_finds_the_named_file:marching_tetrahedra/table.rsis among the Kuhn matches and the descendant count is non-zero, both from the same walk that reports the root count, so a zero root count is not a scanner that finds nothing.
What could and could not be read in full, exactly. full_text_read is true on exactly one of
the eight rows — boissonnat_wintraecken_2020, whose evidence is
full_text_read_p20_1_to_20_18, open access at Dagstuhl. Everything else was read at abstract depth or
shallower, and the evidence column says which: six rows read abstract_verbatim_crossref;
allgower_schmidt_1984 reads title_and_venue_only_no_abstract_deposited, the weakest evidence in
the file, because no abstract was deposited for it at all; and allgower_georg_1990_ncm reads
boissonnat_wintraecken_socg_2020_p20_3_verbatim — its Theorem 15.4.1 is quoted at second hand,
through B&W's own text, and the row says so rather than implying a reading of the textbook. AS85
itself is paywalled and was not read: paper_download found no open-access PDF for
10.1137/0722020 and Crossref lists only an epubs.siam.org link marked for similarity checking, so
full_text_read is false on the row that carries C1 and C2, and the reading is of its abstract
plus two corroborating primary sources.
What AS85 actually proves, which is C2 and is the reason the precedence must be stated with its
limit. The row's hypothesis column reads "H: R^(N+K) -> R^N smooth; the seed x0 lies in H^-1(0)
and DH(x0) has full rank" and its guarantee reads "for any eps > 0 a PL manifold is constructed
along which ||H(x)||_inf < eps". That is a residual bound with a regularity condition at a single
point, claim_type residual_bound, and neither the title nor the abstract contains homeomorphic,
isotopic or topologically equivalent. The nearest thing the older line proves is on the
allgower_georg_1990_ncm row — Theorem 15.4.1, "the zero set of f_PL is a manifold — explicitly
without a homeomorphism with the zero set of f" — and the guarantee the crate actually leans on is
boissonnat_wintraecken_2020's Theorem 20, "the zero set of f_PL is a manifold isotopic to the zero
set of f; plus a Frechet bound", under "0 a regular value of f; longest edge D small enough at
bounded simplex thickness T". So: the technique is 1984/1985 and the topological guarantee is 2020,
and quoting the first as if it delivered the second is exactly the overclaim C2 exists to prevent.
One correction to the registration, which sharpens it rather than weakening it. The registration
attributes the "without a homeomorphism" quote to AS85. It is verbatim in Boissonnat & Wintraecken
and it is about the Allgower line, but B&W's [3] is Allgower & Georg's Numerical Continuation
Methods — and AS85 is not in B&W's bibliography at all. The quote is therefore a fact about the
textbook of the line, not about AS85, and it is recorded on the allgower_georg_1990_ncm row where it
belongs. AS85's own non-homeomorphism status rests on its own abstract, which is stronger evidence than
a third party's remark about a different paper. The registration is not amended
(crates/isomesh/src/experiment.rs:27-31 forbids it) and C2 is answered from two independent primary
sources with the attribution corrected.
C3 held: DLTW traces curves. Its guarantee column is "traces a curve without failing at high
curvature; accumulates essentially no round-off error; has a well-defined integer test for detecting a
loop" — claim_type robustness_and_loop_detection, no topological-correctness claim, and the object
is a curve rather than a surface. The descent into graphics is documented by the graphics paper itself:
cited_by_dltw is true on exactly one row of eight, allgower_schmidt_1985, whose full citation
appears in DLTW's own deposited reference list. That single boolean is the lineage evidence, and it is
in the metadata rather than inferred from a resemblance.
Two rows the registration did not name are in the table anyway, and both were found inside reference
lists of sources it did name. allgower_gnutzmann_1987 is the two-dimensional surface case —
which is the case Marching Cubes solves — and its Crossref reference R2 is 10.1137/0722020, so the
1985 → 1987 link is publisher-asserted rather than inferred. allgower_schmidt_1984 was found as
reference R3 of that 1987 paper and is three years before Lorensen & Cline, the earliest member
of the line this repository can name. Neither is a new clause: both are evidence for C1's existing
precedence clause. Neither is cited anywhere in the tree — this_source_citations_in_repo 0 on
both, as it is on allgower_georg_1990_ncm.
The two counts, and what corpus they are over. descendant_citations_in_repo 21 and
root_citations_in_repo 4 are raw file counts over one declared corpus — files_scanned 531,
every text-extension file under the workspace root minus build/VCS directories, minus
docs/experiments/ (generated output, including this bench's own CSV, so the measurement stays
idempotent) and minus experiment_p170.rs itself. They are global to the run and identical on all
eight rows. The needles are declared: plantinga for the descendant, allgower or
10.1137/0722020 for the root — and the pattern choice is justified by data rather than taste, because
bare schmidt also matches two files that say Gram-Schmidt and naive_schmidt_files records the
over-match at 6 against the root's 4. Two further cuts are reported because the registration's
preamble numbers turn out not to have been counted the same way:
| claim in the registration | raw | excl. phase-27 docs | excl. registration layer | *_reproduced |
|---|---|---|---|---|
| Plantinga–Vegter in 18 files | 21 | 20 | 17 | doc_claim_descendant_reproduced false |
| Freudenthal/Kuhn in 6 files | 12 | 10 | 8 | doc_claim_kuhn_reproduced false |
| the parent theory in none | 4 | 2 | 0 | doc_claim_root_reproduced true |
The descendant figure drifted exactly as the harness predicted it would, and the drift is the
measurement working. phase27_harnesses_in_corpus is 25 — half of Phase 27's fifty harnesses had
landed at d20dde1 — and some of them cite Plantinga–Vegter in their own headers, so the descendant
count rises as the phase proceeds. The harness header records 19 / 18 / 15 measured while authoring
over a 507-file corpus with none of the harnesses landed; the committed CSV reads 21 / 20 / 17 over
531 files, so the claim that was exact under cut A when it was written now reads false. No clause
depends on it: the descendant count's only job is to be non-zero, as the scanner's non-vacuity
witness, and drift can only strengthen that. The reading that carries the thesis — "cites the parent
theory in none" — is root_citations_excl_registration, and it is 0, because the only files in
the tree that name the root are FINDINGS.md, BACKLOG.md and experiment.rs: the registration layer
that introduced the name. The Freudenthal/Kuhn figure is wrong under every cut, off by at least two and
at most six, and narrowing the needle does not rescue it.
Nothing changes for a consumer of this crate, and that is the deliverable rather than a shortfall.
crates/isomesh/src/** is untouched, no golden hash moved, the registered SHARE was none — this is
a citation repair and a scope statement, and it is discharged as registered. What lands is the table
above and one sentence a reader of validate/isotopy.rs:3 should have: the crate's PL-approximation
technique has a 1984/1985 root that proves a residual bound under a regularity hypothesis, and the
topological guarantee the crate actually relies on dates from 2004 (Plantinga–Vegter) and 2020
(Boissonnat & Wintraecken), not from the root. P-171 is the row that then asks how often the
regularity hypothesis those theorems need actually fails.
💥 ✗124 / M-484 — C1 HELD with c1_fields_nonzero 6 of 8 and transversality failing measurably — box_exact reads non_transverse_fraction 0.191406250 / 0.094238281 / 0.046936035 over 784 / 3,088 / 12,304 cells, and every one of its 5,766 cut edges at 65³ places its vertex on a grid corner (edges_at_half_offset = cut_grid_edges = mesh_vertices, max_abs_edge_offset 0.500000000); C2 FALSIFIED on 24 of 24 — Jaccard 0.000000000 on gyroid and 0.054123711 → 0.007722008 on noise_cavity against a 0.10 bar, and unreachable on 18 rows where one of the two sets is empty; C3 HELD on all 6 rows where a defect exists at overlap_with_defects 0.661290323–0.750000000 and unreachable on the other 18 — and the shipped extractor's entire defect population on eight fields at 17/33/65 is degenerate triangles, with non_manifold_edges, non_manifold_vertices, self_intersecting_pairs and inconsistent_edges all 0 on 24 of 24 (P-171, R-171)
M. cargo bench --bench experiment_p171, docs/experiments/p-171.csv, 24 rows across 39
columns — four # comment lines plus one column header plus 24 data rows, counted from the file.
# commit 7220f51 on amd-ryzen-9-5900x-12-core at 2026-08-30T09:30:42Z, no (WORKING TREE DIRTY).
Eight reference fields × three grids at resolution 17 / 33 / 65, so cells 4,096 / 32,768 /
262,144 for 2,392,064 cells and 104,059 active cells over the census, wall_ms
0.448–144.692. The mesh is the default MarchingCubes mesh and crates/isomesh/src/** is
untouched.
| clause | registered | measured |
|---|---|---|
| C1 the non-transverse fraction is measured per field per resolution and is non-zero on at least two fields | c1_fields_nonzero >= 2 |
HELD on 24 of 24 at 6 of 8 fields: sphere 48 cells at every resolution, box_exact 784 / 3,088 / 12,304, csg_difference 716 / 2,774 / 10,964, thin_plate 128 / 256 / 512, gyroid 8, noise_cavity 216; zero on torus and fbm_terrain. regular_value_violations equals non_transverse_cells on 24 of 24 rows — every failure in this census is criterion (a), an exactly-attained isovalue, and none is criterion (b) |
| C2 the non-transverse cells overlap the ambiguous cells substantially, which would say the ambiguity problem and the transversality failure are the same problem seen twice | Jaccard >= C2_JACCARD_FLOOR 0.10 |
FALSIFIED on 24 of 24, and unreachable on 18 of them. c2_reachable (\|N\| > 0 && \|A\| > 0) is true only on the six gyroid and noise_cavity rows; there the Jaccard is 0.000000000 on all three gyroid rows (non_transverse_and_ambiguous 0 against ambiguous_cells 52 / 27 / 132) and 0.054123711 / 0.018439716 / 0.007722008 on noise_cavity (21 / 13 / 6 cells). They are different populations |
| C3 they also overlap T-001's defect cells, or they do not, and which is stated | containment \|N ∩ D\| / \|D\|, reported |
HELD on 6 of 6 rows where D is non-empty, unreachable on the other 18. overlap_with_defects 0.750000000 on gyroid (3 of 4) at all three resolutions and 0.661290323 / 0.697368421 / 0.662337662 on noise_cavity (41 of 62, 53 of 76, 51 of 77). Two thirds of the shipped extractor's defect cells are non-transverse |
C2's and C3's
falseon 18 rows is unreachability and must not be read as refutation — here is the arithmetic. For C2,ambiguous_cellsis 0 on all three rows ofsphere,box_exact,csg_differenceandthin_plate(15 rows), andnon_transverse_cellsis 0 on all three rows oftorusandfbm_terrain(6 rows, one of which,fbm_terrain, does have 16 / 30 / 58 ambiguous cells) — 18 rows in which one of the two sets the Jaccard is taken over is empty. For C3,defect_cellsis 0 on 18 of 24 rows: the shipped extractor produces no defect at all onsphere,torus,box_exact,csg_difference,thin_plateorfbm_terrainat any of the three resolutions, so C3's containment has an empty denominator there and its zero could not have been non-zero (M-44).c3_reachableequalsc3_holdson 24 of 24 rows: wherever C3 could be asked, it held.P-70's C1 is the precedent for recording that as a result rather than as a pass.Three of C2's four zero-ambiguity fields are zero by geometry rather than by luck, and the fourth is a measurement the harness did not predict.
AMBIGUOUS_FACES[case] != 0(marching_cubes/table.rs:196-231) requires a cube face whose four corner signs alternate around the ring, i.e. the two inside corners are diagonal. A box's inside is a product of open intervals, so if a diagonal pair passes all four interval tests then so does the other pair — no alternating face exists, which coversbox_exactandthin_plate. For a ball, either diagonal pair of a square sums to2|c − O|² + 2m²from any point, so the two sums are equal and the alternation is impossible — which coverssphere.csg_differenceis not covered by either argument — the harness header names it,gyroid,fbm_terrainandnoise_cavityas the four fields on which C2 can be asked, twelve rows — and measured, itsambiguous_cellsis 0 on all three of its rows. That is the one place the file disagrees with its own harness's expectation. Withfbm_terrain's three rows failing on the other side (ambiguous cells but no non-transverse cell), C2's population is six rows rather than twelve.
ambiguous_liftis the right column to ask whether a small Jaccard means indifference, and on this fixture it can only be read on two rows. The column is|N ∩ A| · cells / (|N| · |A|), the observed overlap over what independence would give, and the denominator is what limits it here.gyroidreads 0.000000 on all three rows — but its expected overlap under independence is 8 × 52 / 4,096 = 0.102 cells at 17³ and 0.0040 cells at 65³, so a zero there is what chance predicts and says nothing about avoidance.noise_cavityreads 2.063328 / 3.928582 / 12.842642, and only its first two rows rest on an expectation worth dividing by: 21 observed against 216 × 193 / 4,096 = 10.18 expected at 17³, and 13 against 3.31 at 33³. The headline 12.842642 at 65³ is 6 cells against 0.47 expected — a large ratio on a small expectation, and it should be quoted as such. So the honest reading is that the two populations are genuinely different, with a real but modest enrichment on the one field where both are large — which is the difference between "no overlap" and "not substantial overlap", and it is why the lift rises while the Jaccard falls from 0.054123711 to 0.007722008:ambiguous_cellsgrows with the surface whilenon_transverse_cellsstays pinned at 216.Seven vacuity controls fired. (1)
box_exactis in the census, the registration's own named control, because its faces have exactly-equal samples; excluding it would have excluded the phenomenon. (2) Every resolution can land a sample on a box face:box_exactspans [−1, 1]³ inside [−2, 2]³ so its faces sit at sample index (n−1)/4 and 3(n−1)/4, and 17, 33, 65 give 16, 32, 64 — the arithmetic is asserted rather than the constants trusted, because at(n − 1) % 4 != 0the violation count would read zero by the choice of resolution. (3)box_exactreports a non-zero violation count at every resolution, 784 / 3,088 / 12,304 — the assert that would fire if the sign rule, the sampler or the exact comparison were wrong. (4) Something in the fixture is ambiguous,ambiguous_cellssumming to 1,577. (5) Every row has an active surface,active_cells128–28,375. (6) This bench's grid is the extractor's grid:mesh_verticesequalscut_grid_edgeson 24 of 24 rows, which plain Marching Cubes guarantees at one vertex per crossed grid edge (table.rs:128-131,x1 / M-2 / M-22'sV_mc = C) — a disagreement would have meant every number here was about a fixture the crate never saw. (7) The located degenerate triangles are the crate's own,degenerate_trianglesasserted equal toSelfIntersectionReport::degenerate_triangles.
box_exact is not merely the worst field, it is a field whose entire mesh sits on the 0-skeleton.
edges_at_half_offset reads 294 / 1,350 / 5,766 and cut_grid_edges and mesh_vertices read the
same three numbers, so every cut edge of box_exact at every resolution has |d| = 1/2 and places
its vertex exactly on a grid corner. edge_offset (cube.rs:216-225) returns d = ((a + b)/2)/(a − b),
a signed offset from the edge midpoint, so |d| = 1/2 is the maximal transversality failure against
the cell's 0-skeleton and d = 0 is maximally transverse; max_abs_edge_offset is 0.500000000 on
that field and exact_zero_samples is 386 / 1,538 / 6,146. Nowhere else is it total:
csg_difference reads 249 of 294, 1,167 of 1,386 and 5,031 of 6,012 (83.68% at 65³),
thin_plate 28 / 60 / 124 of 126 / 510 / 2,046, sphere 6 of 4,758, noise_cavity 56 / 61 /
65 of up to 28,882, gyroid 3 of 21,534. And the two fields that read zero read it with room to
spare rather than through a coarse instrument: torus's max_abs_edge_offset climbs
0.452010322 → 0.485094524 → 0.496493621 and fbm_terrain's reaches 0.499994012 without ever
attaining ½, which is what makes non_transverse_cells 0 on those six rows a measurement.
The scaling of exact_zero_samples across the three grids reads off the dimension of the set on
which each field exactly attains its isovalue, and that is the sharpest thing in the file. The grids
double, so a count that is constant means a 0-dimensional zero set, ×2 means 1-dimensional and ×4 means
2-dimensional:
- 0-dimensional —
sphere6 / 6 / 6 (the six axis poles),gyroid1 / 1 / 1,noise_cavity27 / 27 / 27.non_transverse_cellsis constant too (48 / 8 / 216, and sphere's 48 is exactly 6 × 8, one isolated zero touching eight cells), sonon_transverse_fractionfalls by exactly 8.0 per refinement — like 1/n³. - 1-dimensional —
thin_plate32 / 64 / 128, and its fraction falls by exactly 4.0 (0.031250000 → 0.007812500 → 0.001953125), like 1/n². - 2-dimensional —
box_exact386 / 1,538 / 6,146 andcsg_difference337 / 1,354 / 5,422, both ×4 to three digits, and their fractions fall by 2.0311 / 2.0078 and 2.0649 / 2.0241 — like 1/n, which is the only one of the three that matches the harness header's prediction for a numerator counting cells that touch a surface.
So the transversality failure is a face plane on the two box-derived fields, a line on the plate and a
handful of isolated points on the curved and procedural ones, and refining the grid one step buys a
factor of 8 on sphere and only a factor of 2 on box_exact — the field most likely to violate
transversality is also the field that refinement helps least.
Criterion (b) is inert on this fixture and the file says so in numbers rather than in silence.
non_transverse_gradient_cells is 0 on 24 of 24: no cell fails transversality through a vanishing
gradient. The arithmetic is gradient_norm_min against gradient_floor 1.000000e-6 —
gradient_norm_min is 1.000000e0 on six fields, above 1 on fbm_terrain
(1.000394e0 / 1.000078e0 / 1.000038e0) and lowest on noise_cavity, where it falls
9.221979e-1 → 3.345362e-1 → 1.787447e-1 with refinement. So gradient_margin spans
1.787447e5 to 1.000394e6: the closest any field comes to a critical point is still 178,744×
above the floor. That is a reported result and not a hidden guard — P-124 and x36 / M-351 are the
standing reason both columns exist — and a reader can re-threshold from gradient_norm_min without
re-running anything. noise_cavity is the only field whose minimum gradient norm is falling, and it
would need to fall another five orders of magnitude to make criterion (b) fire.
This is where the phase's defect-population fact belongs in full, and it is a clean bill of health for
the shipped extractor. On eight reference fields at 17, 33 and 65 samples, non_manifold_edges is
0, non_manifold_vertices is 0, self_intersecting_pairs is 0 and inconsistent_edges is
0 — on 24 of 24 rows, from the shipped validators rather than a re-derivation
(validate::validate_features at validate.rs:653 and validate::self_intersections at
validate/self_intersection.rs:153). The entire defect population is degenerate
triangles: defect_cells sums to 227 over the census, degenerate_triangles to 208 —
gyroid 4 + 4 + 4 and noise_cavity 54 + 68 + 74, and nothing on the other six fields —
with near_degenerate_triangles at 243 and defect_cells_dilated at 1,263. boundary_edges is
deliberately excluded from D, because validate.rs:605-607 states it is not a defect on an open field
and fbm_terrain is open; counting it would have made one field's whole surface a defect. So any
statement about this crate's Marching Cubes defect rate on these fields is a statement about zero-area
triangles and nothing else.
p-132.csv corroborates those zeros, and reading it requires knowing one thing about a registered
column name. R-132 ran the same two shipped validators over its own census of the same eight fields
at 17, 25 and 33, and experiment_p132.rs:308-325 records the result in as many words — "the shipped
Marching Cubes emits ZERO non-manifold edges, zero non-manifold vertices and zero self-intersecting
pairs on all eight reference fields at every resolution" — citing this row, and it therefore takes its
chi-square over the zero-area triangle set instead. But its committed nonmanifold_edges_in_orbit
column reads 326 / 1,936 / 0, which is not a count of non-manifold edges: the column carries that
orbit's defect-cell count (experiment_p132.rs:514, :526), summing to defect_cells_in_orbit
2,262, while self_intersections_in_orbit and orphaned_vertices_in_orbit hold the literal string
see column defect_cells. The registered record name could not be amended, so the two files agree on
the measurement and a reader taking that column at its name would conclude the exact opposite. The
2,262 is also not comparable with the 227 here: R-132 dilates every defect vertex to its full
2×2×2 neighbourhood and includes a resolution this census does not, which is what defect_cells_dilated
1,263 is the local analogue of.
C3 held for the reason the harness predicted before it ran, and the mechanism closes the loop back to
C1. A corner sample of exactly zero forces d = ±1/2 on every cut edge ending at that corner, so
all of those crossings are placed on the same point — the grid vertex itself — and a triangle holding
two of them has zero area. A degenerate triangle is therefore the mechanical consequence of a
regular-value violation, which is why it is the one defect C3 had a reason to expect, and the
containment is what that prediction looks like when measured: 154 of the 227 defect cells across the
census are non-transverse, 3 of 4 on gyroid and 41 / 53 / 51 of 62 / 76 / 77 on noise_cavity. The
dilated form is reported beside it as the check that the containment is not produced by counting a
neighbourhood as a defect: against defect_cells_dilated 20 on gyroid and 334 / 424 / 445 on
noise_cavity, overlap_with_defects_dilated reads 0.400000000 and 0.431137725 / 0.377358491 /
0.359550562 — lower rather than higher, so the 66–75% is a property of the tight defect set.
What a consumer should do differently, and the one thing that is actionable later. Nothing changes
in the extractor: the a - b denominator on a cut edge is strictly non-zero precisely because
is_inside(0.0) is false (cube.rs:157-173, after Lengyel), that choice removes the interpolation's
division guard entirely, and this row does not argue with it. What the row produces is a partition that
did not exist — which cells are inside the theory P-170's sources state and which are outside it —
and the observation that regular_value_violations is a property of the grid, not of the field. A
half-cell shift of the origin removes every exactly-equal corner sample on a lattice-aligned feature,
which is already recorded as the remedy for the thin plate at fields/mod.rs:614-616, where shifting by
half a cell removes the surface entirely. Whether the extractor should ever be told to do that is a
Phase 28 question and is not asked here. The registered SHARE was none and stands: no source change,
no nanosecond moved, no golden hash touched, and the only write is the CSV.
🧊 M-485 — the registered obstruction is real, is one dimension lower than the registration claimed, and does not stop Conley: plateau_fraction 0.500000 on box_exact at all three resolutions with constant_cells 0 on every row, yet conley_applicable_fraction never falls below 0.957031 — C1 HELD on 24 of 24, and C2's ranking came back reversed: c2_holds true on only 3 of 24 rows, all three fbm_terrain at saturated equality, which the harness predicted in advance as the one vacuous way C2 could hold (P-172, R-172)
M. cargo bench --bench experiment_p172, docs/experiments/p-172.csv, 24 rows across 28
columns — four # comment lines plus one column header plus 24 data rows, 29 lines in the file,
counted from it rather than from the brief. Nine of the 28 columns are the registered records and the
other 19 are M-273 extras. The shape, also counted from the file: eight reference fields × {17, 33,
65}, cells reading 4096 on 8 rows, 32768 on 8 and 262144 on 8, i.e. (n−1)³ exactly. Those
three resolutions are P-58 / R-056's own, and the harness says why in advance
(experiment_p172.rs:132-138): vs_discrete_morse_applicable then sits on the same grids as
p-58.csv's tie census and the two files read against each other without a rerun. Provenance line:
# commit 91a5e7b on amd-ryzen-9-5900x-12-core at 2026-08-30T09:30:46Z, with no (WORKING TREE DIRTY).
No source change: crates/isomesh/src/** is untouched by this row and both criteria are bench-local,
driven through the public API, so no golden hash moved and there is nothing to rebaseline.
| clause | registered | measured |
|---|---|---|
| C1 the plateau fraction is measured per field, quantifying the obstruction rather than asserting it; falsified by "negligible plateaus on every field" | some field over NEGLIGIBLE_PERCENT = 1% of its cells, scored as the integer comparison plateau_cells · 100 ≥ cells |
HELD — c1_holds true on 24 of 24 (it is a clause about the sweep, so the global verdict is stamped on every row). plateau_fraction 0.500000 on box_exact at 17/33/65 (plateau_cells 2,048 / 16,384 / 131,072), 0.465088 / 0.461243 / 0.460121 on csg_difference (1,905 / 15,114 / 120,618) and 0.250000 on thin_plate (1,024 / 8,192 / 65,536). row_plateau_is_negligible is false on 9 rows and true on 15, so the clause is carried by three fields and refused by five, which is the per-field shape the clause asked for rather than a sweep-wide average |
| C2 the fraction of cells admitting an isolating neighbourhood is reported and compared against the fraction where discrete Morse theory applies; falsified by "Conley applying more widely than discrete Morse, which would reverse the ranking" | conley_applicable_fraction ≤ vs_discrete_morse_applicable, scored as isolating_cells ≤ discrete_morse_applicable_cells (shared denominator, so exact integers) |
REVERSED — c2_holds true on 3 of 24, and the three are fbm_terrain at 17/33/65 where both fractions read 1.000000 and conley_minus_morse_fraction is exactly 0.000000. On the other 21 rows conley_minus_morse_fraction is strictly positive — 0.910156 / 0.895508 / 0.885986 on box_exact, 0.901367 / 0.875977 / 0.855946 on csg_difference, 0.812500 / 0.781250 / 0.765625 on thin_plate, down to 0.033142 on torus at 65³ — so Conley's requirement is the wider one everywhere it can be strictly compared. c2_global_holds is false on all 24 |
The three rows on which C2 holds are the three on which it could not fail, and that was written down before the run.
experiment_p172.rs:244-251names the case: "fbm_terrainis generic — a four-octave value-noise heightfield has no exactly-tied corner pair — so its discrete-Morse fraction is1by construction, and if its Conley fraction is1too then C2 holds there vacuously." The artefact agrees to the integer:p-58.csvreportsdistinct_values4,913 / 35,937 / 274,625 againstvoxels4,913 / 35,937 / 274,625 andtied_voxels0 onfbm_terrain, so every one of its cells has eight pairwise-distinct corners anddiscrete_morse_applicable_cellsmust equalcells. The column that separates a strict ranking from a saturated tie isconley_minus_morse_fraction, and it reads exactly0.000000on those three rows and nowhere else. So of the 21 rows where C2's ordering is decidable, it goes the wrong way on 21.Five vacuity controls, all assertions before the first
run.record, and every one of them reachable. (1) The registered control:box_exactmust reportplateau_cells > 0— 2,048 / 16,384 / 131,072, so the obstruction this row is built on exists in the fixture and the whole entry is not about an empty set. (2) The plateau criterion must be able to read zero:plateau_cellsis 0 on 15 rows (sphere,torus,gyroid,fbm_terrain,noise_cavity, all resolutions). Without it a criterion firing on every cell would also print0.500000onbox_exactand mean nothing —M-44read backwards. (3) The isolation test must be able to fail:conley_applicable_fraction < 1on 7 rows, minimum 0.957031. (4) And to pass:isolating_neighbourhood_existstrue on 17 rows, withisolating_cells == cellscompared as integers so no float equality decides it. (5) The discrete-Morse column must be non-trivial:vs_discrete_morse_applicableis> 0on all 24 and< 1on 21, spanning 0.046875 (box_exact17³, 192 of 4,096 cells) to 1.000000, so C2 is not a comparison against a constant.
The registration says ∇f = 0 on a set of positive measure, and measured that is true in two
dimensions and false in three. constant_faces — numerically constant cell faces — reads 4,128 /
32,832 / 262,272 on box_exact, 3,696 / 29,718 / 239,178 on csg_difference and 1,992 / 16,264
/ 130,824 on thin_plate. constant_cells, cells whose eight corners agree and on which the
interpolant is genuinely constant, reads 0 on every one of the 24 rows. The arithmetic is short and
the harness gives it (experiment_p172.rs:153-161): box_exact's analytic gradient has unit length
everywhere, so the field is nowhere locally constant in 3D and no cell can carry eight equal corners. A
plateau living on ∂Q rather than in int Q is if anything worse for Conley — ∂Q is exactly where
the theory forbids invariant behaviour — but it is not what the sentence said, and the row records the
correction rather than smoothing it.
A constant face is not automatically an obstruction, and thin_plate is the counterexample in the
file. It reports plateau_fraction 0.250000 at every resolution, plateau_and_isolating equal to
its whole plateau population (1,024 / 8,192 / 65,536), conley_applicable_fraction 1.000000 and
isolating_neighbourhood_exists true. The mechanism is the second of the boundary test's three
exhaustive cases (experiment_p172.rs:94-101): on a constant face every point is tangentially critical, so the face
carries a critical point unless the normal partial is strictly one-signed over it, and a bilinear's
range over [0,1]² is the range over its four corners, so the test is exact and needs no sampling.
thin_plate's plateaus are the slab's own faces, where the normal derivative never changes sign. What
actually kills the isolating neighbourhood is the medial axis, where the max in box_exact's
formula switches argmax — and the column that decides mechanism versus correlate is
boundary_critical_without_plateau, which reads 0 / 0 / 0 on box_exact: every non-isolating cell
there is a plateau cell (boundary_critical_cells 176 / 736 / 3,008, and plateau_cells −
plateau_and_isolating = 2,048 − 1,872 = 176 exactly). On csg_difference it reads 3 / 3 / 18,
and on noise_cavity at 65³ it reads 1 with plateau_cells 0 — a single cell in 262,144 whose
boundary carries ∇f = 0 with no flat face anywhere near it, which is case 1 of the test firing on its
own.
FLAT_REL does no work at all, and the file says so on every row. plateau_cells_exact — the same
scan with the tolerance replaced by f64::total_cmp equality — equals plateau_cells on 24 of 24
rows (2,048 = 2,048; 1,905 = 1,905; 120,618 = 120,618; and 0 = 0 on the fifteen clean rows). The ties in
this crate's fields are bit-exact, which is M-352 / P-53's finding arriving from a new direction.
The tolerance is still the right construction and its scaling is visible in
flat_absolute_tolerance: FLAT_REL · cell_size gives 2.500e-10 / 1.250e-10 / 6.250e-11 on the six
fields whose cell is 0.25 at 17³, 8.750e-10 / 4.375e-10 / 2.188e-10 on gyroid and 1.000e-9 /
5.000e-10 / 2.500e-10 on fbm_terrain. So the criterion is a dimensionless slope floor whose
absolute form halves with the cell at every rung, and it therefore means the same thing at 17³ and at
65³ — which a fixed absolute tolerance would not.
C2's verdict is decided by which denominator "discrete Morse theory applies" means, and the harness
fixed the choice before the run and carried the other reading as a column. The registered column takes
Algorithm 1's raw requirement — pairwise-distinct corner values under f64::total_cmp — because the
clause says "the fraction where discrete Morse theory, already registered, applies", and P-58's
chunk-local total order on (value, linear_index) is this repository's repair, not the paper's
hypothesis. Against that raw denominator Conley wins everywhere:
discrete_morse_applicable_cells is 192 of 4,096 on box_exact at 17³ against isolating_cells
3,920, and p-58.csv explains the 192 exactly — 36 distinct values among 4,913 voxels, against
sphere's 116 and torus's 325. Against the repaired denominator, which is 1 by construction
because a total order always exists, the ranking the registration predicted is the one that holds:
conley_minus_repaired_morse_fraction is strictly negative on exactly 7 rows — box_exact
−0.042969 / −0.022461 / −0.011475, csg_difference −0.041016 / −0.019226 / −0.010014,
noise_cavity 65³ −0.000004 — and exactly 0.000000 on the other 17. Both requirements fail on
this crate's data, and the difference that matters is that discrete Morse's failure is repairable by
relabelling and Conley's is not: one is a statement about labels, the other about the geometry of an
interpolant. That is the sentence this null exists to license.
What a consumer should do: nothing, and that is the point of the row. Conley index theory is not
proposed, not adopted and not needed; what the row produces is a quantified refusal. A future ticket
proposing it for ambiguity resolution now has to explain box_exact's 0.500000 plateau fraction and
the 176 / 736 / 3,008 cells with no isolating neighbourhood, rather than argue past them — and it
also has to explain why its own applicability fraction is wider than discrete Morse's, which is not the
direction the registration expected and is now on the record. ns_per_cell (26.170 on thin_plate
at 65³ to 80.968 on gyroid at 17³) is provenance and gates nothing: M-280 and M-348 are the
incidents, and a census is a count.
SHARE, recomputed. None, and it was registered as none. "None — this closes a candidate." Nothing
here proposes to move a stage, so there is no share to price and no 1/(1 − share/factor) ceiling to
check. Every scored column is an integer over a denominator fixed by construction — C1 is
plateau_cells · 100 ≥ cells and C2 is isolating_cells ≤ discrete_morse_applicable_cells — so this
host's governor cannot move a verdict and ✗51's bar has nothing to apply to.
Would be shown wrong by: a field on which constant_cells is non-zero, which would restore the
registration's positive-measure claim in three dimensions and would have to explain a locally constant
SDF; a corrected reading of the isolating-neighbourhood criterion that admits fewer cells than
P-58's raw distinctness test on box_exact, which would un-reverse C2 — the criterion here is the
exact four-value sign test on each face's bilinear over three exhaustive cases, so a disagreement would
be a bug in the case analysis and locatable; or a resolution at which plateau_cells_exact and
plateau_cells diverge, which would mean the ties stopped being bit-exact and would move M-352's
finding, not this one.
🔬 M-486 — the curl residual is free — worst curl_share 0.008061907, 0.81% of an extraction against a 2% ceiling, on 24 of 24 rows — and it does not predict M-60's second-vertex cells: of the nine rows with a reachable AUC only gyroid at 33³ clears 0.8 at 0.914640664, and fbm_terrain at 25³ reads 0.270443196, worse than chance — C1 HELD on 24 of 24, c2_holds true on 16 of 24 (15 of them control rows discharging their half), c3_holds true on 12 of 24 with the per-cell λ cutting noise_cavity's self-intersections from 388 to 195 at 33³ (P-173, R-173)
M. cargo bench --bench experiment_p173, docs/experiments/p-173.csv, 24 rows across 67
columns — four # comment lines plus one column header plus 24 data rows, 29 lines in the file,
counted from it rather than from the brief. Seventeen of the 67 columns are the registered records; the
other 50 are M-273 extras. The shape, counted from the file: eight reference fields × {17³, 25³,
33³}, cells (active cells, not grid cells) spanning 128 on thin_plate at 17³ to 6,176 on
noise_cavity at 33³, dc_vertices == cells on all 24 rows. Those three grids are M-60's own, so C2's
population is the population M-60 counted. # commit a8d381e on amd-ryzen-9-5900x-12-core at
2026-08-30T09:31:01Z, no (WORKING TREE DIRTY). No source change: the residual, the per-cell λ
map and the substitution driver are bench-local, and every solve they call is the shipped one, so no
golden hash moved.
| clause | registered | measured |
|---|---|---|
| C1 the curl residual costs under 2% of extraction; falsified by above 2% | curl_share = curl_ms / extract_ms < cost_ceiling 0.02 |
HELD on 24 of 24. Worst curl_share 0.008061907 (box_exact 17³), best 0.000988233 (fbm_terrain 33³) — a factor of 2.5 to 20 inside the ceiling, against whole-extraction wall clock, which is the largest honest denominator, so it is under 2% of any stage inside it. curl_ms 0.000670–0.033730 ms against extract_ms 0.100681–11.602284 ms, median of five repeats after a warm-up, curl_ms_min/_max beside them. c1_holds_global true, c1_rows_held 24 |
C2 it separates the cells M-60 says need a second vertex from those that do not — AUC above 0.8 — on gyroid and fbm_terrain; falsified by AUC below 0.8 |
separation_auc > auc_bar 0.8 on rows with positives; near-zero residual on the five zero-second-vertex fields |
SPLIT, and the substance is falsified. c2_holds true on 16 of 24, but 15 of those are the control rows discharging their half of the vacuity control (curl_residual_normalised < control_ceiling 0.25 on sphere, torus, box_exact, csg_difference, thin_plate, all three resolutions, where separation_auc reads unreachable and separation_auc_reachable is false). Of the 9 rows with a reachable AUC, one clears the bar: gyroid 33³ at 0.914640664. The other eight fail — gyroid 0.711415753 / 0.714855412 at 17³/25³, fbm_terrain 0.491883117 / 0.270443196 / 0.492674558, noise_cavity 0.581949666 / 0.583103052 / 0.599750463. c2_holds_global false, c2_rows_held 16 |
C3 a per-cell λ from the residual beats the global constant on QEF residual or sharpness without losing on self-intersections; falsified by the per-cell λ losing on either axis |
strict win on one axis, no loss on the other; every _delta is per-cell minus global |
SPLIT 12 / 12. c3_holds true on box_exact ×3, thin_plate ×3, gyroid 17³, fbm_terrain 17³ and 25³, noise_cavity ×3; false on sphere ×3, torus ×3, csg_difference ×3, gyroid 25³ and 33³, fbm_terrain 33³. c3_holds_global false, c3_rows_held 12 |
C2 fails for a reason the file names rather than leaves open, and it is not "the residual is noise".
mean_residual_second_vertexagainstmean_residual_single_vertexis the diagnostic. Ongyroidthe two populations separate and widen with resolution — 0.070368607 vs 0.041118375 at 17³, 0.080208327 vs 0.028474982 at 25³, 0.122768135 vs 0.020930493 at 33³, a 5.9× gap at the finest rung — which is exactly why its AUC climbs 0.711 → 0.715 → 0.915. Onfbm_terrainthe two populations have the same mean: 0.082913383 vs 0.082874595 at 17³ and 0.052583730 vs 0.052632743 at 33³, within 0.05% and 0.10% of each other, so the score carries no information about the label and the AUC sits at chance; at 25³ the positives are quieter than the negatives (0.046602577 vs 0.066714909) and the AUC falls to 0.270443196, i.e. the residual ranks them backwards.noise_cavityis in between — 0.155794063 vs 0.131437158 at 17³, a real but small gap, AUC 0.582. So inconsistency and multi-sheet-ness are the same phenomenon ongyroidat fine resolution and different phenomena onfbm_terrainat every resolution, which is the falsifier's own wording arriving as a per-field answer rather than a sweep-wide one.Eight vacuity controls, all asserted before the first
run.record, and the label is the crate's own rather than a proxy. (1) The normalising bound is the bound:RESIDUAL_SCALEasserted equal to4√6—reversal_floorreads 0.408248290 on every row, which is1/√6. (2) The mirror is the shipped path:mirror_vertices == dc_verticesandmirror_mismatches0 on all 24 rows, compared as IEEE bit patterns, so the three_deltacolumns are differences againstDualContouring's own output and not against a re-derived solve. (3) The cycle count is the crate's:extra_vertices_measured == extra_vertices_predictedon all 24 — 38 / 59 / 28 ongyroid, 8 / 9 / 15 onfbm_terrain, 97 / 184 / 250 onnoise_cavity, 0 elsewhere — the first from runningManifoldDualContouringandDualContouringlive and differencing their vertex counts, the second fromsegment_links/joined_maskon each cell. (4)M-60's five zero fields are still zero:second_vertex_cells0 onsphere,torus,box_exact,csg_difference,thin_plateat all three resolutions, 15 rows. (5) Those five report a near-zero residual:curl_residual_normalised0.000000000 onbox_exactandthin_plateand 0.000032453–0.022845151 on the other three, every one under the 0.25 ceiling that sits belowreversal_floor, so passing it means no cell in the mean carries a full normal reversal on any face. (6)M-60's two non-zero fields have positives and negatives:second_vertex_cells34 / 49 / 28 ongyroidand 8 / 9 / 15 onfbm_terrainagainstcellsof 1,214–5,240 and 470–1,958. (7) The instrument fires:residual_maxreaches 0.397862469 (noise_cavity17³), well above the 0.25 ceiling the previous control certifies the five clean fields below, so those zeros are zeros that could have been non-zero (M-44);reversal_floor_cellsis 0 on all 24 and is reported rather than asserted, because reaching4√6's single-face extremum needs two exactly axis-aligned, exactly opposed normals and no smooth field produces them. (8) The per-cellλis not the global one:lambda_cell_maxreaches the bracket's top 0.100000000 on 13 rows andlambda_cell_max / lambda_cell_minis exactly 100.0 on 7 of them (csg_difference×3,gyroid33³,noise_cavity×3), against a control bar of 2, so C3 is not comparing 0.01 against 0.01.
The residual is defined on the six faces and not the three axis components, and that is the choice that
makes it a per-cell signal. Twelve unit gradients at the twelve edge midpoints; each of the six
faces is a closed loop through four of them, traversed counter-clockwise as seen from +w, so
C(w, side) = n_bottom[u] − n_top[u] + n_right[v] − n_left[v] with the common edge length divided out and
the normals unit, hence dimensionless; r_cell is the Euclidean norm of that six-vector. A gradient
field has zero circulation around any closed loop, so r_cell is the amount by which these normals fail
to come from one smooth sheet. The three-component form would average the two faces normal to each axis,
and a second sheet entering through one face and not its opposite is precisely the signature averaging
destroys. Two normalisations are recorded: curl_residual_normalised divides by the extremal bound
4√6 = 9.797958971132712, and the λ map reads s = min(‖C‖₂ / UNIT_CIRCULATION, 1) with
lambda_unit_circulation 1 — one whole unit vector's worth of failure to cancel around one loop. The
AUC cannot see the difference, being computed on ranks with ties taking average ranks, which is what keeps
box_exact's exactly-zero plateau of residuals from inflating it.
All twelve midpoints are sampled because a partial loop is not a loop, and complete_faces_mean
measures how badly the alternative would have failed. It reads 0.000000 on all fifteen rows of the
five control fields — not one face of one cell there has all four of its edges cut — and only
0.005725–0.054366 on gyroid, 0.015322–0.034043 on fbm_terrain and 0.096179–0.233304 on
noise_cavity. A residual built on the crossings the crate already has would therefore have had no
closed loop at all on fifteen of the twenty-four rows, and at most 23.3% of faces to work with on any
row anywhere — so it would have been silently vacuous on exactly the five fields the vacuity control uses
as its negatives.
The cost of the diagnostic depends entirely on which reading you buy, and both numbers are in the file
with neither hidden behind the other. curl_share is the registered reading — the residual arithmetic
over normals already in memory, the "few dozen flops on a struct the crate already builds" the
registration names — and it carries c1_holds. curl_share_sampled pays for its own twelve
Sdf::gradient calls per active cell and reads 0.121373053 (sphere 33³) to 0.596246390
(fbm_terrain 17³), so c1_holds_sampled is false on 24 of 24. Here the CSV corrects the
harness's own header, which reasoned from 72 samples per active cell that the sampled share would be
"greater than one, not 0.02": measured, it is 12% to 60% of an extraction — 6× to 30× the registered
2% ceiling, expensive, and never above one. A consumer who wants this diagnostic at zero
marginal sampling cost needs a residual built on the crossings, which is a different construction and is
not what was registered.
C3 is driven through the shipped solve, and the only per-cell thing about it is the λ argument.
DualContouring::set_lambda (dual_contouring.rs:223) sets one λ for a whole grid, so a per-cell
regularizer cannot be driven through the shipped extractor at all — but solve::solve_with(cell, lambda)
(solve.rs:272) is public and takes the regularizer explicitly, and dual_contouring.rs:163-168 shows
those are exactly the calls Qef::place makes. So the per-cell arm is the shipped normal equations
called once per cell with a varying λ, and the only copied code is apply_clamp's twelve lines under
Clamp::ToCell — verified rather than trusted, by mirror_mismatches 0 bit for bit on every row.
Both arms share one index buffer, which is exact rather than convenient: a dual method's topology is one
quad per sign-changing grid edge and depends only on the corner signs, so moving a vertex cannot change an
index, and the substitution is a positions-only swap. The map is
λ(s) = 0.001 · 100^s, fixed before the run, whose geometric mean √(0.001 · 0.1) = 0.01 is exactly
solve::LAMBDA (solve.rs:85) — the shipped constant moved one decade down where the Hermite data is
consistent and one decade up where it is not, with s = 1/2 the crossover.
Six of C3's twelve wins are not per-cell results and the file says so in its own columns. On
box_exact and thin_plate the residual is 0.000000000 at every resolution, so lambda_cell_min and
lambda_cell_max are both 0.001000000 and over_shipped_lambda_share is 0.000000: the map has
degenerated into a global decrease of λ by one decade, which cannot answer a clause asking whether a
per-cell regularizer beats a global one. Those six rows are still a finding, just a different one —
sharpness_delta −0.000704698 / −0.000434066 / −0.000313172 on box_exact and −0.000060502 /
−0.000058982 / −0.000058222 on thin_plate, with self_intersections_delta 0, so λ = 0.001 is
simply better than λ = 0.01 on a field whose normals are exactly consistent. And the same global
decrease loses on sphere (sharpness_delta +0.000304765 / +0.000230766 / +0.000290344), which is
why C3's own falsifier is worth having.
The genuine per-cell result is noise_cavity, and it is the largest effect in the file. With
over_shipped_lambda_share 0.832591 / 0.784722 / 0.734780 — most cells landing above the shipped
constant — the per-cell λ improves every axis at every resolution: self_intersections_delta −47 /
−95 / −193 (388 → 195 at 33³, a 49.7% cut), sharpness_delta −0.019059024 / −0.031181368 /
−0.032149685, qef_residual_delta −0.021269562 / −0.024624400 / −0.016925036. fbm_terrain wins at
17³ and 25³ (self_intersections_delta −8 / −6) and loses at 33³ (+5), and gyroid shows the
clause's asymmetry: at 25³ and 33³ it cuts self-intersections by −9 and −18 while sharpness
worsens by +0.001627561 and +0.003082213, and "beats on at least one without losing on the
other" scores that as a fail. So what a consumer should take from C3 is narrow and real: on
noise_cavity-like fields — CSG-intersected value noise, the closest fixture to a dug voxel world — a
residual-driven λ in [0.001, 0.1] halves self-intersections and sharpens the vertex at the same
time, and on smooth analytic fields it does nothing worth the code.
SHARE, recomputed. curl_share is the share, and it is at most 0.81%. "C1 moves the
vertex-placement stage; C3 moves the same stage's quality, not its cost." Both halves are about
place_vertices and neither touches topology, and the harness makes that visibly true by sharing the
index buffer byte for byte between the arms — nothing this row proposes can move a triangle. C1's
denominator is whole-extraction wall clock rather than the place stage P-121 measured, deliberately:
it is the conservative choice, so a share under 2% of it is under 2% of any stage inside it. C1 is a
ratio of two wall clocks and is therefore the one clause on this row M-280 could move: both clocks are
taken in the same run, five measured repeats after one warm-up with the median as the headline, and the
margin is 2.5× at worst (curl_share 0.008061907 against cost_ceiling 0.02) against the 1.45× swing
M-280 measured on this host. C2 and C3 read no clock at all.
Would be shown wrong by: a field on which the second-vertex population and the residual separate at
AUC above 0.8 at every resolution rather than only at gyroid's finest, which would revive C2 as a
predictor rather than as a gyroid-33³ observation; a crossings-based residual that reaches
curl_share_sampled under 0.02, which would make the diagnostic free in the sampled reading too and is
the one construction this row did not measure; mirror_mismatches ever reading non-zero, which would mean
the _delta columns were never measured against the shipped path; or a noise_cavity run at 65³ where
self_intersections_delta turns positive, which would confine C3's only real win to coarse grids.
🧊 M-487 — the registered null held: at matched cost the normal-cycles incumbent beats discrete varifolds on mean curvature on 28 of 30 rows, error_ratio 1.000821 to 3.358471, and the two rows where it does not are the capsule at 129³ at error_ratio 0.998923 — a 0.1% win inside a C⁰ seam that dominates both arms — C1 held on 28 of 30, c2_holds true on 10 of 30 (the torus, at 6.039637σ) and false on 20, and the one recommendation that does move is on a quantity C1 never scored: on the torus's Gaussian curvature the varifold overtakes at 47³ and is 1.59× better at 129³ with exponent 1.575152 against 1.127950 (P-174, R-174)
M. cargo bench --bench experiment_p174, docs/experiments/p-174.csv, 30 rows across 50
columns — four # comment lines plus one column header plus 30 data rows, 35 lines in the file,
counted from it rather than from the brief. Eleven of the 50 columns are the registered records; the
other 39 are M-273 extras. The shape, counted from the file: two estimators × three fixtures × five
resolutions — normal_cycles and varifold on sphere, torus and capsule at 33 / 47 / 65 / 91 /
129 samples per axis, vertices 518 (capsule 33³) to 19,230 (sphere 129³), triangles
1,032 to 38,456, used_vertices == vertices on all 30. # commit c3cb940 on
amd-ryzen-9-5900x-12-core at 2026-08-30T09:31:11Z, no (WORKING TREE DIRTY). No source change: both
estimators consume a finished MeshBuffer from the shipped MarchingCubes<f64> at its shipped defaults,
neither re-samples the field, and nothing under crates/isomesh/src/ moved.
| clause | registered | measured |
|---|---|---|
| C1 varifold mean curvature is compared against the normal-cycle estimator at matched cost on the analytic fields, where exact curvature is known; falsified by varifolds winning | error_ratio = varifold H error / normal_cycles H error ≥ 1, written on both rows of each pair |
HELD on 28 of 30 rows. sphere: 2.004659 / 2.620924 / 2.570974 / 3.358471 / 2.662591 — the incumbent is 2.0× to 3.4× more accurate at every rung. torus: 1.214081 / 1.523058 / 1.730780 / 2.101892 / 2.448632, the gap widening with resolution. capsule: 1.038899 / 1.052396 / 1.000821 / 1.028691 / 0.998923, the last of which is below one, so c1_holds is false on the two 129³ capsule rows and the registered null is falsified there by 0.1%. c1_holds_global false |
| C2 the convergence exponent is fitted for both, since a method that is worse at our resolutions but converges faster is a different recommendation from one that is simply worse; falsified by indistinguishable exponents | c2_holds = abs(exponent_gap) > 2√(se_nc² + se_var²), a two-sigma separation of two least-squares slopes, per field |
SPLIT 10 / 20 — the torus separates and the other two fixtures do not. torus: convergence_exponent 1.470860 (normal_cycles) against 0.969586 (varifold), exponent_gap 0.501274, exponent_stderr 0.048097 and 0.067641, exponent_gap_sigma 6.039637 → c2_holds true on all ten torus rows. sphere: 1.669604 against 1.432439, gap 0.237165, stderrs 0.055422 / 0.113593, σ 1.876429 — it fails by 0.12σ, which is the honest reading and is why the instrument is the fit rather than a round number. capsule: 0.173820 against 0.203049, gap 0.029229, σ 0.322316: neither arm converges there at all. c2_holds_global false |
The
capsule's near-tie is not a varifold win, and the column that says so issmooth_only_mean_error. At 129³ the headline errors are 7.114255e-2 (normal_cycles) and 7.106592e-2 (varifold), henceerror_ratio0.998923. Restricted to the smooth part of the surface — excluding the band| |y| − half | ≤ epsaround the two seam circles — the same two arms read 1.692471e-3 and 7.383666e-3, so where the surface is C¹ the incumbent is still 4.4× more accurate, and the tie at the finest rung is two mollified estimators both being beaten by the same C⁰ curvature discontinuity. The penalty is priced rather than hidden: the headline stays unfiltered and the filtered reading sits beside it on every row. That is also why bothcapsuleexponents are near zero (0.173820 and 0.203049) — a fixed-radius mollifier over a fixed-size discontinuity does not converge, and the file shows that rather than fitting a slope through it and calling it a rate.Eight vacuity controls, every one asserted before the first
run.record, and one of them changed the ladder. (1) The ladder is the regime the bounds are stated in:epsstrictly decreasing 0.282842712 / 0.235907130 / 0.200000000 / 0.168654809 / 0.141421356 andeps_over_hstrictly increasing 2.262742 / 2.712932 / 3.200000 / 3.794733 / 4.525483, so the fitted exponent runs through one regime rather than splicing two. (2) The mesh is a closed manifold:boundary_edges,non_manifold_edgesandzero_length_sidesall 0 on all 30 rows — a boundary vertex's defect isπ − α_vrather than2π − α_vand a zero-length side costs the per-faceΣα = πidentity, so either one would calibrate the incumbent against the wrong reference. (3) The incumbent reproduces the analytic curvature globally:global_int_h_rel_error1.801237e-3 → 1.120375e-4 on thesphereacross the ladder and 2.676230e-5 → 6.153966e-6 on thetorus, against a 0.02 bar, withglobal_int_h_measured12.564962710 againstglobal_int_h_exact12.566370614 =4πrat 129³ and 19.739330277 against 19.739208802 =2π²R;global_defect_measured12.566370614 =2πχwith χ = 2 onsphereandcapsuleand −0.000000000 on thetorus, well inside the 1e-6 bar. (4) Both arms reproduce it pointwise at the finest rung:mean_curvature_error1.009572e-3 and 2.688077e-3 on thesphere, 4.664466e-3 and 1.142156e-2 on thetorus, all far under the 0.25 bar, soerror_ratiois not a ratio of two noises. (5) The reference is not a constant zero:h_exact_rms1.000000 on thesphere, 1.703672–1.706267 on thetorus, 1.604786–1.643975 on thecapsule, andk_exact_rms1.000000 / 2.441842–2.443510 / 2.951860–3.079275, with all sixty fitted error values strictly positive and finite. (6) Thetorusreally changes the sign ofK:k_positive_vertices692 / 1,348 / 2,540 / 5,116 / 10,484 againstk_negative_vertices428 / 940 / 1,660 / 3,412 / 6,940. (7) Thecapsulereally carries a zero-Kregion:k_zero_exact_vertices252 / 572 / 1,140 / 2,100 / 4,588 besidek_positive_vertices266 / 554 / 1,002 / 2,162 / 4,178 andk_negative_vertices0 — the one regimesphereandtoruscannot test, since an estimator that manufactures curvature out of mesh noise is invisible where the true value is 1 and obvious where it is 0. (8) The mollifier is a convolution and not a handful of terms:support_triangles_mean43.672 to 194.102 against a bar of 8, so the varifold arm is not being blamed for its neighbour count.
The comparison is fair because one radius and one neighbour search serve both arms, and that is the
whole design. The mollifier is ρ_eps(z) = ξ(|z|/eps) with ξ(t) = (1 − t²)³ on [0,1] and zero
outside; ξ(1) = ξ'(1) = ξ''(1) = 0, so it is C² across the support boundary — the regularity
Buet–Leonardi–Masnou's first-variation estimate asks for — and ξ'(0) = 0, so ∇ρ_eps vanishes at the
centre and the z/|z| factor never divides by zero. Its normalising constant is omitted because every
quantity is a ratio of two ρ-weighted sums, and the surviving 1/eps in ∇ρ_eps is the 1/length
that curvature has. eps = 0.8·√h is Buet–Leonardi–Masnou's own balance: their error is O(eps) +
O(h/eps), so eps ~ √h sends both terms to zero together and is the only scaling under which the
challenger converges at its best rate — the ladder's eps and eps_over_h columns are that scaling made
checkable rather than promised. Without a shared radius the comparison would be rigged: a mollified
estimator at radius eps averages O((eps/h)²) triangles and a vertex-star estimator averages six, so
putting those against each other measures the radius and not the formalism.
How much the localisation matters is the most useful number in the file, and it is 302×.
nc_star_mean_error carries the tight vertex-star form of the same Sun & Morvan measure —
0.25 Σ_{e∋v} lβ / A_v with A_v the barycentric third — and it reads 2.685504e-1 to 4.022359e-1
across all 30 rows, essentially flat in resolution, against the ball-localised incumbent's
1.009572e-3 on the sphere at 129³: a factor of 302, with nc_star_gaussian_error
3.629433e-1 to 6.967358e-1 telling the same story. So choosing the wrong localisation of one
measure costs 302×, while choosing the wrong formalism at a fixed localisation costs at most 3.4× —
which is why the vertex-star form is not benched as an arm, and why a reader should not take "normal
cycles beat varifolds" as an argument about normal cycles. It is an argument about a ball.
The one place the challenger genuinely wins is the torus's Gaussian curvature, and C1 does not score
it. error_ratio is defined on mean_curvature_error alone. Taking the same ratio on
gaussian_curvature_error gives, on the torus, 1.163404 / 0.886893 / 0.829138 / 0.647606 /
0.630859 — the varifold overtakes the incumbent at 47³ and is 1.59× more accurate at 129³
(8.423614e-3 against 1.335260e-2) — and its gaussian_exponent there is 1.575152 against the
incumbent's 1.127950, the one exponent pair in the file where the challenger's slope is the steeper
one. On the capsule the same ratio is 0.996858 and 0.997935 at 91³ and 129³, a marginal win, and
on the sphere the varifold loses by 2.56× to 3.10× at every rung. The mechanism is structural rather
than lucky: Gaussian curvature comes from the varifold's second-order data — the analytic tangential
derivative of its own mollified normal, S_ij = t_i·(∇n_eps·t_j), K = det S — so there is no
finite-difference step and no second length scale, while the incumbent's K is an angle defect at a
vertex and the torus is the fixture whose curvature actually varies. A method that is worse now and
converges faster is a different recommendation from one that is simply worse, and this is where that
distinction cashes: if the crate ever wants a pointwise K on a varying-curvature surface at high
resolution, the varifold is the arm to reach for; for H, on this evidence, it is not.
The challenger is roughly half the incumbent's cost, and that makes the null more conservative rather
than less. cost_ratio = varifold_ms / normal_cycles_ms reads 0.471439 to 0.574754 across the
fifteen pairs, rising monotonically with resolution, and cost_matched is false on the six 33³ rows
because those three ratios (0.482274, 0.471439, 0.494540) sit just below the [0.5, 2] band and true
on the other 24. The direction is the structural expectation: the varifold needs one gather over
triangle centroids (19 scalar accumulators), while normal cycles needs three — over centroids, edge
midpoints and vertices — because its measures live on three different supports. cost_matched gates
nothing, and the reason is worth stating: a cost_ratio below 0.5 means the challenger was handed at
least as much budget as the incumbent and still lost on error, so only a ratio above the band would
weaken C1. estimator_ms is the median of five repeats after a warm-up with estimator_ms_scatter
1.000472–1.075137 beside it, and extraction sits outside both clocks. curvature_share —
estimator_ms / (extract_ms + estimator_ms) — is 0.472132 to 0.889551, so this is the stage a change
of estimator can move, and it is most of the post-extraction pipeline.
The ladder is 33 / 47 / 65 / 91 / 129 because a vacuity control refused 49³ during development, and the
measurement that refused it belongs in the record. The naive geometric fill-in is 49 and 97; both are
4t + 1, and 144 = 4² + 8² + 8² and 576 = 8² + 16² + 16² put a grid corner exactly on the unit
sphere at (2/3, 2/3, 1/3) — M-352 / P-53's =-corner case, transversal, so several incident edges
are cut and Marching Cubes' per-edge vertex cache emits coincident vertices. The harness header records
what that cost when measured (experiment_p174.rs:211-246): 40 zero-length sides at 49³, and the
localised normal-cycle mean-curvature error jumping from 1.02e-2 at 33³ to 8.78e-1 — an 87-fold
blow-up on a rung between two clean ones — while the varifold arm barely noticed at 1.34e-2, because
it reads only centroids, normals and areas and never a vertex angle. 47 = 4(11) + 3 and 91 = 4(22) + 3
are transversal by residue alone and sit at the geometric midpoints of [33, 65] and [65, 129], giving
cell_size 0.125 / 0.086956522 / 0.0625 / 0.044444444 / 0.03125 — near-uniform in ln h, which is
what a least-squares slope wants. The capsule's radius is 0.47 and not 0.5 for the same reason:
a² + b² = r²/h² has no integer solution for any h in the ladder. This is the clearest case in the
phase of an angle-defect estimator being resolution-fragile in a way a centroid-based one is not, and it
is the incumbent that is fragile.
Two supporting cross-checks read as they should, so neither arm is doing work off the books.
normal_alignment — the mollified normal against ∇f/|∇f| — is 0.999833250 to 0.999999992 on all 30
rows, so the projection P_n = I − n⊗n in the varifold's first variation is not carrying the result; and
varifold_h_shape_error, the disagreement between 0.5 tr S and the first-variation H (two different
formulas for one quantity), falls 2.306688e-2 → 2.408622e-3 on the sphere and 3.538154e-2 →
4.609448e-3 on the torus, converging, while on the capsule it wanders between 7.103320e-2 and
9.237177e-2 with no trend — the seam again, seen by a third instrument.
SHARE, recomputed. curvature_share, and it is reported rather than claimed. "C1 moves the
curvature stage only, whose share must be reported." Discharged as two columns per row — extract_ms
0.4641–26.9357 ms for the marching-cubes stage and estimator_ms 0.6512–164.0902 ms for the
curvature stage — with the ratio on every row. Nothing else in the pipeline is touched by either arm.
There is no speedup claim anywhere in the row, so ✗51's bar has nothing to divide; M-280's 1.45×
governor scatter is handled by medians and by the fact that C1 and C2 are both scored on errors, not
on clocks.
What a consumer should do: nothing changes. P-42 and P-45's normal-cycles line stands for mean
curvature, and the crate has no pointwise curvature API to reconsider. What the row adds is three things
worth knowing before anyone builds one: a pointwise estimator must be localised over a ball and not a
vertex star (302×); the incumbent's accuracy depends on grid transversality in a way a centroid-based
estimator's does not (87× at 49³); and on a C⁰ crease both formalisms stop converging entirely
(convergence_exponent 0.17 and 0.20), so a crease-aware estimator, not a better formalism, is what that
regime needs.
Would be shown wrong by: a varifold error_ratio below one on sphere or torus, which would put
the challenger ahead on smooth analytic data where the incumbent is calibrated to 1.1e-4 and would
genuinely redirect the P-42/P-45 line; a sphere re-run whose exponent_gap_sigma crosses 2 — it is
at 1.876429, so one more rung or a slightly tighter fit decides C2 there and the row is explicitly not
claiming otherwise; a crease-band-excluded capsule reading in which the varifold wins, which would mean
the seam was masking a real advantage rather than a real tie; or an eps scaling other than 0.8√h under
which the varifold's mean-curvature exponent exceeds the incumbent's, since the exponents fitted here are
properties of this ladder and this balance and the row claims them for no other.
💥 ✗125 / M-488 — C1 FALSIFIED on 24 of 24 rows: intrinsic Delaunay flipping raises the worst-decile minimum angle by at most 1.642437° against a 10° bar, and by at most 5.369167° and 1.951887° under the two alternative statistics recorded beside it. C2 HELD on 24 of 24 and it is the result: vertex_positions_moved 0, hashes_moved 0, extrinsic_geometry_identical true, against a positive control that moves the hash on all 18 rows where a flip happened. C3 FALSIFIED at 0 of 8 surveyed consumers — 15,391 flips reach the intrinsic Delaunay fixed point on every row, remove 1,570 of 10,678 slivers, and reach nothing the crate reads (P-175, R-175)
M. cargo bench --bench experiment_p175, docs/experiments/p-175.csv, 24 rows across 44
columns — four # comment lines plus one column header plus 24 data rows, 29 lines in the file,
counted from it rather than from the brief. Fourteen of the 44 columns are the registered records; the
other 30 are M-273 extras. The shape, counted from the file: eight reference fields × {17, 25, 33}
samples per axis, vertices 126 to 6,522, triangles 248 to 13,236, interior_edges
372 to 19,854. Those three resolutions are not the house default and could not be: hashes_moved
is a comparison against crates/isomesh/golden_hashes.json, the fixture exists at no other resolution,
and the extractor is plain marching_cubes for the same reason — its 24 rows are the only ones of the
committed 216 this harness runs, and claiming the other 192 would be claiming a measurement nobody took.
# commit 320946e on amd-ryzen-9-5900x-12-core at 2026-08-30T09:31:18Z, no (WORKING TREE DIRTY).
No source change: the Δ-complex, the flip loop and the write-back are bench-local, and the row's whole
point is that nothing in crates/isomesh/src/ could have needed changing.
| clause | registered | measured |
|---|---|---|
| C1 intrinsic Delaunay flipping raises the minimum triangle angle materially — at least 10° on the worst decile — on at least four fields; falsified by under 10° | min_angle_after − min_angle_before ≥ 10°, on ≥ 4 fields at every resolution |
FALSIFIED on 24 of 24. min_angle_gain — the mean of the worst decile of per-triangle minimum angles, in degrees, carried in the file's own min_angle_statistic column as worst_decile_mean_degrees — tops out at 1.642437° (torus 17³, 9.519333° → 11.161770°), followed by 1.580372° (sphere 25³), 1.566885° (noise_cavity 17³) and 1.448880° (torus 25³). c1_fields 0 and c1_run false on every row. The bar is missed by a factor of 6.1 at best |
| C2 zero vertex positions move and zero position hashes move, asserted rather than assumed; falsified by any hash movement, which would mean the implementation is not intrinsic | vertex_positions_moved = 0, hashes_moved = 0, three integer equalities |
HELD on 24 of 24, and with a positive control that fires. vertex_positions_moved 0 and hashes_moved 0 on every row, extrinsic_geometry_identical true on every row, measured against the committed golden_hashes.json — which yields exactly 24 marching_cubes rows over the eight fields × {17, 25, 33}, of 216 entries across nine algorithms. control_hash_moved is true on all 18 rows where flips > 0 and false on the six zero-flip rows, so the zero is a zero that could have been non-zero (M-44) |
| C3 the honest falsifier, stated at registration: if every downstream consumer reads extrinsic triangles, nothing measurable changes; falsified by no consumer benefiting | ≥ 1 of the surveyed consumers benefits | FALSIFIED. c3_consumers_benefiting 0 of c3_consumers_surveyed 8 on every row. One of the eight reads triangle angles at all, and it reads them extrinsically |
C1 is falsified under all three statistics, which is why three were recorded. The clause names the worst decile and the harness carries the 10th-percentile value and the global minimum beside it so the verdict cannot rest on one instrument. Best
p10_min_anglegain: +5.369167° onsphere25³ (10.550573° → 15.919740°), then +3.701091° ontorus25³ and +2.693805° onnoise_cavity17³. Bestglobal_min_anglegain: +1.951887° onsphere17³ (13.261947° → 15.213834°), then +0.725188° ontorus17³. Every one of the eighteen flipping rows misses 10° on every statistic, so C1 is not a near miss on the wrong instrument.One row went backwards on the registered statistic while going forwards on the global minimum, and both numbers are in the file.
csg_differenceat 17³:min_angle_gain−0.053590° (25.571386° → 25.517796°) whileglobal_min_angle_before11.127419° rose toglobal_min_angle_after11.130121°. Twenty-three flips raised the smallest angle in the mesh by 0.0027° and redistributed the worst decile downward. A locally Delaunay triangulation of a polyhedral surface carries no global max-min-angle guarantee — that is a planar theorem — and this row is the measurement of it.Six vacuity controls, all before the first
run.record. (1) The registered one: the worst-decile angle before flipping must be under 15° on some field — it is under 15° on 15 of 24 rows, minimum 3.189870° (gyroid25³), so there were slivers to fix. (2) Something was flippable:non_delaunay_beforesums to 12,826 over the sweep, 0 onbox_exactandthin_plateand 2,858 at most (noise_cavity33³). (3) Flips happened:flipssums to 15,391. (4) The hash instrument can report movement:control_hash_movedtrue on all 18 rows with flips, which is the arm that writes the flipped connectivity back beside the untouched positions and re-hashes — without it,hashes_moved0 would be equally consistent with amesh_hashblind to connectivity or with a flipper that silently did nothing. (5) The baseline is the committed fixture: the scanner must find exactly 24marching_cubesrows ingolden_hashes.json, orhashes_movedis measured against something that matched nothing. (6) The fixed point was reached:flip_budget_exhaustedfalse andnon_delaunay_after0 on all 24 rows, againstflip_budget= 64 ·interior_edges(23,808 to 1,270,656), so the "after" arm is the intrinsic Delaunay triangulation and not a partial run.flips_rejectedis 0 on all 24: the numerical guard on the convexity theorem never fired.
C2 is the finding, and it is a stronger statement than "the hashes did not change". The mechanism is
that no position is ever read after the first build. The flip criterion is the cotangent sum
cot α + cot β ≥ 0 with cot = (b² + c² − a²)/(4A) and A from Heron in Kahan's stable ordering, so it
is a function of edge lengths alone and no angle is evaluated to decide a flip. The length update is the
part that earns the word intrinsic: the two triangles are unfolded into the plane along their shared
edge and the new edge's length is |cd| in that unfolded layout — the length of a geodesic across the
surface, not the chord between those two vertices in R³. Take the chord and the result is an ordinary
extrinsic remesh of a different surface. The data structure is a Δ-complex, not a simplicial
complex: corner slots carry a vertex, a halfedge length and a twin, so a flip producing a self-edge or a
second edge between an already-joined pair is legal and needs no special case, which is what refusing
those flips would have cost — the result would no longer be the intrinsic Delaunay triangulation. The loop
is Lawson's, and an empty queue is a proved fixed point rather than a hope: on each flip all six
corner slots of the two modified triangles are re-queued, and that is exactly the set of edges whose
cotangent sum can have changed.
The connectivity does improve, measurably, and by less than the registration hoped. Over the sweep
slivers_before 10,678 falls to slivers_after 9,108 — 1,570 removed, 14.7% — for 15,391
flips. The extremes: sphere 17³ clears every one of its 24 → 0; sphere 25³ 170 → 93;
noise_cavity 17³ 435 → 313; gyroid 33³ 2,410 → 2,181; noise_cavity 33³ 2,334 → 1,990;
csg_difference 25³ 39 → 39, no net change from 67 flips. And 1,380 of the 9,108 survivors are
short_edge_slivers_after — slivers whose shortest side is under 5% of the cell size, i.e. a
near-duplicate vertex pair — which no flip can repair because the defect is a position, not a diagonal.
That is M-48's mechanism, and shortest_edge_over_cell names the fields it owns: 0.000000 on
gyroid at all three resolutions, on noise_cavity at all three, and on sphere at 25³, against
1.000000 on box_exact and thin_plate. So a connectivity-only repair provably cannot reach
1,380 of the 9,108 surviving slivers — 45.2% of them on sphere at 25³ (42 of 93), 26.2% on gyroid at
17³ (99 of 378) and 25.2% on noise_cavity at 25³ (247 of 981) — because their defect is a position and
not a diagonal.
The two zero-flip fields are the control that makes the other numbers mean something. box_exact and
thin_plate report non_delaunay_before 0, flips 0, min_angle_gain 0.000000 and
control_hash_moved false at every resolution, with min_angle_before = min_angle_after =
p10_min_angle_* = global_min_angle_* = 35.264390° and 44.964235° / 44.919654° / 44.857473°
respectively. Marching Cubes' output on those two fields is already intrinsically Delaunay — every
triangle is one of the case table's few shapes on an axis-aligned plateau — so the flipper correctly does
nothing, and a row on which it had "improved" something would have been the instrument inventing work.
C3's answer is a survey of the crate's own source, printed in full beside the numbers rather than
asserted. All eight consumers of triangle connectivity in crates/isomesh/src/**, with
reads_angles / benefits: mass::mass_properties (mass.rs:198) — a divergence theorem over
triangles, invariant under retriangulation of a fixed polyhedron, and an intrinsic edge is a geodesic, so
feeding it this connectivity would integrate over a solid that does not exist; normals::recompute /
AreaWeightedFaces (normals.rs:77, :114) — weights by area, not angle, and the angle-weighted
variant that would care is not implemented; validate::MeshReport::mean_ratio (validate.rs:257,
:903-943) — the one consumer that reads angles, and it computes them from the extrinsic cross
product and edge lengths at validate.rs:917-939, which no intrinsic flip can move;
collider::readiness (collider.rs:183, :168) — counts boundary, non-manifold and duplicate features,
none of which a flip changes; surface_nets::set_smoothing_passes (surface_nets.rs:154 via
dual.rs:550) — a uniform Laplacian over the face-adjacent cell graph that runs before any triangle
exists; orient::orient (orient.rs:148) — purely combinatorial and already exact;
validate::self_intersections (validate/self_intersection.rs:153) — an intrinsic triangle is not a
subset of R³ and cannot be handed to it; validate::pinch_census (validate/pinch.rs:417) —
coincident-vertex grouping over positions, so every count is identical before and after. 0 of 8. The
harness also records why: grep -E 'cotangent|cot_|laplacian|geodesic' over crates/isomesh/src returns
four doc comments and one registration string and no implementation — there is no cotangent Laplacian,
no geodesic solver and no parameterisation in this crate, and those three are the operators an intrinsic
triangulation exists to serve.
What a consumer should do, and why this is the phase's cleanest shippable result even with two clauses
falsified. Nothing changes today, and that is C3's honest answer. What C2 buys is a standing
licence: a connectivity-only quality pass on this crate's meshes is provably free of every risk that
normally kills a remesh. Positions are bit-identical, so the 24 marching_cubes hashes hold as
measured — and since a flip cannot move a position, P-61's 135-of-216 movement cannot recur by
construction, on the other 192 as well, though this harness measured only the 24;
the extrinsic triangle set the collider and self_intersections read is
unchanged, so there is no physics, tunnelling or clearance risk; nothing that syncs or replicates a
position moves, so there is no network risk; and the cost is flip_ms 0.011831 ms to 1.684563 ms
(median of 7 repeats, every repeat's flip count asserted equal to the first, so the repeats are a
determinism check as well as a timing one). So the moment this crate acquires a consumer that actually
reads angles — an angle-weighted normal pass for shading, or a cotangent Laplacian — intrinsic Delaunay
flipping is the one remesh that can be handed to it with no gameplay, collision, hash or replication
consequence at all. The measured gain on the angle statistics is small (1.6° on the worst decile) and
the ceiling is set by coincident vertices, so the value of the ticket is the risk profile, not the
magnitude — and a future ticket proposing it now has both numbers instead of one.
SHARE, recomputed. None, and no clause reads a wall clock. "C1 moves mesh quality, not cost; C3
decides whether that quality reaches anything." C1 is a difference of two angles in degrees, C2 is three
integer equalities, and C3 is a count over a source survey. flip_ms is in the file because the
registration names it and is read by nothing — P-126's rule for wall_seconds exactly — so M-280 /
✗24's 1.45× governor scatter has nothing here to bite on, and every repeat rebuilds the triangulation
outside the timed region so flip_ms is the flipping loop rather than the build.
Would be shown wrong by: a field whose worst-decile angle gains 10° from flipping alone, which would
revive C1 — on this evidence it would have to be a field with few coincident vertices and many
non-Delaunay diagonals, and the two fields here with no coincident vertices have no non-Delaunay diagonals
either; any hashes_moved above zero, which would mean the length update read a chord somewhere and the
implementation is not intrinsic; a ninth consumer, or an angle-weighted normal pass or cotangent
Laplacian landing in crates/isomesh/src/, which would flip C3 to held without any new measurement of
C1 or C2; or non_delaunay_after above zero on some future field, which would mean the Lawson queue's
re-queue set is incomplete and the "after" arm was never the fixed point.
🔬 M-489 — caves percolate in 3D and the transition is now a number: on noise_cavity the giant component appears at percolation_isovalue 0.029340, bracketed by the rungs 0.036372 and 0.019098, and at iso = 0 one component holds 0.814493 of the air against 65 isolated pockets — C1 HELD on 84 of 84, C3 HELD on 84 of 84 with two instruments sharing no data structure agreeing on the component count, the air-sample count and the full sorted size multiset on every row, and C2 split 42 / 42: the theorem's qualitative 2D/3D difference is present on noise_cavity (percolation_isovalue_2d none) and absent on fbm_terrain, whose 2D slices percolate too at 7.272575, which the registration named in advance as a real risk because fbm_terrain is hash-based lattice noise and not a Gaussian field (P-176, R-176)
M. cargo bench --bench experiment_p176, docs/experiments/p-176.csv, 84 rows across 49
columns — four # comment lines plus one column header plus 84 data rows, 89 lines in the file,
counted from it rather than from the brief. Twelve of the 49 columns are the registered records; the
other 37 are M-273 extras. The shape, counted from the file: two fields × 42 isovalues at a single
resolution 97 — 912,673 samples — sweep_rungs 42 on every row (41 rungs spanning each field's
own sampled value range, plus iso = 0.0 inserted because the registration's own sentence is about it),
sweep_hi / sweep_lo 9.419853 / −9.599993 on fbm_terrain at sweep_step 0.475496 and
0.640978 / −0.050000 on noise_cavity at 0.017274. One resolution rather than three because
percolation is a property of the field's feature count and not of the sampling rate: refining the grid
resolves the same blobs better and does not add blobs. # commit f24c09b on amd-ryzen-9-5900x-12-core at
2026-08-30T09:31:23Z, no (WORKING TREE DIRTY). No source change: Air::build(values − l) is
{f ≥ l} with no reinterpretation, because Air takes air to be value >= 0
(connectivity.rs:218-219), so the whole sweep is the shipped API asked 84 questions.
| clause | registered | measured |
|---|---|---|
C1 sweeping the isovalue on fbm_terrain and noise_cavity, a giant component appears — one component holding above 50% of the air volume — and the isovalue at which it appears is reported; falsified by no giant component at any isovalue |
a persistent onset exists and the sweep also contains a fragmented rung, per field | HELD on 84 of 84. percolation_isovalue 0.029340 on noise_cavity (percolation_rung_fragmented 0.036372 → percolation_rung_giant 0.019098, then 14 bisections) and 8.187580 on fbm_terrain (8.468861 → 7.993365). giant_at_zero true on both, with largest_component_fraction_at_zero 0.814493 and 1.000000. The onset is the persistent one — the highest swept isovalue at or below which the giant component never disappears again — because a one-voxel top rung also satisfies "above 50%" |
C2 the 3D behaviour differs qualitatively from a 2D slice of the same field; falsified by 2D and 3D behaving alike, and fbm_terrain being hash-based lattice noise rather than a Gaussian field makes that a real risk |
3D has a persistent giant phase and the 2D slice has none anywhere in the swept range | SPLIT 42 / 42. c2_holds true on all 42 noise_cavity rows: percolation_isovalue_2d reads none, giant_component_2d is true on exactly 1 of its 42 rungs (iso 0.416410, where the slice holds a single air pixel), and largest_component_fraction_2d never exceeds 0.500000 anywhere else. c2_holds false on all 42 fbm_terrain rows: its slices percolate too, percolation_isovalue_2d 7.272575, giant_component_2d true on 39 of 42 rungs |
C3 instrument B's component count, air-sample count and sorted size multiset all equal instrument A's, and label_count() == components(); falsified by disagreement with the union-find |
three equalities plus the label check, per row | HELD on 84 of 84. air_union_find_agreement and air_uf_sizes_match true on every row; air_uf_components == components, air_uf_air_samples == air_samples and air_uf_labels == air_uf_components on every row, with no exceptions to enumerate |
The two instruments share the six-neighbour adjacency and the
value >= 0test and nothing else, so C3's agreement is evidence rather than a tautology. Instrument A is a three-forward-edge union-find with union by size and path halving — deliberately the retired algorithm, the oneM-311's own text describes. Instrument B isAir::buildread throughcomponents(),air_samples(),label_count()andcomponent_size(l), and since✗26that is a flat label array filled by breadth-first flood (connectivity.rs:29-46,floodat:708): no parent pointers, no merge rule, no shared traversal order. The comparison is the full sorted multiset of component sizes and not merely the count, because two labellings can agree on how many components there are and disagree about which samples are in them. The air test is writtenvalues[i] - iso >= 0.0in A, and B is handed an array whose entry is that same subtraction already performed, so the two compare the samef64and cannot disagree through rounding.Connectivity is 6 in 3D and 4 in 2D, and that is not this bench's choice.
Air::neighbours(connectivity.rs:610-646) is the six axis-aligned neighbours, so instrument A must use six or C3 would be comparing two different graphs; the 2D control takes the same rule restricted to the planeslice_planez=48, which is 4. Both are columns —connectivity_3d6 andconnectivity_2d4 on all 84 rows — so no reader has to take a paragraph's word for it.Five vacuity controls, all before the first
run.record, and (4) is the one that decides whether this row measures the field or the sampling box. (1) Both regimes are inside the swept range, per field, which is the registration's own control verbatim:fragmented_rows(rungs with ≥ 8 components and no giant) 28 onnoise_cavityand 1 onfbm_terrain, againstgiant_rows_with_real_air(a giant component over ≥ 5% air) 6 and 37. The air-share floor is what stops the ladder's one-voxel top rung from answering for the whole one-large-component regime. (2) The 2D control is populated:slice_populated_rows(≥ 100 air pixels) 18 and 38, so C2 is not comparing a 3D census against an empty plane. (3) The cap cannot make air:cap_max_sdf−0.050024, strictly belowsweep_lo−0.050000, so insidenoise_cavity's masksphere_sdf < isoeverywhere and{max(noise, sphere) ≥ iso}is exactly{noise ≥ iso}. (4) The mask is necessary: over the unmasked domain atiso = 0,outer_shell_air_fraction0.825811 inouter_shell_components12 whoseouter_shell_largest_fractionis 0.999874 — C1 would have been true by the sampling box rather than by the field, which isM-44's failure mode exactly, so those three numbers ride on all 84 rows. (5) Every sampled value is finite, becausefbm_terraindeclaresFieldBound::Unboundedand a NaN would makev - iso >= 0.0false everywhere and read as a cleanly empty air set.
The per-isovalue rows, which are what the cave_percolation demo consumes. largest_component_fraction
is the giant-component fraction of the air volume, not of the domain; air_fraction_of_region is the
air share of the measured region (region_samples 176,909 for noise_cavity's cap and 912,673 for
fbm_terrain's full domain); the last column is components_2d / largest_component_fraction_2d on the
matched slice. The sweep runs top down, so read the table downward to watch the transition happen.
noise_cavity, region = the field's own cap {p : sphere_sdf(p) < −0.05}, all 42 rungs:
isovalue |
components |
largest_component_fraction |
air_fraction_of_region |
air_samples |
giant_component_exists |
2D: components_2d / fraction |
|---|---|---|---|---|---|---|
0.640978 |
1 | 1.000000 | 0.000006 | 1 | true | 0 / 0.000000 |
0.623703 |
3 | 0.571429 | 0.000040 | 7 | true | 0 / 0.000000 |
0.606429 |
3 | 0.454545 | 0.000062 | 11 | false | 0 / 0.000000 |
0.589155 |
4 | 0.437500 | 0.000090 | 16 | false | 0 / 0.000000 |
0.571880 |
4 | 0.500000 | 0.000113 | 20 | false | 0 / 0.000000 |
0.554606 |
6 | 0.413793 | 0.000164 | 29 | false | 0 / 0.000000 |
0.537331 |
5 | 0.395833 | 0.000271 | 48 | false | 0 / 0.000000 |
0.520057 |
7 | 0.397059 | 0.000384 | 68 | false | 0 / 0.000000 |
0.502782 |
9 | 0.352273 | 0.000497 | 88 | false | 0 / 0.000000 |
0.485508 |
14 | 0.300000 | 0.000678 | 120 | false | 0 / 0.000000 |
0.468233 |
20 | 0.247126 | 0.000984 | 174 | false | 0 / 0.000000 |
0.450959 |
21 | 0.217054 | 0.001458 | 258 | false | 0 / 0.000000 |
0.433685 |
28 | 0.182635 | 0.001888 | 334 | false | 0 / 0.000000 |
0.416410 |
43 | 0.157205 | 0.002589 | 458 | false | 1 / 1.000000 |
0.399136 |
53 | 0.133884 | 0.003420 | 605 | false | 2 / 0.500000 |
0.381861 |
56 | 0.163975 | 0.004550 | 805 | false | 3 / 0.400000 |
0.364587 |
66 | 0.150376 | 0.006014 | 1,064 | false | 3 / 0.375000 |
0.347312 |
80 | 0.127410 | 0.008208 | 1,452 | false | 5 / 0.333333 |
0.330038 |
94 | 0.105699 | 0.010910 | 1,930 | false | 6 / 0.277778 |
0.312763 |
103 | 0.099415 | 0.013532 | 2,394 | false | 7 / 0.280000 |
0.295489 |
120 | 0.089945 | 0.016528 | 2,924 | false | 10 / 0.257143 |
0.278215 |
119 | 0.079555 | 0.019824 | 3,507 | false | 11 / 0.250000 |
0.260940 |
125 | 0.071944 | 0.023492 | 4,156 | false | 11 / 0.232143 |
0.243666 |
167 | 0.065680 | 0.028659 | 5,070 | false | 12 / 0.202899 |
0.226391 |
171 | 0.075748 | 0.035521 | 6,284 | false | 14 / 0.302752 |
0.209117 |
153 | 0.070088 | 0.043067 | 7,619 | false | 14 / 0.269231 |
0.191842 |
150 | 0.078703 | 0.050563 | 8,945 | false | 13 / 0.244898 |
0.174568 |
146 | 0.077707 | 0.058776 | 10,398 | false | 16 / 0.233129 |
0.157293 |
146 | 0.075158 | 0.067238 | 11,895 | false | 16 / 0.214286 |
0.140019 |
137 | 0.074135 | 0.075638 | 13,381 | false | 19 / 0.199029 |
0.122744 |
135 | 0.075378 | 0.084439 | 14,938 | false | 20 / 0.177419 |
0.105470 |
131 | 0.084981 | 0.095185 | 16,839 | false | 21 / 0.183824 |
0.088196 |
138 | 0.133533 | 0.107818 | 19,074 | false | 25 / 0.211656 |
0.070921 |
127 | 0.179270 | 0.121616 | 21,515 | false | 29 / 0.190860 |
0.053647 |
111 | 0.226191 | 0.135623 | 23,993 | false | 34 / 0.175234 |
0.036372 |
100 | 0.360519 | 0.149845 | 26,509 | false | 31 / 0.162393 |
0.019098 |
81 | 0.521363 | 0.165373 | 29,256 | true | 29 / 0.146617 |
0.001823 |
69 | 0.814620 | 0.183105 | 32,393 | true | 30 / 0.135823 |
0.000000 |
66 | 0.814493 | 0.185265 | 32,775 | true | 29 / 0.133111 |
-0.015451 |
71 | 0.839921 | 0.201946 | 35,726 | true | 23 / 0.126677 |
-0.032726 |
66 | 0.842058 | 0.220820 | 39,065 | true | 22 / 0.168464 |
-0.050000 |
70 | 0.850013 | 0.238863 | 42,257 | true | 20 / 0.161728 |
fbm_terrain, region = its own [-8, 8]³ unmasked, the six rungs where anything happens:
isovalue |
components |
largest_component_fraction |
air_fraction_of_region |
air_samples |
giant_component_exists |
2D: components_2d / fraction |
|---|---|---|---|---|---|---|
9.419853 |
1 | 1.000000 | 0.000001 | 1 | true | 0 / 0.000000 |
8.944357 |
11 | 0.583832 | 0.000366 | 334 | true | 0 / 0.000000 |
8.468861 |
20 | 0.340507 | 0.002851 | 2,602 | false | 1 / 1.000000 |
7.993365 |
18 | 0.858262 | 0.011333 | 10,343 | true | 4 / 0.509804 |
7.517869 |
6 | 0.996981 | 0.029030 | 26,495 | true | 4 / 0.457711 |
7.042372 |
2 | 0.999980 | 0.054459 | 49,703 | true | 3 / 0.569476 |
6.566876 |
1 | 1.000000 | 0.083406 | 76,122 | true | 1 / 1.000000 |
The remaining 36 rungs, from iso 6.091380 down to −9.599993, all read components 1 and
largest_component_fraction 1.000000 — single_component_rows is 37 on fbm_terrain against
1 on noise_cavity, and that one number is the whole difference between the two fields.
component_size_distribution carries the shape on every row as {count}c|{top five sizes}|+{the
rest}: at iso = 0 noise_cavity reads 66c|26695|2885|854|626|448|+61 and fbm_terrain reads
1c|446840.
A caveat the demo must not lose: on fbm_terrain the giant component is the sky, not a cave system.
largest_component_span_fraction — the component's index extent over the region's own extent, worst axis
— is 0.587629 for fbm_terrain at iso = 0, so its single component holding 100% of 446,840 air
samples reaches only 57 of 97 planes on its narrowest axis, which is exactly what "everything above a
heightfield" looks like. At the top of its sweep the same column reads 0.010309 / 0.030928 / 0.061856 /
0.092784, rising one grid plane at a time. noise_cavity's giant component at iso = 0 spans
0.927536 of the cap on its worst axis while 65 pockets sit around it. So the cave-relevant
percolation number in this file is noise_cavity's 0.029340, and fbm_terrain's 8.187580 is a
measurement of a heightfield's open air, which is why its 2D slices percolate as well and why C2 reads
false there.
C2's falsification is the registered risk arriving, and the ordering survives it. The theorem is about
smooth Gaussian fields, and fbm_terrain is four-octave hash-based lattice noise; the registration says
so in advance and calls a null there "a real risk … registered as one". What the sweep measures is that
fbm_terrain's 3D onset 8.187580 does sit strictly above its 2D onset 7.272575 — a gap of
0.915005 in the field's own units, and dimension_gap_rows (a giant in 3D and none in 2D on a
populated slice) reads 1 there against 6 on noise_cavity. So the ordering ℓ_c(3) > ℓ_c(2) is
reproduced on both fields; what fails on fbm_terrain is the qualitative claim ℓ_c(2) = 0, because a
2D slice of a heightfield is not a 2D nodal set of anything — it is a sublevel set of a 1D-dominated
function and it connects trivially. noise_cavity is the field where the theorem's shape is actually
measured: ℓ_c(3) = 0.029340 > 0 with no 2D onset anywhere down to −0.050000, which is
ℓ_c(3) > 0 ≥ ℓ_c(2) in the crate's own units.
What a consumer should do, stated for a level designer rather than for a mathematician. At the shipped
iso = 0 a noise_cavity-style field generates one connected cave holding 81.4% of the excavated
volume plus 65 isolated pockets over a 97³ cap — so cave connectivity is emergent and does not need to
be authored, and the pockets are what needs authoring (or a components() filter). The margin
is not large, and the table gives it exactly: the giant component's share is 0.814493 at iso = 0,
0.521363 one rung up at 0.019098, 0.360519 at 0.036372 across 100 components and 0.226191 at
0.053647 across 111 — so raising the isovalue by 0.036372 in these units turns one cave holding four
fifths of the air into a hundred components whose largest holds a third of it. Below zero the field is
generous — 0.850013 of the air in one component at iso = −0.050000. M-311's union-find is still
the instrument for "is this cave sealed?"; what this row adds is what the answer looks like before
anyone digs.
SHARE, recomputed. None, and it was registered as none. "This predicts a property of generated
worlds, and M-311's union-find is the instrument." Nothing here proposes a source change or moves a
stage's time; it changes what a level designer may assume, not what the extractor does. row_ms sits
beside the verdicts and gates nothing — 3.3 to 33.3 ms per rung, 955.4 ms summed over all 84 — and
every clause is an integer count or a comparison of two integer counts, so this host's governor cannot
move a verdict. Determinism: no RNG, both fields are deterministic hash noise, the ladder is arithmetic on
the sampled range, and every sort is on integer keys or f64::total_cmp.
Would be shown wrong by: a resolution above 97³ at which noise_cavity's onset moves materially,
which would mean percolation here is a sampling artefact rather than a property of the field's features —
the row asserts one resolution and claims no other; a 2D slice of noise_cavity on a different plane that
does percolate, which would retire C2's noise_cavity half (the control is z=48 and only z=48); any
row on which air_union_find_agreement reads false, which would put the shipped flood labelling and the
retired union-find in conflict and would be a connectivity.rs bug rather than a finding about caves; or
an unmasked noise_cavity sweep quoted as a cave measurement, which the outer_shell_* columns exist to
refuse.
Discovery loop — results
One entry per EXPERIMENT move of docs/research/2026-09-12-discovery-loop-prompt.md. Each carries two
lines the older entries do not: Surprise:, naming what the result contradicts in
docs/research/what-governs.md, and Raises:, the question it hands back to the ledger.
On the word vacuous. The loop prompt calls a row whose vacuity control fails tier V. This file
already uses V for verified from a primary source (V-51), so a vacuous row is recorded here the way
✗81 was — a falsified entry that says VACUOUS and why. The loop's V and this file's V are not the
same letter twice.
💥 ✗126 / M-490 — VACUOUS as registered, and the reason is the formula's own algebra: at u = ±1 the Gaussian kinematic formula's (u² − 1) factor is zero for any λ, so the 4λ control cannot be rejected on 2 of its 5 rungs — band_rejects_wrong_lambda 3 of 5. Beneath that control the measurements are sharp: C1 HELD on 5 of 5 rungs at relative_departure 0.004342748 / 0.010112782 / 0.004829332 on the three λ-bearing rungs; C2 split, fbm_terrain inside its band at 0.25σ and noise_cavity outside it at 6.77σ; and C3 FALSIFIED at chi_convergence_gap 2.853658537 against a 0.10 bar, with the oracle reproducing M-458's own noise_cavity numbers 82 and −152 exactly and then reading −186 at 129³ (P-178, R-183)
M. cargo bench --bench experiment_p178, docs/experiments/p-178.csv, 22 rows across 21
columns — four # comment lines plus one column header plus 22 data rows, counted from the file. Six
arms, f64, amd-ryzen-9-5900x-12-core (Zen 3), one thread, seed 0x0178_9d5e_c43a_1f07,
REALISATIONS 32, SAMPLES 65, rungs −2, −1, 0, 1, 2 in standard deviations.
crates/isomesh/src/ did not move; this row owns benches/experiment_p178.rs and its [[bench]]
entry and nothing else. The first EXPERIMENT move of the discovery loop, taken because P-178 carried
the highest expected_information (8) of the three registered rows.
The vacuity control failed, and what it failed against is a fact about the theorem rather than about the fixture. The registration reads: "the same run predicts with a deliberately wrong spectral moment,
4λ… if the wrong prediction also lands inside the band the comparison cannot discriminate and the row is vacuous whatever the clauses say." On the 3-torus the prediction is the single termλ^(3/2) · Vol · (2π)^(−2) (u² − 1) e^(−u²/2), so atu = ±1it is exactly zero for everyλ—chi_gkf_predicted0.000000000 on both thegaussian_periodicand thewrong_lambdarows there. Right and wrong predictions are the same number, no band can separate them, and "on every rung" was therefore unsatisfiable the moment±1entered the ladder. The control was written without noticing that two of its five rungs areλ-blind. The threshold was not moved and the clause was not rewritten: the row is recorded vacuous as registered, the harness prints why instead of aborting (an abort would have deleted the CSV that is the evidence), andband_rejects_wrong_lambdacarries true onu = −2, 0, 2— where4λpredicts 109.026525269 / −268.534370494 / 109.026525269 against measurements of 13.687500000 / −33.906250000 / 13.562500000 — and false onu = ±1.
C1 — HELD on 5 of 5, and the two hardest rungs are the parameter-free ones. The fixture is an
exactly Gaussian field on the unit 3-torus: f = N^(−1/2) Σ_j [ξ_j cos(2π k_j·x) + η_j sin(2π k_j·x)]
over the mode shell 1 ≤ |k|² ≤ 14, ξ, η i.i.d. standard normal by Box–Muller on the shared
SplitMix64. Its lambda_spectral is 120.646044199 in closed form, checked against the sampled
central differences and against a unit sample variance before any row is written. Measured against
prediction:
u |
chi_digital_mean |
chi_digital_sem |
chi_gkf_predicted |
relative_departure |
|---|---|---|---|---|
| −2 | 13.687500000 | 0.492765198 | 13.628315659 | 0.004342748 |
| −1 | 0.406250000 | 0.764456605 | 0.000000000 | — |
| 0 | −33.906250000 | 0.554234751 | −33.566796312 | 0.010112782 |
| 1 | 0.031250000 | 0.656057960 | 0.000000000 | — |
| 2 | 13.562500000 | 0.403955992 | 13.628315659 | 0.004829332 |
The λ-blind rungs are useless as a control and are the sharpest check: the theorem says the
expected Euler characteristic is exactly zero one standard deviation either side of the mean,
with no scale to hide behind, and 32 draws give 0.031250000 and 0.406250000 against standard
errors of 0.656057960 and 0.764456605. Nothing in the derivation is transcribed — the four
ρ_j are computed by Simpson quadrature of the paper's ∫_u^∞ H_j(x) e^(−x²/2) dx and by the
closed form that follows from d/dx[H_{j−1} e^(−x²/2)] = −H_j e^(−x²/2), and the two are asserted
equal to 1e-10 before the run proceeds; the box's Lipschitz–Killing curvatures are fitted from the
Steiner tube polynomial and asserted against the box's own geometry.
C2 — split, and the split is the result. With λ estimated from each shipped field's own sampled
derivatives and the band taken from a matched Gaussian ensemble on the same box at the same
resolution through the same bounded digitisation:
| field | lambda_spectral |
chi_digital_mean |
chi_gkf_predicted |
band σ |
gkf_within_band |
relative_departure |
|---|---|---|---|---|---|---|
fbm_terrain |
0.025259313 | 1.000000000 | 1.297632628 | 1.177322687 | true (0.25σ) | 0.229365864 |
noise_cavity |
3.514897286 | 15.000000000 | −6.602285203 | 3.190206789 | false (6.77σ) | 3.271940629 |
The band is not a formality: both matched ensembles land inside their own predictions —
noise_cavity_matched_ksq6 −7.375000000 against −6.606939848 (relative_departure
0.116250514) and fbm_terrain_matched_ksq1 1.031250000 against 1.022851231
(0.008211134) — so the construction that produces the band reproduces the formula on a field that
really is Gaussian, at the same box, resolution and digitisation the shipped row uses. noise_cavity
misses it by 21.602285203 in χ, and the sign is the loud part: the formula predicts a negative
Euler characteristic at the mean level, the field delivers a positive one. The registration's
falsifier names the meaning that applies: "this crate's hash-based lattice noise is far enough from
Gaussian that the formula cannot grade it" — for noise_cavity, and for noise_cavity only. One
caveat is carried rather than hidden: fbm_terrain's matched shell is the coarsest available
(|k|² ≤ 1) and its closed-form λ 0.051404190 is about twice the field's measured
0.025259313, so that band is wider than a perfectly matched one would be and its true is the
weaker of the two verdicts.
C3 — FALSIFIED, and it re-tiers M-458. The clause asks whether χ of a fixed realisation has
converged by the finest rung. Measured on {f < 0} — the crate's own inside test, which is exactly
the solid M-458 read — as surface χ, 2 · χ(solid):
| resolution | surface χ | chi_convergence_gap |
|---|---|---|
| 33³ | 82 | — |
| 65³ | −152 | 2.853658537 |
| 129³ | −186 | 0.223684211 |
The first two numbers are M-458's, exactly, which is this row's strongest single check: a
copied oracle that had drifted could not reproduce 82 and −152 on the nose, and the calibration
arm independently reads calibration_chi_sphere 2 and calibration_chi_torus 0. Both gaps
exceed the 0.10 bar, the second by more than twentyfold. So M-458's "first ground-truth χ on
the two closed fields the crate declares unknowable — noise_cavity 82 and −152" is not two
ground truths; it is two samplings of a quantity that had not converged, and the third rung at
−186 shows it still moving. The registration named this outcome and what it would mean, and that
is what applies. At the standardised level the same fixed field reads −2 / 15 / 21 with gaps
8.500000000 and 0.400000000 — a different set, recorded beside it so the two levels cannot be
confused.
Surprise: docs/research/what-governs.md's Instruments paragraph treated the digital-topology
oracle's outputs as ground truth. They are ground truth about the sampled grid, not about the
field: on noise_cavity the same oracle returns 82, −152 and −186 at three rungs of one fixed
realisation. The paragraph is edited in this commit.
Raises: why does fbm_terrain land inside the Gaussian band and noise_cavity miss it by 6.77σ,
when both are hash noise? The first candidate is stationarity rather than Gaussianity —
noise_cavity carries a spherical cap (fields/mod.rs, radius 1.5, the one P-176 had to mask
around), and the Gaussian kinematic formula's hypothesis is a stationary field on the box it is
integrated over. Logged as Q8.
💥 ✗127 / M-491 — VACUOUS as registered on one field of four, and that field is the finding: box_exact's reach is 0 and this estimator reads 1.000000000, because a measure-zero sharp edge is invisible to both halves of Theorem 3.4 — which presupposes τ > 0 and so never covered it. The other three closed forms land: sphere 0.979703496 against 1.0, torus 0.293412800 against 0.3, capsule 0.342375900 against 0.35, gaps of 0.32h / 0.11h / 0.12h. C1 HELD at 6 bottleneck-bound and 3 curvature-bound of 9; C2 FALSIFIED at an h*/τ spread of 2468.025804 against a 2.0 bar — and 3.339 across the four smooth fields alone; C3 FALSIFIED at bottleneck_distance_auc 0.793001727 on gyroid, 0.007 short of its bar, and unreachable on fbm_terrain, which has no bottleneck at all (P-177, R-182)
M. cargo bench --bench experiment_p177, docs/experiments/p-177.csv, 9 rows across 23
columns — four # comment lines plus one column header plus 9 data rows, counted from the file.
Nine fields (the eight reference fields plus the capsule the registration's calibration names, which
is brush::Capsule and not a reference field), ladder 17 / 25 / 33 / 49 / 65, f64,
amd-ryzen-9-5900x-12-core (Zen 3), no RNG. crates/isomesh/src/ did not move. The second
EXPERIMENT move of the discovery loop; P-177 carried expected_information 7.
Where the reach is measured from matters more than how, and the first run of this harness proved it. Differencing the field's Hessian at the grid spacing caps the measurable curvature at
O(1/h)and so puts a floor of several cells under any reach: that run readtau0.25 onbox_exactath0.0625 — exactly4h, a number about the grid and not about the box. Every field here is an analytic function that can be sampled at any scale, so the instrument differences atCURVATURE_STEP1e-3 instead, andmax_abs_curvature_grid_stepis carried besidemax_abs_curvatureso the gap is visible in the CSV: 0.000000000 against 4.000000000 onbox_exact, 1410.300459162 against 21.643862515 ongyroid, 6854.775391056 against 169.232428002 onnoise_cavity. The grid-stepped column is not a worse measurement of the same thing; it is a measurement of a different thing — the curvature of what the mesh can represent.
The vacuity control — three of four, and the fourth is a category error in the registration. The control asserts four closed forms before any other number is read. Three hold comfortably:
| field | tau_analytic |
tau |
calibration_gap_h |
|---|---|---|---|
sphere |
1.0 | 0.979703496 | 0.324744072 |
torus |
0.3 | 0.293412800 | 0.105395203 |
capsule |
0.35 | 0.342375900 | 0.121985608 |
box_exact |
0.0 | 1.000000000 | 16.000000000 |
box_exact fails, and the reason is not a bug. Its reach is zero because of its edges, and an
edge is a one-dimensional subset of the surface: no vertex of a marching-cubes mesh is required to
land on one, and none did — max_abs_curvature reads 0.000000000, so the Local Case saw a set of
perfectly flat faces. The Global Case then returned the box's genuine bottleneck, 1.000000000,
half the distance between opposite faces. Both halves answered correctly for a positive-reach
manifold, and box_exact is not one: Theorem 3.4 opens with "let M be a compact submanifold
with reach τ_M > 0", so the registration put a field outside the theorem's hypothesis into the
control that anchors the theorem's use. The row is recorded vacuous as registered — no threshold
moved, no clause rewritten — and the harness prints the failure rather than aborting, which is
✗126 / M-490's lesson applied. thin_plate shows the same signature without being in the control:
tau_local unbounded, tau_global 1.000000000, max_abs_curvature_grid_step
24.000000000.
C1 — HELD, 6 bottleneck-bound and 3 curvature-bound. The decomposition is not decorative on this
roster: sphere, torus, box_exact, capsule, csg_difference and thin_plate are global,
and gyroid, fbm_terrain and noise_cavity are local. The split is exactly the smooth/rough
one, and fbm_terrain is the clean case of a field with no bottleneck at all —
bottleneck_pairs 0, tau_global unbounded — which is correct for a heightfield: nothing
faces anything across a gap. noise_cavity is the opposite extreme at 1,857,461 qualifying
pairs.
C2 — FALSIFIED, and the falsification is informative in the direction the registration named.
h*/τ over the nine fields spans 0.250000000 (box_exact, whose τ is wrong) to
617.006450883 (gyroid), a spread of 2468.025804 against a bar of 2.0. The reason is
structural rather than noisy: for a rough field the reach at the scale the field is actually smooth
is minute — gyroid 0.000709069, noise_cavity 0.000145884 — while the extraction settles
its topology at a spacing four to six hundred times larger. Reach is therefore not the denominator
for resolution on this roster. The sharper statement, which the file should carry because it is the
usable half: across the four smooth fields whose τ the calibration validates or nearly does —
sphere 0.255179247, capsule 0.730191583, torus 0.852041902, csg_difference
0.587657905 — the spread is 3.339, still above the bar but within one order of magnitude, and
those four are the fields for which the theorem's hypothesis holds.
C3 — FALSIFIED by 0.007, and unreachable on the second of its two fields. On gyroid the cells
needing a second vertex (28 of them at 33³) do sit nearer a bottleneck axis than the rest —
bottleneck_distance_auc 0.793001727 — but the registered bar is 0.8 and the clause is
scored as written. On fbm_terrain the AUC is unreachable: there are no bottleneck axes to
measure a distance to, bottleneck_pairs 0. Taken with M-486's curl residual reading
0.270443196 on that same field, the registration's stated meaning applies —
"the second-vertex cells are a local combinatorial fact of the trilinear that no geometric
predictor, neither local nor global, will find" — with the qualification that on gyroid the global
predictor came within 0.007 of the bar, which is not nothing and is not a pass.
Surprise: Axis 14's paragraph said the missing denominator was accuracy and named information-based complexity as the unregistered route. It is now measured that reach is not the missing denominator for resolution either — the spread is three orders of magnitude — and Axis 1's "unmeasured" is partly answered: the roster splits 6/3 into bottleneck-bound and curvature-bound fields. Both paragraphs are edited in this commit.
Raises: what certifies a reach of zero? Three of this crate's eight reference fields
(box_exact, thin_plate, and csg_difference at its cut) have sharp features, so no
positive-reach theorem covers them, and the instrument built here reads a confident wrong number
rather than refusing. A detector that answers "this surface has a sharp feature, so τ = 0 and every
sampling theorem is inapplicable" would be the precondition for any future use of this family.
Logged as Q9.
💥 ✗128 / M-492 — the detector works, and it says the opposite of what was registered: C2 HELD on 4 of 4 closed forms — box_exact flagged, sphere, torus, capsule not — with the control separating a 90° crease from a 0.05 fillet and recovering the fillet's curvature as 19.927397 against 20 (0.36%). C1 FALSIFIED on its sharp half: thin_plate has the registered limiting spread of 90.000° but a finest-rung ratio of 0.50000, below the 0.8 bar. C3 FALSIFIED, which is the consequential direction the registration named: gyroid (0.99012) and noise_cavity (0.99990) come back flagged, so M-491's τ of 0.000709069 and 0.000145884 are floors rather than quantities (P-181, R-186)
M. cargo bench --bench experiment_p181, docs/experiments/p-181.csv, 55 rows across 15
columns — nine reference fields plus two synthetic controls, five probe radii each. Radii
0.1 / 0.05 / 0.025 / 0.0125 / 0.00625, 48 Fibonacci directions per ball, gradients differenced
at 1e-5, f64, amd-ryzen-9-5900x-12-core, no RNG. crates/isomesh/src/ did not move. The
third EXPERIMENT move of the discovery loop; P-181 carried expected_information 8.
The vacuity control separated, and this is the first row of the loop where it did. The quarter-space
max(x, y) reads 90.00° at every radius — ratio 1.000000, flagged. The same wedge filleted at
0.05 reads 90.00 / 90.00 / 59.21 / 28.70 / 14.27°: sharp while the ball is wider than the
blend, converging once it is not, ratio 0.497268, unflagged. Its curvature read off the spread's
own slope, κ ≈ spread / 2r with no Hessian anywhere, is 19.927397 against 1/0.05 = 20 —
0.36%. A detector that could not tell those two apart would have voided the row.
One implementation defect, found by the control and fixed before any verdict was read. The first version took the ratio as the maximum over every rung. That flagged the fillet, whose ratio is 1.000 across
r = 0.1 → 0.05— both at or above the blend radius, where a fillet genuinely does look sharp. The registration's words are that a crease's ratio "stays above 0.8 down the ladder", and down the ladder is the fine end, so the statistic is the finest rung's ratio. The bar was not moved; the quantity was made the one the sentence names. The full ladders are in the CSV, five rows per field, so any reader can recompute either statistic.
| field | ladder (degrees) | finest ratio | flagged | tau_known |
|---|---|---|---|---|
sphere |
11.48 / 5.72 / 2.86 / 1.43 / 0.71 | 0.49969 | false | 1.0 |
torus |
38.90 / 19.12 / 9.55 / 4.77 / 2.38 | 0.49930 | false | 0.3 |
capsule |
33.20 / 16.42 / 8.19 / 4.09 / 2.05 | 0.49976 | false | 0.35 |
box_exact |
90.00 × 5 | 1.00000 | true | 0.0 |
csg_difference |
129.04 / 125.54 / 123.85 / 123.04 / 122.63 | 0.99672 | true | — |
thin_plate |
180.00 × 4 / 90.00 | 0.50000 | false | — |
gyroid |
145.18 / 145.97 / 140.35 / 137.59 / 136.23 | 0.99012 | true | — |
fbm_terrain |
94.01 / 61.73 / 33.98 / 17.47 / 8.80 | 0.50362 | false | — |
noise_cavity |
179.75 / 179.89 / 179.99 / 179.99 / 179.97 | 0.99990 | true | — |
C2 — HELD on 4 of 4, which is the result worth keeping. The verdict agrees with every closed form:
flagged exactly where τ = 0 and unflagged on all three positive-reach fields, whose ratios cluster at
0.4993–0.4998 — the O(r) decay a C² surface must show. M-491 could not do this: its
estimator returned a confident 1.000000000 on box_exact. There is now an instrument in this
repository that says when a sampling theorem does not apply.
C1 — FALSIFIED on its sharp half. thin_plate clears the limiting-spread bar at 90.000° and
misses the ratio bar at 0.50000, because its ladder is 180° at four rungs and 90° at the
fifth: the probe found the plate's two faces — antiparallel normals, spread π — long before it
found the rim, and the collapse to 90° at the finest radius is the ball stopping straddling the plate.
The registered falsifier's meaning applies in a narrowed form: the angular spread is the signal,
but it is the signal for "not C²-simple at scale r", which covers a crease and two sheets
closer than r. On a field that is both, the thicker feature wins the search.
C3 — FALSIFIED, on the falsifier the registration called the most consequential available.
gyroid at 0.99012 and noise_cavity at 0.99990 are flagged; only fbm_terrain at
0.50362 is not. The registered meaning: "those fields have reach exactly zero rather than merely
small, and M-491's C2 spread of 2468.025804 was measuring a floor rather than a quantity." That is
now the reading of ✗127's τ on those two fields — 0.000709069 and 0.000145884 are what a
grid-limited search returns on a surface that has no positive reach, not measurements of one. With
box_exact, csg_difference and thin_plate (flagged by its 180° rungs even though its finest ratio
is not), five of this crate's eight reference fields are outside every positive-reach theorem's
hypothesis, and fbm_terrain at ratio 0.50362 is the one rough field that is not.
Surprise: Axis 14's new paragraph said reach is not the denominator for resolution because h*/τ
spans three orders of magnitude. The reason is now sharper and worse: on two of the three fields
driving that spread, τ is not a small number but an absent one. The paragraph is edited in this
commit.
Raises: fbm_terrain is the only rough field the detector clears — ratio 0.50362, clean O(r)
decay — and it is also the only field with no bottleneck at all (✗127, bottleneck_pairs 0)
and the one that landed inside the Gaussian kinematic band (✗126, 0.25σ). Three independent
instruments single out the same field. Is fbm_terrain the roster's only field that satisfies the
regularity hypotheses this crate's theorems are written against — and if so, is a heightfield the only
shape the ledger can currently prove anything about? Logged as Q10.
💥 ✗129 / M-493 — the cap was the sign, and it was not the gap. On the sphere's inscribed cube noise_cavity flips from χ 15 against −6.602285203 to χ −67 against −89.439644587 — right sign, 2.94σ, still outside the band: C1 FALSIFIED. C2 FALSIFIED beside it, skewness 0.149388749 against a 0.1 bar and excess kurtosis −0.315140997 against 0.2 — the consistent pair the registration named. C3 HELD: fbm_terrain inside on its own sub-box at 0.25σ / 0.26σ and the full-box noise_cavity row reproducing M-490's miss at 6.57σ. The vacuity control passes (4λ predicts −776.378808583 against an ensemble of −91.5625 ± 7.628205302). And the premise was wrong by arithmetic: the inscribed cube is cap-free in sign and not in value — cap_dominated_share 0.121813382 where the registration said the noise dominates, because the cube's corners lie on the sphere, where the cap term is 0 and not −0.633974596 (P-180, R-185)
M. cargo bench --bench experiment_p180, docs/experiments/p-180.csv, 8 rows across 24
columns — four # comment lines plus one column header plus 8 data rows, counted from the file; 18
registered records and six extra columns (arm, matched_ksq, matched_lambda, matched_chi_mean,
matched_chi_predicted, wrong_lambda_predicted) that make the band's provenance readable. Three
arms, f64, amd-ryzen-9-5900x-12-core (Zen 3), one thread, seed 0x0180_5f2a_9c1d_7e43,
REALISATIONS 32 per band, FULL_SAMPLES 65, sub-box at 29 (h-matched: side 1.732 at
the full box's h = 0.0625 is 28 cells) and 65 (finest). crates/isomesh/src/ did not move;
this row owns benches/experiment_p180.rs and its [[bench]] entry and nothing else. The fourth
EXPERIMENT move of the discovery loop, and the first taken on a question the loop itself raised (Q8,
from ✗126).
The instrument is M-490's, and it proves it before any verdict is read. Every function from the
block census to the central-difference μ₂ is experiment_p178.rs's verbatim (rho_quadrature and
its assert are the one omission — M-490 already asserted the closed form against it to 1e-10 on
these rungs). Two VOID: asserts stand in front of the clauses: the calibration arm reads surface χ
2 on sphere and 0 on torus, and the full-box arm must reproduce M-490's own rows. It
does, to the digit: noise_cavity chi_digital 15, chi_gkf_predicted −6.602285203,
lambda_spectral 3.514897286; fbm_terrain 1, 1.297632628, 0.025259313. Only the band
differs, because the seed does: band_sigma 3.286703418 against M-490's 3.190206789, so the
same miss reads 6.57σ here and 6.77σ there.
C1 — FALSIFIED, and the sign is the part that moved. On the inscribed cube, half-side 0.866025404, with the cube's own Lipschitz–Killing curvatures and a matched ensemble drawn on the cube:
| region | n |
lambda_spectral |
chi_digital |
chi_gkf_predicted |
band_sigma |
sigma_distance |
gkf_within_band |
cap_dominated_share |
|---|---|---|---|---|---|---|---|---|
| full | 65 | 3.514897286 | 15 | −6.602285203 | 3.286703418 | 6.572629915 | false | 0.861374602 |
| inscribed | 29 | 66.970843691 | −99 | −64.868032207 | 6.860064422 | 4.975458785 | false | 0.133912830 |
| inscribed | 65 | 81.824833503 | −67 | −89.439644587 | 7.628205302 | 2.941667627 | false | 0.121813382 |
Three things are in that table. First, M-490 was grading a sphere: on the full box 86.1% of
samples take the cap's value rather than the noise's, the standardised field's λ is 3.51 — the
sphere's unit gradient over a cap-dominated standard deviation — and the noise's own λ on the cube
is 67–82, twenty times larger. The full-box comparison in ✗126 was never a comparison between
the formula and a noise field. Second, the sign is now right: negative χ predicted, negative χ
measured, at both rungs. Third, the gap is not closed: 4.98σ at the h-matched rung and 2.94σ
at the finest, both outside the registered 2σ band. The band is not a formality here either — the
matched Gaussian ensembles land inside their own predictions at 0.37σ (−64.8125 against
−62.247676475, |k|² ≤ 25) and 0.08σ (−91.5625 against −90.969323723, |k|² ≤ 30), with
the shells matched to within 2.5% and 1.1% of the field's λ, far better than M-490's full-box
shells could. So the construction reproduces the formula on a field that is Gaussian, at this box,
resolution and digitisation, and noise_cavity misses it. The registration's falsifier names the
meaning that applies: "the sub-box missing the band too … moves the blame from stationarity to
Gaussianity: the crate's hash noise would then be non-Gaussian in a way the formula cannot grade
anywhere, and C2's two moments are the measurement that says how" — subject to the confound below.
C2 — FALSIFIED, in the direction a clamp produces. On the finest inscribed grid, standardised,
population moments over all 274,625 samples: skewness 0.149388749 (bar 0.1),
excess_kurtosis −0.315140997 (bar 0.2). Both outside. C1 and C2 fail together, which is the
registration's consistent case — not the "more interesting failure" of the formula surviving a field
that is measurably non-Gaussian. But the two signs are exactly what a floor under the lower tail does
to a symmetric distribution: cut the left tail and the skew goes positive and the kurtosis goes
negative. Whether that floor is the Perlin noise's own bounded range or the cap's 12.2% of samples
cannot be told from this row, and the entry does not pretend otherwise.
C3 — HELD, both halves. fbm_terrain on its own sub-box (half-side 3.464101616, the same
0.433012702 share of its half-extent) reads χ 1 against 1.297453083 at 29³ and 1 against
1.294003447 at 65³, sigma_distance 0.250029215 / 0.256037977 — inside, and unmoved from the
full box's 0.31σ. The full-box noise_cavity row is M-490's. The restriction did not manufacture
agreement on the field that already had it, and did not remove the miss on the field that did not.
fbm_terrain's caveat carries over unchanged from ✗126: its matched shell is the coarsest available
(|k|² ≤ 1, λ 0.274155678 against a measured 0.125960462 / 0.146086512), so its band is
wider than a perfectly matched one would be.
The vacuity control passed, and the way it was written is why. Scored at
u = 0only, on the finest inscribednoise_cavityband, as registered: the4λprediction is −776.378808583 against an ensemble mean of −91.5625 withσ7.628205302 — rejected by ninety standard deviations.band_rejects_wrong_lambdais true on all four inscribed rows andnaon the full-box rows, where it is not scored. This is the second row of the loop whose control separated, and the first of the three Gaussian-kinematic rows.The registered premise was wrong, and the registered record caught it. The hypothesis says of the inscribed cube: "inside it the cap term is at most −0.633974596 and is dominated by the noise."
−0.633974596is0.866025404 − 1.5, the cap's value at the cube's face centres. The cube's corners are at0.866025404·√3 = 1.5— on the sphere — where the cap term is 0, and it is at most−0.633974596only inside the cube's inscribed ball. So the intersection'smaxpicks the cap on 13.4% of theh-matched grid and 12.2% of the finest one, all near the corners, and the pre-run expectation of< 0.01was off by an order of magnitude. What survives: the cap is strictly negative everywhere inside the cube except the eight corners, somax(noise − 0.25, cap) > 0exactly whennoise − 0.25 > 0— the raw sign on the cube is the noise's, and the cube is cap-free in the sense that decides occupancy at the field's own zero. What does not survive: the census is taken at the standardised zero,v > mean(v), andmean(v),λ, and both moments are computed from values, 12% of which are the sphere's. No threshold was moved and no clause rewritten; the confound is recorded on everynoise_cavityrow ascap_dominated_share, which is why the registration listed it.
One more number that was not predicted. Between the two sub-box rungs, chi_digital moves −99 →
−67 and chi_gkf_predicted moves −64.87 → −89.44 — in opposite directions. The digital χ is
✗126's C3 again (a random field's χ has not converged at these rungs); the prediction moves because
λ from central differences rises 66.97 → 81.82 as h halves, the noise having gradient energy
below h = 0.0625. Neither side of the comparison is a converged quantity at 65³, and the sigma_distance
column should be read with that in front of it.
Surprise: docs/research/what-governs.md's Instruments paragraph left "whether the difference
is Gaussianity or stationarity" open. It is no longer open in the form it was asked: the cap set the
sign (and 86% of M-490's full-box field), and once the cap is out of the sign the formula still
misses by 2.94σ on a grid whose third and fourth moments are outside the Gaussian bars. The paragraph
is edited in this commit.
Raises: are the moments the noise's or the clamp's? NoiseVolume::canonical() alone — no
intersection, cap_dominated_share 0 by construction — on the same inscribed cube at the same two
rungs: if skewness 0.149388749 and excess_kurtosis −0.315140997 persist, the crate's Perlin
noise is non-Gaussian in its own right and the formula's miss is the field's; if they fall inside the
bars, the 12% clamp produced C2 and the remaining miss is the unconverged λ and χ above. Logged as
Q11.
🔬 M-494 — **all three clauses HELD, and the landing cost what the ticket said it would plus five contracts nobody had priced. C1: the six prescribed-genus fields read their construction's χ under Marching Cubes at 17³, 25³ and 33³ — 0 / −2 / −2 / −4 / −4 / −8 for ball_drilled_g1, graph_theta_g2, ball_drilled_g2, ball_drilled_g3, graph_k4_g3, graph_cube_g5 — on closed meshes, with sphere and torus reading 2 and 0 through the same helper. C2: golden_hashes.json 216 → 378, 162 entries added, 0 hashes changed (163 lines in, 1 out: the old last entry re-emitted with a trailing comma). C3: graph_cube_g5 reads χ −8 at 7³, 0 triangles at 9³, −8 at 11³ — p-140.csv's row, now a shipped test. The roster is fourteen, and the first full run of the suite over it failed 21 tests: 16 were counts and pinned tables, 5 were contracts the eight-field roster had let stand — pinned with their numbers and owned by R-187 (P-182, R-177)
M. A landing, so there is no CSV; the evidence is cargo test -p isomesh --lib on the landing
commit (730 tests, all green after the pins below), the golden diff, and scripts/doc_facts.sh
reading 14 fields, 378 golden hashes from the tree. crates/isomesh/src/fields/prescribed.rs is
new; for_each_reference_field! grew from 8 to 14 blocks; isomesh_web's registry from 8 to 14
entries; six bevy_isomesh examples and ~100 benches iterate fourteen fields without a line changed.
f64, amd-ryzen-9-5900x-12-core. The thirteen registered records:
field |
prescribed_genus |
prescribed_chi |
measured_chi_17 |
measured_chi_25 |
measured_chi_33 |
MC triangles 17 / 25 / 33 |
|---|---|---|---|---|---|---|
ball_drilled_g1 |
1 | 0 | 0 | 0 | 0 | 1,712 / 3,744 / 6,720 |
graph_theta_g2 |
2 | −2 | −2 | −2 | −2 | 688 / 1,416 / 2,640 |
ball_drilled_g2 |
2 | −2 | −2 | −2 | −2 | 1,864 / 4,120 / 7,208 |
ball_drilled_g3 |
3 | −4 | −4 | −4 | −4 | 1,936 / 4,328 / 7,928 |
graph_k4_g3 |
3 | −4 | −4 | −4 | −4 | 752 / 1,712 / 3,296 |
graph_cube_g5 |
5 | −8 | −8 | −8 | −8 | 1,408 / 2,800 / 4,672 |
golden_entries_before 216, golden_entries_after 378, existing_hashes_changed 0,
g5_triangles_9 0, c1_holds / c2_holds / c3_holds true / true / true.
What landed, and how the genus is carried. DrilledBall<R, const G: usize> (construction A, a ball
of radius 1.55 with G z-parallel bores of radius 0.28; χ = 2 − 2G by Mayer–Vietoris) and
ThickenedGraph<R, const G: usize> (construction B, the 0.28-neighbourhood of an embedded graph with
b₁ = G; χ = 2·(V − E) by graph thickening) — no_std, generic over Real, arrays in every public
signature, analytic gradients, one dependency still. The genus is a type parameter because
ReferenceField::NAME is one constant per type and is the golden fixture's key, so six fields need six
types; expected_euler() is Some(2 − 2·G) with no runtime field to drift, and experiment_p80.rs's
name == F::NAME invariant survives. Each constructor's doc carries both derivations P-140 used.
bound() is Lipschitz { l: 1.0 } on all six, and not by default: the fields are min/max
compositions of exact distances, so they are 1-Lipschitz and underestimate everywhere — but no
positive q exists for Underestimate, because at an off-centre bore's rim or a tube junction the
nearest wall point the formula measures to is outside the solid and |f| / d → 0.
The vacuity controls — one satisfied, one misworded and satisfied in substance. sphere and torus
go through chi_at beside the six and read 2 and 0. The registration's second control said
scripts/doc_facts.sh "fails at the parent of the landing commit and passes at it" — which cannot
happen: the parent is self-consistent (eight blocks, 216 entries, prose saying so) and the gate passes
there. What the control meant, and what was run, is the gate against the mixed state the landing
passes through: with the macro at fourteen and the prose untouched it failed on seven sites
(README.md ×2, DEMOS.md, algorithms.md ×2, correctness.md, experiments.md), and with the
fixture blessed it would have flagged the three 216 golden hashes sites beside them; at the landing
it passes on 14 fields, 378 golden hashes. Seven of the ten sites were renumbered; the three that
quote a historical measurement were dated instead — "five of the eight fields the roster held when
this was measured (M-40)" is true and "five of the fourteen" would not be. Gate 5 of the loop
prompt, added this morning for ✗126 and ✗127, is the rule this control broke: its predicate was
never evaluated on a synthetic case before registration.
Five contracts the eight-field roster let stand, each pinned by name with its number (R-187). The
first cargo test -p isomesh --lib over fourteen fields failed 21 tests. Sixteen were the ripple
the ticket priced — checked == 8 / rows == 8 / 24 counts, the golden fixture, and the subgrid
suite's nine name-keyed tables, extended with eighteen measured rows each in the file's own
"pinned rather than asserted to zero" idiom. Five were contracts:
| # | test | contract | what the roster read | pinned as |
|---|---|---|---|---|
| 1 | marching_tetrahedra::every_closed_reference_field_meshes_cleanly |
every closed field reads its χ at 17³ and 33³ | graph_k4_g3 at 17³: χ −16 against −4, on a closed manifold mesh; −4 at 33³; Marching Cubes −4 at 17³. P-140's number exactly |
("graph_k4_g3", 17, −16) |
| 2 | trilinear::how_often_a_face_is_singular |
(0, 0) — "a continuous field essentially never does" (M-220) |
72: graph_theta_g2 24 of 32 and graph_k4_g3 48 of 96 ambiguous faces at 17³, zero at 33³ and 65³, zero on 400,000 random cells |
(72, 0) |
| 3 | field_bound::tightening_a_declaration_by_one_step_is_caught |
claiming Exact on a Lipschitz field is caught |
not caught on any of the six: ‖∇f‖ = 1 a.e. — M-245's blind spot, on Lipschitz rows for the first time |
unrefutable == 6, asserted not caught |
| 4 | dual_contouring::the_clamp_measured_on_every_reference_field |
the A-009 clamp never increases λ | ball_drilled_g1 at 33³: 4 → 8 intersecting pairs over 6,720 triangles (0.595 → 1.190 per 1,000). One rung: M-109 records the clamped-against-split λ ordering reversing three times across nine resolutions, so this is a 33³ fact until the sweep says otherwise |
(4, 8, 6720) |
| 5 | subgrid::whether_bigons_are_what_leaves_positions_unreferenced |
bigons == 0 ⇔ orphans == 0 — the test's biconditional. M-205's law is one-directional: "one pair per bigon nothing else reaches", so a bigon whose crossings a neighbour consumes leaves nothing, and the ledger never claimed the converse |
graph_cube_g5: 24 bigon regions, 0 orphans; the other thirteen fields hold it at exactly two orphans per affected tetrahedron. M-205's qualifier observed, not its law broken — the falsified sentence is the test's |
(24, 0) |
Row 2 is the one that rewrites a sentence: README.md's Not yet table said the singular face is one
"quantised input reaches and continuous f64 does not". It does — whenever the field's mirror
symmetry is the grid's. The theta graph's poles sit on grid vertices at h = 0.25 and both graphs are
symmetric through grid planes, so a face straddling a symmetry plane has v₀ = v₃ and v₁ = v₂ to the
bit and the diagonal products tie. The decider resolves those 72 faces to separated, which Grosso
2017's Definition 3.2 calls topologically incorrect, and P-140 says χ survives it at 17³ on both.
Not claimed. Manifoldness. P-140's ten measured_genus = none pairs stay None; the subgrid
suite's eighteen new rows carry no non-manifold edge or vertex on any of the six at any of the three
rungs, and their flipped-edge column (17 / 27 / 25 / 42 at 17³ on four of them) goes to 0 under
orient on every row, so the orientation law held without a pin. Dual contouring, surface nets and the
subgrid extractor are non-manifold on many of these pairs in p-140.csv, and nothing in the suite now
says otherwise.
Surprise: two. what-governs.md's Axis 1 called the roster nine fields and Axis 6 said χ is known
exactly on "the one field" — it is fourteen, and χ is asserted on eight closed fields; both paragraphs
are edited in this commit. And A-002i's premise, that the singular face needs quantised input, is
false on symmetric continuous data — Axis 6 carries that too.
Raises: do the six clear ✗128's crease detector? They are unions of balls, cylinders and tubes with
C¹ seams at the drill lines and tube junctions — gradient direction continuous across a seam,
curvature not — and their reach is not known in closed form. One run of experiment_p181's ladder over
them decides whether ✗127's split gains six smooth closed prescribed-χ fields. Logged as Q12.
💥 ✗130 / M-495 — M-31's cross-platform guarantee broke on the first push of M-494: macOS read 48 of 378 golden hashes drifted — every algorithm at every resolution on graph_theta_g2 and ball_drilled_g3, and nothing else — with vertex and triangle counts identical and hashes differing in the last ULP. The cause was two tokens in the new module: ring() computed its three-point ring with a.cos() on a concrete f64, which under #[cfg(test)] extern crate std resolves to the platform's libm rather than Real::cos. Fixed by naming libm::cos/libm::sin; on Linux the re-bless moved exactly those 48 rows and no other, and the new values match neither glibc's nor Apple's — three backends, three roundings, and now one (R-177, follow-up to P-182)
M. gh run 34712346655, test (macos-latest) job 103603257989: golden_hashes_are_unchanged
and the_committed_fixture_is_canonically_formatted failed, 728 of 730 passed; test (ubuntu-latest)
green on the same commit. The drift list from the CI log, tallied: 24 combinations on
graph_theta_g2 and 24 on ball_drilled_g3 — 8 algorithm rows × 3 resolutions each — and 0 on the
other twelve fields; 48 of 48 with unchanged vertices and triangles. Locally, after the fix,
ISOMESH_BLESS=1 moved 48 hashes, the same set to the row, and none of the other 330.
The mechanism, and why 216 hashes never saw it. lib.rs is #![no_std] and links std only under
#[cfg(test)] (lib.rs:103). Every existing field computes through the generic R: Real, whose
sin/cos/sqrt are libm's pure-Rust functions on both scalar types, so their values are
bit-reproducible — which is the whole argument for libm in CLAUDE.md, and M-31 measured it holding
on 216 hashes across macOS and Linux. ring() broke the pattern: it built the ring's (x, y) in plain
f64 before R::from_f64, and on a concrete f64 an inherent method wins over a trait method — so
under test a.cos() was f64::cos, the platform's libm, and the fixture blessed on glibc carried glibc's
cos(2π/3). ball_drilled_g2's ring is at angles 0 and π, where every backend agrees to the bit;
ball_drilled_g1, graph_k4_g3 and graph_cube_g5 use no trig at all. So the leak landed on exactly the
two fields with a three-point ring, and on every mesh of each.
Three backends, three answers. The 48 new Linux hashes equal the macOS run's values on 0 rows: glibc,
Apple's libm and pure-Rust libm round cos(2π/3) and sin(4π/3) three different ways in the last bit,
and the fixture now carries the third on both platforms. M-31's sentence stands as written — the 378 are
generated on one platform and verified on the other — but the reason it held for 216 was narrower than the
prose implied: no earlier field had put a trig call on a concrete float.
Surprise: none in what-governs.md; the belief that libm makes the fixtures reproducible is right, and
what was wrong was a method-resolution trap in one new function. Rule added to Part 5, with this incident.
Raises: none — the fix is the rule, and the macOS re-run on the fixed commit is its test.
Phase 29 — fifty registrations from twenty-six fields of mathematics, each before its harness
Date: 2026-09-04 · Repo state: 31ac0b8 on mac-air (main = origin/main; confirm big has not
moved before registering), 600 findings entries, 25 open tickets
Corpus: home-still, 9,602 documents, 293,344 chunks, both scribe instances healthy, distill on CUDA
Companion: docs/research/2026-09-04-phase-29-axes-and-vocabulary-v3.md (the words)
Numbering. Phase 27 closed at P-176; Phase 28's five tickets (R-177–R-181) are landings and carry
no P-. Drafted as P-177–P-226 against tickets R-182–R-231 on the mac-air checkout at 31ac0b8,
then shifted by six at the 2026-09-12 merge into big's main, because the discovery loop
(docs/research/2026-09-12-discovery-loop-prompt.md) had by then registered P-177–P-182 against
R-182–R-187 in crates/isomesh/src/experiment.rs and landed four of them with their CSVs
(✗126–✗129, M-490–M-494) — landed numbers never move, the arriving text does, as M-440's
phase did twice. Every artefact in this phase — this section, the fifty backlog rows and both source
documents — carries the final numbers P-183–P-232 / R-188–R-237, and nothing else moved.
Method. Twenty-six areas were probed against the corpus and the repository at once, on the rule the
2026-08-23 sweep earned. This time the probes were chosen by reading Phase 27's results rather than its
registrations: every group below hangs on a measured number from M-440–M-489 that the field in question
can explain, bound, or replace. Roughly 40 semantic queries and 60 word-boundary greps; 23 papers acquired (converted or
converting at time of writing), 27 recorded as paywalled or unreachable by the resolver, and 2
acquired by a wrong DOI and flagged for removal (§1).
The calibration, restated. Present at 0.65–0.72; absent at 0.54–0.62 with an unrelated top hit. Two subjects this sweep needed were already present and never cited: Niyogi–Smale–Weinberger (0.69) and Cuel–Lachaud–Thibert's multigrid-convergent Voronoi estimator (in the corpus with a proved theorem). Both are Group E's and Group C's fault for not having been searched, not the corpus's.
Protocol. Phase 15's protocol applies in full. All fifty P- entries are registered in
crates/isomesh/src/experiment.rs before any harness commit; that registration is the first commit of
the phase and is the only write to crates/isomesh/src/** that precedes a measurement. ✗51's rule is
applied: every clause stated as a ratio of a total carries a SHARE line, and every registration carries a
VACUITY CONTROL naming the column that proves the fixture could have failed.
0. The headline, and it is not a paper either
Phase 27's headline was an identity already in the crate's source. This phase's is a sum already
available to it. The extractor indexes every surface cell by its 2×2×2 sign configuration — the 256-entry
case index. Ziegel & Kiderlen (2010) prove that a weighted sum over exactly those configuration counts
estimates surface area with an asymptotic worst-case error under 4%, and that no local weighting can do
better [verified, read after conversion: "Using this optimal weight vector, (9) will imply that the
relative worst case error is asymptotically less than 4%"; only five configuration types carry weight,
the weight family is λ̄ = (sr, 1.358, 2.352 − sr, 0.960, s(1 − r)) with r ∈ [0,1], s ∈ [1.663, 1.745];
Lindblad's earlier weights reach 7.3%; the space spanned by all 2×2×2 h-functions has dimension
50; the result is stated for the Gauss digitization, which is what field.sample()'s sign grid is,
and the authors say it "only hold[s] for digitizations with good or very good resolution"]. Legland, Kiêu & Devaux (2007) give the lattice Crofton
version with 13 directions and an explicit directional bound of −7.33%/+2.27% [verified, read in
full], and their Table 2 reads 1600 against a true 2400 for an axis-aligned cube with 3 directions.
That matters here for one reason. Phase 27's largest structural finding was that four of eight reference
fields are ungradeable: validate::accuracy needs field.bound() == Exact, and ✗107's anisotropy
mechanism demonstrably worked on the one field (fbm_terrain) that could not be graded. A mesh-free area,
mean curvature and Euler characteristic from the sign grid alone grade every field, and their error is a
theorem rather than a bound the field must volunteer. Group A lands that instrument and Groups B, J and Q
use it.
Three further things were verified during the sweep and are recorded once here:
- The lattice-point discrepancy of a sphere has exponent between
1/2and21/32inx = R²:P₃(x) = O(x^{21/32+ε})(Heath-Brown),Ω±(x^{1/2}(log x)^{1/2})(Szegő; Tsang), and Jarník's mean-square∫₀ˣ P₃² = c₃X² log X[verified, Ivić et al. §2]. In radius: RMS jitter~ R (log R)^{1/2}against a surface-cell count~ R². That is a prediction for how much a translating sphere's triangle count flickers, and Group M registers it. - The expected number of critical points of an isotropic Gaussian field depends on the covariance only
through
ρ'(0)andρ''(0)[verified, Cheng & Schwartzman §1, §3]. Two numbers predict the ambiguous cell census. Group B's fixture is what makes that testable. - Weyl–Steiner: the volume of the
r-offset of a set is a polynomial inrwhose coefficients are the intrinsic volumes, forrbelow the reach [verified, Taylor 2006 §1, eq. 1.1]. For an SDF ther-offset is{f ≤ r}for free, so the reach is the radius at which a cubic fit breaks. Group E.
1. What the twenty-six probes found, in one table
| Area | Corpus | Repo cites | Verdict |
|---|---|---|---|
| Integral geometry / stereology (intrinsic volumes, Crofton, configuration weights) | ABSENT (0.60) → acquired Legland, Schladitz, Ziegel–Kiderlen, Lindblad ×2, Schmalzing | 0 | The headline. Group A |
| Random-field geometry (GKF, Kac–Rice, EC densities) | ABSENT (0.60) → acquired Taylor 2006, Cheng–Schwartzman, Letendre | 0 | Group B |
| Digital geometry (digital planes, multigrid convergence) | ABSENT (0.60) for planes; PRESENT Cuel et al. for multigrid convergence | 0 | Group C |
| Higher-order output (PN triangles, superconvergence, Richardson) | marginal (0.65, a textbook); PN/Wang–Olano/ZZ paywalled | 0 | Group D — the lever ✗116 named |
| Reach, tubes, ε-samples | PRESENT 0.69 NSW; Berenfeld already held; acquired Aamari | 0 | Group E — paid for, unmined |
| Besov / Hurst / tree approximation | ABSENT (0.61); DeVore, CDDD paywalled | Hurst in 4 files, no exponent measured |
Group F |
| Entropy rate / source coding | ABSENT (0.57); Ziv–Lempel paywalled | 0 | Group G — Phase 25's denominator |
| Kinetic data structures | PRESENT 0.64 (Acar ×2, Agarwal) | 3 mentions, no certificate | Group H |
| Optimal transport | ABSENT for surfaces (0.66 wrong docs) → acquired Peyré–Cuturi, Solomon | 2 mentions | Group I |
| Robust statistics; conformal prediction | ABSENT (0.66 / 0.60) → acquired Angelopoulos–Bates; Huber paywalled | Huber 1 file |
Group J |
| Quantum information (3-tangle, SLOCC) | ABSENT → acquired CKW, Dür–Vidal–Cirac | W-state named in P-131 |
Group K |
| Discrete Morse on cubical grids; QTAIM/Bader | ABSENT (0.60) → acquired Robins–Wood–Sheppard, Yu–Trinkle | ranked #7 on 2026-08-23, never done | Group L |
| Analytic number theory (lattice points) | ABSENT (0.59) → acquired Ivić et al. | 0 | Group M |
| Crystallographic symmetry reduction | ABSENT (0.58) | space group named in P-143 |
Group N |
| Shape / topological derivative | ABSENT (0.65, topology-optimisation paper) → acquired Sokolowski–Zochowski | 0 | Group O |
| Stochastic sampling / dither | ABSENT (0.62); Cook, Wannamaker paywalled | Poisson-disk 1 file |
Group P |
| Design of experiments | not probed in corpus; McKay–Beckman–Conover paywalled | 0 | Group Q |
| Backward error / conditioning | ABSENT (0.62) | 0 | Group R |
| Affine arithmetic | PRESENT 0.68 Fryazinov et al. | 8 files | Group S — a different use |
| Digital topology / Alexander duality | ABSENT (0.58); Kong–Rosenfeld paywalled | well-composedness mined | Group T |
| Currents / flat norm | ABSENT → acquired Morgan–Vixie | 0 | Group U |
| Approximation constants (Blu–Unser) | held since Phase 27 | 0 for the constant | Group V |
| Chen–Stein / Poisson approximation | ABSENT; Arratia et al. paywalled | 0 | Group W |
| Coarea / divergence theorem | ABSENT (0.55) | 0 | Group X |
| Quasi-Monte Carlo / discrepancy | ABSENT (0.60); Dick–Kuo–Sloan paywalled | 0 | Group Y |
| Harmonic analysis of the error field | not a corpus subject | 0 | Group Z |
| Isogeometric analysis | ABSENT → acquired Hughes et al. (HTML) | 0 | vocabulary only |
| Extreme-value theory for frame times | ABSENT (0.65, wrong field) | 0 | killed — not a meshing question |
| Gaussian-process implicit surfaces | PRESENT (sig2026) | 0 | deferred — Pöthkow paywalled, and Group J's conformal row covers the use |
Killed during the probe, so nobody re-searches them. Extreme-value theory for the worst frame — a statistics-of-the-harness question, not a meshing one. Sum-of-squares certificates for empty cells — the 2026-08-26 audit already showed the box's Positivstellensatz is Handelman's LP and the Bernstein form is that certificate; nothing new. Spectral graph theory of the cave graph — gameplay, not extraction. Well-composed repair before extraction — mined on 2026-08-23. Cellular automata, sheaves, category theory, Ramsey theory — probed for a hook into a measured number and none was found.
Corrections owed to earlier documents. 2026-08-29-phase-27-fifty-experiments...md:117-124 lists nine
paywalled DOIs and the prose says six; Phase 27's M-440 already recorded that. This document's own count is
twenty-seven and is in §1 below. 2026-08-12-axes-and-vocabulary.md Axis 10 says chunk consistency has no
theory; Group N's mirror-plane seams are a theorem for the symmetric case.
Two DOI traps, both this session's own. 10.48550/arXiv.1504.01720 was downloaded as Letendre 2016
and is Isoperimetric regions in ℝⁿ with density rᵖ; Letendre is arXiv:1408.2107 (acquired).
10.1016/j.cviu.2014.04.005 was downloaded as Coeurjolly–Lachaud–Levallois and is an action-recognition
paper; the correct DOI is 10.1016/j.cviu.2014.04.013 (acquired, HTML). Both wrong papers are now in the
corpus and should be removed with the hs CLI — the MCP has no delete.
Blocked acquisitions — paywalled or unreachable by the resolver this session. Lindblad 2005
10.1016/j.imavis.2004.06.012 (the 2002 and 2003 conference versions were acquired instead); Vlachos et al.
Curved PN triangles 10.1145/364338.364387; Wang & Olano 10.1145/2699276.2721400; Zienkiewicz–Zhu
10.1002/nme.1620330702; DeVore 1998 10.1017/S0962492900002816; Cohen–Dahmen–Daubechies–DeVore
10.1006/acha.2000.0336; Basch–Guibas–Hershberger 10.1006/jagm.1998.0988; Huber 1964
10.1214/aoms/1177703732; Henkelman et al. 10.1016/j.commatsci.2005.04.010; Arratia–Goldstein–Gordon
10.1214/aop/1176991491 and 10.1214/ss/1177012015; Christiansen–Petersen 10.1007/BF01932705; Roache
10.1115/1.2910291; Ziv–Lempel 10.1109/TIT.1978.1055934; Dick–Kuo–Sloan 10.1017/S0962492913000044;
Boubekeur–Alexa 10.1145/1409060.1409094; Cook 10.1145/7529.8927; Coeurjolly et al. 2003
10.1007/3-540-36586-9_7; Edelsbrunner et al. time-varying Reeb 10.1016/j.comgeo.2007.11.001; Raman &
Wenger 10.1111/j.1467-8659.2008.01209.x; Kong & Rosenfeld 10.1016/0734-189X(89)90147-3; Worsley 1995
10.2307/1427930; Taylor & Adler 2003 10.1214/aop/1046294306; Adler 2000 10.1214/aoap/1019737664;
Wannamaker et al. 10.1109/78.824859; McKay–Beckman–Conover 10.1080/00401706.1979.10489755. Free
copies located but not fetchable by DOI: Wiley et al. 2003 (escholarship 2fp9j33g); Edelsbrunner &
Mücke is already in the corpus as arXiv:math/9410209.
Sixteen rows are expected to return nulls, and that is registered rather than hoped: P-190, P-197,
P-203, P-206, P-209, P-210, P-213, P-215, P-217, P-219, P-222, P-225, P-226, P-227,
P-229, P-231. Two more (P-204, P-228) are denominators whose most valuable outcome is that the
numerator is already close.
Dependencies, stated once. P-183 runs before P-186 and P-222. P-187 runs before P-188,
P-189, P-190 and P-229. P-195 runs before P-194, P-196 and P-197. P-199 runs before P-198
and P-200. P-204 runs before P-205 and P-206. P-218 runs before P-219. P-186 runs before
P-232. Everything else is independent. Sizes: 23 S, 22 M, 5 L (P-187, P-194,
P-207, P-218, P-223).
Group A — mesh-free measurement (integral geometry, stereology)
P-183 — registered for R-188, before the harness: The case table already carries a ≤4% area estimator, and no field is ungradeable
Ticket: R-188 (M). Records: field, resolution, bound_kind, config_count_nonzero, area_mesh, area_zk_weights, area_crofton_13, area_crofton_3, area_true_or_none, rel_err_mesh, rel_err_zk, rel_err_crofton_13, zk_within_4pct, estimator_cost_share, c1_holds, c2_holds, c3_holds.
Hypothesis. THE EXTRACTOR INDEXES EVERY SURFACE CELL BY ITS 2×2×2 SIGN CONFIGURATION, AND A WEIGHTED SUM OVER THOSE COUNTS IS A PROVEN SURFACE-AREA ESTIMATOR. Ziegel & Kiderlen determine 2×2×2 configuration weights whose "relative worst case error is asymptotically less than 4%" and show that bound is best possible among local weightings [verified]; their weight family is (sr, 1.358, 2.352 − sr, 0.960, s(1 − r)) over the five informative configuration types, and Lindblad's weights reach 7.3%; Legland et al. give the 13-direction lattice Crofton estimator with directional error in [−7.33%, +2.27%] [verified]. (C1) On the four Exact fields at 33³, 65³ and 129³, the Ziegel–Kiderlen sum is within 4% of the true area on every row and the 13-direction Crofton sum within 7.33%, both computed from the sign grid with no mesh. (C2) On the same rows the mesh area is within 2% of the true area, so the mesh is the better instrument where a truth exists — and where none exists (csg_difference, gyroid, fbm_terrain, noise_cavity) the configuration estimator and the mesh area agree to within the estimator's own bound on every row, which makes the estimator a grade for the four fields ✗107 could not grade. (C3) The estimator costs under 2% of an extraction, because the counts are the case-index histogram the extractor already walks. SHARE: C3 is the only clause with a cost; C1 and C2 are accuracy clauses and move nothing.
Falsified by. C1 by any Exact row outside the proven bound, which would mean either the weights were transcribed wrong, the fixture is not a Gauss digitisation in the paper's sense (field.sample() is one, and the row must say so), or the resolution is below the "good or very good" regime the authors scope the bound to — in which case the row reports the rung at which the bound starts to hold, which is itself a number the paper does not give. C2 by the mesh and the estimator disagreeing beyond the bound on an ungradeable field, which is the interesting outcome: one of them is wrong and only a third instrument (P-230) can say which. C3 by a cost above 2%, which would say the histogram is not free after all. VACUITY CONTROL: config_count_nonzero must show at least 30 distinct configurations populated on every field, or the sum is over a table the fixture never exercises.
P-184 — registered for R-189, before the harness: The 6/26 split is an adjacency-pair choice, and the theorem says which pairs are consistent
Ticket: R-189 (S). Records: field, resolution, adjacency_pair, chi_lattice, chi_p145_oracle, chi_mesh, disagreement_cells, split_blocks, complementary_pair_agrees, c1_holds, c2_holds.
Hypothesis. M-458's oracle reports connectivity_split_blocks 487 on noise_cavity at 33³ and "must be a reported column rather than a hidden choice between foreground-6 and foreground-26". Ohser, Nagel & Schladitz's theory of the Euler number on lattices says the choice is not free: foreground and background adjacencies must be chosen as a complementary pair — (6,26), (26,6), (18,6), (6,18), and the 14.1/14.2 pairs — for χ to satisfy the Euler formula on the reconstruction [verified, Legland et al. §"Euler–Poincaré measures", citing Ohser et al. 2002]. (C1) Computing χ by the lattice reconstruction with each complementary pair reproduces P-145's oracle exactly on every field where P-145 reports split_blocks = 0, and on noise_cavity the 487 split blocks are exactly the cells where the two members of a pair disagree with each other — i.e. the split count is the number of cells whose χ contribution depends on which of the pair is foreground. (C2) The mesh χ (Marching Cubes) sits on one specific pair — the registration predicts (6,26)-foreground-inside — and the disagreement between mesh and oracle on noise_cavity (two extractors, two numbers, M-458) is removed by choosing that pair. SHARE: none; this is a classification of an existing count.
Falsified by. C1 by the split count not coinciding with the pair-disagreement count, which would mean P-145's split is measuring something the adjacency theory does not name. C2 by no pair reproducing the mesh χ, which would say Marching Cubes' implied adjacency is not a lattice adjacency at all — a real finding about the case table. VACUITY CONTROL: the non-complementary pair (26,26) must be run as a control and must fail the Euler formula on at least one field, or the harness cannot tell a consistent pair from an inconsistent one.
P-185 — registered for R-190, before the harness: Integrated mean curvature from the sign grid, as a third instrument against normal cycles
Ticket: R-190 (M). Records: field, resolution, mean_breadth_crofton_13, mean_breadth_true_or_none, integrated_H_normal_cycles, integrated_H_varifold, rel_err_crofton, rel_err_normal_cycles, direction_count, c1_holds, c2_holds.
Hypothesis. The mean breadth b̄ = ∫χ(P) dP over planes is the third intrinsic volume and Legland et al. compute it from the sign grid with 13 plane directions [verified]; on a sphere of radius 30 it reads 39.9 against 40.0, on a torus 46.2 against 47.1 [verified, Table 3]. P-174 benched normal cycles against varifolds for mean curvature and neither had a mesh-free reference. (C1) On sphere and torus the lattice mean breadth is within 3% of the closed form at 65³ and 129³. (C2) On every field the lattice value and the normal-cycles integral of H over the mesh agree to within 5%, so the normal-cycles instrument is graded from the field for the first time. SHARE: none — a validation instrument.
Falsified by. C1 by errors above 3% on the two closed forms, which would mean the plane-direction weights were transcribed wrong. C2 by disagreement on box_exact in particular — where Legland's own Table 3 shows the cube is the worst case (27.2 against 30.0) — in which case the row records the field-dependent error and the instrument is scoped to smooth fields. VACUITY CONTROL: direction_count must be run at both 3 and 13, and the 3-direction cube error must reproduce the published −33%, or the harness is not computing the estimator the paper describes.
P-186 — registered for R-191, before the harness: The error has a Wulff plot, and the plot is where BCC and cubic actually differ
Ticket: R-191 (S). Records: normal_direction, lattice, resolution, area_mesh_over_true, hausdorff_over_h, needle_ratio, octahedral_class, class_spread, anisotropy_index, c1_holds, c2_holds, c3_holds.
Hypothesis. M-309 measured a 0.250 mean triangle-quality ratio on box_exact against Marching Cubes' 0.858; P-162/P-163 measured BCC's mean gain against cubic in dB and found it small. Both are averages over a quantity that is a function on the sphere of normals: Legland's Table 2 shows the same cube reading 1600, 1989.3, 2489.3 for a true 2400 at three orientations [verified]. (C1) Sampling a plane's normal over a 48-fold-reduced spherical grid (✗49 licenses the reduction), mesh area error, Hausdorff error and needle ratio are each a smooth function of direction with octahedral symmetry, and the area-error plot's extremes bracket Legland's directional bound [−7.33%, +2.27%] for the 13-direction Crofton arm. (C2) The same plot on BCC has a different shape: its extremes are closer to zero (the registration predicts the max-min spread falls by at least 30%) even though its mean is within 0.3 dB of cubic, which is what ✗119's +5.73 dB on noise_cavity against a predicted 0.011 dB was without a direction axis. (C3) The needle-ratio plot predicts M-309's 0.250 as its value at the axis-aligned direction. SHARE: none; an instrument.
Falsified by. C1 by the plot lacking octahedral symmetry, which would contradict ✗49 and be a bug. C2 by BCC's spread not falling, which would say the lattices differ in mean only and P-162's null stands as a full description. C3 by the axis-aligned value not reproducing M-309. VACUITY CONTROL: class_spread must be non-zero within at least one octahedral class across resolutions, or the plot is a constant and the symmetry test is vacuous.
Group B — the field as a random object (random-field geometry, probability)
P-187 — registered for R-192, before the harness: A Gaussian random field fixture, and the closed-form χ that comes with it
Ticket: R-192 (L). Records: seed, resolution, correlation_length, rho1, rho2, spectral_moment_check, chi_measured_oracle, chi_measured_mesh, chi_expected_gkf, chi_expected_boundary_corrected, seeds, chi_mean, chi_sd, z_score, gaussianity_test_p, c1_holds, c2_holds, c3_holds.
Hypothesis. P-176 established fbm_terrain is hash-based lattice noise and not a Gaussian field; P-144 found χ varies across seeds by 10.24 with no prediction to compare against. Taylor's Gaussian kinematic formula gives E[χ(M ∩ f⁻¹[u,∞))] as Σ_j L_j(M) ρ_j(u) — Lipschitz–Killing curvatures of the domain times EC densities of the field — with the domain's boundary handled by the L_j(M) terms [verified, Taylor 2006 §1 and Thm 4.1]. (C1) A new bench-local field gaussian_rf — a sum of K ≥ 64 random-phase cosines with an isotropic spectral density, unit variance, and known ρ'(0), ρ''(0) — passes a multivariate normality test at every resolution (gaussianity_test_p > 0.01), and its measured spectral moments agree with the construction to 1%. (C2) Over 32 seeds at 65³, the mean of P-145's oracle χ agrees with the GKF prediction within 2 standard errors, at u = 0. (C3) Over the same seeds the two value-noise fields' χ, rescaled to the same correlation length, sit more than 3 standard errors from the GKF prediction — the quantitative version of P-176's "not a Gaussian field". SHARE: none — a fixture and three predictions.
Falsified by. C1 by a failed normality test, which would mean K is too small or the phases are not independent, and the fixture is not the object the theorem is about. C2 by a z_score above 2 on the GRF itself, in which case either the EC densities were transcribed wrong or the boundary terms were dropped — the row must compute both chi_expected_gkf (interior only) and chi_expected_boundary_corrected so the harness can tell which. C3 by the noise fields sitting inside the GRF band, which would be a strictly better result: it would say the closed form applies to them after all. VACUITY CONTROL: chi_sd must be non-zero across seeds and the oracle's split_blocks must be reported per seed, or C2 is a comparison against one number.
P-188 — registered for R-193, before the harness: Kac–Rice predicts the ambiguous-cell census from two numbers, before any mesh exists
Ticket: R-193 (M). Records: seed, resolution, cells_per_correlation_length, rho1, rho2, ambiguous_cells_measured, body_saddle_cells_measured, critical_points_expected_kr, ratio_measured_over_expected, ratio_stability_across_h, c1_holds, c2_holds.
Hypothesis. Cheng & Schwartzman evaluate the Kac–Rice formula for isotropic Gaussian fields and "the obtained formulae depend on the covariance function only through its first and second derivatives at zero" [verified]; for N=2 the expected count per unit area is 1/(√(3π) η²), η = √(−ρ')/√(ρ'') [verified, Example 3.8]. Body saddles are critical points of the trilinear, and P-137 proved there are at most 2 per cell; the trilinear's critical points track the field's as h → 0. (C1) On gaussian_rf, the number of cells with a body saddle, divided by the Kac–Rice expected number of critical points of the field in the box (computed via the N=3 GOE expectation the paper gives), converges to a constant as cells_per_correlation_length grows — ratio_stability_across_h under 10% between 65³ and 129³. (C2) That constant is the same across 8 seeds to within 15%, so the ambiguous-cell fraction of a field is predictable from ρ'(0), ρ''(0) and h alone. SHARE: none; a prediction.
Falsified by. C1 by the ratio drifting with h, which would mean the trilinear's saddles are not tracking the field's — plausible, and it would bound how far below the correlation length the 2×2×2 model can be trusted. C2 by seed-to-seed spread above 15%, which would say the count is not concentrated and P-229's Poisson row inherits the question. VACUITY CONTROL: body_saddle_cells_measured must be non-zero at every rung and P-137's degree-2 eliminant must be the saddle instrument, not a re-transcription.
P-189 — registered for R-194, before the harness: The expected area of a Gaussian level set is 2√λ₂/π per unit volume, and M-13's constant should be it
Ticket: R-194 (S). Records: seed, resolution, lambda2, area_expected_closed_form, area_mesh, area_zk_weights, area_coarea, ratio_mesh_over_expected, ratio_zk_over_expected, derivation_check_symbolic, c1_holds, c2_holds.
Hypothesis. For a stationary unit-variance Gaussian field with Var(∂ᵢX) = λ₂ = −2ρ'(0), the Kac–Rice formula for the level set gives E[Area({X=0})] / Vol = E|∇X| · φ(0) = √λ₂ · 2√(2/π) · (2π)^{−1/2} = 2√λ₂/π [derived here, not quoted — the row must check it]. M-13's area law fits a constant per field with no prediction. (C1) On gaussian_rf over 32 seeds, the mesh area per unit volume agrees with 2√λ₂/π within 2 standard errors, and so do P-183's two mesh-free estimators. (C2) The derivation is checked symbolically in the bench (a committed symbolic integration of ‖z‖ against the 3-D standard normal reproduces 2√(2/π), and the product reproduces 2√λ₂/π), so the constant is a theorem in the ledger rather than a recalled formula. SHARE: none.
Falsified by. C1 by a systematic offset, which would say either the mesh area is biased (Group A grades that separately) or the fixture's λ₂ is not what the construction claims. C2 by the symbolic check disagreeing with the closed form as written here, in which case this document is wrong and the row's value is that it says so. VACUITY CONTROL: derivation_check_symbolic is the vacuity control — it must be a computed true, not a constant.
P-190 — registered for R-195, before the harness: A null registered on purpose — the value-noise percolation threshold is not the Gaussian one
Ticket: R-195 (M). Records: field, seed, resolution, percolation_isovalue, percolation_isovalue_grf, bracket_low, bracket_high, threshold_negative, giant_component_share_at_zero, c1_holds, c2_holds.
Hypothesis. M-489 measured the percolation isovalue on noise_cavity at 0.029340. For Gaussian fields in d ≥ 3 the level-set percolation threshold is a property of the covariance class and is strictly negative for the standard smooth examples (the Bargmann–Fock and Gaussian-free-field results the 2026-08-29 sweep cited). (C1) On gaussian_rf at matched correlation length, percolation_isovalue_grf is negative on 8 of 8 seeds — the giant component of {X ≥ 0} already exists at the zero level. (C2) noise_cavity's positive 0.0293 is therefore not the Gaussian value, and the row records the sign difference as the second quantitative non-Gaussianity of the value-noise fields after P-187 C3. SHARE: none.
Falsified by. C1 by a positive threshold on the GRF, which would either contradict the literature (unlikely) or say the fixture's correlation length is so short relative to the box that finite-size effects dominate — in which case resolution must be pushed until the sign settles, and the row says at what size. C2 by noise_cavity agreeing with the GRF after all, a strictly better result. VACUITY CONTROL: the bracket columns must narrow with resolution on both fields, or the threshold is not being located.
Group C — digital geometry (arithmetic planes, multigrid convergence)
P-191 — registered for R-196, before the harness: Greedy meshing is finished only for axis-aligned planes, and digital plane recognition finishes the rest
Ticket: R-196 (M). Records: rotation_deg, axis, resolution, triangles_mc, triangles_greedy_axis_aligned, planes_recognised, cells_covered_by_planes, coverage_share, triangles_plane_quads, max_plane_deviation_cells, recognition_ms_share, c1_holds, c2_holds, c3_holds.
Hypothesis. M-478 found greedy meshing within 1.12% of Eppstein's optimum and declared the stage finished — for axis-aligned faces, which is all greedy meshing can see. A flat wall at any other orientation leaves a digital plane {μ ≤ ax+by+cz < μ+ω} in the sign grid, and recognising digital planes is a solved problem with a review of its own [Brimkov, Coeurjolly & Klette 2007 — landing page; body unread]. (C1) On box_exact rotated by 10°, 20°, 35° about one axis at 65³, a greedy digital-plane recogniser covers at least 80% of surface cells with recognised planes whose true-face deviation is under 1 cell. (C2) Emitting one quad per recognised plane (clipped to the chunk) cuts triangle count below Marching Cubes' by at least 5× on those rows, against an axis-aligned greedy arm that cannot apply. (C3) Recognition costs under 50% of an extraction. SHARE: C2 moves the triangle count of flat-walled fields only; the share of surface cells on flat walls must be reported per field and it is near zero on sphere, torus and gyroid.
Falsified by. C1 by coverage under 80%, which would say the sign grid of a rotated box is not a clean digital plane at this h — P-192 then measures why. C2 by the quads not saving triangles, which cannot happen if C1 holds and is a harness bug. C3 by cost above 50%, which prices the mechanism out of the hot path and leaves it for the CAD consumer. VACUITY CONTROL: at 0° the recogniser must reproduce M-478's greedy rectangle count to within 5%, or it is not recognising planes.
P-192 — registered for R-197, before the harness: The staircase has a period, and the period is a continued fraction
Ticket: R-197 (S). Records: rotation_deg, slope_rational_approx, continued_fraction_depth, staircase_period_predicted, staircase_period_measured, needle_ratio_mean, needle_ratio_predicted, c1_holds, c2_holds.
Hypothesis. A naive digital plane's staircase repeats with a period set by the slopes' continued-fraction expansions (the 2-D case — digital straight segments — is classical). M-309's 0.250 needle ratio on box_exact is the axis-aligned limit of a function of rotation angle that this structure predicts. (C1) On rotated box_exact the measured staircase period along the wall (run-length of identical case indices) equals the continued-fraction prediction on every angle tested, to ±1 cell. (C2) Marching Tetrahedra's mean needle ratio as a function of angle is predicted by the staircase period to within 0.05 — the registration expects the ratio to improve off-axis, since the needles are an axis-aligned pathology. SHARE: none; a model.
Falsified by. C1 by periods that do not match, which would mean the sign grid of a trilinear-sampled plane is not the naive plane of the definition (thickness ω differs), and the row records the measured ω. C2 by the needle ratio being angle-independent, which would say the slivers are not a lattice-alignment effect and Treece's randomised split (novelty table #3) is the wrong remedy. VACUITY CONTROL: at least two angles must produce different predicted periods, or C1 is a single-point match.
P-193 — registered for R-198, before the harness: The normal estimator has a multigrid-convergence order, and it is the order DC's QEF inherits
Ticket: R-198 (M). Records: field, resolution, normal_estimator, normal_error_l2, normal_error_max, fitted_order, qef_vertex_error, qef_vertex_order, c1_holds, c2_holds.
Hypothesis. The crate's Hermite normals are gradients of the trilinear; digital geometry states normal-estimator accuracy as multigrid convergence with a proved order — Cuel, Lachaud & Thibert 2014 (in the corpus) give an explicit bound with an h^{1/2} term for a Voronoi-covariance estimator [verified, Theorem 1]. (C1) The trilinear-gradient normal converges at fitted order 1 on smooth fields (its truncation error is O(h)), and the Voronoi-covariance estimator at its published order, measured on the same rows. (C2) Dual Contouring's vertex error order equals the normal error order plus one on sphere and torus, i.e. the QEF is normal-limited, which says a higher-order normal is the lever for DC that ✗116 said no filter is for MC. SHARE: none; orders.
Falsified by. C1 by the gradient normal converging faster than 1, which would be a pleasant surprise about the trilinear at the crossing point (superconvergence, Group D). C2 by the vertex order not tracking the normal order, which would say the QEF error is dominated by the positions of the Hermite samples, not their normals. VACUITY CONTROL: a deliberately degraded normal (one-sided difference) must lower the fitted order, or the instrument is not measuring the estimator.
Group D — output representation order (CAGD, higher-order FEM, numerical analysis)
P-195 — registered for R-199, before the harness: Vertex error and surface error have different orders, and nobody has measured them apart
Ticket: R-199 (S). Records: field, resolution, filter, vertex_error_rms, vertex_error_order, barycenter_error_rms, barycenter_error_order, edge_midpoint_error_order, order_gap, c1_holds, c2_holds.
Hypothesis. ✗116 measured a tricubic filter reconstructing at order 3.84–4.04 while the mesh converged at 1.77–1.98, and concluded the second order belongs to the PL mesh. That conclusion has an untested corollary: the vertices of that mesh — points on the tricubic's zero set — should carry the filter's order, and only the flat triangles between them the PL order. (C1) Under the tricubic filter, vertex_error_order is ≥ 3.5 on sphere and torus while barycenter_error_order is ≤ 2.2 — an order_gap above 1.3. (C2) Under the shipped trilinear filter both orders are 2 ± 0.2, so the gap is created by the filter and consumed by the representation. SHARE: none; reuses p-157.csv's arms.
Falsified by. C1 by the vertices converging at order 2 under the tricubic, which would locate ✗116's bottleneck in vertex placement along the edge (the crossing-position lottery of ✗42) rather than in the representation, and would retire P-194, P-196 and P-197 before they are built — the cheapest possible outcome for Group D and the reason this row runs first. C2 by a gap under the trilinear, which would be a superconvergence result in its own right. VACUITY CONTROL: an infinite-order exact_oracle arm (as in ✗116) must show the same vertex/barycenter split, or the split is a filter artefact.
P-194 — registered for R-200, before the harness: Curved PN triangles from the Hermite data DC already has, and the order they buy
Ticket: R-200 (L). Records: field, resolution, extractor, patch_kind, tessellation_level, hausdorff_pl, hausdorff_patch, fitted_order_pl, fitted_order_patch, triangles_pl, triangles_patch_tessellated, error_at_matched_triangles, normal_source, c1_holds, c2_holds, c3_holds.
Hypothesis. Vlachos et al.'s PN triangle needs three vertices and three normals; Dual Contouring's HermiteCell has both; Wang & Olano applied PN triangles to Marching Cubes in 2015 (paywalled — prior art, unread, cited as such). ✗116 says the PL representation caps the order at 2. (C1) With PN-triangle patches built from DC's vertices and Hermite normals, tessellated at level 4, the Hausdorff exponent on sphere and torus rises to ≥ 2.8 from PL's ~1.9. (C2) At matched output triangle count — the tessellated patch against a PL mesh at the finer resolution that produces the same count — the patch arm's Hausdorff error is lower on 3 of 4 smooth fields. (C3) On box_exact and csg_difference the patch arm is no worse than PL: the crease normals from DC's two-vertex cells must not bulge the patches across the crease. SHARE: C2 is the claim that matters; C1 is the mechanism. The cost of tessellation is reported but not claimed against.
Falsified by. C1 by the exponent staying near 2, which — if P-195 C1 held — means the patch construction is wrong, and if P-195 C1 failed means the vertices were never better than order 2 and the row should not have run. C2 by PL winning at matched count, which is the honest likely outcome on fields with any curvature variation and would scope patches to the CAD consumer. C3 by crease bulging, which names the exact defect a future row must fix. VACUITY CONTROL: normal_source must be run as both hermite and finite_difference, and the two must differ in C1, or the Hermite data is not load-bearing.
P-196 — registered for R-201, before the harness: The triquadratic's isosurface is a rational-quadratic patch per cell, and the table is tabulable
Ticket: R-201 (M). Records: field, resolution, cells_quadratic_fit_ok, patch_rank_deficient, hausdorff_patch, fitted_order, patch_eval_cost_share, crease_cells_excluded, c1_holds, c2_holds.
Hypothesis. M-451 priced the triquadratic rung: mixed volume 29, case space 2^27, "the only rung that has both order and a tabulable table". Wiley et al. 2003 show a quadratic element's isosurface "is represented as a rational-quadratic patch in parameter space and a rational-quartic patch in physical space" [abstract; free copy at escholarship, not fetchable by DOI]. (C1) Fitting a triquadratic per cell from the 27-point stencil and emitting Wiley's rational-quadratic patch, the Hausdorff exponent on sphere and torus is ≥ 2.8. (C2) The patch evaluation costs under 3× an extraction, and the rank-deficient patches (patch_rank_deficient) are confined to cells P-171 already flags as non-transverse. SHARE: none claimed; the row exists to price a rung M-451 said was tabulable.
Falsified by. C1 by order 2, which would put this row in the same bin as P-194's failure and say the bottleneck is upstream. C2 by rank deficiency spreading beyond the non-transverse cells, which would say a 3×3×3 stencil is too small for a stable quadratic fit on real fields. VACUITY CONTROL: cells_quadratic_fit_ok must be under 100% on at least one field, or the fit is never stressed.
P-197 — registered for R-202, before the harness: A null registered on purpose — Richardson extrapolation of vertex positions across two resolutions
Ticket: R-202 (S). Records: field, resolution_pair, shared_edges, vertex_error_h, vertex_error_h2, vertex_error_extrapolated, observed_order_from_pair, extrapolation_gain, expansion_regular_share, c1_holds, c2_holds.
Hypothesis. If the vertex error has a regular expansion e(h) = C h² + O(h⁴) then (4v_{h/2} − v_h)/3 on the edges the two grids share is O(h⁴), for free. ✗42 measured the crossing-position lottery — the error's sign depends on where in the cell the surface crosses — which is precisely a failure of regularity, so the registration expects the null. (C1) On sphere, expansion_regular_share (edges where the two-resolution error ratio is within 20% of 4) is under 60%, and the extrapolated vertex error is not better than vertex_error_h2 on more than 60% of shared edges. (C2) On the minority of regular edges the extrapolation gain exceeds 3×, so the mechanism is real where its hypothesis holds and a per-edge regularity test would be the gate. SHARE: none.
Falsified by. C1 by the extrapolation working on most edges, a strictly better result that would say ✗42's lottery averages out at the vertex level. C2 by no gain even on the regular edges, which would say the expansion's leading term is not h² at the vertex — consistent with P-195 finding a higher vertex order. VACUITY CONTROL: observed_order_from_pair must be reported per edge and its distribution must have non-zero spread, or the regular/irregular split is a constant.
Group E — reach, tubes and sampling (geometric measure theory, learning theory)
P-199 — registered for R-203, before the harness: The reach of an SDF is where its tube polynomial breaks, and that is a measurement not a lookup
Ticket: R-203 (S). Records: field, resolution, offset_radii, volume_of_offset, cubic_fit_residual, breakpoint_radius, reach_closed_form_or_none, reach_medial_axis_estimate, intrinsic_volumes_from_fit, c1_holds, c2_holds.
Hypothesis. Weyl–Steiner: Vol({x : d(x,M) ≤ r}) = Σ_j L_j(M) ω_{k−j} r^{k−j} for r small enough — a cubic in r whose coefficients are the intrinsic volumes, valid below the reach [verified, Taylor 2006 eq. 1.1]. For an SDF, {f ≤ r} is that offset with no computation. (C1) On sphere (reach R) and torus (reach r_minor) the volume of {f ≤ r}, counted on the grid, is fitted by a cubic in r with residual under 0.5% up to the closed-form reach and the residual grows past it, so breakpoint_radius is within one cell of the true reach at 65³. (C2) The cubic's fitted coefficients reproduce the closed-form area and integrated mean curvature of sphere within 3%, so the tube fit is a fourth mesh-free instrument for Group A's quantities. SHARE: none.
Falsified by. C1 by no breakpoint, which on torus would mean the offset volume stays cubic past r_minor — impossible for the true torus, so it would be a sampling artefact and the row records the resolution at which it appears. C2 by the coefficients disagreeing with Group A's, which would say one of the two integral-geometric routes was transcribed wrong. VACUITY CONTROL: box_exact (reach 0, a polyhedron) must fail the cubic fit at every r > 0, or the fit is not sensitive to the reach.
P-198 — registered for R-204, before the harness: graph_cube_g5's hole at 9³ is a sampling-density event, and the reach predicts it
Ticket: R-204 (M). Records: field, genus, reach_measured, min_feature_size, resolution, h_over_reach, chi_correct, first_correct_rung, predicted_rung_from_reach, nonmonotone_rungs, c1_holds, c2_holds.
Hypothesis. M-453: "graph_cube_g5, the highest-genus fixture, is perfect at 7³ and 11³ and meshes literally nothing at 9³". Niyogi, Smale & Weinberger (in the corpus at 0.69, cited nowhere) give a sampling-density condition in terms of the reach under which homology is recovered. (C1) With reach_measured from P-199 on all six prescribed-genus fields, the first rung at which χ is correct is predicted by a single threshold on h_over_reach — the same threshold for all six fields, to within one rung. (C2) The non-monotone rungs (correct, wrong, correct) all lie at h_over_reach values where a thin feature's diameter is within ±0.25 cells of an integer number of cells — i.e. the 9³ hole is a commensurability event of the kind Group M names, not a density one, and the reach threshold governs only the first correct rung. SHARE: none.
Falsified by. C1 by no common threshold, which would say the six fields' failures are not governed by one regularity number — plausible for the graph-based ones whose thinnest feature is a tube, where the relevant number is the tube radius, not the reach; the row reports min_feature_size beside reach_measured for that reason. C2 by the non-monotone rungs not being commensurability events, which would leave M-453's sharpest finding unexplained and worth a row of its own. VACUITY CONTROL: nonmonotone_rungs must be non-empty on at least one field, or C2 is about nothing.
P-200 — registered for R-205, before the harness: A topology certificate computed before extraction, from the reach and the grid spacing
Ticket: R-205 (M). Records: field, resolution, reach_measured, h, nsw_condition_satisfied, chi_correct_measured, certificate_true_and_wrong, certificate_false_and_right, certificate_cost_share, c1_holds, c2_holds.
Hypothesis. CLAUDE.md says χ is unassertable outside sphere and torus; P-145 added an oracle that reads the field; NSW's theorem adds a certificate that needs only the reach and h. (C1) On all fourteen post-R-177 reference fields at 17/33/65/129, certificate_true_and_wrong is 0: whenever the NSW condition is satisfied, the extracted χ equals the prescribed or oracle χ. (C2) The certificate is conservative — certificate_false_and_right is non-zero on at least half the rows — and the row reports how conservative, because a certificate that never fires is a certificate that costs P-199's reach measurement for nothing. SHARE: C1 is a soundness clause and moves nothing.
Falsified by. C1 by a single true-and-wrong row, which is the important outcome: it would mean the NSW hypotheses (a C² manifold, the sample within the reach) are not met by the field or the extractor, and the row must say which. C2 by the certificate being tight, a strictly better result. VACUITY CONTROL: box_exact and csg_difference (reach 0) must produce nsw_condition_satisfied = false on every row, or the certificate ignores the reach.
Group F — regularity predicts adaptivity (nonlinear approximation, fractal geometry)
P-201 — registered for R-206, before the harness: The Besov index of the field predicts M-474's s, from Haar coefficients alone
Ticket: R-206 (M). Records: field, resolution, haar_levels, coefficient_decay_exponent, besov_index_estimate, s_adaptive_p161, s_uniform_p161, s_difference_p161, rank_correlation, c1_holds, c2_holds.
Hypothesis. DeVore's survey (paywalled; its abstract states the theorem) characterises the rate of nonlinear approximation by a Besov regularity that is "significantly weaker than required in the linear theory", and Besov regularity is read off wavelet coefficient decay. M-474 measured s for both families on eight fields over two decades of field evaluations — the hard way. (C1) A Haar decomposition of the sampled field at 129³ gives a besov_index_estimate per field that rank-correlates with M-474's s_adaptive at ≥ 0.7 across the eight fields. (C2) The difference between the Besov and Sobolev indices — the regularity gap the nonlinear theory says adaptivity can exploit — rank-correlates with s_difference at ≥ 0.7, so lod_helps is predictable from the field's coefficients before an octree is built. SHARE: none; a predictor.
Falsified by. C1 by correlation under 0.7, which with eight fields is easy to fail and would say the Haar estimate at this resolution is too coarse — the row reports haar_levels so a finer sweep can follow. C2 by the gap not predicting s_difference, which would say M-474's field-dependence is not a regularity effect. VACUITY CONTROL: fbm_terrain's estimated index must come out below sphere's, or the estimator is not measuring roughness.
P-202 — registered for R-207, before the harness: The word fractal pays its exponent — fbm_terrain's triangle count scales as h^{−(3−H)}
Ticket: R-207 (S). Records: field, hurst_H_configured, hurst_H_measured, resolution, surface_cells, triangles, fitted_count_exponent, predicted_exponent, area_law_exponent_m13, c1_holds, c2_holds.
Hypothesis. M-13's area law says surface-cell count scales as h^{−2} times a per-field constant. Fractional Brownian terrain with Hurst exponent H has a level set of box-counting dimension 3 − H, so its cell count must scale as h^{−(3−H)} and the area law must fail on it by exactly 1 − H in the exponent — the axes document v2 listed fractal (no measured exponent) as folklore; this is the exponent. (C1) On fbm_terrain across 17/33/65/129/257, fitted_count_exponent equals 3 − H within 0.1, where H is measured from the field's own structure function (not taken from the generator). (C2) On the seven non-fractal fields the exponent is 2 ± 0.1, so the deviation is specific to the fractal field. SHARE: none.
Falsified by. C1 by an exponent of 2, which would say the hashed lattice noise is smooth below its finest octave and the "fractal" description is wrong at these resolutions — P-176 already found the field is not a Gaussian fBm, so this is a live possibility and worth one afternoon. C2 by another field showing a non-2 exponent, which would be a finding about that field. VACUITY CONTROL: hurst_H_measured must be reported with its fit's confidence interval, and the generator's configured H must lie outside that interval on at least the finest rung, or the two numbers are the same number.
P-203 — registered for R-208, before the harness: A null registered on purpose — the octree's tree constraint costs a constant, not a rate
Ticket: R-208 (M). Records: field, budget, error_free_nterm, error_tree_nterm, error_octree_shipped, tree_over_free_ratio, octree_over_tree_ratio, ratio_stable_across_budget, c1_holds, c2_holds.
Hypothesis. Cohen, Dahmen, Daubechies & DeVore (paywalled) prove tree-structured N-term approximation achieves the same rate as unconstrained N-term approximation, at the cost of a constant. M-473 measured the octree's gain against uniform; nothing measured its loss against the unconstrained best. (C1) On the four Exact fields at matched sample budget, the error of the best free N-term Haar approximation and of the best tree-constrained one differ by a tree_over_free_ratio that is stable across budgets (±20%), i.e. a constant. (C2) The shipped greedy octree sits within a further 2× of the tree optimum, so the remaining headroom for adaptivity is a constant of at most tree_over_free × 2 — a number the ledger does not have. SHARE: none; a denominator for Axis 7.
Falsified by. C1 by the ratio growing with budget, which would contradict the theorem's hypotheses being met and would say these fields are outside its Besov class. C2 by the greedy octree being far from the tree optimum, which would be a live lever. VACUITY CONTROL: error_free_nterm must be strictly below error_tree_nterm on every row, or the free arm is not free.
Group G — the denominator for Phase 25 (information theory)
P-204 — registered for R-209, before the harness: The case-index stream has an entropy rate, and no bit-packing beats it
Ticket: R-209 (S). Records: field, resolution, scan_order, symbols, h0_marginal_bits, h1_conditional_bits, h2_conditional_bits, lz78_bits_per_symbol, entropy_rate_estimate, phase25_best_bits_per_cell, gap_to_floor_ratio, c1_holds, c2_holds.
Hypothesis. Phase 25 measured twenty bit-packing numerators (R-103–R-122) and no denominator. The case-index stream along a scanline is a stationary source; its entropy rate bounds every lossless encoding of it, and the Lempel–Ziv code length per symbol converges to that rate (Ziv & Lempel 1978, paywalled — the theorem is standard). (C1) On every field at 65³, the order-2 conditional entropy H(X_n | X_{n−1}, X_{n−2}) and the LZ78 length per symbol agree within 15%, and both are below the marginal entropy H₀ by at least 30% — the stream is compressible beyond a per-symbol code. (C2) Phase 25's best measured bits-per-cell is within 1.5× of the entropy-rate estimate on the majority of fields, which would say the bit-packing line is near its floor and should stop — the most valuable outcome. SHARE: none — this row is the denominator, and it reports gap_to_floor_ratio per field.
Falsified by. C1 by the two estimates disagreeing, which would mean the stream has long-range structure order-2 conditioning misses (Group Z's spectral row is the follow-up). C2 by a gap above 1.5×, which would say Phase 25 left a measurable amount on the table and names how much. VACUITY CONTROL: a scrambled-order arm (random permutation of cells) must raise the LZ78 length toward H₀, or the estimator is insensitive to order.
P-205 — registered for R-210, before the harness: Adjacent cells share four corners, so the case-index transition is a walk on a 16-out graph and its entropy is at most 4 bits
Ticket: R-210 (S). Records: field, resolution, axis, transitions_observed, transitions_possible_16, h1_conditional_bits, bound_4_bits, predictive_coder_bits_per_cell, arithmetic_coder_bits_per_cell, c1_holds, c2_holds.
Hypothesis. Along any axis, the next cell's case index shares the four corner signs of the shared face with the current one, so at most 2⁴ = 16 successors are possible and H(X_n | X_{n−1}) ≤ 4 bits by a counting argument, against H₀ ≤ 8 — a de Bruijn-like transition structure the bit-packing sweep never used. (C1) transitions_observed never exceeds 16 per predecessor on any field (a correctness check on the encoding), and h1_conditional_bits is under 4 on every row. (C2) A predictive coder that transmits only the four new bits per cell, arithmetic-coded against the empirical conditional distribution, achieves bits-per-cell within 10% of P-204's entropy-rate estimate. SHARE: C2's bits-per-cell is compared to Phase 25's best; the row claims nothing about speed.
Falsified by. C1 by more than 16 successors, which would be a bug in the case-index encoding and worth finding. C2 by the coder sitting far from the rate, which would mean the order-1 model is too weak and the residual structure is across rows, not along them. VACUITY CONTROL: the harness must show transitions_observed reaching 16 for at least one predecessor on gyroid, or the bound is not being approached.
P-206 — registered for R-211, before the harness: A null registered on purpose — the mesh is far above the metric-entropy floor of the surface class, and by how much
Ticket: R-211 (M). Records: field, resolution, epsilon, mesh_bits_position, mesh_bits_index, mesh_bits_total, sign_grid_bits, metric_entropy_bound_bits, mesh_over_floor_ratio, signgrid_over_floor_ratio, c1_holds, c2_holds.
Hypothesis. Axis 14 named ε-entropy — the number of bits any representation of a surface to accuracy ε must carry — and nobody computed it. For a W^{2,∞}-bounded surface in a unit box the ε-entropy scales as ε^{−1} (dimension 2, smoothness 2: ε^{−d/s} = ε^{−1}), with a constant the field's Hessian bound sets. (C1) The emitted mesh (positions at f32, indices at u32) carries at least 50× the ε-entropy bound at its own Hausdorff ε on every Exact field, and the sign grid alone at least 10×. (C2) The ratio is stable across resolutions to ±30%, i.e. it is a constant of the representation, not of the resolution. SHARE: none — a denominator that says how much a future compressed representation could gain, and the registration expects the answer to be "a lot", which is why the row is cheap and registered as a null-shaped result.
Falsified by. C1 by the mesh being within 50× of the floor, a surprise that would say the mesh is already a near-optimal code for the surface — worth knowing. C2 by a ratio that grows with resolution, which would say the mesh's redundancy is resolution-dependent and the compressibility story is about coarse grids only. VACUITY CONTROL: metric_entropy_bound_bits must be computed from the field's measured Hessian bound and reported with it, not from a constant.
Group H — time (kinetic data structures)
P-207 — registered for R-212, before the harness: A sliding brush is a kinetic problem, and the number of certificate failures per frame is the incremental cost
Ticket: R-212 (L). Records: field, brush_radius_cells, speed_cells_per_frame, frames, certificates_total, failures_per_frame_mean, failures_per_frame_max, cells_remeshed_per_frame, cells_full_remesh, event_cost_share, output_identical_to_full, c1_holds, c2_holds, c3_holds.
Hypothesis. v1's Axis 8 read "full re-mesh" in every column. A KDS maintains a structure under continuous motion by certificates with failure times (Basch, Guibas & Hershberger 1999, paywalled; Acar et al.'s kinetic convex hulls and kinetic mesh refinement are in the corpus). For a brush SDF b(x − vt) combined by min with a static field, the certificate for a corner is "sign(f) unchanged" and its failure time is the root of a one-dimensional function of t. (C1) Over 120 frames of a brush of radius 8 cells moving at 0.5 cells/frame through noise_cavity at 65³, the number of certificate failures per frame is under 2% of the surface cells, and remeshing only the cells whose certificates failed produces output byte-identical to a full remesh on every frame. (C2) failures_per_frame_max is under 3× the mean — the worst frame is bounded, which M-322's adversarial bisect was not. (C3) Event processing plus local remesh costs under 20% of a full remesh per frame. SHARE: C3 is the claim; the share of a frame that is remesh must be reported from edit_trace's numbers.
Falsified by. C1 by any non-identical frame, which would mean a certificate was missed — the union-find of R-022 is the obvious culprit and the row names it. C2 by a worst frame well above the mean, which is the adversarial case again and would say the KDS bounds events, not their cost. C3 by cost above 20%, which would price the mechanism against a full remesh and settle Axis 8 for this workload. VACUITY CONTROL: a brush that moves 0 cells/frame must produce 0 failures, and a brush that jumps its full diameter per frame must produce failures on essentially every cell it covers, or the certificate set is wrong.
P-208 — registered for R-213, before the harness: Topology changes at discrete times, and the sealing check need only run at them
Ticket: R-213 (M). Records: field, brush_path, frames, topology_events_predicted, topology_events_observed, frames_with_sealing_change, events_missed, events_spurious, sealing_checks_saved_share, c1_holds, c2_holds.
Hypothesis. Edelsbrunner et al.'s time-varying Reeb graph (paywalled) computes the times at which the topology of f(x,t) changes. A sealing check (validate::sealing) that runs every frame is wasted on frames between events. (C1) Over the P-207 brush path, the set of frames at which the extracted mesh's χ or component count changes is exactly the set of predicted topology events (events_missed = 0, events_spurious ≤ 5%). (C2) Running the sealing check only at events saves at least 80% of the checks with no change in what is caught. SHARE: C2's saving is of a validation stage, not of extraction, and must be reported as such.
Falsified by. C1 by missed events, which would mean the event predictor (critical points of f in (x,t)) is missing the discrete events the PL extractor creates that the smooth field does not — a genuine discrepancy between the continuous and PL topology and worth a row. C2 by savings under 80%, which would say events are dense along a dig path and the check is not the cost. VACUITY CONTROL: a path that does not touch the surface must produce 0 predicted and 0 observed events.
Group I — optimal transport
P-209 — registered for R-214, before the harness: A null registered on purpose — sliced Wasserstein between mesh and surface measures, against Hausdorff
Ticket: R-214 (M). Records: field, resolution, extractor, hausdorff, sliced_w2, w2_sinkhorn_coarse, rank_correlation_with_hausdorff, topology_defect_planted, hausdorff_response, sw2_response, c1_holds, c2_holds.
Hypothesis. Hausdorff distance is not a metric on measures: it is blind to how much surface sits where, and a mesh with a missing thin sheet can score well on it. The 2-Wasserstein distance between the mesh's area measure and the true surface's is a metric that sees mass, and its sliced form is O(n log n) (Peyré & Cuturi, acquired). (C1) On the four Exact fields at three resolutions, sliced_w2 rank-correlates with Hausdorff at ≥ 0.9 — the null: on well-behaved meshes the two metrics agree and the new one adds nothing. (C2) With a planted defect — a thin sheet of thin_plate deleted from the mesh — Hausdorff moves by under 10% and sliced_w2 by over 50%, which is the one situation where the metric earns its cost. SHARE: none; an instrument.
Falsified by. C1 by low correlation on clean meshes, which would say the two metrics measure different things even in the benign case and one of them is the wrong grade. C2 by sliced_w2 not responding to the planted defect, which would retire it. VACUITY CONTROL: topology_defect_planted must be a committed fixture whose triangle count differs from the clean mesh by a stated amount.
P-210 — registered for R-215, before the harness: A null registered on purpose — displacement interpolation between LOD levels
Ticket: R-215 (M). Records: field, lod_pair, t, error_linear_blend, error_displacement_interp, error_ratio_at_half, precompute_ms, per_frame_ms, c1_holds, c2_holds.
Hypothesis. LOD transitions pop; the usual fix is a linear vertex blend, which is not a geodesic in any shape space. McCann's displacement interpolation — the W₂ geodesic between the two LOD meshes' measures, computable by Solomon et al.'s convolutional method on the grid (acquired) — is the canonical path. (C1) At t = 0.5 between 33³ and 65³ meshes of sphere and torus, the displacement-interpolated mesh's Hausdorff error to the true surface is at least 30% lower than the linear blend's. (C2) The precompute costs more than 10 extractions, which prices it out of the hot path regardless of C1 — the registered null. SHARE: C2 is the price and is expected to kill the row for the game; the CAD consumer is offline.
Falsified by. C1 by no improvement, which would say the linear blend is already near-geodesic for meshes this close. C2 by a cheap precompute, a strictly better result that reopens the row. VACUITY CONTROL: at t = 0 and t = 1 both arms must reproduce the endpoint meshes to 1e-6, or the interpolant is not an interpolant.
Group J — robust statistics and distribution-free grading
P-211 — registered for R-216, before the harness: A Huber QEF and a 2-means split on normals, against the λ the curl residual could not replace
Ticket: R-216 (M). Records: field, resolution, cells_second_vertex_m60, huber_delta, irls_iterations, huber_vertex_moved_cells, two_means_split_cells, auc_two_means_vs_m60, auc_curl_p173, self_intersections_before, self_intersections_after, cost_share, c1_holds, c2_holds, c3_holds.
Hypothesis. M-486: the curl residual is free and "does not predict M-60's second-vertex cells" (AUC 0.27–0.91). M-60 says two of seven fields ever need a second vertex, with no rule. A cell whose Hermite normals come from two sheets is a mixture, and the robust-statistics answer to a mixture in a least-squares fit is a Huber loss solved by IRLS, or a 2-means split on the normal directions. (C1) A 2-means split on the normals (two centroids on S², one iteration from antipodal seeds) predicts M-60's second-vertex cells with AUC ≥ 0.85 on every field where M-60 has any, beating P-173's curl AUC on every row. (C2) The Huber-IRLS QEF with δ at the median residual moves the vertex by more than 0.1 cells on at least 80% of M-60's cells and on under 5% of the others — it acts where the mixture is. (C3) On noise_cavity at 33³ the Huber arm cuts M-486's 388 self-intersections by at least half, and costs under 15% of an extraction. SHARE: C3's share is the QEF stage's; M-486's per-cell λ already got 388 → 195 and the row must beat that comparand, not the shipped one.
Falsified by. C1 by AUC under 0.85, which would say the second-vertex cells are not a two-cluster mixture in normal space — then they are something else and the row names it. C2 by the Huber vertex moving on ordinary cells, which would say δ is mis-set and the robust fit is over-reacting to trilinear noise. C3 by fewer than half, or by cost above 15%. VACUITY CONTROL: auc_curl_p173 must be recomputed on the same rows from p-173.csv, not quoted, or the comparison is against a memory.
P-212 — registered for R-217, before the harness: Conformal prediction grades the four fields validate::accuracy cannot
Ticket: R-217 (M). Records: calibration_fields, test_field, resolution, alpha, nonconformity_score, interval_width, coverage_measured_on_exact_holdout, predicted_hausdorff_interval_unbounded, coverage_target, c1_holds, c2_holds.
Hypothesis. ✗107: "validate::accuracy is meaningless where field.bound() is not Exact", and 20 of 40 rows read unmeasurable. Conformal prediction produces a prediction interval with guaranteed marginal coverage 1 − α from a calibration set, under exchangeability alone (Angelopoulos & Bates, acquired). Per-cell features the extractor already has — |Δ|-normalised, ‖∇f‖, P-173's curl residual, the case index — are the covariates; per-cell Hausdorff on Exact fields is the label. (C1) Calibrated on three Exact fields and tested on the held-out fourth, the α = 0.1 intervals cover the true per-cell Hausdorff on 88–92% of cells — the coverage guarantee holds on a field the calibration never saw. (C2) Applied to the four ungradeable fields, the intervals are informative: their width is under half the cell size on at least 70% of surface cells, so the grade is a number and not a shrug. SHARE: none; a grade.
Falsified by. C1 by coverage outside [0.85, 0.95], which would say the fields are not exchangeable — the honest likely failure on box_exact (creases are a different population), and the row reports coverage per held-out field so the exchangeable subset is visible. C2 by wide intervals, which would say the covariates carry no information about error — a finding about the covariates. VACUITY CONTROL: a random-label control must produce coverage at 1 − α with intervals as wide as the label range, or the harness is not computing conformal intervals.
Group K — quantum information (the 3-tangle is the hyperdeterminant)
P-213 — registered for R-218, before the harness: A null registered on purpose — a W-class entanglement monotone on the cells where |Δ| is blind
Ticket: R-218 (M). Records: field, resolution, cells_delta_zero, cells_w_class, w_monotone_value, tau_abc_value, rank_correlation_with_hausdorff, rank_correlation_delta_p134, defect_rate_by_monotone_quartile, c1_holds, c2_holds.
Hypothesis. Coffman, Kundu & Wootters' three-way tangle is 4|Δ| for the 2×2×2 tensor (their abstract defines "the three-way tangle … invariant under permutations of the qubits"; the hyperdeterminant identity is standard). Dür, Vidal & Cirac's SLOCC classification is de Silva & Lim's orbit classification under another name, and the W class is exactly P-131's Δ = 0, rank 3, border rank 2 stratum — where |Δ| vanishes identically and ✗103 found it uninformative on 5 of 8 fields. The physics literature has monotones that are non-zero on W states. (C1) On the cells P-131 classified as W-class, a W-class monotone (the registration names the Dür–Vidal–Cirac |⟨ψ|ψ̃⟩|-based measure, computed from the normalised corner tensor) rank-correlates with per-cell Hausdorff at ≥ 0.5 — on cells where |Δ| correlates at exactly 0 because it is exactly 0. (C2) Outside the W class the monotone adds nothing over |Δ| (correlation within 0.05 of ✗103's), which is the registered null and the reason this is one row and not a group. SHARE: none.
Falsified by. C1 by no correlation on the W cells, which retires the dictionary as a source of measures while leaving it as a source of names. C2 by the monotone beating |Δ| outside the W class, a strictly better result. VACUITY CONTROL: cells_w_class must be non-zero on csg_difference (where M-444 counted 2,222 rank-3/border-rank-2 hits), or C1 is over an empty set.
Group L — critical points on grids (discrete Morse theory, quantum chemistry)
P-214 — registered for R-219, before the harness: Discrete Morse on the cubical complex is a third χ oracle, and its critical cells should be the body saddles
Ticket: R-219 (M). Records: field, resolution, critical_cells_by_dim, chi_dms, chi_p145_oracle, chi_p142_analytic, chi_mesh, saddle_cells_p137, critical_2cells_in_saddle_cells_share, cost_share, c1_holds, c2_holds.
Hypothesis. Robins, Wood & Sheppard 2011 (acquired) construct a discrete Morse complex on the cubical complex of a grayscale image in linear time, with critical cells that correspond to the field's critical points. The 2026-08-23 memo ranked it #7 and it was never run. (C1) χ = Σ_k (−1)^k c_k over the discrete Morse critical cells equals P-145's oracle on every field where that oracle reports split_blocks = 0, and equals P-142's analytic −8N³ on the periodic gyroid — a third oracle, this one with a gradient field attached. (C2) At least 80% of critical 2-cells and 3-cells lie in cells P-137's eliminant flags as body-saddle cells, so the combinatorial and the algebraic saddle instruments agree on where the topology is decided. SHARE: C1's cost share is reported against P-145's 0.47–1.06×.
Falsified by. C1 by χ disagreeing with the oracle where the oracle is trusted, which would mean the cubical complex's adjacency and the oracle's are different pairs — P-184 would then say which. C2 by the critical cells and the algebraic saddles living in different places, which would be a real discrepancy between the discrete and the trilinear model of the same samples. VACUITY CONTROL: critical_cells_by_dim must be non-zero in dimensions 1 and 2 on gyroid, or the complex has collapsed to its minima.
P-215 — registered for R-220, before the harness: A null registered on purpose — a regular isovalue by Sard, located with the chemists' grid algorithm
Ticket: R-220 (S). Records: field, resolution, critical_values_found, isovalue_distance_to_nearest_critical, non_transverse_cells_at_zero_p171, non_transverse_cells_at_shifted, shift_applied, hausdorff_delta_from_shift, c1_holds, c2_holds.
Hypothesis. M-484: transversality fails on 19% of box_exact's cells at 17³. Sard's theorem says the set of critical values has measure zero — so a tiny shift of the isovalue away from the nearest critical value makes the level set transverse almost surely. Yu & Trinkle's weight method (acquired) locates a grid function's basins and critical points in linear time with quadratic convergence [abstract]. (C1) The weight method finds the critical values of each sampled field; the shipped isovalue 0 is within 1e-3 of a critical value on box_exact and csg_difference (their faces sit on the isovalue by construction) and not on the smooth fields. (C2) Shifting the isovalue by 1e-4 on those two fields reduces non_transverse_cells by at least 90% while moving the Hausdorff error by under 1e-3 cells — which is the null: it works, and it is the same thing as M-317's exactly-zero-corner problem, so the correct landing is an exact predicate (novelty table #6), not a shift. SHARE: none.
Falsified by. C1 by the weight method missing the polyhedral critical values, which are degenerate (a whole face is critical) and may defeat a method built for smooth densities — the row records that as the boundary of the transfer. C2 by the shift not removing non-transversality, which would say the failures are not isovalue-coincidence and P-171 needs another explanation. VACUITY CONTROL: sphere must show non_transverse_cells = 0 before and after, or the shift is not neutral where it should be.
Group M — analytic number theory (lattice points)
P-216 — registered for R-221, before the harness: A translating sphere's triangle count flickers with the sphere-problem exponent
Ticket: R-221 (S). Records: radius_cells, translations, surface_cells_mean, surface_cells_sd, triangles_mean, triangles_sd, relative_jitter, fitted_jitter_exponent, predicted_exponent_range, interior_count_discrepancy_rms, c1_holds, c2_holds.
Hypothesis. The number of lattice points in a ball of radius R is (4/3)πR³ + P₃(R²) with P₃(x) = O(x^{21/32+ε}) and Ω±(x^{1/2}(log x)^{1/2}), and Jarník's mean square ∫₀ˣ P₃² dx = c₃ X² log X [verified, Ivić et al. §2, eqs. 2.5, 2.9, 2.10]. The surface-cell count of a digitised sphere is a shell count — a difference of two such discrepancies — so its jitter under sub-cell translation is bounded by the same exponents: RMS ~ R (log R)^{1/2} against a mean ~ R². (C1) Over 64 sub-cell translations of sphere at radii 8, 16, 32, 64 cells, interior_count_discrepancy_rms grows with R at a fitted exponent in [1.0, 1.32] — Jarník's 1 with the log, Heath-Brown's 21/16 = 1.3125 as the ceiling. (C2) relative_jitter of the triangle count falls with R at exponent ≈ −1 (i.e. as R^{1−2} · (log R)^{1/2}), so a sphere of radius 32 cells has a triangle-count jitter under 3% under motion — the number a frame-budget predictor needs. SHARE: none; a prediction about output-size variance under motion.
Falsified by. C1 by an exponent above 1.32, which would contradict Heath-Brown and be a bug; by an exponent well below 1, which would say the shifted-centre problem has a smaller discrepancy than the origin-centred one — a genuine number-theoretic question the row would then have data on. C2 by the triangle jitter not tracking the cell jitter, which would say triangles per cell vary under translation more than cells do. VACUITY CONTROL: translations must include the origin and at least one irrational offset per axis, or the sample is the rational special case Landau's theorem separates.
P-217 — registered for R-222, before the harness: A null registered on purpose — the gyroid's χ converges at integer cells-per-period and jitters otherwise, and that is Landau's rational/irrational dichotomy
Ticket: R-222 (S). Records: cells_per_period, rational, resolution, chi_measured, chi_analytic_p142, chi_error, chi_error_rms_over_phase, phase_offsets, c1_holds, c2_holds.
Hypothesis. M-455 reproduced −8N³ at integer N; M-457 found the noise field's χ "still moving at 129³". For lattice points in ellipsoids, Landau and Jarník prove different discrepancy orders for rational and irrational quadratic forms [verified, Ivić et al. §3]. A periodic field sampled at an integer number of cells per period is the rational case; at an irrational ratio the sampling phase drifts across the box. (C1) At cells_per_period ∈ {16, 32, 64} the gyroid's χ equals −8N³ exactly at every phase offset (chi_error_rms_over_phase = 0). (C2) At cells_per_period ∈ {16·√2, 32·φ} the χ error over 16 phase offsets has non-zero RMS that does not fall with resolution — the registered null: the irrational case never converges pointwise, only in mean, and the ledger should say so before someone reports it as a bug. SHARE: none.
Falsified by. C1 by any error at integer ratios, a bug. C2 by the irrational RMS falling with resolution, which would say the periodic surface's χ is more forgiving of incommensurate sampling than lattice-point theory suggests — an interesting positive. VACUITY CONTROL: phase_offsets must include at least 8 distinct values and the integer arm must show chi_error = 0 on all of them, or the phase sweep is not sweeping.
Group N — symmetry reduction (crystallography)
P-218 — registered for R-223, before the harness: Mesh one asymmetric unit of a symmetric field and replicate it, bit-identically, at 1/|G| of the cost
Ticket: R-223 (L). Records: field, space_group, group_order, resolution, fundamental_domain_cells, full_cells, cell_ratio, replicated_hash, full_hash, hashes_identical, vertex_max_deviation, extract_ms_full, extract_ms_reduced_plus_replicate, speedup, c1_holds, c2_holds, c3_holds.
Hypothesis. M-456 classified the gyroid's primitive lattice and space group; ✗49 proved bit-exact octahedral equivariance of Marching Cubes. Together they license a construction crystallography has used for a century: compute in the asymmetric unit and generate the rest by the group. (C1) On gyroid (Ia-3d, 96 operations per conventional cell) and schwarz_p (Im-3m), extracting the fundamental domain and replicating by the group produces a mesh whose golden hash is identical to the full extraction's, after a canonical vertex-order sort — the registration predicts identity for the 48 point-group operations (✗49's guarantee) and records separately whether the translational and glide operations, which ✗49 did not test, preserve it. (C2) speedup is at least 20× at 129³, against a theoretical |G| of 96 minus replication cost. (C3) sphere (O(3) — infinite group; reduce by the 48-element cube group only) shows a 48× cell reduction and hash identity. SHARE: C2 is a cost claim on symmetric fields only; the share of a game world that is symmetric is zero and the row says so — this is for the periodic-tile and CAD consumers.
Falsified by. C1 by non-identical hashes under glide or translation operations, which is the finding: it would locate the exact operation under which the extractor is not equivariant, and ✗49 would gain a caveat. C2 by replication cost eating the gain, which prices the mechanism. C3 by sphere failing, which cannot happen if ✗49 holds and would be a bug in the replication. VACUITY CONTROL: a deliberately mis-specified group (one operation removed) must produce a hash mismatch, or the identity check is comparing a mesh to itself.
P-219 — registered for R-224, before the harness: A null registered on purpose — seams on mirror planes cannot crack
Ticket: R-224 (S). Records: field, seam_plane, is_mirror_plane, seam_vertices_a, seam_vertices_b, seam_pairs, injective, crack_count, max_gap, c1_holds, c2_holds.
Hypothesis. M-461 found the gyroid's seam correspondence non-injective (295 / 294 / 295), which is M-48 again. A chunk boundary that lies on a mirror plane of the field's symmetry group has a seam whose two sides are each other's images under a reflection the extractor is equivariant to, so the correspondence is the identity and the seam cannot crack — a theorem, not a weld. (C1) On gyroid chunked along its mirror planes, every seam has injective = true and crack_count = 0 with no weld pass. (C2) Chunked along a plane that is not a mirror plane, the same field reproduces M-461's non-injective seams — the null half, which says the mechanism is the symmetry and not the chunking. SHARE: none.
Falsified by. C1 by a crack on a mirror seam, which would say the extractor is not equivariant under that reflection — the same finding P-218 C1 would make from the other side. C2 by non-mirror seams also being clean, which would say M-461's defect was resolution-specific. VACUITY CONTROL: is_mirror_plane must be computed from the space group's operations, not asserted per row.
Group O — shape calculus
P-220 — registered for R-225, before the harness: The shape derivative of area predicts a CSG edit's triangle delta before the remesh
Ticket: R-225 (S). Records: field, edit_kind, edit_radius_cells, triangles_before, triangles_after, delta_measured, delta_predicted_first_order, delta_predicted_with_curvature_term, relative_error, prediction_cost_share, c1_holds, c2_holds.
Hypothesis. Hadamard's shape derivative of the area functional under a normal displacement φ is ∫ H φ dA (mean curvature times displacement); Sokolowski & Zochowski's topological derivative (acquired) handles the case where the edit creates a hole. M-13 makes triangle count proportional to area, so the derivative predicts the triangle delta of an edit to first order from data on the old mesh. (C1) For spherical subtractions of radius 2–8 cells from sphere, torus and noise_cavity, the first-order prediction is within 15% of the measured delta on 80% of edits; the topological-derivative term is needed exactly when the edit punches through (edit_radius_cells exceeds local thickness). (C2) The prediction costs under 1% of a remesh. SHARE: none — a budget predictor for the scheduler, which is a consumer, not this crate; the row exists because the derivative is a theorem about the field the crate owns.
Falsified by. C1 by errors above 15%, which would say the second-order (Gaussian curvature) term is not negligible at these radii — the row reports the curvature-corrected prediction beside the first-order one for that reason. C2 by cost, which cannot happen for a surface integral over the old mesh. VACUITY CONTROL: an edit that misses the surface entirely must predict and measure a delta of 0.
Group P — stochastic sampling and dither (signal processing)
P-221 — registered for R-226, before the harness: A jittered grid kills the axis-aligned grain, and the Wulff plot says by how much
Ticket: R-226 (M). Records: field, resolution, jitter_amplitude_cells, needle_ratio_mean, needle_ratio_axis_aligned, wulff_spread_regular, wulff_spread_jittered, hausdorff_regular, hausdorff_jittered, hashes_deterministic, cost_share, c1_holds, c2_holds, c3_holds.
Hypothesis. Cook 1986 (paywalled): stochastic sampling converts aliasing into noise. A per-cell deterministic hash offset of the sample positions (bounded to 0.25 cells) is a jittered grid, and the extractor on a jittered grid is Marching Tetrahedra on a perturbed lattice — the Kuhn triangulation M-452 proved regular survives small perturbation. Treece's randomised tet split (novelty table #3) randomises topology; this randomises position, which is the other half. (C1) On box_exact at 65³, the mean needle ratio moves from M-309's 0.250 to above 0.5 at jitter 0.25. (C2) P-186's Wulff-plot spread falls by at least 50% under jitter, at a Hausdorff cost under 10%. (C3) Output is deterministic (hashes_deterministic = true across runs), because the jitter is a pure function of grid coordinates. SHARE: C2's Hausdorff cost is the price and is reported against the regular grid on every field, including the smooth ones where jitter has nothing to fix.
Falsified by. C1 by the needle ratio not moving, which would say the slivers are a property of the tet split and not of the lattice alignment, and P-192 C2 inherits the question. C2 by Hausdorff cost above 10%, which prices jitter out on smooth fields. C3 by any non-determinism, a bug. VACUITY CONTROL: jitter amplitude 0 must reproduce every golden hash, or the jittered path is not the shipped path at zero.
P-222 — registered for R-227, before the harness: A null registered on purpose — dithering the isovalue does not unbias the mesh area
Ticket: R-227 (S). Records: field, resolution, dither_amplitude, area_mesh_undithered, area_mesh_dithered_mean, area_true_or_zk, bias_undithered, bias_dithered, variance_dithered, c1_holds, c2_holds.
Hypothesis. Subtractive dither makes quantisation error independent of the signal (Schuchman's condition; Wannamaker et al., paywalled). A sign grid is a 1-bit quantiser of the field, and the mesh area's orientation bias (P-186) is quantisation error. Dithering the isovalue per cell by a zero-mean amount would, if the analogy held, make the expected area unbiased. (C1) The registered null: over 32 dither seeds, the dithered mean area's bias against P-183's estimator is not smaller than the undithered bias on box_exact, because the bias is directional (a function of the normal) and a scalar dither does not see direction. (C2) Dither does reduce the bias on sphere, where the bias averages over all normals, by at least 30% — the half of the mechanism that works, and the reason the analogy is tempting. SHARE: none.
Falsified by. C1 by dither removing the box bias, a strictly better result that would give a two-line area fix. C2 by no effect on the sphere, which would say the mesh area bias is not a quantisation effect at all. VACUITY CONTROL: variance_dithered must grow with dither_amplitude, or the dither is not reaching the sign decision.
Group Q — the roster is a designed experiment (statistics)
P-223 — registered for R-228, before the harness: A space-filling roster of reference fields, so that no future mechanism is judged by a roster accident
Ticket: R-228 (L). Records: field, curvature_ratio_max, besov_index_p195, genus, bound_kind, flat_axis_aligned_fraction, reach_over_h, design_cell, design_coverage_before, design_coverage_after, anisotropy_rerun_c1_winners, c1_holds, c2_holds.
Hypothesis. M-459: "this crate's reference-field roster is adversarial to global anisotropy"; M-462: 70 of 112 rows unmeasurable because five of eight fields make two arms one grid. A roster chosen for coverage of the invariants that decide experiments — curvature ratio, regularity, genus, bound kind, axis-aligned fraction, reach-to-cell ratio — is a designed experiment (McKay, Beckman & Conover's Latin hypercube, paywalled; the construction is elementary). (C1) The current eight fields occupy at most 40% of a 6-factor, 3-level design's cells; six new bench-local fields chosen by a maximin criterion raise coverage above 75%. (C2) Re-running P-146's anisotropy comparison on the designed roster produces c1_winners ≥ 3 where M-459 had 0 of 4 — not because the mechanism changed but because the roster now contains fields with a flat direction and an Exact bound. SHARE: none — this row buys future rows their denominators.
Falsified by. C1 by the current roster already covering the design, which would say M-459's complaint was about one factor, not the roster. C2 by anisotropy still losing on a roster designed to let it win, which would be the definitive negative for Group D of Phase 27 and worth having. VACUITY CONTROL: design_coverage_before must be computed from measured invariants (P-201, P-199), not from the fields' names.
Group R — backward error and conditioning (numerical analysis)
P-224 — registered for R-229, before the harness: The backward error of an extraction, and the condition number that turns it into Hausdorff
Ticket: R-229 (S). Records: field, resolution, extractor, backward_error_vertex_rms, backward_error_face_max, forward_hausdorff, gradient_norm_min, condition_number_estimate, forward_over_backward, ratio_matches_condition, c1_holds, c2_holds.
Hypothesis. Every accuracy number in the ledger is a forward error. The backward error — the smallest ‖δf‖∞ such that the mesh lies exactly on {f + δf = 0} — is max |f(x)| over the mesh, a field evaluation per vertex and no true surface needed, so it grades every field. Forward error is backward error times the condition number 1/‖∇f‖ at the surface. (C1) On the four Exact fields, forward_over_backward equals 1/gradient_norm_min within a factor of 2 on every row — the condition-number relation holds. (C2) On the four ungradeable fields the backward error is reported and is within the range the Exact fields span, so a second mesh-free grade (after Group A's) exists for them, and thin_plate's difficulty in ✗107 is explained as a conditioning effect (gradient_norm_min small where the plate is thin) rather than a mechanism failure. SHARE: none; an instrument.
Falsified by. C1 by the ratio not tracking the gradient, which would say the mesh error is not first-order in the field perturbation — a real statement about the extractor. C2 by backward errors on the unbounded fields outside the Exact range, which would be a finding about those fields. VACUITY CONTROL: the backward error must be computed with the field, not the trilinear interpolant, and the row must report both so the interpolation error is visible as their difference.
Group S — affine arithmetic, pointed at the empty-cell test (interval analysis)
P-225 — registered for R-230, before the harness: A null registered on purpose — extended revised affine arithmetic on gyroid's rejected share
Ticket: R-230 (M). Records: field, resolution, coarse_level, rejected_share_corner_sampling, rejected_share_interval, rejected_share_affine, false_rejections, cost_ratio_affine_over_corner, c1_holds, c2_holds.
Hypothesis. M-306: corner sampling rejects 16.8% of coarse cells on gyroid against 95.1% on thin_plate. Fryazinov, Pasko & Comninos' extended revised affine arithmetic (in the corpus, 0.68) bounds procedural implicit functions more tightly than interval arithmetic. The 2026-08-26 audit rejected affine arithmetic for the trilinear, where the corner range is exact; the coarse-cell test evaluates the field, where it is not. (C1) Affine arithmetic raises gyroid's rejected share from 16.8% to at least 40% with false_rejections = 0. (C2) The registered null: it costs more than 5× corner sampling per coarse cell, and the net traversal time does not fall, because gyroid's surface cells are dense enough that rejection buys little — the row prices the trade rather than assuming it. SHARE: C2 is the traversal stage's share and must be reported from M-306's own numbers.
Falsified by. C1 by a share under 40%, which would say gyroid's sin·cos products defeat affine forms as they defeat intervals. C2 by a net win, a strictly better result. VACUITY CONTROL: false_rejections must be checked against a full-resolution extraction on every row, or the tighter bound could be tighter than the truth.
Group T — digital topology (Alexander duality)
P-226 — registered for R-231, before the harness: A null registered on purpose — solid and air have dual Betti numbers, and the split blocks are where the duality fails
Ticket: R-231 (S). Records: field, resolution, adjacency_pair, b0_solid, b1_solid, b2_solid, b0_air, b1_air, duality_holds, split_blocks_p145, duality_failures_in_split_blocks_share, c1_holds, c2_holds.
Hypothesis. For a closed surface in a ball, Alexander duality gives b₁(solid) = b₁(air) and relates the component counts. P-145's oracle chooses a foreground adjacency and reports split_blocks; P-184 names the complementary pairs. The registered null: with a complementary pair the duality holds exactly, and every failure of it under a non-complementary pair lies in a split block. (C1) Under (6,26) and (26,6), duality_holds on every field at 33³ and 65³. (C2) Under (26,26) — deliberately inconsistent — duality_holds fails, and 100% of the failing cells are P-145's split blocks. SHARE: none.
Falsified by. C1 by a duality failure under a complementary pair, which would say the field is not closed in the box (the gyroid and fbm_terrain leave through the sides, so they are excluded by expected_euler's own rule and the row says so). C2 by failures outside the split blocks, which would say the split count under-reports. VACUITY CONTROL: (26,26) must fail on at least one field, or the control is not a control.
Group U — currents and the flat norm (geometric measure theory)
P-227 — registered for R-232, before the harness: A null registered on purpose — the flat norm sees a missing sheet that Hausdorff sees too, and costs an LP
Ticket: R-232 (S). Records: field, resolution, flat_norm_scale, flat_norm_distance, hausdorff, planted_defect, flat_norm_response, hausdorff_response, lp_solve_ms, cost_share, c1_holds, c2_holds.
Hypothesis. Morgan & Vixie (acquired) show the flat norm between boundaries is computed by an L¹TV minimisation — a linear program on the grid. The flat norm is a true metric on currents that sees orientation flips and mass, unlike Hausdorff. (C1) On a planted orientation flip (one triangle strip inverted on sphere) the flat norm responds by more than 10× its clean-mesh value while Hausdorff responds by 0 — the one defect class Hausdorff is structurally blind to and the orientation test already catches combinatorially. (C2) The registered null: on every other planted defect (P-209's deleted sheet, a displaced vertex) Hausdorff and the flat norm respond in the same direction, and the LP costs more than 10 extractions, so the instrument is not worth shipping. SHARE: none.
Falsified by. C1 by no response to a flip, which would mean the current's orientation was dropped in the discretisation. C2 by a cheap LP, which would reopen the row as a validation metric. VACUITY CONTROL: the clean-mesh flat norm must be non-zero and reported, so responses are ratios and not absolutes.
Group V — approximation constants (the 7× has three factors)
P-228 — registered for R-233, before the harness: M-472's constant gap decomposes into a filter constant, a representation constant and a placement constant, and the ledger should say which is 5 of the 7
Ticket: R-233 (S). Records: field, resolution, constant_gap_m472, filter_constant_blu_unser_closed_form, filter_constant_measured, representation_constant, placement_constant, product_of_three, product_matches_gap, largest_factor, c1_holds, c2_holds.
Hypothesis. M-472 bounded the constant gap to the W_inf^2 minimal error at 6.26–7.25. Three stages each contribute a constant: the trilinear filter (Blu & Unser give the asymptotic constant in closed form — Part I paywalled, but the Blu paper the corpus already held states the formula), the PL representation (the interpolation constant of a triangle of the mesh's shape), and vertex placement along the edge (✗42's lottery, a measurable factor). (C1) The three constants, each measured in isolation by holding the other two stages exact (an exact_oracle field for the filter, exact vertices for the representation, exact surface for placement), multiply to within 20% of M-472's gap on sphere and torus. (C2) The representation constant is the largest of the three on both fields, which is ✗116's conclusion stated as a number and is what licenses Group D. SHARE: none — a decomposition.
Falsified by. C1 by a product far from the gap, which would say the three stages interact and the decomposition is wrong — worth knowing before Group D spends L on the representation. C2 by the filter or placement constant being largest, which would redirect Group D's effort to ✗42's lottery or to Axis 11. VACUITY CONTROL: filter_constant_measured must reproduce the Blu–Unser closed form within 10%, or the filter arm is not isolated.
Group W — Poisson approximation (probability)
P-229 — registered for R-234, before the harness: A null registered on purpose — ambiguous cells are Poisson at large correlation length
Ticket: R-234 (S). Records: seed, resolution, cells_per_correlation_length, ambiguous_cells, mean_over_seeds, variance_over_seeds, variance_over_mean, chi_variance_p144_style, chi_variance_predicted_from_ambiguous, c1_holds, c2_holds.
Hypothesis. Chen–Stein (Arratia, Goldstein & Gordon, paywalled): rare, weakly dependent events are Poisson to a bounded total-variation error. Ambiguous cells on gaussian_rf are rare when the correlation length is many cells, and dependent only within a correlation length. (C1) Over 32 seeds, variance_over_mean of the ambiguous-cell count is within [0.8, 1.2] once cells_per_correlation_length ≥ 8, and drifts away from 1 below that. (C2) P-144's per-seed χ variance is predicted by the ambiguous-cell count's Poisson variance times a per-cell χ contribution measured on the same rows, within a factor of 2 — the null being that the topological variance across seeds is explained by the rare-cell count and needs no further mechanism. SHARE: none.
Falsified by. C1 by over-dispersion at large correlation length, which would say ambiguous cells cluster and the dependence is longer-range than the covariance suggests. C2 by the χ variance not being explained, which would leave M-457's spread as a live question. VACUITY CONTROL: the count's mean must exceed 20 on every row, or the Poisson test is on a handful of events.
Group X — coarea and the divergence theorem (measure theory)
P-230 — registered for R-235, before the harness: Area from the coarea integral and volume from the divergence theorem, as the tie-breaker for Group A
Ticket: R-235 (S). Records: field, resolution, smoothing_epsilon, area_coarea, area_zk_p177, area_mesh, volume_grid_count, volume_mesh_divergence, volume_true_or_none, area_disagreement_arbitrated, c1_holds, c2_holds.
Hypothesis. ∫ |∇f| δ_ε(f) dx is a third area estimate, from the values rather than the signs; ∮ x·n dA / 3 over the mesh is its volume by the divergence theorem, against the voxel count. P-183 C2 needs a tie-breaker when the mesh and the configuration estimator disagree on an ungradeable field. (C1) On the Exact fields the coarea area is within 3% of truth at 65³ for ε = 1.5h, and the mesh's divergence-theorem volume within 1% of the voxel count plus the surface correction. (C2) On any row where P-183 recorded a mesh/estimator disagreement beyond the bound, the coarea value sides with one of them by a margin larger than its own 3%, so the disagreement is arbitrated. SHARE: none.
Falsified by. C1 by errors above 3%, which would say δ_ε at this ε is too wide for the field's gradient variation — the row sweeps ε. C2 by the coarea value sitting between the two, which would leave the disagreement unarbitrated and would say three instruments are not enough. VACUITY CONTROL: the divergence-theorem volume must fail on a mesh with a planted inverted strip (P-227's fixture), or the orientation dependence that makes it a check is not present.
Group Y — quasi-Monte Carlo (discrepancy theory)
P-231 — registered for R-236, before the harness: A null registered on purpose — eight Sobol points per coarse cell against eight corners
Ticket: R-236 (S). Records: field, coarse_level, probe_set, probes_per_cell, rejected_share, missed_surface_cells, koksma_hlawka_bound, cost_ratio, c1_holds, c2_holds.
Hypothesis. Corner sampling is a 2×2×2 regular probe of a coarse cell; the Koksma–Hlawka inequality bounds a quasi-Monte Carlo probe's miss rate by the field's variation times the point set's discrepancy, and a Sobol set of 8 points has lower discrepancy than the corners. (C1) With 8 Sobol probes per coarse cell, missed_surface_cells (cells rejected that contain surface at full resolution) on gyroid is at least 30% lower than with 8 corners at the same cost. (C2) The registered null: the corners are exact for the trilinear and the Sobol set is not, so on the smooth fields the Sobol arm rejects fewer cells and the mechanism is a wash — the only field it can help is the one whose surface is dense relative to the coarse cell, and there P-225's affine arm is the comparand. SHARE: none.
Falsified by. C1 by no reduction in misses, which retires the row. C2 by Sobol winning on smooth fields, a surprise about the trilinear's corner exactness. VACUITY CONTROL: probes_per_cell must be equal across arms, or the comparison is of budgets.
Group Z — the error field has a spectrum (harmonic analysis, reciprocal lattices)
P-232 — registered for R-237, before the harness: The mesh error's power spectrum peaks at the reciprocal lattice, and BCC moves the peaks
Ticket: R-237 (M). Records: field, lattice, resolution, error_field_resolution, spectrum_peaks, peaks_at_reciprocal_vectors_share, peak_power_share, isotropic_power_share, bcc_peak_set, cubic_peak_set, peak_sets_differ, c1_holds, c2_holds.
Hypothesis. The signed distance from the true surface to the mesh, sampled on a fine grid, is a field whose power spectrum should concentrate at the reciprocal lattice vectors of the sampling lattice — the aliasing signature, which P-186 measures in the direction domain and this row measures in the frequency domain. (C1) On sphere at 65³ with the error sampled at 4× resolution, at least 60% of the error power above the isotropic floor sits within one bin of a reciprocal lattice vector of Z³. (C2) On BCC the peaks sit at the reciprocal (FCC) vectors instead — peak_sets_differ = true — and the peak power share falls even where P-162 found the total error unchanged, which is the frequency-domain version of P-186 C2. SHARE: none; an instrument that makes P-162's null legible.
Falsified by. C1 by diffuse power, which would say the error is not aliasing-dominated and the lattice choice is genuinely irrelevant — closing Axis 12 for this crate. C2 by BCC's peaks not moving, a bug in the BCC arm. VACUITY CONTROL: a mesh with white-noise vertex perturbation must show a flat spectrum, or the FFT is seeing the grid rather than the error.
12. What this phase deliberately does not claim
- No row claims a speedup on the shipped path. Every cost clause is a price (
P-207,P-210,P-218,P-225,P-227), reported so that the landing decision has a number. - No row re-runs a Phase 27 mechanism except
P-223, which re-runsP-146's anisotropy on a roster designed to let it win, becauseM-459said the roster was the confound and that is a testable sentence. - Nothing here needs a paywalled paper to run. Where the source is paywalled the row's claim is derived (
P-189), classical (P-204,P-215), or uses an acquired conference version (P-183's Lindblad 2002/2003). - The two wrongly-acquired papers are not cited anywhere in this document, and are listed once in §1 for removal.
Acquired and in the corpus at time of writing (23). Taylor 2006 10.1214/009117905000000594; Letendre arXiv:1408.2107; Cheng & Schwartzman arXiv:1511.06835; Legland et al. 10.5566/ias.v26.p83-92; Schladitz–Ohser–Nagel 10.1007/11907350_21; Ziegel & Kiderlen 10.1016/j.imavis.2009.04.013; Lindblad 2003 10.1007/978-3-540-39966-7_33; Lindblad & Nyström 2002 10.1007/3-540-45986-3_24; Schmalzing & Buchert 10.1086/310680; Brimkov–Coeurjolly–Klette 10.1016/j.dam.2006.08.004 (HTML landing); Coeurjolly–Lachaud–Levallois 10.1016/j.cviu.2014.04.013 (HTML landing); Aamari et al. 10.1214/19-EJS1551; Angelopoulos & Bates arXiv:2107.07511; Ivić et al. arXiv:math/0410522; Peyré & Cuturi arXiv:1803.00567; Solomon et al. 10.1145/2766963 (HTML); Sokolowski & Zochowski 10.1137/S0363012997323230 (HTML); Coffman–Kundu–Wootters arXiv:quant-ph/9907047; Dür–Vidal–Cirac arXiv:quant-ph/0005115; Robins–Wood–Sheppard 10.1109/TPAMI.2011.95; Yu & Trinkle 10.1063/1.3553716; Morgan & Vixie arXiv:math/0612287; Hughes–Cottrell–Bazilevs 10.1016/j.cma.2004.10.008 (HTML). Already held and newly cited (6): Niyogi–Smale–Weinberger 10.1007/s00454-008-9053-2; Berenfeld et al. 10.1007/s00454-021-00290-8; Cuel–Lachaud–Thibert 10.1007/978-3-319-09955-2_12; Fryazinov et al. 10.1016/j.cag.2010.07.003; Acar et al. kinetic hulls 10.1007/978-3-540-87744-8_3; Edelsbrunner & Mücke arXiv:math/9410209.
Phase 31 — thirty registrations for game features and performance, each before its harness
Date: 2026-09-12 · Repo state: 329747e on big (main = origin/main), 606 findings entries, 76
open tickets
Corpus: home-still, 9,723 documents, 296,176 chunks, distill on CUDA
Companion vocabulary: docs/research/2026-09-04-phase-29-axes-and-vocabulary-v3.md is the latest on
main — v4 (Axes 19–23) has not landed — and the words for this phase's fields are in each group header.
Numbering. Phase 29 closed at P-232 / R-237. Drafted as P-277–P-306 against tickets
R-282–R-311 on the mac-air checkout, numbered after a Phase 30 drafted there and ending at
P-276/R-281, then shifted by −44 at the 2026-09-12 landing on big's main, where Phase 30 had
not landed — landed numbers never move, the arriving text does, as M-440's phase did twice and Phase 29
did once. Every artefact in this phase — this document, the FINDINGS.md section and the thirty backlog
rows — carries the final numbers P-233–P-262 / R-238–R-267. Phase 30 will renumber above this
block when it arrives.
Phase 30 is not on main, so its eleven cross-references are by title and carry no number. The draft
cited P-231, P-235, P-237, P-238, P-246, P-257, P-258, P-261, P-270, P-271 and P-276;
seven of those numbers now belong to this phase's rows, so a number here would be worse than no number.
Each reads as "Phase 30's ⟨instrument⟩ registration", and the record columns that named them read
thickness_phase30_depth0, local_thickness_min_phase30 and crease_edges_flagged_phase30_indicator.
Back-linking them is Phase 30's landing's job, not this one's. Cross-references to Phase 29 rows were
resolved by title, not by arithmetic; the corrections paragraph below lists the three the draft got wrong
by content as well.
What this phase is for. Phases 27–30 were grades and guarantees — how to know a mesh is right. This phase is the other half of the memory file: features a game would notice and speed it would feel, each from a mathematical result the ledger has not touched, each with a hook into a number already measured, each falsifiable on the crate's own roster. Tag per group: [feature], [perf], or both.
Corpus status. Probed at landing; §1 is the record. Every group header still names the field's canonical result and the search terms, so a ticket can re-probe.
Protocol. Phase 15's rules. Every P- registered in experiment.rs before any harness commit; every
ratio-of-total carries SHARE; every row carries a VACUITY CONTROL; timings are minima over repetitions with
the count and CSV hash (Phase 30's timing-protocol registration: minima over repetitions with the count and
CSV hash). Falsified rows record which of the falsifier's meanings applies and end there.
Eight registered nulls: P-235, P-238, P-243, P-246, P-249, P-254, P-256, P-261.
Corrections owed to the draft. (1) The draft cited ✗42 for crossing positions vary with evaluation
order within one machine; ✗42 / M-359 is P-60's root-position gain and says nothing about order. The
within-machine order sensitivity is M-32 (two expressions for one seam point, 1.57e-16 world units) and
M-175 (a sum's result depends on tie order); Group F cites M-32. (2) The draft cited P-183 for a
mesh-free Gaussian-curvature / mean-breadth instrument; on the landed numbering P-183 is Phase 29's area
estimator, and the instrument described is P-185 (R-190), integrated mean curvature from the sign grid.
R-248 is blocked on it. (3) The draft's Group I proposes a Barnes–Hut dipole expansion after Barill et al.
2018. S-007's own backlog row already records the opposite verdict, from the 2026 Antipodal paper
(10.1145/3811323): the order-0/order-1 expansions are "very imprecise… not useful for applications."
Antipodal and Xie, Hafner & Wojtan (10.1145/3811339) are both in the corpus and both exact. R-258
measures those; Barnes–Hut is the baseline the ledger already distrusts, not the proposal.
1. What the fourteen probes found, in one table
| Area | Corpus | Repo cites | Verdict |
|---|---|---|---|
| Simplicial refinement (Freudenthal–Bey, Kuhn simplices, congruence classes) | ABSENT (0.62) → acquired Maubach; Bey 1995 and Bey 2000 paywalled | 11 (5 in crates/) |
Group A |
| Multi-material meshing (multi-label level sets, non-manifold PL complexes) | ABSENT (0.60); Wu & Sullivan paywalled | 6 | Group B |
| Curvilinear grids on the sphere (cubed sphere, gnomonic projection) | ABSENT (0.62); Ronchi–Iacono–Paolucci paywalled | 0 | Group C |
| Singularity theory (apparent contours, folds and cusps) | ABSENT (0.59); Koenderink and Whitney paywalled | 0 | Group D |
| Mathematical morphology (offset surfaces, erosion and dilation, Lipschitz bounds) | ABSENT (0.58), no canonical paper | 4 (1 in crates/) |
Group E |
| Floating-point determinism (reproducibility, FMA contraction, reduction order) | PRESENT 0.66 Revol & Théveny | 30 (24 in crates/) |
Group F — re-scoped: M-32, M-175, M-31 |
| Discrete conformal geometry (conformal equivalence, cone singularities) | PRESENT 0.64 Bobenko–Pinkall–Springborn; Springborn–Schröder–Pinkall 2008 paywalled | 5 | Group G |
| Heat-kernel PDE (the heat method, prefactored Laplacian) | PRESENT 0.68 Crane–Weischedel–Wardetzky; Caissard et al. 2018 at 0.6766 | 16 (5 in crates/) |
Group H |
| Generalized winding numbers (solid angle, inside–outside segmentation) | PRESENT 0.72 Jacobson–Kavan–Sorkine-Hornung | 16 (7 in crates/) |
Group I — re-scoped: S-006, S-007, M-262, M-299, M-303 |
| Sparse voxel DAGs (hash-consing, subtree deduplication) | PRESENT 0.77 Kämpe–Sintorn–Assarsson | 6 (1 in crates/) |
Group J |
| Vertex quantisation (rate–distortion, uniform scalar quantiser) | ABSENT (0.62), no canonical paper | 70 (36 in crates/) |
Group K |
| Space-filling curve analysis (Hilbert against Morton, clustering) | PRESENT 0.64 Haverkort & van Walderveen; Moon et al. 2001 paywalled | 8 | Group L |
| Power diagrams (Laguerre tessellation, prescribed volumes) | ABSENT (0.58); Aurenhammer–Hoffmann–Aronov paywalled | 8 | Group M |
| Anisotropic diffusion (Perona–Malik, edge-stopping conductance) | ABSENT (0.53); Perona & Malik paywalled | 0 | Group N |
The calibration, and the top hits that decided the absences. Phase 29's rule was applied unchanged:
present at a top score of 0.65 or above with a relevant top hit, absent at 0.62 or below or with an unrelated
top hit, and the 0.62–0.65 band decided by the top hit's relevance with the score recorded either way. Six
areas came back present and eight absent. The absences are absences of the canonical result, not of the
field: Group A's top hit was Stevenson 2007's bisection-completion paper (10.1090/s0025-5718-07-01959-x) —
adjacent to Bey and not Bey; Group B's was Sphere Carving; Group C's was Springborn's ideal hyperbolic
polyhedra; Group D's was 10.1109_tvcg.2003.1207447; Group E's was 10.1145_258734.258781; Group K's was
Bounded-Distortion Piecewise Mesh Parameterization, with High-Pass Quantization for Mesh Encoding just
behind at 0.6144; Group M's was Diagrammes de puissance restreint sur le GPU — the right field and the
wrong result; and Group N's was a set of eth-cgl-various-Pap13 slides. Two present verdicts fell inside the
band and were decided on relevance: Group G at 0.6382 (Bobenko–Pinkall–Springborn 2010,
10.48550/arXiv.1005.2698, whose canonical SSP 2008 companion is a different document) and Group L at 0.6416
(Haverkort & van Walderveen 2008, 10.48550/arXiv.0806.4787, with Moon et al. 2001 absent). Repo cites were
counted over crates/ docs/ bevy_isomesh/ isomesh_web/ FINDINGS.md BACKLOG.md BACKLOG_ARCHIVE.md, *.rs and
*.md, case-insensitive, over files matching either of a group's two search terms — 478 files scanned.
Two groups are re-scoped, because the probe came back present and the repo already measures part of the
hypothesis. Group F: 24 files under crates/ name mul_add, and M-32, M-175 and M-31/T-007's 378
golden hashes are the determinism entries already on the books; what is unmeasured is the thread count and a
cross-machine hash of the same edit. Group I: the crate ships both directions of the mesh ↔ field conversion
(crates/isomesh/src/construct/winding.rs, S-007; crates/isomesh/src/construct/from_mesh.rs, S-006) and
M-262, M-299 and M-303 priced them; what is unmeasured is S-006's own stated acceptance — mesh a
sphere, convert back to a field, re-mesh, compare — which has no Hausdorff or χ number in FINDINGS.md.
Groups A and K are heavily cited but their probes came back absent, so the re-scope rule does not fire; their
hooks already cite M-452 and Phase 25 respectively.
Acquired and in the corpus at time of writing (1). Maubach 1995, Local bisection refinement for
n-simplicial grids generated by reflection, 10.1137/0916014 (downloaded and converted this session).
Blocked acquisitions — paywalled or unreachable by the resolver this session. Bey 1995 Tetrahedral grid
refinement 10.1007/bf02238487; Bey 2000 Simplicial grid refinement 10.1007/s002110050475; Wu &
Sullivan Multiple material marching cubes algorithm 10.1002/nme.775; Ronchi–Iacono–Paolucci The "Cubed
Sphere" 10.1006/jcph.1996.0047; Koenderink What does the occluding contour tell us about solid shape?
10.1068/p130321; Whitney On singularities of mappings of Euclidean spaces. I 10.2307/1970070;
Springborn–Schröder–Pinkall Conformal equivalence of triangle meshes 10.1145/1360612.1360676;
Moon–Jagadish–Faloutsos–Saltz Analysis of the clustering properties of the Hilbert space-filling curve
10.1109/69.908985; Aurenhammer–Hoffmann–Aronov Minkowski-type theorems and least-squares clustering
10.1007/pl00009187; Perona & Malik Scale-space and edge detection using anisotropic diffusion
10.1109/34.56205. Every title was matched against the canonical title in paper_search before the
identifier was used; no DOI or arXiv id was supplied from memory.
Group A — LOD without a stitching table: Freudenthal–Bey refinement of the Kuhn triangulation (finite-element mesh refinement) [feature][perf]
Field and words. Bey 1995 Tetrahedral grid refinement; Bey 2000 Simplicial grid refinement: on
Freudenthal's algorithm; Maubach 1995 bisection on Kuhn simplices; Rivara longest-edge bisection. Terms:
Freudenthal refinement, Kuhn simplex, congruence classes, conforming refinement, hanging node,
red-green refinement. The result [classical]: a Kuhn tetrahedron refines into eight Kuhn-type
tetrahedra with a bounded number of congruence classes, so recursive refinement never degrades shape; and
bisection-based refinement of Kuhn simplices produces conforming meshes — no hanging nodes — with local
refinement closed by a bounded number of extra bisections. The hook: M-474's LOD stitches levels with
a Transvoxel-style transition table; the Kuhn triangulation M-452 already uses admits a conforming
refinement that needs no transition cases at all.
P-233 — registered for R-238, before the harness: Bey refinement of the crate's six-tet cell stays in a bounded congruence class set, so needle ratio does not grow with LOD depth
Ticket: R-238 (S). Records: refinement_depth, tet_count, congruence_classes_observed, congruence_classes_bound, thickness_min, thickness_phase30_depth0, needle_ratio_extracted, c1_holds, c2_holds.
Hypothesis. (C1) Refining each Kuhn tet by Freudenthal's rule to depth 4 produces at most the classical bound of congruence classes (three for d = 3), verified by canonicalising each tet's edge-length multiset. (C2) thickness_min at every depth equals the depth-0 value of Phase 30's tetrahedron-thickness registration (the thickness_min of the six-tet cell) to precision — quality is exactly preserved, not merely bounded — and the extracted needle ratio on sphere at mixed depth is within 10% of uniform-depth extraction. SHARE: none.
Falsified by. C1 by more classes, which would mean the crate's six-tet split is the chiral variant Bey's rule does not preserve, and the row names which. C2 by degrading thickness, which would say the implementation bisected the wrong edge — Maubach's rule picks a specific one. VACUITY CONTROL: longest-edge bisection of a non-Kuhn regular tet must produce new congruence classes.
P-234 — registered for R-239, before the harness: Conforming Kuhn refinement replaces the LOD transition table, with no cracks and no special cases
Ticket: R-239 (M). Records: field, lod_layout, transition_faces, hanging_nodes, crack_edges (boundary edges of the merged mesh), transition_table_entries_used, chi_merged, chi_true_p145, hausdorff_vs_uniform, c1_holds, c2_holds, c3_holds.
Hypothesis. (C1) With coarse cells refined by bisection closure to meet fine neighbours, hanging_nodes = 0 and crack_edges = 0 on every field at every LOD layout the harness generates — conformity is a property of the triangulation, not of a case table. (C2) transition_table_entries_used = 0: the Transvoxel path is bypassed entirely and Marching Tetrahedra runs unchanged on the refined complex. (C3) chi_merged = chi_true wherever M-474's stitched mesh also had it right, and hausdorff_vs_uniform is within 2× of M-474's. SHARE: none.
Falsified by. C1 by a crack, which would be a closure bug — the number of closure bisections is bounded and the row reports where the bound was exceeded. C3 by worse Hausdorff, which would say bisection puts vertices on cell edges where the crossing is poorly resolved — the price of conformity, and worth a number. VACUITY CONTROL: skipping the closure step must produce crack_edges > 0.
P-235 — registered for R-240, before the harness: A null registered on purpose — conforming refinement costs more triangles than Transvoxel at the transition, and the ratio is bounded by the closure depth
Ticket: R-240 (S). Records: field, triangles_conforming, triangles_transvoxel_m474, ratio, closure_bisections_per_transition_cell, c1_holds.
Hypothesis. The registered null: (C1) ratio ∈ [1.0, 1.5] on every field — conformity is paid for in transition-cell triangles, and the price is bounded by the closure depth. SHARE: ratio is over the whole mesh; the transition cells' share of triangles is reported so a 1.5 on 5% of cells is read correctly.
Falsified by. C1 by ratio < 1, a strictly better result (Marching Tets on refined Kuhn cells emitting fewer triangles than a transition table is plausible on flat regions), or > 1.5, which prices the feature. VACUITY CONTROL: with no LOD (uniform depth) the ratio must be exactly 1.
Group B — multi-material meshing (multi-label level sets, non-manifold PL complexes) [feature]
Field and words. Wu & Sullivan 2003 Multiple material marching cubes; multi-label / multi-phase level
sets; non-manifold cell complex, material interface, triple junction, label configuration. The
result [classical]: with k labels per corner, the cell has k⁸ label configurations; the interface is a
non-manifold 2-complex whose 1-skeleton (triple-junction curves) is where the manifold case table fails, and
the number of orbits under O_h × S_k (cube symmetries times label permutations) is what a table must
enumerate. The hook: the roster is single-material; a game's terrain is not (rock / dirt / grass / ore),
and the M-160 extraction has no seam path at all.
P-236 — registered for R-241, before the harness: The multi-label configuration count under O_h × S_k is small enough to table for k ≤ 4, and Burnside gives the number before enumeration
Ticket: R-241 (S). Records: k, configurations_total, orbits_burnside, orbits_enumerated, agree, orbits_with_triple_junction, table_bytes, c1_holds, c2_holds.
Hypothesis. (C1) Burnside's lemma over O_h × S_k (48·k! elements) predicts the orbit count for k = 2, 3, 4, and the exhaustive enumeration (the A-002f machinery extended to labels) agrees — the k = 2 case must reproduce the 22 orbits of MC with complement. (C2) For k = 4 the orbit count is under 5,000 and table_bytes under 1 MB — tableable, not a runtime decision. SHARE: none.
Falsified by. C1 by disagreement, a bug in the group action (label permutation composed with cube symmetry has a non-obvious order). C2 by a larger count, which prices multi-material at a per-cell solve rather than a lookup, and the row records the crossover k. VACUITY CONTROL: k = 1 must give exactly one orbit.
P-237 — registered for R-242, before the harness: Material seams are closed curves on the mesh, and the mesh-free χ of each material's solid grades them
Ticket: R-242 (M). Records: fixture, k, resolution, material_id, chi_material_mesh, chi_material_oracle_p145, seam_curves, seam_curves_closed, triple_junction_vertices, nonmanifold_edges_expected, nonmanifold_edges_found, c1_holds, c2_holds.
Hypothesis. (C1) On a three-material fixture (three overlapping spheres, each cell's label by nearest centre, a triple junction where all three meet), each material's own solid — label = i as a binary field — has chi_material_mesh = chi_material_oracle at 33³ and above, using P-145's oracle per label. (C2) Every seam curve is closed, and the non-manifold edges of the merged complex are exactly the triple-junction edges (found = expected) — the complex is non-manifold only where the geometry is. SHARE: none.
Falsified by. C1 by a χ mismatch on one material, which locates a wrong orbit in P-236's table — the oracle finds the table's bug. C2 by non-manifold edges away from junctions, a seam-stitching bug. VACUITY CONTROL: two materials with no contact must produce seam_curves = 0.
P-238 — registered for R-243, before the harness: A null registered on purpose — multi-material extraction costs under 1.3× single-material on the same grid
Ticket: R-243 (S). Records: k, resolution, wall_ms_multi, wall_ms_single_m160, ratio, mixed_cells_share, c1_holds.
Hypothesis. The registered null: (C1) with a lookup table, the per-cell cost is a wider index and one extra branch, so ratio ≤ 1.3 at k = 3 on the three-sphere fixture. SHARE: mixed_cells_share (cells with more than one label) is reported so the ratio is read against how often the multi-label path runs.
Falsified by. C1 by a larger ratio, which would say the table's cache footprint (P-236's bytes) is the cost, and the row names the k where it starts. VACUITY CONTROL: k = 1 must give ratio = 1.00 ± 0.02.
Group C — planets: extraction on the cubed sphere and under diffeomorphism (curvilinear grids, differential topology) [feature]
Field and words. Ronchi–Iacono–Paolucci 1996 The cubed sphere; gnomonic projection; curvilinear grid,
Jacobian of the map, topological invariance of sign structure. The result [classical]: a
homeomorphism of the parameter domain preserves the sign of the field at every corner, so the combinatorial
output of the case table is invariant under the warp; only the geometry changes, by the map's Jacobian.
The trilinear is exact only for affine maps, so on the cubed sphere the extracted surface is the image of the
parameter-domain PL surface, with Hausdorff error bounded by ‖J‖·h²-type terms. The hook: games want
spherical worlds; the crate meshes boxes. The cubed sphere has six cube-face charts, each a near-uniform grid,
and the seams between charts are the interesting part.
P-239 — registered for R-244, before the harness: Case indices are invariant under the cubed-sphere warp, so topology on the planet equals topology in the parameter cube
Ticket: R-244 (S). Records: field, resolution, chart, case_index_hash_param, case_index_hash_warped, equal, chi_param, chi_warped, c1_holds.
Hypothesis. (C1) For a field defined on the sphere (sphere with radius varying by fbm_terrain's heights, sampled through the gnomonic map), the per-cell case indices computed in the parameter cube and after the warp are identical on every chart, and chi_warped = chi_param — a theorem checked. SHARE: none.
Falsified by. C1 by any difference, which can only come from the field being sampled at different points (the warp applied to corners after sampling rather than before) — a fixture bug, but exactly the bug a planet implementation will have. VACUITY CONTROL: a warp with a fold (non-injective) must change case indices.
P-240 — registered for R-245, before the harness: Hausdorff error on the planet scales with the chart's Jacobian, and is worst at the cube's corners by the gnomonic distortion factor
Ticket: R-245 (M). Records: field, resolution, chart, cell, jacobian_norm, jacobian_norm_max_over_min, hausdorff_cell, hausdorff_over_h2, correlation_with_jacobian, corner_over_centre, c1_holds, c2_holds.
Hypothesis. (C1) Per-cell Hausdorff error correlates with jacobian_norm at ρ ≥ 0.7 on a planet-sized sphere. (C2) The ratio of error at chart corners to chart centres is within 30% of the gnomonic distortion ratio (classically about 1.3–1.4 for the equal-angle cubed sphere) — the error is the map, not the extractor. SHARE: none.
Falsified by. C1 by low correlation, which would locate the error in the warp of the crossing positions (interpolated in the parameter domain, then mapped) — fixable by mapping corners first and interpolating in world space, and the row measures both orders. C2 by a larger ratio, which would say the extractor's own anisotropy (P-186) compounds the map's. VACUITY CONTROL: the identity map must give corner_over_centre = 1.
P-241 — registered for R-246, before the harness: Chart seams are conforming if the six charts share their edge samples, and the seam's crack count is zero without any stitching code
Ticket: R-246 (M). Records: resolution, seam_edges, seam_vertices_shared, crack_edges, duplicate_vertices, chi_planet, chi_true, c1_holds, c2_holds.
Hypothesis. (C1) When adjacent charts sample the same world points on their shared edge (the cubed sphere's charts meet at cube edges with a common parameterisation), the two charts' meshes share vertices by construction and crack_edges = 0. (C2) chi_planet = 2 for a planet with no caves and chi_true (from P-145 run in world space) for one with. SHARE: none.
Falsified by. C1 by cracks at seams, which come from the two charts interpolating the crossing along the shared edge from different corner pairs — the cubed sphere's known subtlety at the eight cube corners where three charts meet, and the row reports whether the cracks are only there. VACUITY CONTROL: offsetting one chart's samples by h/2 must produce cracks.
Group D — silhouettes from the field: apparent contours (singularity theory) [feature]
Field and words. Whitney 1955 (folds and cusps of maps from surfaces to the plane); Koenderink 1984 What
does the occluding contour tell us about solid shape?; apparent contour, contour generator, fold,
cusp, T-junction. The result [classical]: the silhouette of a smooth surface under a generic view is
the image of the contour generator {x : n(x)·v = 0}, whose singularities are only folds and cusps
(Whitney), and the sign of the silhouette's curvature equals the sign of the surface's Gaussian curvature at
the generator (Koenderink). The hook: outline rendering and shadow silhouettes walk mesh edges looking
for normal-sign changes; the generator is a level set of ∇f·v and the crate has a level-set extractor.
P-242 — registered for R-247, before the harness: The contour generator is the zero set of ∇f·v on the surface, extractable by the same machinery as a curve, and its cusp count matches Whitney's genericity
Ticket: R-247 (M). Records: field, view_direction, resolution, generator_curves, generator_closed, cusps_found, cusps_by_koenderink_sign_change, mesh_silhouette_edges, hausdorff_generator_vs_mesh_silhouette, cost_share, c1_holds, c2_holds.
Hypothesis. (C1) Extracting {f = 0} ∩ {∇f·v = 0} as the intersection of two level sets (a curve on the surface — per-cell, both signs, a 1-D case table) gives closed generator curves on sphere, torus, gyroid, with cusps_found equal to the number of points where the generator's tangent aligns with v. (C2) The generator's projection is within 2h Hausdorff of the mesh's silhouette edges, at a cost under 10% of extraction (the second field is a dot product on already-computed gradients). SHARE: C2's cost is against one extraction.
Falsified by. C1 by open generator curves, which come from the two level sets being extracted from different interpolants — the per-cell curve must use the same trilinear as the surface. C2 by a larger cost, which would say the gradients were not already available (they are for DC, not for MC) and the row prices both paths. VACUITY CONTROL: v along a symmetry axis of sphere must give exactly one generator curve (the equator).
P-243 — registered for R-248, before the harness: A null registered on purpose — Koenderink's sign theorem holds on the mesh's silhouette only where P-185's Gaussian curvature estimate has a sign
Ticket: R-248 (S). Records: field, view_direction, silhouette_vertex, silhouette_curvature_sign, gaussian_curvature_sign_p185, agree, agree_share, indeterminate_share, c1_holds.
Hypothesis. The registered null: (C1) on torus, silhouette curvature sign agrees with the mesh-free Gaussian curvature sign at ≥ 90% of silhouette vertices where P-185's estimate is not within its own error of zero — a theorem about smooth surfaces surviving discretisation on the vertices where the discretisation has an opinion. SHARE: agree_share is of determinate silhouette vertices; indeterminate_share is reported.
Falsified by. C1 by low agreement, which would say the silhouette walked on the mesh is not the contour generator — the mesh's silhouette includes staircase edges (P-186) that have no smooth counterpart — and would make P-242's field-derived generator the only correct outline. VACUITY CONTROL: sphere must give 100% positive on both.
Group E — conservative offset meshes: occluders and hulls by isovalue shift (mathematical morphology, Lipschitz analysis) [feature]
Field and words. Minkowski erosion/dilation, offset surfaces, 1-Lipschitz, conservative occluder,
bounding hull. The result [classical]: for a signed distance function, {f ≤ −ε} is exactly the
ε-erosion of the solid and {f ≤ +ε} exactly its ε-dilation; for an L-Lipschitz field that is not a
distance function, {f ≤ −Lε} is contained in the erosion and {f ≤ +Lε} contains the dilation. The
hook: software occlusion culling needs a mesh strictly inside the solid; broad-phase collision needs one
strictly outside; both are one isovalue away, and the Lipschitz bound the crate already computes for
empty-cell rejection is the constant.
P-244 — registered for R-249, before the harness: The −Lε isosurface is a conservative occluder — inside the true solid everywhere — and the +Lε one a conservative hull, verified by the oracle
Ticket: R-249 (M). Records: field, is_sdf, lipschitz_L, epsilon, resolution, occluder_vertices_outside_solid, hull_vertices_inside_solid, occluder_volume_over_true, hull_volume_over_true, c1_holds, c2_holds.
Hypothesis. (C1) On every field, extracting at −Lε with ε = 2h gives a mesh with occluder_vertices_outside_solid = 0 (each vertex tested against the field, and against the mesh's own Hausdorff bound from M-472), and at +Lε a mesh with hull_vertices_inside_solid = 0. (C2) On the SDF fields (is_sdf = true) the occluder's volume ratio is within 5% of the analytic erosion volume (V − ε·A + ε²·M − …, the Steiner formula the mean-breadth instrument P-185 already uses), so the shift is not merely conservative but tight. SHARE: none.
Falsified by. C1 by a vertex on the wrong side, which would mean ε < 2h is below the extractor's own error — the row raises ε until it holds and reports the multiple of h that suffices, which is the conservative offset a game must use. C2 by a loose volume on an SDF, which would say the crossing interpolation biases inward (Phase 30's signed-defect registration's inward bias) more than ε absorbs. VACUITY CONTROL: ε = 0 must reproduce the ordinary mesh and fail C1 on at least one field.
P-245 — registered for R-250, before the harness: The occluder needs fewer triangles than the render mesh at the same resolution, because erosion removes features smaller than ε
Ticket: R-250 (S). Records: field, epsilon_over_h, triangles_occluder, triangles_render, ratio, components_occluder, components_render, local_thickness_min_phase30, c1_holds, c2_holds.
Hypothesis. (C1) On noise_cavity and thin_plate, ratio ≤ 0.7 at ε = 2h — thin features vanish under erosion and take their triangles with them. (C2) components_occluder ≤ components_render, with the difference equal to the number of components whose local thickness (Phase 30's local-thickness registration) is below 2ε. SHARE: ratio is over whole meshes.
Falsified by. C1 by ratio ≈ 1, which would say the roster's features are all thicker than 2ε — a statement about the roster, and P-223 records it. C2 by more components after erosion, which is possible (erosion can disconnect) and the row records it as the feature's known behaviour. VACUITY CONTROL: ε = 0 must give ratio = 1.
Group F — bit-identical extraction across threads and architectures (floating-point determinism) [feature][perf]
Field and words. IEEE 754 reproducibility; fused multiply-add contraction, reduction order,
canonical order, lockstep determinism. The result [classical]: floating-point addition is not
associative, so any parallel reduction whose order depends on thread scheduling is non-deterministic; and
arm64 and x86-64 differ in whether a*b+c contracts to an FMA unless the code forbids it. The hook:
lockstep multiplayer and replay require every machine to produce the same mesh from the same edits; M-32
showed the crate's seam vertices differ by up to 1.57e-16 world units when the same point is reached by
two algebraically equal expressions within one machine. M-32, M-175 and M-31's 378 cross-platform
golden hashes are what the repo has already measured — two expressions for one seam point, a sum that
depends on tie order, and bit-identity of one machine's output across macOS/arm64 and Linux/x86-64. None of
them varies the thread count or hashes the same edit on two different machines, which is what this
group's two rows do.
P-246 — registered for R-251, before the harness: A null registered on purpose — with a canonical (Morton) emission order the mesh hash is invariant across thread counts on one machine
Ticket: R-251 (S). Records: field, resolution, thread_count, mesh_hash, hashes_equal_across_threads, c1_holds.
Hypothesis. The registered null: (C1) the current extractor, run at 1, 4, 8 and 16 threads with output sorted into Morton order before hashing, produces identical hashes on every field — thread count does not reach the arithmetic. SHARE: none.
Falsified by. C1 by differing hashes, which would locate a reduction whose order depends on scheduling (a QEF accumulation, a vertex-dedup hash-map iteration) and would be a real bug for any multiplayer use. VACUITY CONTROL: hashing without the canonical sort must differ across thread counts, or the sort is not the thing making them equal.
P-247 — registered for R-252, before the harness: Across mac-air (arm64) and big (x86-64) the hashes differ, and forbidding FMA contraction plus a fixed reduction order makes them equal at under 5% cost
Ticket: R-252 (M). Records: field, resolution, hash_arm64, hash_x86, equal_default, equal_no_fma_fixed_order, differing_vertices_default, max_vertex_delta_default, wall_ms_default, wall_ms_deterministic, cost_share, c1_holds, c2_holds, c3_holds.
Hypothesis. (C1) With default settings the two machines' hashes differ on at least one field, and max_vertex_delta_default is at the ulp scale of M-32 — not a bug, an architecture. (C2) With mul_add replaced by explicit mul then add (or all arithmetic routed through mul_add) and the crossing evaluation order fixed as P-224's backward-error row prescribes, equal_no_fma_fixed_order = true on every field. (C3) cost_share ≤ 5% of extraction. SHARE: C3 is against M-160's per-chunk time on each machine separately.
Falsified by. C1 by equal hashes, which would say the crate already avoids contraction — good, and the row documents why. C2 by remaining differences, which would locate them in a library (libm transcendental in the noise fields) and the row names the function; a game then ships its own. C3 by a larger cost, which prices determinism as a build flag rather than a default. VACUITY CONTROL: a deliberate mul_add in the crossing path must break equality.
Group G — automatic UVs for voxel terrain: discrete conformal equivalence (discrete conformal geometry) [feature]
Field and words. Springborn–Schröder–Pinkall 2008 Conformal equivalence of triangle meshes; discrete
Ricci flow (Gu–Yau); discrete conformal map, quasi-conformal dilatation, cone singularity, seam,
atlas. The result [classical]: a triangle mesh admits a discrete conformal flattening obtained by
minimising a convex energy in per-vertex log scale factors, with prescribed cone angles; the flattening's
distortion is measured by the per-triangle dilatation. The hook: voxel terrain is textured by tri-planar
projection (three samples, blended) because it has no UVs; an atlas per chunk with bounded dilatation would
cost one sample.
P-248 — registered for R-253, before the harness: A per-chunk discrete conformal flattening of the extracted mesh has median dilatation under 1.2 and is computed at under 3× extraction cost
Ticket: R-253 (L). Records: field, chunk, resolution, cone_vertices, flattening_converged, dilatation_median, dilatation_p95, seam_length_over_perimeter, wall_ms_flatten, wall_ms_extract, cost_share, c1_holds, c2_holds, c3_holds.
Hypothesis. (C1) On every chunk of every field, the convex energy minimisation converges (Newton on the SSP energy) with cone singularities placed by Gaussian-curvature clustering, and dilatation_median ≤ 1.2, p95 ≤ 2.0. (C2) seam_length_over_perimeter ≤ 1.5 — the atlas cuts are mostly the chunk boundary, which is a seam already. (C3) cost_share ≤ 3× extraction. SHARE: C3 is a multiple of one chunk's extraction.
Falsified by. C1 by non-convergence, which happens when the mesh has near-degenerate triangles — M-309's needle ratio on box_exact is the suspect, and the row reports whether Phase 30's edge-flip registration's post-flip mesh converges where the raw one does not. C2 by long seams, which prices the atlas against tri-planar's zero seams. C3 by a larger cost, which moves flattening to a background pass. VACUITY CONTROL: a planar chunk must flatten with dilatation exactly 1.
P-249 — registered for R-254, before the harness: A null registered on purpose — one-sample atlas texturing and three-sample tri-planar differ by under 10% in fragment cost on the render path
Ticket: R-254 (S). Records: field, scene, fragment_ms_triplanar, fragment_ms_atlas, ratio, seam_visible_pixels_share, c1_holds.
Hypothesis. The registered null: (C1) on the Bevy example scene, ratio ≥ 0.9 — the GPU's texture cache makes the three samples nearly free, and the atlas's benefit is quality (no blend smearing), not speed. SHARE: fragment_ms is the fragment stage alone, from GPU timestamps.
Falsified by. C1 by ratio < 0.9, which would make the atlas a performance feature as well, and the row records the bandwidth-bound scene where it happens. VACUITY CONTROL: a scene with the texture cache defeated (random UV offsets) must show ratio ≈ 1/3.
Group H — geodesic distance as an extraction by-product: the heat method (heat-kernel PDE) [feature]
Field and words. Crane–Weischedel–Wardetzky 2013 Geodesics in heat; Varadhan's formula; heat method,
prefactored Laplacian, geodesic distance field. The result [classical]: geodesic distance from a
source on a mesh is obtained by one short-time heat diffusion, normalising the gradient, and one Poisson solve
— two sparse linear solves with a matrix that can be prefactored once per mesh. The hook: pathfinding and
"distance to the player" over terrain currently run on a navmesh graph (✗67's octree); the extracted mesh's
cotan Laplacian (already built for Phase 30's cotan-Laplacian registration) gives geodesic distance in two
solves per query.
P-250 — registered for R-255, before the harness: Heat-method geodesics on the extracted mesh are within 3% of true geodesics on sphere and torus, and a prefactored chunk answers a query in under 1 ms
Ticket: R-255 (M). Records: field, resolution, source, target, geodesic_heat, geodesic_true, relative_error, t_parameter_over_h2, prefactor_ms, query_ms, c1_holds, c2_holds.
Hypothesis. (C1) On sphere (great-circle distance) and torus (numerically integrated geodesic), relative_error ≤ 3% at 65³ with t = h². (C2) query_ms ≤ 1 per chunk after a prefactor_ms reported once — a distance field per frame is affordable. SHARE: none.
Falsified by. C1 by larger error, which on an MC mesh is the needle-triangle conditioning of the cotan matrix (M-309) and the row reports error on Phase 30's edge-flip registration's post-flip mesh alongside. C2 by slow queries, which prices the feature per chunk size. VACUITY CONTROL: source equal to target must give distance 0 ± h.
P-251 — registered for R-256, before the harness: Geodesic distance from the field — the heat method on the digital surface — agrees with the mesh's, so navigation needs no mesh either
Ticket: R-256 (M). Records: field, resolution, source, target, geodesic_mesh_p250, geodesic_digital, relative_difference, c1_holds.
Hypothesis. [abstract — Caissard et al. 2018, in the corpus at 10.1007/s10851-018-0839-4, 0.6766 at this phase's probe] The digital Laplace–Beltrami operator of Phase 30's digital-operator registration supports the same two solves on the voxel boundary. (C1) relative_difference ≤ 5% on every field at 65³ — a navigation distance field that is a by-product of the sign grid, before any mesh exists, which is what a server without a renderer wants. SHARE: none.
Falsified by. C1 by larger differences on the ungradeable fields, which is a finding about which of the two is closer to the truth — and on sphere the row can say which. VACUITY CONTROL: the digital operator with the integration radius set to zero must fail to converge.
Group I — importing meshes into the voxel world: generalized winding numbers (computational topology) [feature][perf]
Field and words. Jacobson–Kavan–Sorkine 2013 Robust inside-outside segmentation using generalized winding
numbers; Barill et al. 2018 Fast winding numbers for soups and clouds; generalized winding number, solid
angle, Barnes–Hut dipole expansion. The result [classical]: the winding number w(p) = (1/4π) Σ solid
angles is an integer inside a closed mesh, fractional near holes, and robust to self-intersections and open
boundaries — a signed indicator that degrades gracefully; with a dipole-tree expansion it is O(log n) per
query. The hook: the crate goes field → mesh; a game also needs mesh → field (drop a prop, carve it into
the world), and P-230's volume test is the oracle for whether the round trip closes. Re-scoped at this
phase's probe: the crate already ships both directions — crates/isomesh/src/construct/winding.rs (S-007) and
crates/isomesh/src/construct/from_mesh.rs (S-006) — and M-262, M-299 and M-303 priced them (the
winding number beats the pseudonormal on holed meshes; the on-demand split costs a factor of N; the crossover
is N² with per-point cost linear in boundary edges). What is unmeasured is S-006's own acceptance criterion —
mesh a sphere, convert back to a field, re-mesh, compare — which has no Hausdorff or χ number in
FINDINGS.md, and which is this group's first row.
P-252 — registered for R-257, before the harness: The round trip field → mesh → winding number → field → mesh closes to within 2h Hausdorff and preserves χ
Ticket: R-257 (M). Records: field, resolution, hausdorff_roundtrip, hausdorff_over_h, chi_original, chi_roundtrip, winding_fractional_cells_share, c1_holds, c2_holds.
Hypothesis. (C1) On every closed-mesh field, re-voxelising the extracted mesh by w(p) ≥ ½ and re-extracting gives hausdorff_over_h ≤ 2 and chi_roundtrip = chi_original. (C2) winding_fractional_cells_share (cells whose corner values are not near 0 or 1) is under 2% — the extracted mesh is closed enough that the winding number is essentially an indicator. SHARE: none.
Falsified by. C1 by χ changing, which would locate a non-closed mesh (a chunk seam with a crack, ✗-class bug) that the winding number tolerates — which is the point of using it, and the row reports where the fraction lives. C2 by a large fractional share, the same finding stated the other way. VACUITY CONTROL: deleting 5% of triangles before re-voxelising must raise the fractional share and not change χ, or the winding number is not doing its job.
P-253 — registered for R-258, before the harness: The Barnes–Hut winding number voxelises a 100k-triangle prop into a 65³ chunk in under 50 ms, against seconds for the exact sum
Ticket: R-258 (S). Records: mesh_triangles, resolution, wall_ms_exact, wall_ms_fast, speedup, max_abs_winding_error, sign_flips_vs_exact, c1_holds, c2_holds.
Hypothesis. (C1) speedup ≥ 20× at 100k triangles and 65³. (C2) sign_flips_vs_exact = 0 — the approximation never changes a corner's side, because the error is far from ½ away from the surface and the near-field is evaluated exactly. SHARE: none.
Falsified by. C1 by less speedup, which prices the tree's construction against the query count and the row reports the crossover. C2 by sign flips, which are at cells within h of the surface and the row reports whether the exact near-field radius was set below h. VACUITY CONTROL: a mesh of 100 triangles must give speedup < 2.
Group J — compressing the sign grid: sparse voxel DAGs against the entropy floor (data structures, information theory) [perf]
Field and words. Kämpe–Sintorn–Assarsson 2013 High resolution sparse voxel DAGs; hash-consing,
subtree deduplication, symmetry-aware DAG. The result [classical]: an octree of a binary volume whose
identical subtrees are merged into a DAG compresses geometry by orders of magnitude where the volume is
self-similar. The hook: P-204 (R-209) measured the sign grid's entropy rate as the lossless floor for
bit-packing; a DAG is the other way to approach that floor, and it is queryable in place.
P-254 — registered for R-259, before the harness: A null registered on purpose — the DAG compresses the sign grid to within 4× of the entropy-rate floor on smooth fields and cannot approach it on noise
Ticket: R-259 (M). Records: field, resolution, bits_dag, bits_entropy_floor_p204, ratio_over_floor, subtrees_merged_share, bits_bitpacked_phase25, c1_holds, c2_holds.
Hypothesis. The registered null: (C1) on sphere, torus, box_exact, ratio_over_floor ≤ 4 and below Phase 25's bit-packed size. (C2) On noise_cavity the DAG is larger than the bit-packed grid — dedup finds nothing and the pointers are overhead. SHARE: none.
Falsified by. C1 by a larger ratio on smooth fields, which would say the octree's node overhead dominates at 65³ and the row reports the resolution where the DAG wins. C2 by the DAG winning on noise, which would be surprising and would say value noise at one octave has more repeated subtrees than its entropy rate suggests. VACUITY CONTROL: a constant field must compress to one node.
P-255 — registered for R-260, before the harness: In-place surface-cell enumeration on the DAG is faster than the bit-packed scan at 257³ because it skips merged empty subtrees
Ticket: R-260 (S). Records: field, resolution, surface_cells, wall_ms_dag_enumerate, wall_ms_bitpacked_scan_m306, ratio, nodes_visited, nodes_total, c1_holds.
Hypothesis. (C1) At 257³ on sphere, enumerating surface cells by DAG traversal visits under 10% of nodes and is faster than M-306's rejection scan by at least 2×. SHARE: the ratio is of the enumeration stage.
Falsified by. C1 by no speedup, which would say M-306's coarse rejection is already skipping the same volume and the DAG's pointer chasing costs what the skip saves. VACUITY CONTROL: at 33³ the DAG must lose, or the traversal is not paying its overhead.
Group K — a 6-byte vertex: quantised crossing parameters (rate–distortion, lattice quantisation) [perf]
Field and words. rate–distortion, uniform scalar quantiser, edge-indexed vertex, vertex shader
decode. The result [classical]: a crossing position on grid edge e at parameter t ∈ [0,1] quantised
to b bits has error ≤ h/2^{b+1} along the edge and zero across it; a vertex is then (edge_id: u32, t:
u16) = 6 bytes, decoded in the vertex shader, against 12 bytes for f32×3 (plus 12 for a normal). The
hook: Phase 25 compressed the input; the output vertex buffer is the bandwidth the GPU actually moves,
and its size has never had a floor.
P-256 — registered for R-261, before the harness: A null registered on purpose — 16-bit t is below the extractor's own error at every resolution on the roster
Ticket: R-261 (S). Records: field, resolution, bits_t, quantisation_error_bound, hausdorff_m472, bound_over_hausdorff, hausdorff_quantised, c1_holds.
Hypothesis. The registered null: (C1) quantisation_error_bound / hausdorff_m472 ≤ 0.01 at b = 16 on every row, and hausdorff_quantised equals hausdorff_m472 to three digits — quantisation is invisible. SHARE: none.
Falsified by. C1 by a visible change, which can only happen at resolutions above 4096³ where h/2^17 competes with h² — and the row states that crossover. VACUITY CONTROL: b = 4 must raise Hausdorff measurably.
P-257 — registered for R-262, before the harness: The 6-byte vertex halves vertex-buffer bandwidth and does not slow the vertex stage
Ticket: R-262 (M). Records: field, scene, vertex_bytes_f32, vertex_bytes_quantised, ratio, vertex_stage_ms_f32, vertex_stage_ms_quantised, decode_cost_ratio, c1_holds, c2_holds.
Hypothesis. (C1) ratio ≤ 0.5 including a 4-byte octahedral-encoded normal in the quantised format against f32×3 + f32×3. (C2) decode_cost_ratio ≤ 1.1 — the two integer-to-float conversions in the shader are hidden under memory latency. SHARE: vertex_stage_ms is from GPU timestamps, the vertex stage alone.
Falsified by. C1 by a ratio above 0.5, an arithmetic error. C2 by a slower vertex stage, which would say the scene is ALU-bound, and the row names it. VACUITY CONTROL: a scene with one triangle must show decode_cost_ratio ≈ 1.
Group L — traversal order with a theorem: Hilbert against Morton (space-filling curve analysis) [perf]
Field and words. Moon–Jagadish–Faloutsos–Saltz 2001 Analysis of the clustering properties of the Hilbert
space-filling curve; clustering, number of runs, locality. The result [classical]: for a query
region, the expected number of contiguous runs along the Hilbert curve is provably lower than along the
Z-order (Morton) curve, with the constant derived. The hook: M-306's scan and Phase 30's
memory-traffic-floor registration are measured on Morton; Hilbert has a theorem saying it should touch fewer
cache lines.
P-258 — registered for R-263, before the harness: Hilbert order reduces cache-line runs per chunk by the Moon et al. constant and wall time by less than 5%
Ticket: R-263 (S). Records: field, resolution, order, runs_per_chunk, runs_ratio_hilbert_over_morton, moon_predicted_ratio, l2_misses, wall_ms, wall_ratio, c1_holds, c2_holds.
Hypothesis. (C1) runs_ratio is within 20% of the theorem's prediction for a 2×2×2 stencil window. (C2) wall_ratio ∈ [0.95, 1.0] — the theorem is right about runs and the runs do not matter at chunk size, because the chunk fits in L2 (Phase 30's "the chunk fits in L2" reading). SHARE: none.
Falsified by. C1 by a ratio far from prediction, which would mean the runs were counted over the wrong window. C2 by a real speedup, which would say the working set exceeds L2 at 65³ and the row reports the resolution boundary — exactly the number that registration needs. VACUITY CONTROL: lexicographic order must have more runs than either.
Group M — destruction with prescribed fragment volumes: power diagrams (computational geometry, semi-discrete optimal transport) [feature]
Field and words. Aurenhammer–Hoffmann–Aronov 1998 Minkowski-type theorems and least-squares clustering;
power diagram, Laguerre tessellation, weights, prescribed volumes. The result [classical]: for any
set of sites and any prescribed volumes summing to the solid's volume, there exist weights making the power
diagram's cells have exactly those volumes, found by a concave maximisation. The hook: Voronoi fracture
gives fragments whose sizes are whatever they are; a designer wants "one big chunk and five small ones". OT
was mined in Phase 27 for a different purpose (transport of the error field); the semi-discrete case as a
fracture control is new to the ledger and the row says so.
P-259 — registered for R-264, before the harness: Fragment volumes are controllable to 2% by power-diagram weights, and each fragment's mesh is the solid clipped by the cell
Ticket: R-264 (M). Records: field, sites, prescribed_volumes, weights_converged, newton_iterations, fragment_volume_p230, volume_error_share, fragment_chi, fragments_closed, total_volume_conserved, c1_holds, c2_holds.
Hypothesis. (C1) On sphere with 8 sites and volumes (50%, 7×~7%), the concave maximisation converges in under 30 Newton steps and every fragment's P-230 volume is within 2% of prescribed. (C2) Each fragment (field ∧ power cell, extracted with the cell's planes as additional half-space fields) is a closed mesh with chi = 2 and the fragment volumes sum to the solid's within extraction error. SHARE: volume_error_share is per fragment against its own prescribed volume.
Falsified by. C1 by non-convergence, which happens when a prescribed volume exceeds what its site can reach — the theorem needs volumes in the feasible set, and the row records the feasibility test. C2 by a non-closed fragment, a clipping seam bug at the power-cell face. VACUITY CONTROL: equal prescribed volumes with equal weights must reproduce the plain Voronoi fracture.
P-260 — registered for R-265, before the harness: The clipped-fragment extraction costs under 2× the unfragmented mesh for 8 fragments, because each cell's planes touch few grid cells
Ticket: R-265 (S). Records: sites, wall_ms_fragmented, wall_ms_whole, ratio, cells_touched_by_any_plane_share, c1_holds.
Hypothesis. (C1) ratio ≤ 2 at 8 sites and 65³; cells_touched_by_any_plane_share ≤ 15% — the planes are sparse in the grid and the rest of the extraction is unchanged. SHARE: the ratio is of whole extractions; the touched share explains it.
Falsified by. C1 by a larger ratio, which prices fragmentation per site and the row fits the linear model. VACUITY CONTROL: one site must give ratio = 1.00 ± 0.02.
Group N — ridge-preserving pre-filter: anisotropic diffusion of the field (PDE image processing) [feature]
Field and words. Perona–Malik 1990 Scale-space and edge detection using anisotropic diffusion; edge-
stopping function, anisotropic diffusion, scale space. The result [classical]: diffusing a field with
conductance that vanishes at large gradient smooths noise inside regions while sharpening, not blurring, the
boundaries between them. The hook: ✗116 found the tricubic pre-filter blurs box_exact's creases; Phase
30's WENO crossing registration attacks the crossing; this attacks the field, so terrain noise smooths and
cliff edges stay.
P-261 — registered for R-266, before the harness: A null registered on purpose — Perona–Malik on fbm_terrain removes octave-3 noise triangles and does not move the ridge lines
Ticket: R-266 (M). Records: field, iterations, kappa, triangles_before, triangles_after, triangle_ratio, ridge_displacement_max, ridge_displacement_over_h, hausdorff_to_unfiltered, c1_holds, c2_holds.
Hypothesis. The registered null: (C1) 10 iterations at κ set to the octave-2 gradient magnitude reduce triangle count by at least 20% on fbm_terrain. (C2) Ridge lines (the crest lines of P-242's machinery with v vertical) move by ridge_displacement_over_h ≤ 0.5 — the filter is anisotropic where it matters. SHARE: triangle_ratio is over the whole mesh.
Falsified by. C1 by a small reduction, which would say the field's noise is below κ everywhere and the filter is isotropic in practice — a κ calibration finding. C2 by ridges moving, which would say κ was set below the ridge gradient and the row reports the κ at which they stop. VACUITY CONTROL: κ = ∞ must reduce to Gaussian blur and move ridges by more than h.
P-262 — registered for R-267, before the harness: On box_exact the diffused field's creases are sharper than the tricubic's, measured by Phase 30's smoothness indicator
Ticket: R-267 (S). Records: filter, crease_edges_flagged_phase30_indicator, crease_edges_true, recall, crease_sharpness_beta_mean, hausdorff_at_crease_cells, c1_holds.
Hypothesis. (C1) After Perona–Malik, recall of true crease edges by Phase 30's smoothness-indicator registration is above 0.9 and hausdorff_at_crease_cells is below the tricubic filter's (✗116) by at least 30% — the crease survives the pre-filter that ✗116's did not. SHARE: none.
Falsified by. C1 by no improvement, which would say the diffusion's stopping function saturates at the SDF's constant gradient magnitude (an SDF has |∇f| = 1 everywhere, so gradient magnitude cannot distinguish crease from face) — and the row switches the conductance to the Hessian norm, which does. That is the expected outcome on an SDF, and it is registered here because it is the right diagnosis. VACUITY CONTROL: sphere must be unchanged by the filter to within 0.1h.
What this phase does not claim
- No row claims the feature is shippable; each claims a measurable property of a prototype on the roster.
- The corpus probe was run at landing (§1); a group whose probe came back present-and-cited in the repo is re-scoped there to what the repo did not measure.
- Group M's field overlaps Phase 27's optimal transport row in name only; the row states the difference.
- Groups G and H produce assets a renderer and a navigation system consume; they are registered here
because each is a by-product of the mesh the crate already builds, and each is graded against a truth the
crate already computes (Phase 30's cotan Laplacian,
sphere's great circles). - Group F is the only group whose failure is a bug rather than a finding, and
P-246is registered as a null for that reason: it is the cheapest test in the phase and the most expensive to be wrong about.