acdream/docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md
Erik 4e863f7486 docs(overhaul): authorize bounded S4-c2 repair
Record the owner override after the required stop and bind the one-attempt repair to exact EnvCell pass membership, retail CLIP state, bounded source scratch, and production-path discriminators. Keep G3/G4 unpassed and the implementation unlanded pending dual review.
2026-09-04 09:42:59 +02:00

78 KiB
Raw Blame History

S4 packet — depth and alpha: what S3 already delivered, what remains (lead draft, 2026-09-03 evening)

Status: DRAFT written while the S3 post-hoc lenses ran; NOT dispatchable until the S3 review closes (plan §9 order: S3 review → G3 → S4). Every owner named below is re-located at chunk time; names, not line numbers.

Specs: oh1-depth-lifecycle.md, oh1-alpha-list-contract.md; the plan's §9 S4 section; the §7 alpha/depth captures under oh-capture/ (*.alphadepth.log, line formats in tools/walk-oracle/oh/oh-capture-alphadepth.cdb.template).

1. What S3 already delivered of S4's chunk 1

S3 chunk 2 (§8 of the S3 packet, landed be9b4c1f + 434a7df2) implemented the S4 chunk-1 scope almost whole, because the walk could not be exact without it:

S4 chunk-1 item (plan §9) State after S3 Where
one frame-persistent latch owner for portalsDrawnCount DONE — WalkFrameDriver.PortalsDrawnCount, retained across frames, never cleared by Begin/Abort/EndFrame S3 §8.2 B2
landscape → flush → stamp → clear → seal block gated exactly as retail (outside_view.view_count > 0) DONE — OnInteriorFloodDrawTurn(cells, outsideViewCount); LandscapeFlush leaf; stamp advance; clear ONLY IF count ≠ 0 (read-then-zero); seals S3 §8.2 B1/B3
WalkFrameDriver's unconditional interior clear deleted DONE S3 §8.2 B1
mid-frame stamp placed exactly (0x005a4886) DONE (AdvanceWalkPartPassStamp at the flush leaf) S3 §8.2 B1
exit seals from the exact current views and cell order, counted by the seal leaf's return value DONE — DrawExitSeals returns the submitted count; punch fans never count S3 §8.2 B2
look-ins cannot touch the root latch DONE (look-in DrawCells never increments) S3 §8.2 B2
truth-table tests over root kind / draw_landscape / outside-view count / previous-current portal count PARTIAL — the chunk-2 tests flipped the two wrong contracts (§8.3); the full truth table and the two-consecutive-frames latch test are NOT yet one theory S4-c1 below

The depth-lifecycle spec's "Current acdream correspondence" table (its rows marked missing / wrong for the counter, the gate and the test contracts) is therefore stale for those rows; the rows that still stand are the three below.

2. What remains for S4 chunk 1 (S4-c1, small)

  • Far-punch depth constant. Retail writes the far-Z punch at the exact bits 0x3F7FFFEF; portal_depth.vert uses the decimal 0.99999988. The chunk decides by TEST, not by eye: a pin that reinterprets 0.99999988f and asserts BitConverter.SingleToInt32Bits == 0x3F7FFFEF; if they differ, the shader takes the hex literal (uintBitsToFloat(0x3F7FFFEFu)) and the manifest hash is re-pinned. (1 2⁻²³ is the expected identity; prove it.)
  • The ±12 local-input reject. Ghidra arbitration (S3 packet §2, the "±12 test is an equality degenerate guard") says the check rejects a whole polygon whose local x/y equals ±12 exactly — a degenerate-input guard, not a clip rule. Port it at the punch-event producer as an equality test on the LOCAL polygon before transform, with a test that feeds one exact ±12 vertex polygon and one at ±11.999 (only the first is rejected). If the arbitration table shows the branch can never fire for a real DAT polygon, record that as the reason to skip and cite the table.
  • Seal/punch color state. Retail's portal-depth draws keep color writes ENABLED with SRCALPHA/INVSRCALPHA and source alpha 0 (a no-op blend); acdream sets ColorWrite=false. Pixel-identical by construction; the chunk adds the register row (AD-nnn: "portal-depth color path: write-mask off instead of a zero-alpha blend — identical output, different state") OR ports the exact state if the Vulkan pipeline already carries the blend attachment; the reviewer decides which is cheaper to keep honest.
  • Truth table + two-frame latch test (plan §9 S4 tests): one theory in WalkFrameDriverTests over (root kind, draw_landscape, outside-view count, previous count) → the exact event subsequence (LFLUSH, stamp, CLEAR?, SEALS?), plus the consecutive-frames case proving the latch crosses frames, plus "multiple look-ins isolated from the root".

3. S4 chunk 2 — the alpha lists (the slice's body)

Current state (verified 2026-09-03 at 7df0b94c9): RetailAlphaQueue is ONE scope-global list sorted by viewer distance at flush (SortRetailOrder in Flush / FlushFartherThan); submitters: WbDrawDispatcher (two queue.Submit sites: the packed path and the walk classify path with viewerDistance) and ParticleRenderer (one site). Barriers: IWalkFrameLeafRenderer.AlphaBarrierFlushLandscapeAlpha_alpha.Flush() at the building turn (retail DrawBuilding's FlushAlphaList(0f)), the LandscapeFlush leaf (retail PView::DrawCells's FlushAlphaList(0f) @0x005a4872), and two RetailPViewRenderer end-of-pass calls (the top-level SmartBox::RenderNormalMode flush). FlushFartherThan (the pre-punch "drain the farther content" approximation) is the AP-34 row.

Retail (spec §5§7, verified against the decomp at chunk time): two independent FIFO lists (CLIP and ALPHA) of 3000 AlphaListEntry each; AddMeshToAlphaList appends, never sorts; each DrawMesh invocation owns a first-for-this-list flag that captures material + object matrix for the list's replay; FlushAlphaList(threshold) is a no-op only when BOTH counts are below threshold × 3000, otherwise drains CLIP then ALPHA in append order, resets both, restores the object matrix, does NOT restore the material; capacity overflow = append returns false and the delayed subset is NOT drawn; DrawBlock calls FlushAlphaList(0.75) per land cell (the pressure valve — inert below 2250 entries).

Behavior change (chunk contract to be written after the S3 review):

  1. Replace the sorted single queue with two FIFO records mirroring the retail entry (source token, first-for-list material/matrix capture, overrideClipmap, list id) — no distance field, no sort.
  2. Route every submitter to the exact list by the retail DrawMesh branch table (spec §4): CLIP for the multipass clip-map delayed duplicate, ALPHA for delayed subsets; sky/detail immediate gates; material has_alpha fallback.
  3. Flush sites exactly: DrawBuilding 0f (the existing AlphaBarrier), DrawBlock 0.75 per land cell (NEW — a threshold flush at the SC turn; inert at today's counts, pinned by a capacity test), PView::DrawCells 0f (the existing LandscapeFlush), top-level 0f (the existing pass-end flush). Delete FlushFartherThan and retire AP-34.
  4. Capacity 3000 per list with the exact overflow behavior (append false, subset dropped) — pinned, not "expanded or recovered".
  5. Transparent EnvCell subsets routed to their retail list (spec §6: the environment detail surface makes eligible subsets immediate).

Tests (plan §9 S4): multiple translucent objects in one cell with reversed distance vs insertion order (FIFO wins); equal-key stable tie; two cells where a global sort disagrees with traversal; particle/object/ transparent-cell overlap; DrawBuilding 0f flush; pre-clear and final flush; the 0.75 partial flush at exactly 2250; alternating blend modes across Vulkan batches; capacity 3000 overflow drops the subset.

Gate: the alpha/depth transcripts exact against the §7 captures (*.alphadepth.logAM add-mesh, FL flush, PM portal mask lines), the walk/depth/alpha suites, Release build; then the owner's G3 (S4's owner gate per the plan) — the lead's S3-state G3 pre-run of 2026-09-03 (20/20 frames) is the baseline to diff against.

4. S4 chunk 3 — deletions

Delete the obsolete stencil/bias/skip paths and the CYpt sort once chunk 2's transcript is exact: RetailAlphaOrdering.ComputeViewerDistance and every viewerDistance argument on the submit path; any remaining FlushFartherThan consumer; the #117/#129 bias remnants the S1 hygiene already removed from portal_depth.vert (verify nothing else carries them). Register: AP-34 retired; any row describing the distance sort retired; the seal/punch color-state row from S4-c1 kept or retired per its decision.

6. S4-c1 contract (lead draft, 2026-09-03 evening — dispatch after the S3 review closes; re-locate every owner)

Retail facts (verified in the decomp / the Ghidra arbitration table of oh1-depth-lifecycle.md):

  • R1 far-Z punch: DrawPortalPolyInternal @0x0059bc90's tail writes the punch depth from the constant with bits 0x3F7FFFEF.
  • R2 the ±12 reject: 0x59BCD60x59BD28 then 0x59BD400x59BD66 compare each SOURCE vertex's LOCAL x/y against ±12 BEFORE xformStart. The QUANTIFIER (S4-c1 round-1 retail lens, 2026-09-03 night — the lead's first wording here and in T2 was inverted): retail rejects the polygon only when ALL of its local vertices lie on ONE of the four planes x=+12, x=12, y=+12, y=12 — a polygon degenerate onto a bounding plane; a polygon with merely one vertex on such a plane is drawn and counted. Four accumulating predicates, one per plane, each true only if every vertex satisfied it; return if any predicate survives (degenerate-input guard, S3 packet §2). Then 0x59BD700x59BD74: only false/true-depth SEALS increment the counter (modulo 65,536); far punches never do (already ported, S3 §8.2 B2). 0x59BDBC0x59BDBF: fewer than 3 CLIPPED vertices submit no fan (after the possible increment).
  • R3 portal-depth state: depth test ALWAYS, depth write on, no cull; color writes ENABLED with SRCALPHA/INVSRCALPHA and source alpha 0 (a no-op blend); no stencil.

