The shader compiler targets Vulkan 1.3 / SPIR-V 1.6, where glslang lowers a
fragment discard to OpDemoteToHelperInvocation; five committed modules
(sky, mesh_detail, mesh_atmospheric, both directional-shadow cutouts)
declare the capability, and vkCreateShaderModule reported
VUID-VkShaderModuleCreateInfo-pCode-08740 twice per launch under the
Khronos validation layer because the device never enabled the feature.
The feature is core 1.3 (the device gate already requires 1.3), so it is
read through the existing Vulkan13Features chain, enabled at device
creation next to dynamicRendering/synchronization2/maintenance4, and
gated as required in VulkanCapabilityRecord with its own failure text.
Found by the first validation-layer self-gate of Campaign OVERHAUL v2
(S3 chunk 4 round 2); no register row, no behavior change on a
conformant driver.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Both found by the G3 self-gate part C at 2fbfdf18a; evidence paths and the
sequence lines are in the entries.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Rounds ff607a1e0 + 7df0b94c9 delete the union-AABB scissor fallback, the
sky's doorway scissor bracket and the TerrainClip UBO; AD-17 now describes
the two surviving portal-polygon clips and their overflow behavior, and
AP-117 records that the walk's ported landcell_check feeds the production
particle in-view state. The three-lens re-review is owed post-hoc (API
overload); the lead's item-by-item verification is in the ledger.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Round-1 three-lens FAIL at d60ca4ea0 found: the K2 fix was right in
production but nothing pinned the draw side (restoring the pre-fix gate
left every lane green); a stale "still ends an active scissor" comment
asserted a mechanism the same round had already deleted; the sky.vert
comment claimed retail clips the sky when it draws unclipped; the K6
pin ran through ClipFrameAssembler.Assemble, which has zero production
callers, so it proved nothing about the producer that actually runs.
This round closes L1-L9.
L1 (BLOCKING) — draw-side weather-gate pin. Added
RetailPViewPassExecutorTests.DrawLandscapeDynamicsPhase_GatesDrawWeatherOnceOnWalkDriverWeatherTurnFired:
reads DrawLandscapeDynamicsPhase's compiled call graph and asserts (a)
the call immediately before DrawWeatherOnce is
WalkFrameDriver.get_WeatherTurnFired and (b) exactly one
brfalse/brfalse.s branch sits between that call and the draw, jumping
forward past it. Three mutations, each shown failing:
M1 (restore `if (clipAssembly.OutsideViewSlices.Length != 0)`):
Assert.Equal() Failure: Values differ
Expected: typeof(AcDream.App.Rendering.Walk.WalkFrameDriver)
Actual: typeof(AcDream.App.Rendering.ClipFrameAssembly)
M2 (drop the gate, unconditional call):
Assert.Equal() Failure: Values differ
Expected: typeof(AcDream.App.Rendering.Walk.WalkFrameDriver)
Actual: typeof(AcDream.App.Rendering.RetailPViewPassExecutor)
M3 (invert to `if (!walkDriver.WeatherTurnFired)`):
Assert.Single() Failure: The collection did not contain any matching items
Expected: (predicate expression)
Collection: [CompiledBranch { Offset = 7, OpCode = brfalse.s, TargetOffset = 17 }, CompiledBranch { Offset = 24, OpCode = brtrue.s, TargetOffset = 33 }]
Corrected WalkFrameDriverTranscriptTests.cs's doc comment (the
Collect_WeatherTurnFiredMatchesThePrintedOcLineExactly block): it pins
the print half and the flag only, and now names the real draw-side pin
instead of falsely claiming to double as one.
L2 (MAJOR) — scissor stack deleted, K4 comment corrected. Deleted
IWorldPassSurface.BeginScissor/EndScissor and their RhiWorldPassSurface
bodies, the scissor call inside ClearInteriorDepth, NdcScissorRect.cs +
NdcScissorRectTests.cs (BeginScissor had zero remaining callers, and
RhiWorldPassSurface.BeginScissor was NdcScissorRect.ToPixels' only
production caller). This left RhiWorldPassSurface's 4th constructor
parameter (IRetailPViewFramebufferSource) and RetailPViewPassExecutor.cs's
RetailPViewFramebufferSize/IRetailPViewFramebufferSource/
SilkRetailPViewFramebufferSource types entirely dead (framebuffer size
was needed only for the scissor's NDC-to-pixel conversion) — removed
them and their one call site in FrameRootComposition.cs. Rewrote
RetailPViewPassExecutor.cs's K4 comment: it no longer asserts a live
scissor mechanism; it states that VulkanGpuPassEncoder's constructor
sets the full-attachment scissor once, at pass begin
(VulkanGpuPassEncoder.cs:87), and nothing narrows it after that. KEPT
per the round-1 verdict: ScissorFallbacks, OutsidePlaneCount,
OutsideViewNdcAabb, HasOutsideView, OutdoorVisible, OutdoorSlot,
ClipViewSlice.NdcAabb (the >8-edge zero-plane slice case the punch fans
still consume) and the VulkanViewportMapping.ScissorToVulkan pass-begin
path (IGpuPassEncoder.SetScissor stays). Also deleted
ClipFrameAssembly.TerrainMode/TerrainScissorNdcAabb and their writers
in ClipFrameAssembler.cs (both Assemble and ReassembleOutsideViewFromWalk);
OutsidePlaneCount's formula reduces to `outsideHasScissorFallback ? 0 :
outsideMaxPlaneCount` without needing the deleted TerrainClipMode
comparison (a scissor-fallback slice can only exist when outdoorVisible
is already true, so the three original cases collapse identically).
Deleted the two "terrain=" / "outMode=" diagnostic reads in
WorldRenderDiagnostics.cs (:345, :409) and the now-vestigial
EmitClipRouteProbe "ubo: n=..." segment that read ClipFrame's deleted
terrain bytes.
DEVIATION from L2's literal text: kept the TerrainClipMode enum type
itself — WorldSceneRenderer.cs's flat-world safety path (explicitly
"out of this chunk's scope" per K4's own round-1 comment) still uses it
for an unrelated "did the flat terrain draw" diagnostic flag, with its
own WorldSceneDiagnosticsController/WorldRenderDiagnostics/test
consumers. Deleting the type would require rewriting files outside
every round's declared file list. Reworded its doc comment to state
this plainly.
L3 (MAJOR, completes K3) — dead TerrainClip UBO deleted from the sky
and terrain shaders. Deleted the block, both gl_ClipDistance loops, and
the gl_PerVertex redeclaration (nothing else needs it) from sky.vert,
terrain_modern.vert, terrain_atmospheric.vert. Recompiled via
tools/compile-shaders.ps1 (glslc via the Vulkan SDK, managed shaderc
fallback also runs) — 24/24 pairs compiled; only sky.vert.spv,
terrain_atmospheric.vert.spv and terrain_modern.vert.spv changed.
Re-pinned VulkanShaderManifestTests.cs's frozen retail-oracle hashes
for sky.vert.spv (7d67a9e3624d198b370d402b5c12e4ce925bf9b8e646ef5123636a86d5985ab5)
and terrain_modern.vert.spv (8a73d89ef0e51e550327b9ff8c24857e309103b1d491030cf0d4d8594b45068c)
with dated comments, matching the existing re-pin convention.
Deleted WorldFrameSectionBinding.BindTerrainClip and
WorldFrameSections.TerrainClip (+ its Reset) with its two callers
(SkyRenderer.Rhi.cs:258, TerrainModernRenderer.Rhi.cs:259). DEVIATION
from L3's literal text: kept the shared Zeroed(...) helper in
WorldPassScope.cs — it is also called by BindSceneLighting and
BindClipRegions, both of which stay; deleting it would have broken
those two live bindings. Deleted IWorldPassSurface.BindTerrainClip
(no-op interface method + RhiWorldPassSurface body) and
WorldScenePassExecutor.cs's two calls to it (:121, :235).
Deleted ClipFrame's _terrainBytes field, TerrainBytes/TerrainBytesForTest
properties, Reset's Array.Clear(_terrainBytes), and the stale
header/K3 comment paragraphs. DEVIATION from L3's literal text: kept
ClipFrame.TerrainUboBytes and ClipFrame.TerrainClipUboBinding —
PortalDepthMaskRenderer.Rhi.cs (:140, :187) is a live production
consumer of both constants for the KEPT exit-seal/punch-fan clip block,
which was never in scope for deletion (portal_depth.vert's own
TerrainClip UBO declaration is the KEEP block, untouched). Reworded
both constants' doc comments (ClipFrame.cs, VulkanPipelineLayouts.cs's
UniformTerrainClip) to say only the portal-depth clip block uses
binding 2 now, and corrected the two GpuBindingModel.cs comments that
explained why terrain-tiling/sky-params bindings are 3/4 by naming "the
terrain clip block". Updated VulkanShaderDescriptorContractTests.cs's
TerrainVertexShaderDeclaresItsClipBlockInTheUniformSet (renamed
TerrainVertexShaderDeclaresOnlySceneLightingInTheUniformSet):
terrain_modern.vert's uniform set is now {SceneLighting} only. Deleted
ClipFrameLayoutTests.NoClip_TerrainBytes_Count0_AllZeros and its K3
comment; corrected the class doc comment and LayoutConstants_MatchShaderStruct's
"terrain UBO"/binding-contract comments to describe the portal-depth
consumer instead.
REQUIRED L3 fact (declared-but-never-bound dynamic uniform binding):
VulkanFrameBindings's constructor seeds EVERY declared uniform binding
(0..UniformBindingCount-1, including binding 2) with the shared dummy
buffer's range before any renderer runs (VulkanFrameBindings.cs:128-130,
`_arena.SeedUniform(binding, dummy.Handle.Handle, dummyUniformRange)`
in a loop over every binding) — "Every binding is always bound, whether
a renderer uses it or not... unused ones point at a shared dummy range"
(VulkanFrameBindings.cs:27-31). So after this round, when the sky or
terrain pipeline draws, set 1's shared descriptor layout still declares
binding 2 (portal_depth.vert's own declaration keeps
IsDeclaredUniformBinding(2) true), and its descriptor still points at a
valid (dummy) range from that seed — vkCmdBindDescriptorSets stays
legal even though neither shader statically uses binding 2 any more.
No SPIR-V-side change was needed to keep this legal.
L4 (MAJOR) — one outside-view slice constructor. Extracted
ClipFrameAssembler.AppendOutsideSlice (frame, ViewPolygon,
outsideSlicesList, ref maxPlaneCount, ref hasScissorFallback, ref
scissorFallbacks) — the exact ClipPlaneSet.From/AppendSlot/
ClipViewSlice-construction body — and call it from both Assemble's
outside_view loop and ReassembleOutsideViewFromWalk's outside_view
loop. Rewrote ClipFrameLayoutTests's K6 pin
(ClipViewSlicePlanes_PunchFanPath_EqualsCpuViewPolygonEdgePlanes_ForASyntheticView):
builds a synthetic WalkPortalView from pixel-space points (the
WalkCopyViewTests pattern) via a trivial IWalkRayCaster, runs
BeginWalkFrame(frame, outdoorRoot: false) then
ReassembleOutsideViewFromWalk(assembly, walkView, 640, 480), and reads
assembly.OutsideViewSlices[0].Planes — the exact production pair
RetailPViewPassExecutor.cs's BeginWalkFrame call and
RetailPViewRenderer.cs's ReassembleOutsideViewFromWalk call make.
Mutation (perturbed planes[0].W inside the shared helper, right after
`planes = cps.PlaneArray;`):
edge 0 midpoint (-0.3,0.10000001) should lie ~on its OWN GPU plane; the closest plane was only 0.5251073 away
The pin's own source contains no `Assemble(` call — grep-checked by
extracting the method body and searching it for the literal text; no
match.
L5 — shader comments corrected. sky.vert/terrain_modern.vert/
terrain_atmospheric.vert now state retail draws the sky once
(LScape::draw @0x00506330 -> GameSky::Draw(sky,0) @0x0050633c, before
draw_check_blocks) and the landscape is view-culled per cell, never
GPU-clipped (RenderDeviceD3D::DrawBlock @0x005a17c0). The "Phase W
Stage 4"/"U.3 default" clip narratives are deleted along with the
blocks they described.
L6 — grep sweep. `grep -rn "<token>" src tests docs/architecture`
returns nothing for SetTerrainClip, BeginDoorwayScissor,
BindTerrainClip, TerrainBytes, "active scissor", and NdcScissorRect —
confirmed after this commit (docs/plans and docs/research keep the
historical record, untouched). TerrainClipMode is the one deliberate
exception (see the L2 deviation note above); every one of its 9
remaining hits is a live, non-stale reference (the enum declaration,
WorldSceneRenderer's flat-path local, or their diagnostic/test
plumbing), not a stale mention of a deleted mechanism.
L7 — Issue130DoorwayStripTests. Deleted AnySliceAdmitsScissor,
worstScissorGapPx and its PIN 1 assertion, the header's scissor
sentences, and the scissorGap half of MeasureTopEdgeGap (dropped the
fbW parameter it alone needed). Rewrote the header: the scissor
mechanism is retired (the sky and landscape draw unclipped; aperture
exactness comes from the depth clear, the exit seals and the interior
repaint). The remaining plane-gap half (the canary PIN,
`worstPlaneGapPx <= 1.2f`) still pins something production reads:
AnySliceAdmitsPlanes walks slice.Planes from the SAME ProjectToClip ->
ClipToRegion -> ClipPlaneSet.From pipeline
RetailPViewPassExecutor.DrawWalkPunchFan reads through
clipAssembly.OutsideViewSlices[activeViewIndex].Planes — so the test
was kept, not deleted.
L8 — DrawWalkSky loop-shape pin. Added
DrawWalkSky_RenderSkyCallSiteHasNoEnclosingBackwardBranch (same
backward-branch-span shape as K1's DrawWeatherOnce pin), plus a note in
both pins that CompiledCallGraph.ReadBranches does not decode a
compiled switch jump table, but no C# loop construct compiles to one.
Mutation (wrapped the RenderSky call in `for (int i = 0; i < 2; i++)`):
Assert.DoesNotContain() Failure: Filter matched in collection
Collection: [..., CompiledBranch { Offset = 20, OpCode = brtrue.s, TargetOffset = 25 }, CompiledBranch { Offset = 23, OpCode = br.s, TargetOffset = 66 }, CompiledBranch { Offset = 72, OpCode = blt.s, TargetOffset = 13 }, CompiledBranch { Offset = 80, OpCode = brfalse.s, TargetOffset = 116 }, CompiledBranch { Offset = 88, OpCode = brfalse.s, TargetOffset = 116 }]
(the Offset=72 -> TargetOffset=13 entry is the injected loop's backward
branch spanning the call).
L9 — this message.
Gates: dotnet build 0 warnings / 0 errors. Hermetic filter
(Lane!=InstalledDat&...&Status!=KnownFailure): 6827 passed, 0 failed.
InstalledDat lane against a real DAT directory: 244 passed, 4 failed —
exactly the four known failures (LayoutImporterMediaBearingChildSweepTests
+ LayoutImporterInvisibleSweepTests, both #383; TowerAscentReplayTests,
KnownFailure; WalkTraceConformanceTests.Oh_doorway_still_first_frame_diff,
#458 KnownFailure). No register row added (every deletion here removes
an acdream-only rule; the KEEP items already had their equivalence
pins from round 1). No new flag/probe.
OWED: the lead's ACDREAM_DEVTOOLS=1 four-pose visual self-gate against
the running client is not run by this agent — CLAUDE.md and this
task's own instructions forbid launching the graphical client from
here; that visual/validation-layer pass remains the user's to run
before this round is accepted.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Campaign OVERHAUL S3 chunk 4 fix round 1 (docs/research/2026-09-01-overhaul/s3-walk-ownership-map.md
§10.4), on top of 6ba4b0b87. K1, K2, K3, K4, K6, K7, K8 (K5 was the lead's own plan-doc note, already
done).
K1 (blocking) — the Assert.Single pin over DrawLandscapeDynamicsPhase's DrawWeatherOnce call site
stayed green even wrapped in a foreach (it counts distinct call-site offsets, not loop shape). Added
a real LOOP-SHAPE pin reusing CompiledCallGraph.ReadBranches: asserts no backward branch (target
offset < its own offset) spans the DrawWeatherOnce call's IL offset — the shape every C#
for/foreach/while loop compiles to.
K2 (minor) — the Collect-time "OC" print fired on ctx.WeatherGateOpen alone while the Replay-time
draw independently re-derived clipAssembly.OutsideViewSlices.Length > 0, which could diverge on an
interior root whose landscape turn ran but whose reassembled outside-view slices ended up empty.
WalkFrameDriver now owns one WeatherTurnFired flag, set unconditionally inside OnWeatherTurn (so it
tracks "did the print's own gate hold" regardless of the transcript flag) and reset every
BeginFrame/AbortFrame; RetailPViewRenderer.DrawLandscapeDynamicsPhase gates DrawWeatherOnce on it
instead of re-deriving its own condition.
K3 (minor) — ClipFrame.SetTerrainClip (the terrain OutsideView writer) had no remaining caller after
chunk 4's original round and K4 below; deleted along with IWorldPassSurface.SetTerrainClip,
RhiWorldPassSurface.SetTerrainClip, the now-orphaned PublishTerrainClip helper, and PrepareClipFrame's
terrain-clip publish call. The terrain/sky shaders still declare the TerrainClip UBO (verified:
terrain_modern.vert, terrain_atmospheric.vert, sky.vert all read uTerrainClipCount/uTerrainClipPlanes),
so the section binding itself (WorldFrameSectionBinding.BindTerrainClip) stays — its existing
zeroed-ring fallback (for when nothing published the section) now binds that same all-zero disabled
block on every frame, identical bytes to the old permanent NoClip/Reset default.
K4 (major) — DrawWalkSky still looped the OUTDOOR case once per active landscape view under a doorway
scissor + BindTerrainClip + EnableClipDistances (the INTERIOR case already drew once unclipped, FW4
slice 6). Retail draws GameSky::Draw(sky,0) ONCE, unconditionally, before LScape::draw's block loop,
for both root kinds. Collapsed DrawWalkSky to one unconditional, unclipped draw; deleted
BeginDoorwayScissor and the RetailPViewPassExecutor.EnableClipDistances wrapper (both lost their only
caller). _surface.BeginScissor/EndScissor and IWorldPassSurface.EnableClipDistances stay:
RhiWorldPassSurface.ClearInteriorDepth still ends an active scissor, and WorldScenePassExecutor (the
separate flat-world path) still calls EnableClipDistances directly.
K6 (minor) — the punch-fan CPU/GPU equivalence pin hand-built a ClipViewSlice from ClipPlaneSet.From's
raw output, which could pass even if ClipFrameAssembler.Assemble's own packing/array-construction
diverged from that output. Rewrote it to build a real PortalVisibilityFrame and run it through
ClipFrameAssembler.Assemble, reading the planes back through assembly.OutsideViewSlices[0].Planes —
the exact outsideSlicesList.Add(new ClipViewSlice(slot, AabbOf(poly), planes)) path
ReassembleOutsideViewFromWalk (the walk's real interior-root producer) shares.
K7 (note) — restored the "a real look-in slice never reuses the reserved no-clip slot 0" assertion
the deleted VisibleClipSlotsInLookInTurn used to prove, via a new internal test-only accessor
(WalkFrameDriver.LookInSliceClipSlotAt) reading the same _lookInSlices storage
InteriorFloodViewClipPlanesAt resolves through _clipFrame.GetSlotPlanes(slice.ClipSlot).
K8 (note) — documented in DrawWeatherOnce's own comment that the weather mesh drawing before the rain
particles is this method's own call-order choice; retail's single GameSky::Draw(sky,1) imposes no
order between acdream's two substitutes.
Every new/changed pin's mutation was hand-verified this session (temporarily applied, ran the
specific test, confirmed the exact failing assertion, then reverted — see the parent task's structured
report for the four failing-assertion texts).
No register row added or removed — every change here deletes an acdream-only rule or repairs a pin;
none introduces a new deviation.
Full solution build: 0 warnings/0 errors. App hermetic (Lane!=InstalledDat/PreparedPackage/Live/
Manual/Timing/Windows/Linux/SystemFont & Purpose!=Diagnostic & Status!=KnownFailure): 6831/6831.
InstalledDat: 244 pass/1 skip/4 known — identical to 6ba4b0b87's own baseline (2x #383 layout tests,
TowerAscent, and the pre-existing #458 WalkLandscape.CheckBlocks block-visibility divergence,
unrelated to and untouched by this round).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Found by the first validation-layer self-gate (S3 chunk 4 round 2). The
capability set is identical on the tip and the round-2 worktree, so it
predates chunk 4; the fix (enable the 1.3 feature or pin the compiler's
target to SPIR-V 1.5) gets its own commit.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Two live cdb captures on the paired 2013 client at the Holtburg doorway:
the blockset template (every Render::block_check call of one frame — 2,601
resident blocks x 2 exit views) proves retail tests a9c9 at ring slot
25,46 and returns PARTIALLY then OUTSIDE; the blockcheck template dumps
its four corner interval vectors (0 0 0 0 300.4|310.2 and 0 0 0 1001 ...,
slab 75..330). acdream's replay at the same P pose reproduces the sentinel
pattern, the four edge planes and both verdicts, drawing a9c9 once, with
clip heights 298.8/308.5 m — a 0.5 % plane difference (about 0.35 px of
projected door-vertex position). At the fixture pose that margin is what
flips the south-west corner from inside to outside on the fourth edge
plane, so retail's four-corner unanimity test says OUTSIDE where ours
says PartiallyInside. Not fixable bit-exactly short of D3D's x87
transform; the KnownFailure row stays with its comment rewritten, the
register carries AD-118, and the first filtered capture's silent miss
(cdb sign-extends poi() inside .if; use dwo()) is noted in the template.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Round 1 (d60ca4ea0) failed all three lenses: the draw-side weather gate is
unpinned, the scissor stack survived K4 on a false comment, the sky shader
still claims retail clips the sky, the K6 pin runs through an assembler
overload production never calls, and K3 left a dead UBO fed per draw.
L1-L9 delete the stacks outright and pin the draw gate's condition.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Campaign OVERHAUL S3 chunk 4 (docs/research/2026-09-01-overhaul/s3-walk-ownership-map.md §10). Retail
polygon-clips exactly three things on the CPU — portal polygons (PView::GetClip), punch fans
(DrawPortalPolyInternal against building_view), and exit seals (setup_view + polyClipFinish);
ordinary meshes, cell shells, terrain, particles and the weather are never view-clipped. Every
acdream-only clip rule beyond those three is deleted; the two that remain get a new CPU/GPU
equivalence pin.
DELETED (no retail counterpart):
- RetailPViewRenderer.DrawLandscapeDynamicsPhase's per-outside-view-slice weather loop
(SetTerrainClip + ClearClipRouting + the old DrawLandscapeSliceLate leaf, one call per active
landscape view) — retail's GameSky::Draw(sky,1) @0x00506ff0 runs ONCE, unclipped, after
LScape::draw's whole block loop. RetailPViewPassExecutor.DrawWeatherOnce stays the one call site;
it now also submits the rain particles (ParticleRenderPass.SkyPostScene) as ONE unclipped
submission, folded in from the deleted loop's per-slice clipSlot draw.
- RetailPViewPassExecutor.DrawLandscapeSliceLate, RetailPViewLandscapeLateSliceContext,
SetTerrainClip (the walk-level wrapper — its only caller was the deleted loop),
ClearClipRouting (same), SetCellShellClipRouting (already had no caller), and
UseIndoorMembershipOnlyRouting (4 call sites in RetailPViewRenderer.cs) — all "first view clips
the shell" residue: SetCellShellClipRouting was the ONLY place EnvCellRenderer.SetClipRouting
ever received a non-null value anywhere in the app, so once it's gone,
UseIndoorMembershipOnlyRouting's own clear calls are provably permanent no-ops. AbortFrame's
matching TryAbort(SetClipRouting(null))/TryAbort(ClearClipRouting) lines are dropped for the
same reason. KEPT: BeginDoorwayScissor, _surface.BindTerrainClip(), EnableClipDistances/
DisableClipDistances, and IWorldPassSurface.SetTerrainClip/ClipFrame.SetTerrainClip/
PrepareClipFrame's terrain-clip publish — all still have real consumers (DrawWalkSky's per-slice
outdoor sky mesh draw; the always-bound TerrainClip UBO section) or are shared classic (non-walk)
infrastructure out of this chunk's ownership (WorldScenePassExecutor, PortalTunnelPresentation).
- WbDrawDispatcher.WalkClassify.ResolvePartClipSlots (renamed ResolvePartVisible, returns bool) and
RetailWholeMeshSlot: the per-view clip-slot LIST always collapsed to either nothing or one
element (RenderDeviceD3D::DrawMesh @0x005A0860 submits the whole mesh once any view admits it) —
never anything but a Boolean wearing a list-shaped costume. IWalkLookInViewSource.
VisibleClipSlotsInLookInTurn is deleted outright (no consumer besides that collapse);
SphereVisibleInLookInTurn gained VisibleClipSlotsInLookInTurn's own testSphere parameter so the
no-authored-sphere case ("any admitted view, geometry ignored") still has a home.
EmitClassifiedBatches now emits exactly one batch per surviving TryClassifyBatch using the
entity's own classic slot (always 0 while _clipRoutingActive is never armed by the walk path).
- The six ProbeCathedralSkip*/ProbeCathedralShellOrderEnabled discriminators (RenderingDiagnostics,
their six docs/launch-options.md rows, every read site in WalkFrameDriver/
RetailPViewPassExecutor.WalkLeaf/RetailPViewRenderer, and the WalkFrameDriver.
TraceCathedralShellOrder method + RetailPViewRenderer._probeCathedralShellOrderFrame it served) —
the investigation is closed: the cathedral leak is retail behavior, not an acdream defect to
discriminate.
O1-O4 (the ledger's carried chunk-1 items, closed here because this chunk owns the weather path):
IWalkEventSink gains OnWeatherTurn(viewerCellId), fired by RetailFrameWalk.DrawLandscape
UNCONDITIONALLY at retail's own call-site shape (GameSky::Draw(sky,1) is itself unconditional from
LScape::draw; the is_player_outside gate lives inside it) but gated by the walk context's own new
WeatherGateOpen/ViewerCellId members (default false/0, so every other IRetailFrameWalkContext
implementer — test fixtures, the FW1 conformance replay context — is unaffected).
WalkProductionFrameContext wires RetailPViewFrameInput.ViewerCellId and
RetailPViewPassExecutor.ShouldDrawWeatherOnce(RenderSky, RenderWeather, PlayerCellId) into those two
members. WalkFrameDriver.OnWeatherTurn prints the "OC" transcript line at COLLECT time; the print is
removed from DrawWeatherOnce (the DRAW stays there, at Replay). Because DrawLandscape's new call sits
at the very end of the method, an outdoor root's transcript naturally ends with the line and an
interior root's lands strictly between "LS" and the flood's first "EC" — exactly retail's position —
with no extra plumbing.
Kept items each get a synthetic-view CPU/GPU equivalence pin (ClipFrameLayoutTests): exit seals via
the real ClipFrame.AppendSlot/GetSlotPlanes round trip, punch fans via the direct
ClipViewSlice.Planes = cps.PlaneArray assignment ClipFrameAssembler.Assemble uses — both assert every
polygon edge midpoint has ~0 signed distance under the GPU-read-back planes and non-negative distance
under every plane.
Every new pin's mutation was hand-verified this session (temporarily reintroduced, confirmed the
exact failing assertion, then reverted): a duplicated OnWeatherTurn call fails Assert.Single with
"2 matching items" on both the outdoor and interior position tests; suppressing the Collect-time
call fails the same assertions with "did not contain any matching items"; perturbing one GPU plane's
offset by 0.05 fails the exit-seal equivalence pin with "the closest plane was only 0.050000012
away". WalkProductionFrameContextTests pins that the ViewerCellId/WeatherGateOpen storage seam
itself never drops or swaps its own two constructor/Reset arguments.
No register row added or removed — every change here deletes an acdream-only rule; none introduces
a new deviation. Full solution build: 0 warnings/0 errors. App hermetic 6,829/6,829 (was 6,828 base
+ 1 new pin). InstalledDat 244 pass/1 skip/4 known (2x #383, TowerAscent, and the pre-existing #458
WalkLandscape.CheckBlocks block-visibility divergence — unrelated to this chunk, untouched by it).
Core.Tests Rendering 216/216.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Campaign OVERHAUL S3 chunk 1 fix round 2 (docs/research/2026-09-01-overhaul/
s3-walk-ownership-map.md §11.6), applied on top of 36be6b598 after the
three-lens re-review. H1-H6, the last round the plan allows.
H1 — the weather OC printed 2-4 times per interior-rooted frame instead of
once: the print (and the `_sky.RenderWeather` mesh draw it sits beside) lived
inside `DrawLandscapeSliceLate`, which `RetailPViewRenderer` calls once per
active `OutsideViewSlices` entry. Moved both into a new
`RetailPViewPassExecutor.DrawWeatherOnce`, called ONCE, unclipped/no-scissor,
after the slice loop in `DrawLandscapeDynamicsPhase` — retail's own
`GameSky::Draw(1)` runs once, after `LScape::draw`'s whole landblock loop.
The gate is extracted as a pure `ShouldDrawWeatherOnce(bool,bool,uint)`
predicate (retail's `SmartBox::is_player_outside` ANDed with the two render
toggles) so `RetailPViewPassExecutorTests` can pin "no OC while the player
stands indoors" without a live GL/DAT `SkyRenderer`; two structural
(CompiledCallGraph) tests prove the call moved out of the per-slice loop and
that the mesh draw + print each fire exactly once per invocation — this
codebase has no existing runtime-construction fixture for
`RetailPViewPassExecutor`, so the pin is structural + a testable pure gate
rather than an end-to-end GL drive. One deliberate deviation from the literal
"gated exactly as today": the print now runs through `_sky?.RenderWeather(...)`
(null-conditional, matching every other `_sky?.RenderSky(...)` call site in
this codebase) instead of an explicit `if (_sky is not null)` wrapper — a
missing sky asset no longer also suppresses the transcript print, since the
print's only job is trace fidelity and retail's own `GameSky` is never null.
H2 — WalkFrameDriver's EC-print comment still claimed "EC and OC counts are
always exactly equal"; replaced with the real citation
(holtburg-doorway-still.walk.log:1126,1131,1134,1137 — four EC prints for one
cell across four look-in DC turns), matching WalkTranscriptDump.
PrintEnvCellShell's own comment (already corrected in round 1).
H3 — the eight-kind signature's ORACLE side
(WalkTraceReplayContext.Signature8(WalkOracleFrame)) derived EC/OC from each
DC's cell list — the SAME derivation the REPLAY side's Recorder already used,
so the comparison could never disagree with itself on EC/OC placement or
content (how G7's SC-ordering regression shipped green with LC/SC). Now reads
its own literally captured EC/OC events, excluding only the trailing
per-frame weather OC — refined beyond the spec's literal "last event + P-cell
id" rule with an additional "P cell itself looks outdoor" check, after
cathedral-arrival and foundry-deep both proved the naive rule also strips an
interior root's OWN real trailing object-list turn when its nearest cell (the
reversed flood loop's last draw) happens to be the camera's own root cell.
All four kit-pose rows still reproduce: three exactly; #458 (this round's new
issue, formerly an inline-only note) re-verified at the SAME token index 165
under the new literal comparison.
H4 — OnSortCellTurn ran RequireOpenFrame + two range validations before
testing the flag. Since the hook is print-only (no stream side effect, unlike
OnLandCellTurn's unconditional WalkFrameEvent record), the flag check now
runs FIRST and returns immediately when off — flag-off cost drops to one
interface dispatch per visited land cell.
H5 — launch-options.md's ACDREAM_DUMP_WALK_TRANSCRIPT row: measured
≈1,200-1,400 lines per outdoor frame (terrace-edge 1,384; cathedral-arrival
1,269; doorway 1,187), replacing the earlier "600-800" estimate; documents
H4's residual flag-off interface-dispatch cost.
H6 — filed docs/ISSUES.md #458 for round 1's LOD-boundary land-cell
divergence (previously only an inline test comment); the InstalledDat lane's
known-failure set is now four (two #383 layout tests, TowerAscent, #458) —
confirmed by a clean run.
MUTATION CHECKS (both restored after confirming failure):
- H1: deleting the OC print inside DrawWeatherOnce made
DrawWeatherOnce_DrawsTheWeatherMeshAndPrintsExactlyOnce fail with
"Assert.Single() Failure: The collection did not contain any matching
items".
- H3: reversing AppendFloodTurns (OC before EC) made
Still_fixture_first_frame_reproduces_exactly(cathedral-arrival.walk) fail
("walk diverged from retail (cathedral-arrival.walk)"), diverging at token
index 1241: expected "EC:f4180112" vs actual "OC:f4180112".
Gates: hermetic App suite 6823/6823 passed; InstalledDat lane 244/249 passed
with exactly the four known failures (two #383 layout tests, TowerAscent,
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Campaign OVERHAUL S3 chunk 1 fix round 1 (docs/research/2026-09-01-overhaul/
s3-walk-ownership-map.md §11.5), applied on top of 079483bb6 after the
three-lens review. G1-G10, each verified against source and (where the item
adds a pin) mutation-checked.
G1 — the flag-off integration test was vacuous: Collect_TranscriptFlagOff_
ProducesNoConsoleOutput drove ONE frame, and WalkOracleTrace.Parse
structurally discards the last (open) frame, so it passed whether or not
the flag gate worked. Now drives TWO frames and asserts BOTH that Parse
sees zero frames AND that no captured line starts with any of the ten
transcript-kind prefixes (F /P /LS/LC /SC /BLD /DI /DC /EC /OC ) — robust
to unrelated console noise from parallel test classes.
G2 — LC/SC computed LodCellId before testing the flag (~1,300 land-cell
turns/frame of division/modulo/checked-conversion work paid even when the
flag is off). Both OnLandCellTurn and the new OnSortCellTurn now guard the
LodCellId call itself, not just WalkTranscriptDump's internal check.
G3 — the flag-on round trip never exercised LC/SC/BLD (the T2 fixture's
stub 1x1 landscape has zero blocks). New
OutdoorRoot_TranscriptFlagOn_PrintsLandscapeThenLandCellThenSortCellThen
Building_InOrder drives RetailFrameWalk.DrawLandscape directly (the same
deterministic "CY-only" admission technique the existing outdoor LandCell
test uses) over a landscape with one block + one building, and asserts
LS < LC < SC < BLD by position, with the exact cell/building ids.
G4 — the parts/alpha-depth smoke tests asserted FL/PC (Flushes/
DrawCellsSamples) but never AM/PM (MeshAdds/PortalPolyDraws) for the
alpha-depth log, even though PD/DM were already asserted for the parts
log. Added the missing Assert.Contains for MeshAdds and PortalPolyDraws.
G5 — launch-options.md's side-effects column now states the flag off/on
costs explicitly ("one bool read per print site, nothing else" / "one
console line per walk turn, ≈600-800 lines per outdoor frame").
G6 — removed the "DI f4180108... no, a9b4013f" self-correction in
Oh_doorway_still_first_frame_diff's comment; added a one-line note on why
it and Oh_foundry_deep_... stay bespoke Facts rather than folding into the
Theory (no functional reason, just history).
G7 — SC printed from OnLandscapeCellTurn, which RetailFrameWalk.
DrawLandscape calls AFTER DrawBuilding — retail's own order is
LC -> SC -> BLD (terrace-edge.walk.log:2331-2333), not LC -> BLD -> SC.
Fixed by adding IWalkEventSink.OnSortCellTurn, fired at the DrawSortCell
entry point (same alwaysDrawObjects||cellInView gate, before DrawBuilding);
the driver moves its SC print there and OnLandscapeCellTurn no longer
prints one.
G8 — the trailing "OC <viewer land cell>" retail prints once per complete
outdoor frame is GameSky::Draw's weather branch calling
DrawObjCellForDummies(after_sky_cell) @0x005070da, not a walk turn.
RetailPViewPassExecutor.DrawLandscapeSliceLate now prints it at the point
it actually calls RenderWeather; PrintObjectCellTurn's doc, which denied
this line existed, is corrected. New
Oh_terrace_edge_outdoor_frame_ends_with_the_weather_ObjectCellTurn pins
this directly against the OH capture: every complete outdoor frame's last
event is an OC whose cell id equals that same frame's own P-line cell id.
G9 — "EC and OC counts are always exactly equal per pose" was false
(terrace-edge: 12 EC vs 16 OC, the extra 4 being G8's weather OC, which
has no EC counterpart). The visit-scoped/stamp-dedupe conclusion was
right; only the count claim needed fixing. Both doc sites corrected.
G10 — the conformance signature dropped LC/SC/EC/OC entirely, which is
how G7 shipped green: no test ever compared their placement. Recorder now
tracks LC/SC via the new OnLandCellTurn/OnSortCellTurn hooks and derives
EC/OC per DC from PView::DrawCells's own two reverse loops (shell
far-to-near, then object-list far-to-near) — a look-in flood's DC derives
them immediately, the interior root's OWN flood defers to
OnInteriorFloodDrawTurn (verified against cathedral-leak.walk.log:4,1328,
where the root DC's own EC/OC print last). WalkTraceReplayContext.
Signature8 applies the identical derivation to oracle frames and never
produces the trailing weather OC (G8's own dedicated pin covers that
separately, matching the spec's "exclude from the comparison, assert
separately" instruction). Used ONLY for the four OH-capture-rooted
conformance rows (the older FW0 fixtures predate the LC/SC/EC/OC
breakpoints and carry none of those lines).
Applying the eight-kind check surfaced a real, separate bug: WalkLandscape
DatBuilder never set WalkLandBlock.LandblockId, so every LC/SC token any
DAT-built world ever produced read landblockId=0 — latent because the old
four-kind signature filtered LC/SC out. Fixed (one field, test-fixture-
only, no production behavior change). With that fixed, three of the four
OH rows (terrace-edge, cathedral-arrival, foundry-deep) reproduce EXACTLY
at the eight-kind level. Oh_doorway_still_first_frame_diff still diverges
by one extra LC/SC pair (token index 165: replay draws LC:a9c90001|
SC:a9c90001 that retail never does) — a real WalkLandscape.CheckBlocks
visibility question at a ring-2/ring-3 LOD boundary, out of this round's
print-only scope, needing the retail oracle to resolve. Marked
[Trait("Status","KnownFailure")] with the exact position recorded in its
own doc comment, matching TowerAscent's existing pattern — the InstalledDat
lane now shows FOUR known failures (the pre-existing two #383 layout tests
+ TowerAscent, plus this new finding), not three; never weakened the pin
itself.
Mutation checks (all four restored after observing the failure):
- G1: forcing WalkTranscriptDump.Enabled true made
Collect_TranscriptFlagOff_ProducesNoConsoleOutput fail with
"Assert.DoesNotContain() Failure: Filter matched in collection ... Collection:
[\"DI 00000100\", \"DC pv=00000000 ov=1 n=2: 00000100 00000101\", \"LS\", ...]".
- G3: deleting PrintLandCell's Console.WriteLine made the new outdoor test
fail with "expected an LC line".
- G4: making MeshAddPattern unmatchable made all five
Alpha_depth_log_parses_with_nonempty_samples rows fail with
"Assert.Contains() Failure: Filter not matched in collection".
- G7/G10: moving OnSortCellTurn back after DrawBuilding made the
terrace-edge conformance row fail with "walk diverged from retail
(terrace-edge.walk)", first divergence exactly at its first building
(f518002e): expected ...SC:f518002e|BLD:f518002e..., actual
...BLD:f518002e|SC:f518002e....
Gates: hermetic lane 6,816/0 (baseline 6,814 + G3's new test + G8's new
test); InstalledDat lane 244/4 known failures (two pre-existing #383
layout tests + TowerAscent + the new Oh_doorway_still_first_frame_diff
finding, documented above).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Campaign OVERHAUL S3 chunk 1 (docs/research/2026-09-01-overhaul/s3-walk-ownership-map.md
§11): the transcript-kinds/fixtures/print-only-emitter half of the walk work,
built AFTER chunk 3 landed LC/SC (the per-land-cell interleave).
B1 — the emitter (print-only, never gates admission/depth/order):
- ACDREAM_DUMP_WALK_TRANSCRIPT=1 is read once into RuntimeOptions.DumpWalkTranscript
(rule 4) and handed to RenderingDiagnostics.DumpWalkTranscriptEnabled (rule 5,
a settable static, not a second env read) once at GameWindow construction — the
deep walk call sites have no reachable RuntimeOptions reference.
- WalkTranscriptDump (new) prints the OH line kinds — F/P/LS/LC/SC/BLD/DI/DC/EC/OC —
to Console at the exact points retail's cdb breakpoints sit
(tools/walk-oracle/oh/oh-capture-walk.cdb.template), gated internally so every
method bails out before any string work when the flag is off.
- Every call site lives in WalkFrameDriver.cs, at the point the driver already
processes that turn: Collect (F/P, after BeginFrame), Emit's DI/LS/DC/BLD cases,
OnLandCellTurn/OnLandscapeCellTurn (LC/SC, at LOD resolution via the new
WalkTranscriptDump.LodCellId helper, before the 8x8-bucket expansion), and the
EmitFloodTurns/EmitCellContentsTurn loops (EC/OC — both UNCONDITIONAL per flood
visit, matching the OH captures' always-equal EC/OC counts; retail's own
DrawEnvCell stamp dedupe sits past the breakpoint, inside the function).
- DC's "pv=" field encodes interior(0)/outdoor(1) as an 8-hex-digit 0/1 so it
satisfies the same pv=[0-9a-f]{8} regex real captures use; derived from
_currentDcStage at the DC event (CellStatic = interior pview, else outdoor).
- The frame-root pose (origin, quaternion) is a reasonable orthonormal basis built
from the walk's own CyPlane.Normal forward vector and WalkLandscape's own
ViewerWorldOriginX/Y block origin — self-consistent for the round-trip parser,
not a byte-exact reproduction of retail's Frame (B4's diff never compares P).
B2 — WalkOracleTrace learns EC/OC event kinds (LC/SC already existed from chunk 3).
New WalkOraclePartsTrace.cs holds two small read-only parsers for the parts log
(PD/DM) and the alpha-depth log (AM/FL/PM/PC) — records only, no validator, no
canonical JSONL, no new tool.
B3 — fixtures: the five OH walk captures join WalkOracleTraceTests.AllFixtures
(now (root, name) pairs — FW0's own root plus the OH capture directory) for
parse + complete-frame pins. The four kit poses join WalkTraceConformanceTests'
still-fixture coverage as NEW rows (the OH cathedral-arrival root is f4180108,
not FW0's f4180106): terrace-edge/cathedral-arrival extend the existing theory
(now (root, fixture) parameterized); holtburg-doorway-still and foundry-deep get
dedicated tests mirroring their FW0 siblings' own structure. Finding: the OH
foundry-deep capture's own retail transcript draws 12 real town buildings through
its exit chain (unlike the FW0 capture, which apparently reached none at that
pose) — the FW0 test's stub 1x1 landscape undershoots it (first divergence:
nothing after "LS" vs retail's real BLD content); fixed by building the full
landscape/building world via WalkLandscapeDatBuilder.Build, matching the shared
theory's own approach, not by skipping or weakening the row.
WalkTraceReplayContext.Signature(WalkOracleFrame) now filters to the DI/DC/BLD/LS
kinds (LC/SC/EC/OC never had a WalkEvent analogue in RetailFrameWalk's own
four-kind vocabulary) instead of mapping them to a "?" placeholder, so the still-
fixture comparison stays apples-to-apples on both sides.
B4 — WalkTranscriptSignatureDiff (test-side only, no runner/tool): diffs two
transcripts (raw lines or parsed frames) at the full DI/DC/BLD/LS/LC/SC/EC/OC
level, reporting the first divergent event and position per frame. Proven over a
synthetic self-vs-self-minus-one-event pair (SignatureDiff_ReportsTheExactRemovedEvent).
Tests: T1 (flag off) is split into a unit-level zero-allocation/zero-output check
on WalkTranscriptDump itself (the walk's pre-existing allocation, e.g.
RetailFrameWalk.EmitDrawCells's per-call array, is untouched by this chunk and not
independently zero-alloc) and an integration-level Collect() check; both assert via
WalkOracleTrace.Parse returning zero frames rather than raw string equality, which
is robust to unrelated Console.WriteLine noise from other test classes running in
parallel (a real, observed hazard — WalkFrameDriverTests joins
CameraDiagnosticsCollection for the same reason CornerFloodReplayTests/
Issue181WallPressEquilibriumTests already do, issue #251). T2 proves the
emitter/parser round trip on a synthetic interior frame. T3's InstalledDat rows all
pass. T4: LaunchOptionsDocumentationTests green with the ACDREAM_DUMP_WALK_TRANSCRIPT
row (both directions).
Gates: hermetic lane 6,814/0 (was 6,795 baseline + new tests), three consecutive
clean runs; InstalledDat lane 245/3 known-failures (the two pre-existing #383
layout tests + TowerAscent) unchanged from baseline.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The re-expressed F4(c) pin installed an empty landscape view, so nothing
classified visible, the ordered stream never grew, and no StreamMark
fired: the one behavior round 2 changes was unpinned (review finding).
The test now installs a real full-viewport view and records the trace,
asserting two FLUSH lines ahead of the merged three-cell terrain batch.
The LandCell doc no longer claims an identical submission order; the
resolved image is identical (opaque-vs-opaque order is depth-resolved,
every observable order still flushes first).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Measured (§9.7): the connected R6 soak at e10765aa showed the round-1
batching fix (§9.6 F2) was inert in practice — CPU p50 flat at 31.2 ms
and FPS flat at 32 across every outdoor destination (baseline 2.0-15.5 ms
/ 51-452 FPS), GPU p50 2-4x baseline. Root cause: nearly every admitted
land cell carries scenery statics, so a StreamMark (recorded whenever the
walk's ordered stream grows) follows almost every LandCell event and was
itself treated as a flush point, splitting the pending terrain batch back
down to ~500 submissions/frame — each paying TerrainModernRenderer's full
bind sequence plus a ring allocation and an MDI.
F10: a StreamMark no longer flushes the pending terrain batch. Citation —
the walk's ordered stream holds ONLY opaque batches
(WalkStaticStreamPopulator.cs:179, `if (batch.IsOpaque)` routes translucent
batches to the alpha list instead of the stream) drawn through the
Opaque/OpaqueAlphaToCoverage pipelines, both created with depth test AND
write ON and GpuBlendMode.None (WbDrawDispatcher.Rhi.cs:240-248,343:
`Depth = new GpuDepthState(Test: true, Write: depthWrite, depthCompare)`
with depthWrite: true); DrawOrderedRange resolves every walk-stream
command's bucket to PipelineBucket.Opaque because every command it holds
is opaque (WbDrawDispatcher.OrderedStream.cs:569-571). Opaque terrain and
opaque statics are therefore depth-resolved identically in either
submission order, so deferring the terrain batch across a StreamMark is
pixel-identical (except exact z-ties, which retail itself leaves
order-independent).
Flush points that REMAIN, because their GPU order against terrain IS
observable: PunchFan (DEPTHTEST_ALWAYS + write — the far-Z stamp this
chunk's interleave exists to order correctly), AlphaBarrier and
LandscapeFlush (translucent drains), ClearInteriorDepth, ExitSeals, Sky,
CellShell, a particle turn whose cell has a renderable emitter, and the
end of Replay. AlphaSubmitMark stays a non-flush point (unchanged — it
only enqueues into the CPU alpha list). No ordered-stream stage found
that blends or disables depth write, so no amendment to the contract was
needed; the Replay doc comment records the citation so a future stage
that does must become a flush point again.
F11: no per-batch bind latch added (tens of batches/frame is acceptable).
F12: the F4(c) driver pin is re-expressed to prove a StreamMark from a
cell with real content (not just an empty particle turn) no longer
splits, while PunchFan/AlphaBarrier/a has-emitter particle turn still do;
a new punch-order pin (LandCell(far), building turn with a PunchFan,
LandCell(near)) proves the far terrain flushes before the punch and the
near terrain starts a fresh batch after it. Hermetic App lane: 6,796
passed (6,795 base + 1 new fact), 0 failed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- the LandCell event doc states the deferred cross-block batch rule (the
same-landblock lookahead text was stale);
- the AlphaSubmitMark arm's comment gives the true reason it is not a
flush point (it only enqueues into the CPU alpha list; the drain leaves
flush first);
- the pending terrain batch is cleared with the other transient frame
lists in AbortFrame/BeginFrame;
- CompleteWalkTerrainFrame runs in a finally so a throwing Replay cannot
leak its accumulated ticks into the next frame's sample;
- CopyRenderableEmittersInCell keeps its own doc comment;
- the outdoor-root LandCell pin now observes one real cell turn after its
terrain;
- the oh1 landscape contract's stale "whole pre-stage" prose is resolved.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>