Was about to spec a Codex fix for OC_Chunk / BM_Chunk / FChunkBiomeCache,
which three docs still list as open. Checked the sites first. All of them
already carry a layout-version guard:
CP_Chunk -> CP_Version OC_Chunk -> OC_Version
BM_Chunk -> BM_Version TC_BiomeCache -> TC_SeenVersion
FChunkBiomeCache::Invalidate() exists precisely because the validity box says
nothing about the FBiomeContext its cells were classified against, and all four
thread_local instances call it on a version change. The only other two
instances in the tree (VoxelContentManager ~445, the height-stack test) are
function-local, constructed per task, so staleness is impossible there.
Seventh time in this project a confident premise reversed on reading. It cost
a doc edit instead of a Codex run and a build cycle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Jahni built a world and said "I don't know if it dropped any meshing? but it
looks alright by the eye." That sentence is the honest state of this refactor:
everything proved so far was proved in an automation harness on 40 sampled
tiles, and in the running game tile-skipping is unobservable.
grep INC_DWORD_STAT over Source/ returns nothing -- the plugin has zero stat
counters -- and "skipped correctly" renders identically to "skipped nothing", so
no visual check can separate them. The tests got the "coverage is a number, not
a boolean" discipline this session; the game never did.
CODEX-TASK-001-tile-skip-stats.md specs a stat VoxelForge group with
TilesClassified / TilesSkippedAllSolid / TilesSkippedAllAir / TilesMeshed. Solid
and air are split deliberately: cave archetypes prove AllSolid, so that counter
is the one that says whether the op-stack work did anything real. Its deliverable
is the before/after that constitutes the PRODUCTION proof of T1.d, which does not
exist today.
The spec carries the invariants rather than just the task, which is the point of
a spec here: bTrivialEmpty decides whether a tile has COLLISION, the five-clause
gate is load-bearing, and GenerateTileResult runs on worker threads -- so a plain
static int32++ is a data race while INC_DWORD_STAT is not.
Handoff updated: a "How we work now" section (Codex Model Luna xHigh writes most
code, Claude orchestrates -- hand over the INVARIANT, review against the code and
not the description), first actions split into the Codex task and the pending
e002bd4 build, and the T1.d heading qualified as harness-measured rather than
game-proven. Also records the Insights interim answer and its trap: ~84% of tiles
were already rejected by the hand-written surface/bedrock paths, so surface skips
drown the cave ones unless you are underground in an opted-in strate.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The rule said "Never push" without qualification, which was true while
experimental existed only locally and became misleading the moment it did not:
a future session would read it and let origin/experimental drift.
Now: push experimental freely (tracked since 2026-07-29), never push main, which
stays pinned at the known-good commit. Both statements of the rule are updated
(OPSTACK-HANDOFF.md and OPSTACK-PROMPT.md's crash-safe discipline).
Also added at both sites, because it is the failure mode this creates: a pushed
commit is NOT a "verified green" marker. This branch carries unbuilt work by
design, so OPSTACK-PROGRESS.md remains the only record of what was actually
built and measured, and the remote records only what was written.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The old handoff's "first action" (confirm the Underwater coverage number) and its
"one task everything is waiting on" (make FRoomGraphSource::EffectOverBox answer
spatially) are both done, so most of it was actively misleading.
What it says now:
- T1.d is real and measured: 11 of 40 tiles proved AllSolid at production
defaults, 14641 voxels brute-forced, 0 violations; dense fixture correctly 0.
- A boxed invariant near the top, because it is the most dangerous thing in the
current code: Identity from the room source means Sdf >= T, not FLT_MAX, and
any new Sdf consumer with a bigger threshold silently produces tiles with no
geometry and no collision.
- First action is now "build e002bd4 and read ONE line" (VerticalShafts box
verdicts), including what to check first if it is still 0 -- ExtraReach --
rather than re-deriving, which is what cost three rounds on TunnelNetwork.
- Both old debts restated with their real status: the per-room-op bound is
DORMANT (checked, premise reversed), and AUDIT C2 is FIXED on the switch path
with a note on why the audit's own suggested alternative was the wrong fix.
- The warp squeeze is parked WITH its measured ceiling and a recorded negative
result, so the obvious next attempt (local Lipschitz warp bound) is not
repeated: 8.5 * 0.206 = 1.75 exceeds the global range bound of 1.5.
New method lessons, led by the one this session actually paid for: instrument
what you ASSUMED, not just what you changed. Also that a sampler must cover a
period of what it samples, that a fixture tuned for coverage can be antagonistic
to what you are measuring, that diagnostics must report this run rather than
carry narrative, and that you must not assert a number you intend to improve.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two green builds now, so the handoff's most prominent instruction (build ce409e7, it is unverified)
was stale, and a stale first action is worse than no first action: it sends a fresh context looking
for a bug that may already be fixed.
What I did NOT see is the number. The floor-division fix probably resolved the 0% cave coverage, but
'the suite is green' is not evidence of that -- a bit-identity over solid rock is green for exactly
the wrong reason, which is why that counter exists at all. So the section now states both branches
explicitly: non-zero coverage closes it and says so in the log; still 0.0% and the diagnosis line
names which of the three causes it is.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
OPSTACK-PROGRESS gets the measured entry: every number the run produced, what each one settles, and
the single open warning. OPSTACK-PLAN's status header goes from UNVERIFIED to BUILT AND GREEN.
OPSTACK-HANDOFF is rewritten end to end. It no longer describes a transition in progress but a
completed one, and it leads with the two things a cold context needs: the Underwater 0%-coverage
warning (with the truncation-vs-floor finding behind it, and the reminder that a green bit-identity
over solid rock is not evidence), and the one task everything else now waits on -- making
FRoomGraphSource::EffectOverBox answer spatially.
It also carries forward the two debts that must be paid BEFORE that lands rather than after: box
bounds computed from strate params can be too optimistic once a per-room op raises them, and AUDIT
C2 is confirmed but unfixed on the switch path.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Jahni, twice and explicitly: he is fine with unverified work as long as it
is committed per group, and he wants the successor working toward full op
stack completeness. So the queue no longer stops at stage B.
Removed the hard stops on stage C and on flipping the ported list. Two facts
make that reasonable rather than reckless, and both are now written down:
committing per group IS the safety net (he reverts by sha), and reaching
8 of 8 does not change his world by itself — UsesOperatorStackForChunk still
returns false unless a strate has bUseOperatorStack ticked, so the flag flip
is inert until he ticks a box.
Queue is now B1-B5 (13 detail modifiers), C1 (per-room op override), C2
(Underwater, which §8 establishes has no density difference at all), C3
(both into the ported list = 8 of 8), then the §C2 audit question, the worm
amplitude cap, and making ClassifyTile consume ClassifyBox.
C1's design is settled here rather than left open, because an unattended run
should not be improvising architecture: take §2's option (a), and use the
mechanism this codebase already has three instances of — one op owns shared
state, others read it through a non-owning pointer (overhang <- column
source, ledge <- shaft source). FRoomGraphSource exposes LocalParamsAt();
detail ops read their fields from it. Same resolution as the pit/chimney
"fiddliest thing in the decomposition": the difficulty came from assuming
each op must own its params.
Still off limits: build, editor, push, ticking bUseOperatorStack on an
asset, and Phase 3.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Jahni may start a session and leave, then have it shut the PC down. The
successor still cannot build, so the section is about shaping ~680 lines of
mechanical transcription for ONE informative build afterwards rather than
pretending verification is available.
Work queue B1-B5 (roughness / terrace-layerlines-ribbing / overhang-cliff-
scallop-arch / columns-domes-pinch-floorbias / the bNearCaveSurface gate),
one commit per group with the group named in the subject line, since Jahni
reverts by group. Transcribe literally, note anything that looks wrong in
the log and port it as-is anyway — that is how C1 and the MinDivisor split
were both found without breaking anything.
Records the subtlety that lets B precede C: the 13 modifiers read a copy of
the params with the nearest room's op applied, so porting them against
strate-level params is equivalent only while the test's room pool stays
Pit/Chimney-only.
Hard stops: do not flip TunnelNetwork or Underwater on, do not start stage C
(design freedom without feedback), do not start the worm amplitude cap (it
changes the fold contract all 13 tests rest on), do not build or push.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The run that matters: bit-identical over 6000 samples with 23.9% of them in
open cave, and a bake carrying 49 rooms / 56 pits / 28 chimneys / 0 columns
— so the pit and chimney loops finally ran on real data, and 0 columns
confirms STEP 4d stayed dormant as stage A requires.
Same code and same colour as the previous green run, three different
strengths of evidence. That is the argument for printing coverage numbers
rather than pass/fail.
Handoff rewritten for a fresh context: the three-stage TunnelNetwork plan
and why stage A is verifiable while incomplete, the calls-not-transcribes
rule for BuildChunkCache, FRAME ops recorded as retired (0 of 3 candidates
needed one), the per-room override reclassified as load-bearing rather than
polish, and the method lessons regrouped around the three coverage traps.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rewrites OPSTACK-HANDOFF.md for a fresh context: the port table, what is left in
order, the two things Phase 2 invented that were not in the original design (height
space as a second operator family, and IVoxelBiomeField so ops depend on a capability
rather than the generator), and the method lessons that cost build cycles to learn.
Open items, none blocking: perf (parked by Jahni), C9's library half (no measured
risk), VerticalShafts' pessimistic box verdicts, and ClassifyTile still using
hand-written guards while ClassifyBox sits verified but unconsumed — which is where
the measured tile-skipping would actually become frames.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Handoff: a pasteable resume prompt at the plugin root -- read order, exact state
(Phase 0.5 green, Phase 1 done and measured, step 3 written but not compiled),
the immediate next action, hard rules, open items, and the method lesson from
this session.
Skills: Jahni's UE library was at .claude/skills/core/<name>/SKILL.md, two levels
deep, where Claude Code discovers skills one level deep -- so none of the 39 were
loading. Flattened; 124 reference files intact, all frontmatter valid, folder
names already matched their name: field. core/category.md left as documentation.
Confirmed loading.
They are untracked and cannot be tracked without un-ignoring .claude/ itself
(git cannot re-include a file whose parent directory is excluded). Same shape as
AUDIT P1; flagged, not actioned.
Note for the next session: module-and-build-system documents PCHUsage, shared
PCHs and IWYU -- the exact mechanism that blocked C10's settling experiment. That
skill was in the repo, undiscovered, while it was worked out the slow way.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>