Current acdream (at d0c981212):

  • portal_depth.vert:53 clipPos.z = clipPos.w * 0.99999988; — the decimal literal is 1 2⁻²³ = bits 0x3F7FFFFE; retail's constant 0x3F7FFFEF is 0.99999898672… — FIFTEEN ULPs nearer the camera (lead's bit check, 2026-09-03: SingleToInt32Bits(0.99999988f) == 0x3F7FFFFE). The depth spec's "wrong constant" row is right. C0 below fixes it; T1 pins it.
  • No ±12 reject anywhere on the punch/seal producers (WalkFrameDriver.OnPunchGeometry @ the walk's punch event; RetailPViewRenderer.DrawWalkExitPortalMasks); the clipped-count <3 gate exists as the vertices.Length < 3 early return in DrawWalkPunchFan.
  • PortalDepthMaskRenderer.Rhi.cs: GpuCompareOp.Always, depth write on, Blend = GpuBlendMode.None, ColorWrite = false — pixel-identical to R3 (a zero-alpha blend changes no color), state-different.

Behavior change (small):

  • C0 the far-punch constant: portal_depth.vert takes retail's exact bits (uintBitsToFloat(0x3F7FFFEFu), comment citing DrawPortalPolyInternal @0x0059bc90's tail), the SPIR-V is recompiled and VulkanShaderManifestTests re-pinned. Visible effect: the far punch lands 15 ULPs nearer than before — at 24-bit depth that is the difference between "at the far plane" and "one step in front of it", which is exactly the retail relationship the seals (true depth) and the interior repaint rely on; any capture pose whose PM lines show mode=1 punches is the regression check.
  • C1 the ±12 local-input reject ported at the producer that owns the LOCAL polygon (the walk's punch-event producer for punch fans; the exit-seal enumeration for seals — both read the dat portal polygon in cell-local space before the world transform), as retail's four per-plane predicates: the polygon is dropped only when EVERY source vertex lies on the same one of x=+12, x=12, y=+12, y=12 (exact equality), BEFORE any counter increment (order: reject → transform → clip → count). A polygon with one vertex on a bound is NOT rejected. If the table shows the bound can never be hit by an authored portal polygon, the port still lands (it is retail's code) with the test proving the reject fires on a synthetic all-on-one- plane polygon and NOT on a one-vertex-on-the-plane polygon.
  • C2 no state change for R3: add register row "portal-depth color path: ColorWrite=false instead of retail's zero-alpha SRCALPHA/INVSRCALPHA blend — identical output, different pipeline state" (an AD row, with the citation), unless the reviewer prefers the exact blend attachment; the lead's default is the row (zero-risk, honest).
  • C3 the truth-table theory and the two-frame latch test (§2 above).

Tests: T1 reads portal_depth.vert's punch line and asserts the literal it carries has bits 0x3F7FFFEF (a source pin — it FAILS at d0c981212, where the line reads 0.99999988 = 0x3F7FFFFE; MUTATION: any other literal); T2 ±12 reject (corrected 2026-09-03 night — the lead's first wording inverted retail's quantifier): a synthetic local polygon with EVERY vertex at x = 12 exactly (degenerate onto the plane) → no punch event and no seal, counter unchanged; the same polygon with ONE vertex at x = 12 and the rest inside → punched/sealed and counted; every vertex at x = 11.999 → punched/sealed; T3 the truth table (root kind × draw_landscape × outside-view count × previous count) → the exact event subsequence; T4 two consecutive frames prove the latch crosses frames (frame 1 seals N>0 → frame 2 clears; frame 1 seals 0 → frame 2 does not clear); T5 multiple look-ins never touch the root latch. Mutation checks for every new pin, texts inline in the commit body.

Gates: build 0 warnings; hermetic green; InstalledDat the four known; depth-event transcript unchanged at the four capture poses (the PM/PC lines of the alpha-depth captures — S4-c1 changes no event unless a ±12 polygon exists in a captured pose, in which case the transcript is the proof); the lead's four-pose self-gate with validation on (zero errors).

7. S4-c1 fix round 1 (lead, 2026-09-03 night — after the three-lens review of c7ab5b6d8; round 1 of the two the plan allows)

Verdicts. Retail lens FAIL, production lens FAIL, build lens FAIL (the same blocking quantifier; plus: the commit body's "register tests 52/52" gate is vacuous — no test in the repository reads the divergence register, so a register row is checked only by a human read; §7's gates say so and drop that filter from the claimed evidence). The BLOCKING finding is one defect seen by all three: C1's quantifier is inverted — the port rejects a polygon when ANY vertex lies on ANY ±12 plane; retail (PDB-paired bytes at VA 0x59BCD60x59BCE5: fld/fcomp 12.0/fnstsw/test ah,0x44/jnp over xor bl,bl — four accumulating per-plane flags) rejects only when EVERY vertex lies on the SAME plane. The lead's §6 paraphrase carried the same inversion and is already corrected (§6 R2/C1/T2). Consequences the lenses proved: the T2 pins lock the wrong rule in; the guard's doc claims authored polygons "essentially never" hit the bound, but the production lens's DAT scan found 2,889 portal polygons with a ±12 vertex and 2,163 EXIT polygons lying ENTIRELY on a ±12 plane; and the §6 depth-event transcript gate (PM/PC lines) was neither run nor automated — the one check that would have shown the effect on real data. Minor: the manifest re-pin comment has the ULP direction inverted and points at the wrong test class.

Why this matters beyond the round. If 2,163 exit polygons lie entirely on a bounding plane, retail never punches or seals THOSE portals — which is the "never-drawn portal polygon = panel" family the PV campaign named (#456) and very likely the mechanism behind retail's own cathedral seam leak (#465's "hole"). Porting the guard correctly therefore changes acdream's seal/punch set at many poses toward retail's; the captured PM/PC lines are the only proof that the change lands exactly, so F3 builds that comparison as this slice's own gate (S4's automated gate already requires "depth-event transcripts exact against the §7 captures").

F1 (BLOCKING) — port the quantifier retail has. Replace IsRejectedByPortalPolygonBoundaryGuard's any-vertex test with four per-plane predicates (x=+12, x=12, y=+12, y=12), each initially true and cleared by the first vertex NOT on that plane; reject iff any predicate survives all vertices (exact float equality, LOCAL coordinates, before any transform), at both producers (WalkFrameDriver.OnPunchGeometry's punch path and RetailPViewPassExecutor's seal enumeration). Rewrite the doc comment with the DAT counts (recompute them with a scratch scan over the installed DAT and cite the numbers in the commit body — the "essentially never" sentence is deleted). T2 becomes: every vertex at x=12 → rejected; one vertex at x=12, the rest inside → kept, punched/sealed, counted; every vertex at x=11.999 → kept; every vertex at y=12 → rejected; vertices split across x=12 and y=12 (none on one common plane) → kept. MUTATION: restore the any-vertex form → the "one vertex" and "split planes" cases fail; delete the guard → the all-on-plane cases fail. Rewrite the existing T2 tests and WalkFrameDriverTests.OnPunchGeometry_RejectsWholePolygonOn… to these semantics (the names say what they pin).

F2 — count order at the seal path. Retail: guard → transform → clip → count; the fan is skipped when the CLIPPED count is under 3, AFTER the counter increment (0x59BDBC0x59BDBF). RetailPViewPassExecutor's seal loop drops sub-3-vertex LOCAL polygons before the guard and before counting. Port retail's order (authored polygons always have ≥3 vertices, so this changes no real frame — pin it with a synthetic 2-vertex polygon: counted, not drawn) and note the register row AD-119's neighbour if a comment there describes the old order.

F3 — the depth-event transcript gate, automated. Parse the four oh-capture/*.alphadepth.log fixtures' PM poly=<ptr> mode=<0|1> counterBefore=<hex> and PC ov=<n> counter=<hex> fc=<0|1> lines per frame (the oh-capture-alpha-depth.cdb.template documents them) into per-frame sequences of (mode, counterBefore) and (ov, counter, fc); replay each pose's frame 2 through RetailFrameWalk/WalkFrameDriver with a recording leaf (the existing WalkTraceReplayContext + DAT builder; punch fans = mode 1 events, exit seals = mode 0 events; the driver's PortalsDrawnCount before each event = counterBefore; the interior turn's ov/count/forceClear = PC) and compare the sequences exactly. Pointers are not compared. Expect: with F1 correct, the four poses match; if a pose does not, the test prints both sequences and is tagged Status=KnownFailure with the divergence written into this section — never weakened. The oracle-side parser lives beside WalkOracleTrace (a WalkAlphaDepthTrace), the comparison beside WalkTraceConformanceTests. This is the slice's own gate, not extra infrastructure.

F4 — comment truth. VulkanShaderManifestTests.cs:80-81: 0x3F7FFFFE is FARTHER from the camera (larger z/w), and T1 is PortalDepthVert_FarPunchConstant_MatchesRetailExactBits in that same file, not in WalkVisibilityMathTests.

F5 — commit message: every mutation text verbatim (F1's four, F2's one, F3's "swap one PM mode" mutation), the DAT scan numbers and the scan method, the per-pose PM/PC match/mismatch table, Co-Authored-By last.

Gates: build 0 warnings; hermetic fully green; InstalledDat exactly the four known plus, if F3 finds a divergence, that row tagged KnownFailure and written up here; the shader and register test classes green; the lead's four-pose validation self-gate afterwards (zero validation errors; the cathedral floating-stairs frame diffed against the S3-closed gate — a changed seal set is EXPECTED to change the exterior-slab region if retail's panel family is what the guard reproduces; the owner's retail screenshot is the oracle for that pose).

5. Open questions to settle before dispatch

  • SETTLED (2026-09-03): the walk's SC turn is IWalkEventSink.OnSortCellTurn in WalkFrameDriver (today a transcript print at DrawSortCell ENTRY, fired from RetailFrameWalk.DrawLandscape); the 0.75 valve is retail's DrawBlock call AFTER DrawSortCell returns, so chunk 2 adds one leaf method at the sort-cell EXIT (a WalkFrameEventKind of its own, ordered after the cell's object turn) — not a print-site change.
  • PARTLY SETTLED (2026-09-03): ParticleRenderer submits every deferred particle draw (billboard and mesh kinds alike) to the single queue with a viewer distance (queue.Submit(_alphaSource, token, sqrt(DistanceSq))). In retail a particle is a DrawMesh like any other subset, so its list is decided by the §4 branch table on the emitter's subset mask and material (rows 3/4 → ALPHA under the default 0x0E delay mask; row 1 immediate while m_currentlyDrawingSky is set — the weather emitters). Chunk 2 routes particles through the same branch table, not a particle-specific rule; the parts capture (*.parts.log, PD/DM lines) is the oracle for which emitters ever appear as immediate draws.
  • SETTLED (2026-09-03): the alphadepth captures' AM lines carry the list selector (AM mesh=… surf=… csurf=… new=… clip=… listSel=…listSel is the list, new the first-for-list flag, clip the clip-map duplicate, surf/csurf the raw surface type and material), and FL lines mark every flush (terrace-edge: 3,515 FL lines over its frames), so the chunk-2 transcript compares per list and per flush site, not merged.

8. S4-c2 contract (lead draft, 2026-09-03 night — dispatch after S4-c1 lands on the campaign branch; re-locate every owner at dispatch)

Scope (ONE production behavior change): replace the single distance-sorted RetailAlphaQueue with retail's two append-order lists, route every delayed subset by the exact DrawMesh branch table, and flush at retail's four normal-world sites under retail's threshold rule. No evidence infrastructure beyond the transcript gate this chunk consumes (G-c2 below).

Capture profile the contract rests on (the five *.alphadepth.log files, counted 2026-09-03): 10,556 AM lines, every one clip=0 (so retail's MultiPassAlpha row 2 never fired live — default false, spec §3); listSel 0 = 6,330 lines, 1 = 4,183 (two lists, both live); FL lines by return address: 005a1a0c (DrawBlock 0.75) 13,705, 0059f310 (DrawBuilding 0f) 309, 005a4877 (PView::DrawCells 0f) 18, 00453b90 (RenderNormalMode 0f) 23; new=1 9,685 / new=0 871 (the first-for-list flag is mostly set — most DrawMesh invocations append one subset per list).

Retail facts the implementer verifies at the decomp BEFORE writing (quote the predicate, never paraphrase — feedback_quote_decomp_predicates):

  1. D3DPolyRender::AddMeshToAlphaList @0x0059C230 — append only, two static arrays of 3000 entries and two uint16 counts, returns false at capacity (spec §5). Identify which listSel value is CLIP and which is ALPHA from the bytes (the capture's listSel is the raw byte at @esp+0x18), and record it in the code comment.
  2. D3DPolyRender::FlushAlphaList(threshold) @0x0059D2E0 — the early return fires only when BOTH counts are under threshold × 3000; quote the comparison (strict < or <=) from the bytes and pin the boundary count the bytes give (spec §5 says equality at 2250 drains); drain CLIP fully, then ALPHA fully, in append order; reset both counts; restore the object matrix, not the material.
  3. DrawMesh branch table = spec §4 rows 15 verbatim; delay mask s_AlphaDelayMask @0x00820D88 default 0x0E; MultiPassAlpha @0x0081EF96 default false; the constructed subset mask = spec §2 (surface type bits 0x000103000x02, 0x040x08, 0x100x04, else 0x00; OR 0x01 when the polygon's signed stippling byte is > 0).
  4. The four normal-world flush sites (spec §7) — confirm each capture return address above lies inside the named function in docs/research/named-retail/symbols.json.

C1 — two lists. RetailAlphaQueue becomes two FIFO records, CLIP and ALPHA, capacity 3000 each. Entry = (source, token, list, overrideClipmap, first-for-list). NO distance field; Submit takes the list and the override flag, never a viewer distance. Append at capacity returns false and the subset is DROPPED (no immediate fallback) — pinned. Keep the IRetailAlphaDrawSource protocol (PrepareAlphaDraws once per drain with the tokens in list order, CLIP then ALPHA; only adjacent same-source entries form a batch — the "never group across another entry" invariant stays, it is what keeps compositing exact).

C2 — flush semantics and sites. Flush(threshold) implements fact 2. Sites: AlphaBarrier (DrawBuilding) → 0f; NEW leaf event at the sort-cell EXIT — its own WalkFrameEventKind, recorded after OnLandscapeCellTurn (the object turn) and before the next cell's land turn (packet §5 SETTLED) → 0.75f; LandscapeFlush (PView::DrawCells) → 0f; pass end (RenderNormalMode) → 0f. FlushFartherThan deleted; AP-34 retired in the same commit; every viewerDistance argument on the submit path and RetailAlphaOrdering.ComputeViewerDistance (with its test) deleted — chunk 3's deletion list shrinks accordingly.

C3 — routing. Both WbDrawDispatcher submit sites (SubmitWalkAlphaInstance, DeferTransparentGroups) and ParticleRenderer's site route through ONE pure router implementing spec §4 with these inputs: currently-drawing-sky (true only inside the Sky leaf — weather emitters draw immediately there; *.parts.log is the oracle for which emitters ever appear immediate), the delay mask (one owner, default 0x0E, no environment read), detail-surface presence (the active detail owner from VisualMaster), MultiPassAlpha (one owner, false), the spec §2 constructed mask from the DAT surface type and the polygon's stippling, and the material's has_alpha. Row 1 draws never touch a list. Truth-table test over every (mask 0x000x09) × delay 0x0E × sky × detail × multipass × has_alpha cell in spec §4, each row with a mutation text.

C4 — transparent EnvCell subsets go through the same router (spec §6: the environment detail surface makes eligible subsets immediate).

C5 — register. AP-34 deleted; any row describing the distance sort deleted; retail's non-restored material after a flush is a no-op under Vulkan's per-batch material binding — a code comment at the drain, not a row, unless the implementer can argue a visible effect.

Must NOT: keep any distance anywhere on the alpha path; "recover" a capacity overflow; touch S4-c1's punch/seal machinery; add flush sites beyond the four; read an environment variable for the delay mask.

Tests (each with a mutation text showing the pin fails without the change — feedback_every_new_pin_must_be_shown_to_fail): FIFO beats reversed distance in one cell; equal-key stable tie; two cells where a global sort disagrees with traversal; particle/object/transparent-cell overlap; DrawBuilding 0f flush; pre-clear and final flush; the 0.75 valve exactly at the boundary count from fact 2 (and one below it: no-op); alternating blend modes across Vulkan batches; capacity 3000 overflow drops the subset; the router truth table; the new event kind's ordering.

Gate G-c2 (the chunk's real proof): extend S4-c1's automated alphadepth transcript gate from PM/PC to AM/FL — per capture frame, the sequence of (flush site, threshold) and, per flush, the drained entry count PER LIST must match the capture's AM/FL stream; a diverging pose is tagged KnownFailure with a written explanation, never weakened. Then the walk/ depth/alpha suites, Release build, the validation self-gate at the S3-closed poses diffed against the S3-closed run, and a stationary-phase soak A/B against the S4-c1 binary (removing the sort must not regress; #463's turn-phase rule).

Lenses: one Sonnet implementer; two sequential review lenses on the session model (retail-faithful — every predicate quoted; production — allocation, the scratch budget, the gate's honesty); each lens returns PASS/FAIL with file:line findings; two fix rounds maximum, then the ledger.

9. S4-c1 fix round 2 (lead, 2026-09-03 23:05 — the LAST round; a third stops the chunk and writes it up)

Round 1 (2bd353234) verdicts: retail-faithful lens PASS, production lens PASS, gate-honesty lens FAIL. All findings converge on the transcript gate's terrace-edge row plus one pin gap. Fix these, nothing else:

R2-1 (blocking, gate honesty). The terrace-edge KnownFailure write-up (test doc comment and commit body) claims "the PC sequence matches exactly"; it does not — PC diverges in the same counter field (expected [(0,2,0),(0,2,0)], actual [(0,0,0),(0,0,0)]), and the PM assert throws before the PC assert runs, so the test never printed both sequences as §7 F3 required. Resolution: R2-2 below removes the divergence; whatever remains must be asserted so that BOTH sequences are always compared and printed together (collect both diffs, one assertion message), and every written claim about a sequence must be one the test actually evaluated.

R2-2 (major, both PASS lenses). The terrace-edge divergence is a harness initial-condition choice: retail's portalsDrawnCount (wo(008719b4)) is a persistent session value that the capture's FIRST PC/PM line already carries (cathedral 0, foundry 1, holtburg 2, terrace 2, cathedral-stair-arch 8). Seed WalkFrameDriver.PortalsDrawnCount from the fixture's first observed counter before the ONE replay pass (the field is settable from the test assembly), delete the two-pass "priming" replay, and re-run all poses. Expected: terrace-edge turns green with NO KnownFailure tag; every other pose stays exact by the same arithmetic the passing poses already prove. If any pose still diverges after seeding, it keeps a KnownFailure tag AND its divergence is written into THIS section (not only into a doc comment) with both sequences quoted.

R2-3 (major, retail lens). T2's five cases do not discriminate "every vertex lies on SOME plane" (per-vertex OR, AND across vertices) from retail's "every vertex lies on the SAME plane", and real DAT content exists where they disagree. Add the discriminating case to T2 and to the punch pin: a polygon whose every vertex is on a ±12 plane but not all on the same one, e.g. [(12,0,3), (0,12,3), (12,5,3)] — ADMITTED by retail's four per-plane accumulators (no accumulator survives: x+12 is cleared by vertex 2, y+12 by vertex 1). Mutation text: implementing the per-vertex-OR form rejects it (assert flips).

R2-4 (sixth pose). The campaign branch now carries docs/research/2026-09-01-overhaul/oh-capture/cathedral-stair-arch.walk.log + .alphadepth.log (commit 4f12cd06b on claude/campaign-w-retail-frame-walk; also .pmverts.log at 3a6aa7eef) — the #464 artifact pose, root 0xF4180114, seven outside views, sixteen building punches (twelve rejected by the guard on local y=12.000) and eight seals with counterBefore 0..7, steady-state counter 8. Cherry-pick those two capture commits into the impl worktree (git cherry-pick 4f12cd06b 3a6aa7eef; if either conflicts on README.md, keep both rows) and add AlphaDepthTranscript_CathedralStairArch_MatchesRetailFrame2 as a sixth Fact. The lead already ran it against 2bd353234 with the capture copied in: PASS (the seed value 8 comes from the fixture under R2-2).

R2-5 (comment truth, minor ×4). (a) RetailPViewPassExecutor.DrawPortalDepthWrite's summary still describes the retired ">=3 vertices" enumeration and DrawExitPortalMask's summary still promises the counter "always matches what reached the GPU" — both false after F2; fix the text. (b) The F2 pin's doc comment names a mutation that would NOT fail (moving submitted++ after DrawDepthFan is unobservable — void return, no throw); say so, keep only the mutation that fails (restoring the <3 pre-filter). (c) WalkVisibilityMath's doc comment states DAT-scan figures as exact facts that an independent scan does not fully reproduce; state each figure WITH its counting rule (what is counted, over which id range, how unresolvable polygons are treated) or keep only the figures both scans agree on (2,889 any-vertex / 2,163 all-on-one-plane / 100 % exits / 0 interior). (d) The commit body must not cite "register tests 52/52" as evidence — no test reads the register; register truth is the human read (no row changes; AD-119 unchanged).

Not in scope: anything under src/ beyond R2-5(a)'s comments; the seal path's test-side reproduction (accepted as-is under F3's "recording leaf" wording); the lead's punch-geometry scratch dump (stays in s4-c1-gate, never committed).

Gates (all reproduced by the lenses, none claimed vacuously): Release build 0 warnings; hermetic lane green; InstalledDat lane with ONLY the pre-existing #383 ×2, TowerAscent, #458 KnownFailure failures (terrace-edge must no longer be among them); all six transcript Facts green; the shader classes green. One commit on top of 2bd353234 in s4-c1-impl.

Lenses (sequential, session model, narrowed to the round-2 diff): retail-faithful (R2-3's predicate and R2-2's seeding argued from the bytes/decomp — the counter's persistence across frames at PView::DrawCells and the reset site), gate-honesty (every sentence in the commit body and every test doc comment is something the tests evaluate; both sequences compared together), production (no allocation/behavior change outside the test project except R2-5(a) comments).

§10 (the implementer's S4-c2 landing note) lives in the chunk commit 048d5b12f in worktree s4-c2-impl and arrives with the cherry-pick; §11 below was written on the campaign branch so the fixer reads it from here.

11. S4-c2 fix round 1 (lead, 2026-09-04 — after the two-lens review of 048d5b12f; round 1 of the two the plan allows)

Verdicts on 048d5b12f (worktree s4-c2-impl, on 766f9e749): retail-faithful lens FAIL (one blocking, four major, three minor — every predicate of the core port confirmed exact against the bytes: AddMeshToAlphaList @0x0059C230 list select/capacity/return, FlushAlphaList @0x0059D2E0 early-return test ah,5; jp = strict-less on BOTH counts so 2250 drains, CLIP-then-ALPHA drain, DrawMesh @0x0059D4A0 rows 15, the four call sites' bytes and symbol ranges, ::flush = 0.75f @0x820ed0, s_AlphaDelayMask = 0x0E @0x820d88, MultiPassAlpha = 0 @0x81ef96, alwaysDrawObjects = 1 @0x820ed4, SortCellExit placed at DrawBlock's 0x5a19e6 DrawSortCell → 0x5a1a07 FlushAlphaList under the same gate); lead verification agrees on every one of those and adds the C4 ruling. Production/gate lens: see the addendum at the end of this section when it reports. The failures are at the three call sites, the register, and the gate's CI value — the list/router/flush core stands.

Items (each is a contract; quote decomp predicates, never paraphrase — feedback_quote_decomp_predicates; every new or changed pin carries a mutation text in the commit body — feedback_every_new_pin_must_be_shown_to_fail):

M1 (BLOCKING) — the particle site throws on a data-driven row. ParticleRenderer.TryAppendMeshDraws (ParticleRenderer.cs:645-663) appends EVERY renderData.Batches[i] with IndexCount > 0 and an assigned texture; ObjectRenderBatch.Translucency is the mesh classification (ObjectMeshManager.cs:2253), so TranslucencyKind.Opaque is an ordinary value for a FullMesh particle GfxObj → MaskFromTranslucencyKind(Opaque) = 0x00Route(..., mask 0x00, materialHasAlpha:false) → row 5 Immediate → the InvalidOperationException at ParticleRenderer.cs:361-372 fires in the render loop. Retail defines row 5 (0x0059d58c RenderMeshSubset, draw now) and row 4 ((delayMask & 4) != 0 && material != 0 && *(material+8) != 0 → append ALPHA). Fix: (a) delete the throw at BOTH sites (ParticleRenderer.cs:361-372, WbDrawDispatcher.SubmitToAlphaQueue) — a router row is a data-driven outcome, never an invariant (feedback_retail_dispatch_is_data_driven); (b) for particles derive materialHasAlpha from retail's particle material: find where the emitter's CMaterial is created/translucency set (grep ParticleEmitter:: / CParticle / CMaterial::has_alpha in the named pseudo-C; has_alpha is the field at +0x8 DrawMesh row 4 reads) and QUOTE the rule (expected: a particle whose translucency < 1 or whose material carries alpha has has_alpha != 0 → row 4 ALPHA; a fully opaque particle material → row 5 immediate); (c) implement the immediate outcome for rows 1/5 at the particle site by drawing the submission now through the existing non-deferring particle draw path (the same code DrawOrdered/DrawOrderedRhi uses for one submission) — no new renderer; (d) pins: an Opaque-classified mesh-particle batch with has_alpha routes to ALPHA and is drawn at the flush; the same batch with no material alpha draws immediately and never enters a list; mutation text for each.

M2 (MAJOR) — the CLIP list is structurally unreachable for ordinary content, undeclared. WbDrawDispatcher.IsOpaque(t) => t == Opaque || t == ClipMap (WbDrawDispatcher.cs:3567) keeps every clip-mapped subset out of _translucentDraws/SubmitWalkAlphaInstance; retail's ConstructMesh gives them mask 0x08 → row 3 → CLIP, and the six captures show 4,183 of 10,556 AM lines on CLIP (e.g. the §10 quotes (DrawBuilding,0,158,452): 158 CLIP entries acdream reports as 0). Fix (no pipeline change in this round — the alpha-to-coverage treatment of clip-mapped surfaces predates S4 and is a VisualMaster-era translucency decision): file a NEW AP row stating exactly this — clip-mapped GfxObj/scenery/building subsets draw immediately on the OpaqueAlphaToCoverage pipeline and never enter retail's CLIP FIFO; consequence = compositing in draw-call order instead of retail's deferred CLIP drain (depth-writing cutouts, so ordering is mostly invisible; edges differ by the older alpha-to-coverage choice); the only CLIP-list feeders left are clip-mapped mesh PARTICLES; cite D3DPolyRender::ConstructMesh 0x0059DFA0 / DrawMesh 0x0059D4A0 row 3 / AddMeshToAlphaList 0x0059C230 — and correct AP-236's sentence "the ONE residual AP-34 documented that this chunk does NOT fix" (false: there are two, this and EnvCell).

M3 (MAJOR) — contract C3's detail-surface input is hardcoded false and the drain applies detail. Retail DrawBuilding @0x0059f2a0: 0059f2eb curr_detail_surface = building_detail_surface; 0059f30b FlushAlphaList(0f); 0059f31d CPhysicsPart::Draw(parts,1); 0059f336 CPhysicsPart::Draw(parts,0); 0059f345 curr_detail_surface = nullptr → with a non-null building detail EVERY shell subset takes row 1 (immediate, WITH detail); the delayed replay always passes detailEnabled = 0 (FlushAlphaList @0x0059d3c7/@0x0059d45d call RenderMeshSubset(..., 0, entry.clip, ...)). acdream: SubmitToAlphaQueue passes detailSurfaceActive:false while building shells DO reach the alpha path (WalkClassify.cs:310 detailCategory = entity.IsBuildingShell ? 1u : 0u) and DrawPreparedAlphaBatchRhi (WbDrawDispatcher.Rhi.cs:642-694) runs the detail pass ON THE DRAIN — the exact state spec §4 says replay never has. Fix: (a) router input detailSurfaceActive = entity.IsBuildingShell && RetailDetailTextureContract.ShouldRender(_buildingDetailEnabled(), _buildingDetail) at both Wb sites (the walk site knows the entity; DeferTransparentGroups must carry the category per instance — it already has DetailCategories); (b) row 1 for a translucent building-shell instance = draw it NOW at its own turn (adaptation: retail draws the subset in place inside the mesh; the walk's opaque instances are stream-batched, so "now" = at the entity's stream mark, i.e. when Replay reaches that instance's AlphaSubmitMark) through a new single-instance immediate draw on the alpha source — bind the blend pipeline, one indirect draw, then the detail pass — reusing DrawPreparedAlphaBatchRhi's pipeline/detail code; (c) the drain never applies detail: delete the hasDetail/DrawBuildingDetailRangeRhi branch from DrawPreparedAlphaBatchRhi (retail replay is detailEnabled = 0); (d) a register row for the "in place → at the entity's stream mark" granularity adaptation; (e) pins: a translucent building-shell instance with building detail ON draws at its turn with the detail pass and never enters a list; with detail OFF it is appended and drained WITHOUT detail; an ordinary (non-shell) translucent instance is unaffected by the detail flag; mutation texts.

M4 (MAJOR) — IsFirstForList has the wrong quantifier. Retail: 0059d4cc arg3 = 1; 0059d4d0 var_c = 1 at DrawMesh ENTRY, cleared after the first append to each list within THAT call (0059d5ef if (var_4_1 == 0) var_c = 0; else arg3 = 0;); spec §5: "Each DrawMesh invocation owns two independent first-for-this-list flags"; the captures: new=1 on 9,685 of 10,556 AM lines — impossible under "first since the last drain" (RetailAlphaQueue.TryAppend isFirstForList = target.Count == 0). Each acdream append is one instance = its own DrawMesh call, so the truthful port is IsFirstForList = true on every append — or delete the field. Fix: choose one, fix the doc comments (RetailAlphaEntry, RetailAlphaQueue.TryAppend, WalkAlphaDepthTrace's "new" comment), delete or rewrite TryAppend_FlagsOnlyTheFirstEntrySinceTheLastDrain (a pin of the wrong semantic), mutation text if a pin remains.

M5 (MAJOR) — gate G-c2 has no CI signal. All six AlphaFlushTranscript_* Facts are Status=KnownFailure, so the ONE dimension the harness proves (the (site, threshold) sequence) is excluded from the hermetic lane and expected-red in InstalledDat; a future site-sequence regression is invisible. Also the sequence contains zero SortCellExit entries in every pose (0 < 2250 on both sides), so the gate exercises nothing the chunk added. Fix: split over the SAME replay into AlphaFlushSites_<pose>_MatchesRetailFrame2 (live in the lane, asserts (site, threshold) only) and AlphaFlushCounts_<pose>_MatchesRetailFrame2 (KnownFailure). Rewrite the KnownFailure reason truthfully in the Facts' doc comments AND packet §10: the counts can never match by construction — (1) this harness has no mesh content, (2) acdream appends one entry per INSTANCE where retail appends one per SUBSET per DrawMesh, (3) acdream's CLIP list is empty for ordinary content (M2) — not "harness content only". Add ONE live pin that exercises the valve the chunk added: a driver test where ≥2250 entries sit in a list when the SortCellExit event replays and the drain fires there (and 2249 does not) — RetailAlphaQueueTests has the boundary; this one goes through WalkFrameDriver.Replay's SortCellExit arm; mutation text.

M6 (MAJOR) — contract C4 (EnvCell) is smaller than claimed; do it. Retail DrawEnvCell @0x0059f1c2 sets curr_detail_surface = environment_detail_surface (may be null) before DrawMesh @0x0059f212 and clears it @0x0059f21a: detail ON → row 1 immediate (acdream already matches — EnvCellRenderer.Rhi.cs:254 detailEnabled); detail OFF → row 3 append (mask from the cell surface: alpha-family → 0x02 ALPHA). EnvCellRenderer.RenderTransparentOrdered(IReadOnlyList<uint>) (EnvCellRenderer.cs:828) already replays a cell's transparent batch on demand, so no "new deferred-replay abstraction" is needed. Fix: an EnvCell IRetailAlphaDrawSource owned by RetailPViewPassExecutor: WalkProductionLeafRenderer.DrawCellShell (RetailPViewPassExecutor.WalkLeaf.cs:262) appends ONE token (the cellId) to ALPHA when detailEnabled == false (route through the router with the shell's mask so the decision is the table's, not a hand-coded branch), draws immediately when detailEnabled == true (today's path); PrepareAlphaDraws collects the cell ids in token order; DrawPreparedAlphaBatch(first, count) calls RenderTransparentOrdered on that slice. One token per cell is coarser than retail's per-subset entries — AP-236 shrinks to exactly that granularity residual (rewrite the row; drop its "substantial separate architecture change" text). Pins: detail-off cell shell is drained at the next AlphaBarrier/LandscapeFlush/pass end and never before; detail-on draws at its turn; a particle appended between two cell tokens keeps its position (adjacent-only batching); mutation texts.

M7 (MINOR) — AP-237's only cited example is disproven. TranslucencyKind.cs:65-68 records cloud surface 0x08000023 as Type=0x10114 = ADDITIVE|ALPHA|TRANSLUCENT|BASE1_CLIPMAP; 0x10114 & 0x10300 ≠ 0 → retail mask 0x02 → ALPHA — identical to the port. The abstract class (Translucent+ClipMap with NO alpha-family bit) may still exist: run a DAT scan over every Surface (SurfaceType bits: Translucent 0x10, Base1ClipMap 0x04, alpha family 0x00010300) and either cite a real instance (id, type, where used) or rewrite AP-237 as "no known instance in the installed DATs (scan date, count scanned)"; delete "extremely narrow… only known example is the cloud GfxObj".

M8 (MINOR) — citations and register convention. (a) RenderDeviceD3D::DrawBlock is @0x005a17c0 (symbols.json); 0x005a18d0 is its loop head — fix RetailAlphaQueue.cs:41, RetailPViewPassExecutor.cs:350, WalkEvents.cs:159, WalkFrameDriver.cs:242,1479, RetailFrameWalk.cs:250. (b) RetailAlphaQueue.cs:39-50 label the CALL instructions (0x0059f30b / 0x005a1a07 / 0x005a4872 / 0x00453b8b) as "return site"; the return addresses are +5 (0059f310 / 005a1a0c / 005a4877 / 00453b90) — say "call at … (returns to …)". (c) Register: keep ~~AP-34~~ struck through with "RETIRED 2026-09-04 (S4-c2) — residuals AP-236 / AP-237 / <M2's new row>" per the register's own convention (see ~~AP-28~~, ~~AD-23~~), fix AP-236's lead sentence ("retired, not narrowed" contradicts its content), and update the "## 3. Approximation (AP) — N active rows" header count. (d) docs/architecture/worldbuilder-inventory.md:420 cites AP-34 — update it (that file is added to this round's allowed list).

Gates (real output lines in the commit body; a lens reproduces each): Release build 0 warnings; hermetic lane green; InstalledDat lane = the four pre-existing failures + the six AlphaFlushCounts_* KnownFailure Facts (and NOTHING else — the six AlphaFlushSites_* Facts pass in the lane); shader classes; RetailAlphaQueueTests, RetailAlphaMeshRouterTests, RetailFrameWalkTests, WalkFrameDriverTests, ParticleRenderer*Tests, EnvCellRenderer*Tests classes green. Allowed files: src/AcDream.App, tests/AcDream.App.Tests, docs/architecture/retail-divergence-register.md, docs/architecture/worldbuilder-inventory.md (line 420 only), this packet (§10 correction + a "§11 result" note). One commit on top of 048d5b12f in s4-c2-impl. Must NOT: reintroduce any distance; change the alpha-to-coverage classification of clip-mapped surfaces (M2 is a register row this round); touch S4-c1's punch/seal machinery; add flush sites.

Lenses after the round: retail-faithful (narrowed to M1/M3/M6's decomp claims and the router inputs) and production/gate-honesty (the six live Sites Facts, the valve pin, the immediate-draw paths' allocation, the register). A third round stops the chunk (plan §5).

11.1 Addendum — production/gate-honesty lens (reported 2026-09-04 ~10:45, VERDICT FAIL; all four claimed gates reproduced; four mutation checks re-performed; lead verified A1 and A2 at the source)

A1 (MAJOR) — a third FlushLandscapeAlpha caller the gate never sees, mislabelled. RetailPViewRenderer.cs:485: if (ctx.RootCell.IsOutdoorNode) passes.FlushLandscapeAlpha(); — the #132 outdoor-root drain after DrawDynamicsLast, before DrawUnattachedSceneParticles(ctx, outdoorCells:false). It flushes under the LandscapeFlush label (PView::DrawCells @0x005a4872), but that retail flush runs ONLY inside outside_view.view_count > 0 on the INTERIOR PView; an outdoor root has no such call (terrace-edge's capture: zero 005a4877 FL lines). Retail's outdoor-root drains are DrawBlock's 0.75 valve per cell and SmartBox::RenderNormalMode's FlushAlphaList(0f) @0x00453b8b at the pass end — which acdream already performs in RetailAlphaQueue.EndFrame. Fix: delete the :485 call if (verify and quote) EndFrame's RenderNormalMode flush runs after DrawUnattachedSceneParticles and before any further opaque world draw (then #132's "drain after the finished opaque world" invariant is kept by the pass-end flush alone, and the interior unattached emitters join the same final drain as retail); if some opaque draw intervenes, keep ONE drain but label it RenderNormalMode, move it after those draws, and file a register row for the relocation. Pin at the renderer level (not the driver gate): an outdoor-root DrawInside produces flush sites [DrawBuilding×N, RenderNormalMode] and never LandscapeFlush; mutation text.

A2 (MAJOR) — register id collision. AP-236 was filed AND retired on main by #132 (e102fb363; docs/ISSUES.md:19978 "register AP-236 retired in the same commit"). Ids are never reused. Renumber the chunk's AP-236 → the next free id and AP-237 → the one after (the register's highest live id is AP-235; verify by grep over ^| ~*AP- before choosing), fix the dangling register row AP-236b citation at RetailAlphaMeshRouter.cs:101, keep ~~AP-34~~ struck through per the convention (M8c), and recount the "## 3. Approximation (AP) — N active rows" header honestly (it reads 161 while the live count is 157/158 — state the real number).

A3 (MAJOR) — the unreachability enumeration at WbDrawDispatcher.cs:2474 is wrong. MaskFromTranslucencyKind returns only 0x08 / 0x00 / 0x02; it never sets 0x01 and never returns 0x04; 0x08 and 0x00 are filtered upstream by IsOpaque, so the only reachable mask there is 0x02. Rewrite the comment to the truth (with M1 the throw is gone anyway; the comment must describe what CAN reach the router and why each row is or is not reachable).

A4 (MINOR) — ApplyScratchRetention(observedClip + observedAlpha, observedClip + observedAlpha) at RetailAlphaQueue.cs:330 and :408 passes the ENTRY count as observedSourceCount, so _sources/_sourceDrawOffsets never shrink (HEAD~1 passed the real source count). Capture _sources.Count before Clear() and pass it.

A5 (MINOR) — text truth. WalkStaticStreamPopulatorTests.cs:554 banner still says "same viewer distance"; §10's inline sequences are off by one (foundry-deep ×10 should be ×11 for its 12 DrawBuilding entries; holtburg-doorway-still ×5 should be ×6 for 13); the commit body's "6 cases" for the hand-traced Theory is 5, and the 2250 mutation's first failing assertion is RetailAlphaQueueTests.cs:197 (PendingCount), not :198. The new commit body states each mutation's ACTUAL first failing assertion.

A6 (MINOR) — WalkAlphaDepthTrace parses new= into AmEvents[i].IsNew and never uses it. Either use it (after M4: with per-append new = true a comparison is meaningless — say so) or drop the column and its comment; no dead parse presented as evidence.

A7 (MINOR) — RetailAlphaMeshRouterTests.cs:159-166 "independent oracle" is the same if-chain restated. Replace IndependentReferenceRoute with a hand-written expected-decision TABLE transcribed from spec §4 (one literal row per (mask, sky, detail, multipass, hasAlpha) cell, no control flow), or delete the word "independent" and the sentence "each of the five rows' conditions was flipped in turn and this test failed every time" unless every flip's failing text is in the commit body.

A8 (NOTE, no action) — the non-deferring particle path keeps ParticleSubmissionOrdering.Sort (ParticleRenderer.Rhi.cs:298); it is outside the queue and pre-existing. M1's immediate draws for rows 1/5 must not add a sort (retail's immediate RenderMeshSubset draws in mesh order).

Gate additions for this round: the renderer-level A1 pin; the register grep proving no id collision (grep -c "^| ~*AP-<new>" == 1 for each new id). Allowed files unchanged except RetailPViewRenderer.cs (A1) and its tests.

12. S4-c2 fix round 2 (lead, 2026-09-04 — FINAL allowed round; any further code-fix finding stops the chunk and is written up)

Input under review: 048d5b12f (chunk implementation) plus cc8e5677a (fix round 1), clean in s4-c2-impl and directly descended from S4-c1 766f9e749. The lead verified the paired binary before writing this contract (C:\Users\erikn\Downloads\acclient.exe matches the exact retail PDB).

Sequential verdicts on cc8e5677a: retail-faithful FAIL (two major, five minor); production/gate-honesty FAIL (six major, three minor). The Release build, hermetic lane, InstalledDat identities, shader lane, allowed file scope, core two-list FIFO, strict-less valve, and the three re-performed round-1 mutations all pass. Fix ONLY the items below. This is round 2 of the two allowed by §8/the campaign process.

12.1 Retail facts that bound the fix

  1. CMaterial::CheckAlphaValues @0x005396a0 uses fcomp 1.0; test ah,5: any material-alpha channel below 1 sets has_alpha; channels at or above 1 leave it clear (unordered does not take the claimed else path). Production particle opacity is clamped to [0,1], so the top-byte != 0xff predicate is behaviorally exact only under that stated domain. SetTranslucencySimple @0x005396f0 writes the same 1-translucency value to all four channels; Particle::Update @0x0051c290 reaches it through CPhysicsPart::SetTranslucency at the call 0x0051c79d.
  2. A row-5 opaque immediate subset reaches RenderMeshSubset @0x0059ca10 and SetSurface @0x0059c4d0. For opaque/no-material-alpha the paired bytes at 0x0059c6e4..0x0059c6f9 and 0x0059c7b7..0x0059c806 select ONE/ZERO, disable alpha blending, and pass depth-write 1 to SetDepthBufferMode (call at 0x0059c866). Immediate timing on an alpha/no-depth-write pipeline is therefore NOT a faithful row-5 port.
  3. DrawEnvCell @0x0059f170 installs environment detail at 0x0059f1c2, calls DrawMesh at 0x0059f212, and clears detail at 0x0059f21a (fallback 0x0059f287). With detail absent, list selection is still the exact constructed per-subset mask. ConstructMesh @0x0059dfa0 maps an alpha-family surface to 0x02, then a pure Base1ClipMap surface to 0x08; DrawMesh row 3 sends 0x08 to CLIP. Canonical installed-DAT witness: cell 0xF4180104, surface 0x08000BFF, type BASE1_CLIPMAP (0x4), including eight reversed-side copies (see oh2-cellstruct-surface-contract.md). The extracted TextureBatchData.RetailSurfaceMask already preserves this fact; the App upload currently discards it.
  4. DrawMesh initializes two independent first-for-list flags at entry and clears a given flag after the first append to that list within the same DrawMesh call. The capture's 9,685 new=1 / 871 new=0 entries prove that it is not “true for every subset.” The port may continue to omit this unread optimization flag, but every comment and evidence claim states the actual quantifier.
  5. PView::DrawCells' LandscapeFlush at call 0x005a4872 is inside the nonzero outside-view branch. An outdoor-root frame has DrawBuilding barriers and the final SmartBox::RenderNormalMode drain, not a LandscapeFlush; no opaque world draw follows the removed call before RetailAlphaQueue.EndFrame performs that final drain.

12.2 R2-1 — opaque particle row 5 must use opaque depth state

Add the mesh-particle opaque pipeline beside the existing mesh alpha/additive/ inverse pipelines, using the existing particle_mesh shaders and vertex layout, GpuBlendMode.None, depth test ON, depth write ON, retail world compare, the existing dynamic per-batch cull override, and no alpha-to- coverage. Row-5 immediate mesh submissions bind this pipeline. Do not change billboard behavior, queued row-4 replay, additive/inverse replay, the pre-existing non-queue DrawOrderedRhi sort, or add a shader.

The production pin must drive DeferToRetailAlphaQueue (not only RouteParticleSubmission): an opaque mesh particle with alpha <1 appends to ALPHA, draws once at flush, and never invokes the immediate draw; the same mesh at alpha 1 invokes immediate once, appends nothing, and binds a pipeline whose description proves Blend=None and Depth=(test true, write true). Restoring the throw, deleting the immediate call, or selecting the old _meshAlphaPipeline must each fail a named assertion. Correct the M1 comments: at this hardcoded scene/no-detail/no-multipass site only row 5 is reachable as Immediate; row 1 is not.

12.3 R2-2 — EnvCell routing is exact per subset and replay is list-filtered

Carry TextureBatchData.RetailSurfaceMask into ObjectRenderBatch at the existing upload boundary. The detail-off cell-shell path scans the real transparent render batches and applies RetailAlphaMeshRouter.Route to each batch's retained mask. It may coalesce only to at most one token per (cellId, RetailAlphaList); a CLIP token's replay draws only batches routed to CLIP and an ALPHA token's replay draws only batches routed to ALPHA. A mixed cell therefore contributes to both lists without either replay drawing the other list's subsets. Any mask whose table result is Immediate is drawn at the cell turn and is excluded from both deferred replays; do not replace the table with “detail on/off” branching. With environment detail active, eligible subsets remain immediate with their detail pass at that turn.

Use separate CLIP/ALPHA source identity, or an equivalently discriminating retained token, so CLIP-then-ALPHA adjacency cannot lose the list filter. Retain bounded, reusable scratch; no per-frame LINQ/closure/array allocation. The accepted residual is only per-cell-per-list token granularity (rather than retail per-subset tokens), not list selection. Rewrite AP-238 to say that. Rewrite AP-240 because EnvCell pure-ClipMap subsets are now genuine CLIP feeders; ordinary Wb GfxObj/scenery/building ClipMap remains the registered alpha-to-coverage structural gap.

Production pins (not a hand-constructed source-only test):

  • canonical/synthetic RetailSurfaceMask=0x08 reaches CLIP, while 0x02 reaches ALPHA;
  • a mixed 0x08/0x02 cell creates one token in each list and each drain renders only its own batch set, exactly once;
  • detail OFF draws neither deferred set before the next real queue drain; detail ON draws at the cell turn, with detail, and queues nothing;
  • a particle/ordinary source between two cell tokens remains between them;
  • hardcoding MaskAlphaFamily, inverting the production immediate predicate, or removing the replay filter fails the named assertion. Structural IL-call order and a manually assembled EnvCellAlphaDrawSource alone do not count.

12.4 R2-3 — rejected sources still participate in frame cleanup

All three production callers reserve source-owned payload before TryAppend. When a list already holds 3,000 entries, TryAppend must still register that source for the frame's reset, then return false without adding, preparing, or drawing the rejected token. Pin with source A filling ALPHA and source B making its first, rejected append: B is never prepared/drawn but is reset exactly once at flush/end/abort, and its retained payload is empty for the next frame. This test must use two sources; the existing same-source overflow pin cannot detect the leak. Preserve retail's drop/no-immediate- fallback behavior and the queue's warmed scratch-retention policy.

12.5 R2-4 — replace structural/pure claims with real production pins

  1. M3: drive both Wb production submit sites. Building shell + detail ON draws immediately at its AlphaSubmitMark, performs the detail pass, and queues nothing; detail OFF queues and drains without a detail pass; an ordinary non-shell translucent batch is unchanged by the building-detail flag. Hardcoding detailSurfaceActive=false at the production line must fail. No source-text/IL-only substitute.
  2. M1/M6: the tests in §§12.212.3 call the production dispatch methods. Keep the pure router/source tests as narrow unit coverage, but delete their false claims that a production mutation fails “here.”
  3. A1: add the positive renderer-level outdoor sequence pin through the real RetailPViewRenderer frame owner: [DrawBuilding x N, RenderNormalMode], never LandscapeFlush, with pass-end after the last outdoor particle/world contribution. Restoring the deleted direct outdoor FlushLandscapeAlpha fails this test. The existing source/IL absence test may remain but is not the positive proof.
  4. Every new/changed behavior pin has a commit-body mutation report naming the exact production mutation and the actual first failing assertion. A test that still passes the mutation is not a pin and is not claimed.

12.6 R2-5 — evidence, register, and prose truth

  • ParticleRenderer says CheckAlphaValues is <1 and explicitly bounds the equivalence to the clamped [0,1] production domain.
  • RetailAlphaQueue/trace prose gives the true per-DrawMesh first-for-list lifecycle; it does not say every append is new=1.
  • Packet §10 names the landed AlphaFlushSites_* (live) and AlphaFlushCounts_* (KnownFailure) split. Zero mesh content is sufficient to explain the present count failure. If future-content residuals are described, name only the proven ones: EnvCell's coarser one-token-per-cell- per-list replay and ordinary-Wb CLIP's AP-240 structural gap. Do not claim all acdream entries are per instance—Wb and mesh particles already submit per batch/subset instance. Fix the stale removed Fact names and the packet's off-by-one sequence multipliers.
  • AP-239 says its blend mode is unchanged but overlap-dependent compositing can be visibly different; delete “never a visual difference.” AP-238 and AP-240 change as in §12.3. Fix RetailPViewPassExecutor's stale AP-236 citation to AP-238. No new AP row is needed if the production fixes satisfy this contract; keep the one-occurrence/id-count checks honest.
  • Focused-gate prose lists the exact filters it actually runs. The round-1 claimed filter produced 123/123, not 120, and the corrected filter must explicitly include EnvCellAlphaDrawSourceTests and RetailPViewPassExecutorTests. Report the new post-fix total from output, never a forecast.
  • Add a concise “§12 result” note only after every gate below passes; it lists real output and real mutation failures, not intent.

12.7 Scope, gates, and stop rule

Allowed files: src/AcDream.App/**, tests/AcDream.App.Tests/**, docs/architecture/retail-divergence-register.md, and this packet. The Content model/serializer already retains the mask and must not be changed. docs/architecture/worldbuilder-inventory.md may change only if a now-stale S4-c2 citation introduced by round 1 must be corrected. One implementation commit on top of cc8e5677a in s4-c2-impl.

Must NOT: reintroduce distance; add a flush site; alter S4-c1 punch/seal; change ordinary Wb ClipMap alpha-to-coverage (AP-240); add alpha-to-coverage to particles; add a shader; recover an overflow with an immediate draw; hide a production gap behind an IL/source-text-only test; run a graphical client from the implementation/review worktree.

Automated gates (real output copied into the commit body/result note): Release solution build, 0 warnings/errors; hermetic lane wholly green; InstalledDat exactly 255 pass / 10 fail / 1 skip with only TowerAscent, the two #383 layout sweeps, #458 doorway, and six AlphaFlushCounts_* failures (all six AlphaFlushSites_* pass); shaders 32/32; corrected focused filter including queue/router/walk/driver/particle/Wb/EnvCell/PView production tests; the new capacity-cleanup pins; register identities/counts; warmed allocation proof for the changed immediate/filter/source paths.

Sequential lenses after implementation: (1) retail-faithful, narrowed to the row-5 pipeline and exact EnvCell per-subset mask/list; then (2) production/gate-honesty, narrowed to rejected-source cleanup, production-path mutation discrimination, scratch bounds, gate identities, register/prose, and allowed scope. Each returns PASS/FAIL with file:line findings. Because this is the final allowed fix round, any finding that requires another code change is a third round: STOP, leave the implementation unlanded, and write the chunk failure into the packet/ledger. Comment-only clarification that does not change a claim may be adjudicated by the lead; it may not conceal a behavior or test defect.

13. S4-c2 final-round result — STOPPED UNLANDED (2026-09-04)

Stop rule fired. Final-fix implementation c4cbc1d0d (directly on cc8e5677a, worktree s4-c2-impl) passed its implementer matrix, but BOTH sequential §12 lenses found code/test/register changes that would require a third fix round. Section 12 explicitly bars that round. None of 048d5b12f, cc8e5677a, or c4cbc1d0d was cherry-picked to the campaign branch; the branch's latest renderer code remains S4-c1 766f9e749.

13.1 Retail-faithful lens — FAIL

Paired executable/PDB was re-confirmed ({9e847e2f-777c-4bd9-886c-22256bb87f32}, age 1). The particle row-5 fix and exact EnvCell ConstructMesh mask/list selection are correct. The following are not:

  1. BLOCKING — a deferred EnvCell subset already draws at the cell turn. WalkProductionLeafRenderer.DrawCellShell calls DrawOpaqueCellShells before SubmitOrDrawTransparentCellShell. EnvCellRenderer's opaque pass does not exclude a non-additive IsTransparent batch, so canonical pure ClipMap F4180104 / surface 08000BFF is drawn immediately before its CLIP token is appended, then drawn again at the drain. Retail row 3 only appends. The new production fixture starts at dispatch and never executes this preceding opaque-shell call.
  2. MAJOR — CLIP/detail-immediate surface state is wrong. All non-additive EnvCell transparent ranges bind _alphaPipeline (StraightAlpha, depth-write off). Retail's pure ClipMap replay uses ONE/INVSRCALPHA, alpha test, and depth-write on (SetSurface 0x0059c6e40x0059c806; SetDepthBufferMode call 0x0059c866). Detail-active row 1 uses that same retail base state before its detail combine. The port also hardcodes overrideClipmap:true although the router's ordinary mask-0x08 row has false; replay ignores the flag. Tests assert draw counts, not bound pipeline/blend/depth/override state, and construct mask-0x08 as AlphaBlend, so the wrong state stays green.
  3. MAJOR — register/result claims are false. AP-238's “token granularity only” statement omits premature/double draw and surface-state divergence; AP-240's EnvCell “CLIP feeder” is only queue bookkeeping while the visible subset has already drawn. The implementation's §12 result repeats those claims.
  4. MINOR truth: the mesh-particle pipeline summary still says it shares the billboard depth bracket despite the opaque depth-write exception; an EnvCell test comment cites a nonexistent Assert.Empty(log).

The lens reproduced 46/46 relevant queue/particle/EnvCell/PView tests and 42/42 particle/EnvCell renderer tests. Green tests do not contradict the findings because they omit the preceding opaque pass and pipeline state.

13.2 Production/gate-honesty lens — FAIL

The second lens independently confirmed both rendering blockers and added:

  1. MAJOR — source scratch is not queue-bounded. Each fixed-list EnvCellAlphaDrawSource retains pending/prepared/draw List<uint> buffers. Payload is reserved before queue admission; after 3,000 entries TryAppend rejects, but the source continues growing and Reset only clears capacity. The queue's scratch budget/capacity therefore does not bound retained source memory under rejection pressure.
  2. MAJOR — allocation evidence is vacuous for the claimed paths. The two 0-B tests feed route flags directly into static dispatch with no-op sinks; they do not run the production EnvCell scan/filter/RHI path, and the particle test does not run DrawImmediateParticleSubmissionRhi.
  3. R2-3's rejected-first-use cleanup itself is correct for flush/end/abort; M1, M3, and A1 have material production pins; allowed scope and git diff --check pass.

This lens reproduced Release 0 warnings/errors, 81/81 focused production tests, and 32/32 shader tests. Its official hermetic no-retry run was 16,727 pass / 1 pre-existing Console.Out capture-race failure; isolated App rerun passed 6,875/6,875. InstalledDat was unavailable in that lens because the opt-in DAT environment was not configured. The implementer's clean-state evidence remains: hermetic 16,728/16,728; InstalledDat 255 pass / 10 expected fail / 1 skip; shaders 32/32; corrected focused 211/211. Those counts prove the tested behavior only; they do not repair the missing discriminators.

13.3 Disposition

  • s4-c2-impl remains clean, detached at unlanded c4cbc1d0d for evidence.
  • No code fix, cherry-pick, graphical client, validation self-gate, or stationary A/B was performed after the stop. The user-required graphical gate is deliberately inapplicable to unlanded code.
  • A technically complete next attempt would need to fix pass membership, carry exact clip/override state into an EnvCell clip/depth-writing pipeline, bound source-owned payload under rejection, add end-to-end walk-leaf plus pipeline-state/allocation discriminators, and rewrite AP-238/AP-240/result truth. That is a THIRD fix round and is NOT authorized by this campaign chunk. Resume only by an explicit owner decision that changes the process; otherwise S4-c2 is stopped and G3/G4 remain unpassed.

14. S4-c2 owner-authorized repair after the stop (2026-09-04)

Authority and base. The owner replied “Ok do fix it” after receiving the §13 stop explanation. That explicitly authorizes the otherwise-forbidden third fix round for this chunk only. It does not weaken plan §5's general two-round rule. Work from clean evidence commit c4cbc1d0d in s4-c2-impl; the campaign branch remains at stop record dc971ea2b with S4-c1 766f9e749 as its latest renderer until both review lenses pass. This exception is one bounded repair: any new code/test/register finding after its reviews stops again and returns to the owner; there is no implicit fourth round.

The lead re-read docs/architecture/worldbuilder-inventory.md before writing this contract and re-verified the surface state in the named retail decomp and the paired executable/PDB. D3DPolyRender::SetSurface @0x0059c4d0 does the following for a pure Base1ClipMap surface when overrideClipmap == 0:

  • @0x0059c724..0x0059c743 selects BLEND_ONE/BLEND_INVSRCALPHA, enables alpha test, and leaves alpha blending enabled;
  • @0x0059c73c..0x0059c75d selects alpha-test reference 100 for a paletted texture and 200 for a DDS/non-paletted texture; @0x0059c821..0x0059c838 uses GREATER_EQUAL;
  • @0x0059c7b7..0x0059c806 and the SetDepthBufferMode call @0x0059c866 keep depth test and depth write enabled for this state.

The existing prepared payload already preserves everything needed without a Content/package change: RetailSurfaceMask identifies the CLIP subset and TextureKey.PaletteId distinguishes the 100/255 versus 200/255 reference. RetailAlphaMeshRouter.Route is also decisive here: this EnvCell call site hardcodes multiPassAlpha:false, so ordinary mask 0x08 is row 3, CLIP, OverrideClipmap=false. The current hardcoded true is not an approximation.

14.1 F3-1 — a deferred EnvCell subset is absent from the opaque turn

Correct both pass-filter loops in EnvCellRenderer.RenderModernMDIInternal. WbRenderPass.Opaque admits only non-additive, non-transparent batches; WbRenderPass.Transparent admits the transparent/additive batches selected by the exact route filter. Do not change SinglePass behavior. Consequently, WalkProductionLeafRenderer.DrawCellShell may call DrawOpaqueCellShells before transparent dispatch, but canonical F4180104 / surface 08000BFF must produce no draw there, append one CLIP token, and draw exactly once at the next real queue drain.

The required production pin calls the real leaf's DrawCellShell, not the static dispatcher in isolation. It records the complete sequence through the preceding opaque call, submission, and queue drain. Mutating either pass-filter loop back to the current predicate must first fail the “no pre-drain ClipMap draw” assertion. Keep a mixed opaque + 0x08 + 0x02 cell in the fixture so the opaque subset still draws once at the turn while CLIP and ALPHA do not.

14.2 F3-2 — exact CLIP state and exact row-3 override

Add the backend blend spelling for ONE/ONE_MINUS_SRC_ALPHA (normally named premultiplied/source-over) and map it explicitly in the Vulkan blend table. Add an EnvCell CLIP pipeline using the existing mesh_modern shader and world mesh layout: that blend, depth test ON, depth write ON, retail world compare, clockwise front face with the existing per-range cull override, alpha-to- coverage OFF. Do not add a shader.

Extend the existing shader/pass-state input just enough to express retail's CLIP test: GREATER_EQUAL 100/255 when TextureKey.PaletteId != 0, otherwise GREATER_EQUAL 200/255. Preserve ordinary opaque/alpha/additive behavior. Because one MDI run cannot carry two alpha references or two base states, range grouping must include the CLIP-vs-ALPHA/additive state and the applicable reference; it must not infer state from IsTransparent alone. Detail-active row-1 replay uses the same CLIP base state before the already-established detail combine and applies the same alpha reference. Do not route a pure ClipMap subset through _alphaPipeline or _transparentDetailPipeline's no-depth base state.

Queue submission for the ordinary mask-0x08 EnvCell token carries overrideClipmap:false, exactly as the router decision says. Either retain the decision/flag in the EnvCell token or make the row-3-only invariant explicit and pinned; do not hardcode true, and do not add a generic flag that replay ignores.

Production RHI pins inspect actual GpuRecordedPipelineBind calls and the created pipeline descriptions, not only MDI counts. They prove:

  • CLIP drain: the CLIP pipeline immediately precedes its draw; blend factors are ONE/ONE_MINUS_SRC_ALPHA; depth test/write are true; A2C is false; the paletted and DDS thresholds are 100/255 and 200/255;
  • ALPHA drain remains StraightAlpha with depth write off; mixed CLIP/ALPHA replay does not cross-feed subsets;
  • detail ON draws at the leaf turn, queues nothing, and a pure ClipMap base draw still uses CLIP/depth-writing state before its detail contribution;
  • the recorded queue entry for canonical row 3 has OverrideClipmap=false.

Mutations selecting _alphaPipeline for CLIP, disabling CLIP depth write, swapping either alpha reference, using strict GREATER instead of GREATER_EQUAL, or restoring overrideClipmap:true must each fail a named assertion. Recompile the checked-in SPIR-V and run the shader contract/manifest lane if shader source changes.

14.3 F3-3 — rejected payload cannot grow source scratch

Keep the queue rule from §12.4: a rejected first-use source is registered and reset exactly once, and overflow drops rather than drawing immediately. Change the EnvCell reservation API so a failed TryAppend rolls back the just- reserved cell id (or equivalently never retains it after rejection). Accepted token indices remain stable. Pending, prepared, and draw scratch may retain warmed capacity, but each is bounded by the 3,000-entry list limit; repeated rejection cannot grow count or retained capacity beyond the one bounded geometric allocation needed for that limit.

Pins use two sources and more than one full list's worth of rejected attempts. They assert the rejected source participates in flush/end/abort cleanup, never prepares/draws, its pending count returns to zero, and its retained capacity is bounded after the rejection storm. Restoring reserve-without-rollback must fail on the first bounded-count/capacity assertion.

14.4 F3-4 — production-path allocation evidence, not delegate exercises

Delete or relabel the two vacuous 0-B claims. The replacement EnvCell warmed measurement must execute the real route scan, the real leaf submission, the real list-filtered replay, and EnvCellRenderer.SubmitRhi. The particle measurement must execute DrawImmediateParticleSubmissionRhi. Instrumentation objects from RecordingGpuDevice are not production allocations; use a preallocated/no-recording test RHI if necessary, but do not replace the production method with a no-op delegate. After warm-up, the changed hot paths must report 0 managed bytes per iteration. If production itself allocates, fix the production path rather than weakening or rewording the assertion.

14.5 F3-5 — truth, scope, gates, and return

Correct the stale particle depth-bracket summary and the nonexistent Assert.Empty(log) comment. Rewrite AP-238, AP-240, and the §12 result so they state only what the repaired production path and tests prove. Any remaining modern translation (including an alpha-reference or detail-combine mismatch) gets a divergence-register row in the same implementation commit; do not bury it in prose. No new row is needed for an exact port.

Allowed files: src/AcDream.App/**, tests/AcDream.App.Tests/**, docs/architecture/retail-divergence-register.md, and this packet. The prepared Content model/serializer and recipe-8 package format do not change; the existing TextureKey.PaletteId is the required source fact. One lead-made implementation commit on top of c4cbc1d0d; the implementer returns a clean diff and evidence but does not commit.

Must not: reintroduce viewer distance or another flush site; change the two-list FIFO/strict-less valve; change ordinary Wb ClipMap A2C (AP-240); add particle A2C; add a shader; recover overflow with an immediate draw; run a graphical client from the implementation or review worktree; touch S4-c1's punch/seal behavior.

Automated return matrix: Release solution build with zero warnings/errors; hermetic lane wholly green; InstalledDat exactly the expected known-failure set from §12 unless a named, evidenced count changes; shader classes and SPIR-V manifest green; focused queue/router/walk/particle/Wb/EnvCell/PView suite; the new whole-leaf, pipeline-state, rejection-storm, and real production allocation pins; register identity/count checks; git diff --check. The commit body names every mutation and its actual first failing assertion.

Sequential reviews: first retail-faithful against ConstructMesh/DrawMesh/SetSurface and the paired executable, then production/gate-honesty against pass membership, range grouping, bounds, allocation, mutations, scope, register, and gate output. The lead verifies every finding. Only dual PASS authorizes landing the complete S4-c2 stack, followed by a fresh campaign Release build and the graphical/soak gates. G3/G4 remain unpassed until those later gates; nothing merges to main before G4.