2200 lines
138 KiB
Markdown
2200 lines
138 KiB
Markdown
# 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.AlphaBarrier` → `FlushLandscapeAlpha` →
|
||
`_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.log` — `AM` 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: `0x59BCD6–0x59BD28` then `0x59BD40–0x59BD66` 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 `0x59BD70–0x59BD74`: only false/true-depth SEALS increment the
|
||
counter (modulo 65,536); far punches never do (already ported, S3 §8.2 B2).
|
||
`0x59BDBC–0x59BDBF`: 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 0x59BCD6–0x59BCE5:
|
||
`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 (`0x59BDBC–0x59BDBF`). `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 1–5 verbatim; delay mask
|
||
`s_AlphaDelayMask` @0x00820D88 default `0x0E`; `MultiPassAlpha`
|
||
@0x0081EF96 default false; the constructed subset mask = spec §2
|
||
(surface type bits `0x00010300` → `0x02`, `0x04` → `0x08`, `0x10` →
|
||
`0x04`, 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 `0x00`–`0x09`) × 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. S4-c2 landing (Sonnet implementer, 2026-09-04) — gate G-c2 result and open scope
|
||
|
||
**C1/C2/C3/C5 landed as specified.** `RetailAlphaQueue` is retail's own two FIFO
|
||
lists (`RetailAlphaEntry`, capacity 3000 each, `TryAppend` returns `false` and
|
||
drops the subset at capacity, `Flush(site, threshold)` implements the exact
|
||
Ghidra-verified no-op predicate — `if (clipCount < threshold*3000 && alphaCount
|
||
< threshold*3000) return;` — and drains CLIP fully then ALPHA fully, only
|
||
adjacent same-source runs batched). `RetailAlphaMeshRouter` ports `DrawMesh`'s
|
||
five-row branch table and `ConstructMesh`'s mask formula as pure functions,
|
||
independently verified against a fresh 2026-09-04 Ghidra decompile of both
|
||
functions plus `AddMeshToAlphaList` and `FlushAlphaList` (not just the
|
||
packet's own researched spec — see the commit body for the exact quoted
|
||
predicates). `WbDrawDispatcher`'s two submit sites and `ParticleRenderer`'s
|
||
one route through the router with a shared `SubmitToAlphaQueue`/inline
|
||
equivalent; **S4-c2 fix round 1 correction (M1, blocking):** the claim that
|
||
"rows 1/2/4/5 are provably unreachable there" was WRONG for the particle
|
||
site, which the round's own retail-faithful review lens caught as a
|
||
production crash. `WbDrawDispatcher`'s sites genuinely never reach a mask
|
||
other than 0x02 (`IsOpaque` pre-filters both Opaque and ClipMap upstream, so
|
||
row 3 always fires there — this part of the claim holds). But
|
||
`ParticleRenderer.TryAppendMeshDraws` applies NO such pre-filter: a
|
||
mesh-particle batch's `TranslucencyKind.Opaque` classification (mask 0x00) is
|
||
a real, reachable input, hitting row 5 (Immediate) — and the throw-on-non-
|
||
Append guard fired in the render loop. The fix round deleted both throws,
|
||
implemented rows 1/5's immediate draw at the particle site (reusing the
|
||
non-deferring `DrawOrdered` code, no new renderer), and derived
|
||
`materialHasAlpha` for row 4 from `CMaterial::CheckAlphaValues`
|
||
@0x005396a0/`SetTranslucencySimple` @0x005396f0's retail rule — a particle's
|
||
current interpolated alpha (already carried in `ColorArgb`'s top byte) stands
|
||
in for retail's live per-instance material alpha. `FlushFartherThan`, `RetailAlphaOrdering.ComputeViewerDistance`,
|
||
and every `viewerDistance` argument on the submit path are deleted. A NEW
|
||
`WalkFrameEventKind.SortCellExit` / `IWalkEventSink.OnSortCellExit` /
|
||
`IWalkFrameLeafRenderer.FlushSortCellExit` fires once per admitted land-block
|
||
cell, immediately after that cell's `OnLandscapeCellTurn` and before the next
|
||
cell's `OnLandCellTurn` — pinned by a dedicated two-block far/near ordering
|
||
test in `RetailFrameWalkTests.cs`, mutation-checked (reordering the two calls
|
||
in `RetailFrameWalk.cs` makes the pin fail with "SCX must immediately follow
|
||
its own cell's SC").
|
||
|
||
**C4 (EnvCell) — SUPERSEDED, S4-c2 fix round 1 (M6, 2026-09-04).** This
|
||
landing's original claim (EnvCell "deliberately NOT done," needing "a
|
||
genuinely new deferred-replay abstraction") was WRONG in the same round's own
|
||
two-lens review: `EnvCellRenderer.RenderTransparentOrdered` already replayed a
|
||
cell's transparent batch on demand, so no new abstraction was needed. The fix
|
||
round wired it: `RetailPViewPassExecutor.SubmitOrDrawTransparentCellShell`
|
||
routes every real transparent subset through the SAME
|
||
`RetailAlphaMeshRouter` table every other alpha submitter uses. Fix round 2
|
||
retains `TextureBatchData.RetailSurfaceMask` on each `ObjectRenderBatch`:
|
||
canonical `0x08` reaches CLIP, `0x02` reaches ALPHA, and a mixed cell appends
|
||
at most one filtered replay token per `(cell,list)`; detail-active eligible
|
||
subsets remain immediate at the cell turn. AP-34's residuals are now filed as **AP-238**
|
||
(EnvCell — narrowed to the per-cell-vs-per-subset token GRANULARITY only,
|
||
not "never through the shared queue") and **AP-239** (the mask-reconstruction
|
||
gap, formerly filed as the colliding id "AP-237" — see A2/M8c below); a THIRD
|
||
residual, **AP-240**, was filed this round for M2's separate finding: ordinary
|
||
clip-mapped GfxObj/scenery/building content never reaches the CLIP list at
|
||
all (`WbDrawDispatcher.IsOpaque` filters it out upstream). CLIP nevertheless
|
||
has two genuine production feeder families: clip-mapped mesh particles and
|
||
exact-mask EnvCell subsets. AP-239's own cited example (cloud
|
||
GfxObj `0x01004C35`) was DISPROVEN this round (M7) — its surface's alpha-family
|
||
bits win in both retail's real priority and acdream's reconstruction, so it
|
||
never actually diverges; a 2026-09-04 DAT scan found 27 real instances instead
|
||
(e.g. surface `0x08000015` on GfxObj `0x010001EC`). These residuals do not
|
||
change the affected subset's blend mode, but overlap-dependent compositing
|
||
order can be visibly different; AP-238/AP-240 state the concrete overlap.
|
||
|
||
**Gate G-c2 result, all six poses, real InstalledDat run
|
||
(`RunAlphaFlushTranscriptGate`, `WalkTraceConformanceTests.AlphaDepthTranscript.cs`):**
|
||
the flush **SITE+THRESHOLD sequence matches the capture EXACTLY for all six
|
||
poses** — same count and order of `DrawBuilding`(0f)/`LandscapeFlush`(0f)/
|
||
`RenderNormalMode`(0f) calls, and (confirming the packet's own capture-profile
|
||
prediction) **zero `SortCellExit`(0.75f) drains in any of the six captures'
|
||
frame 2** — every real per-land-cell valve call stayed under the 2250-entry
|
||
no-op threshold at these scene complexities, exactly matching this gate's own
|
||
zero-content replay. The **drained-count-per-list dimension diverges on every
|
||
0f flush for every pose** — this hermetic replay (`EmptyAlphaDepthWorldData`,
|
||
the same zero-content design the PM/PC gate it extends already uses) submits
|
||
no real GfxObj/particle content, so every observed count is `(0,0)` where
|
||
retail's capture shows real volume. Full quoted sequences (site, threshold,
|
||
clip, alpha), expected vs. actual, per pose:
|
||
|
||
- **cathedral-arrival:** expected `[(DrawBuilding,0,108,40), (DrawBuilding,0,3,0), (DrawBuilding,0,28,7), (DrawBuilding,0,7,5), (DrawBuilding,0,70,24), (DrawBuilding,0,13,0), (DrawBuilding,0,0,0), (DrawBuilding,0,0,4), (DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (DrawBuilding,0,34,7), (DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (LandscapeFlush,0,0,0), (RenderNormalMode,0,0,0)]`; actual: same 16-entry SITE sequence, every count `(0,0)`.
|
||
- **cathedral-leak:** expected `[(DrawBuilding,0,108,40), (DrawBuilding,0,3,0), (DrawBuilding,0,28,7), (DrawBuilding,0,7,5), (DrawBuilding,0,70,24), (DrawBuilding,0,13,0), (DrawBuilding,0,0,0), (DrawBuilding,0,0,4), (DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (DrawBuilding,0,34,9), (DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (LandscapeFlush,0,0,0), (RenderNormalMode,0,0,0)]`; actual: same 16-entry SITE sequence, every count `(0,0)`.
|
||
- **cathedral-stair-arch:** expected `[(DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (DrawBuilding,0,47,30), (DrawBuilding,0,21,0), (DrawBuilding,0,2,0), (DrawBuilding,0,34,27), (DrawBuilding,0,43,1), (DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (DrawBuilding,0,2,4), (LandscapeFlush,0,0,0), (RenderNormalMode,0,32,6)]`; actual: same 13-entry SITE sequence, every count `(0,0)`.
|
||
- **foundry-deep:** expected `[(DrawBuilding,0,1,0), (DrawBuilding,0,0,0)×11, (LandscapeFlush,0,0,0), (RenderNormalMode,0,18,7)]` (12 DrawBuilding entries total — **S4-c2 fix round 1 correction, A5: the landing note originally said "×10", undercounting by one against its own stated 12-entry total; 1+11=12**); actual: same 14-entry SITE sequence, every count `(0,0)`.
|
||
- **holtburg-doorway-still:** expected `[(DrawBuilding,0,12,0), (DrawBuilding,0,23,6), (DrawBuilding,0,0,0), (DrawBuilding,0,15,0), (DrawBuilding,0,0,0), (DrawBuilding,0,0,0), (DrawBuilding,0,0,1), (DrawBuilding,0,0,0)×6, (LandscapeFlush,0,0,0), (RenderNormalMode,0,33,0)]` (13 DrawBuilding entries total — **S4-c2 fix round 1 correction, A5: the landing note originally said "×5", undercounting by one against its own stated 13-entry total; 7+6=13**); actual: same 15-entry SITE sequence, every count `(0,0)`.
|
||
- **terrace-edge:** expected `[(DrawBuilding,0,158,452), (DrawBuilding,0,22,204), (DrawBuilding,0,0,0)×3, (DrawBuilding,0,22,523), (DrawBuilding,0,13,7), (DrawBuilding,0,14,5), (DrawBuilding,0,0,0)×3, (DrawBuilding,0,11,0), (DrawBuilding,0,0,0), (DrawBuilding,0,13,12), (RenderNormalMode,0,56,0)]` (14 DrawBuilding entries, no LandscapeFlush — this pose never runs a qualifying interior turn, matching its own PM/PC KnownFailure history); actual: same 15-entry SITE sequence, every count `(0,0)`.
|
||
|
||
All six `AlphaFlushCounts_*` Facts are tagged `[Trait("Status",
|
||
"KnownFailure")]`; the paired `AlphaFlushSites_*` Facts are live and pass.
|
||
The count Facts remain KnownFailure for exactly this reason, never weakened (the real
|
||
comparison runs and genuinely fails on the count dimension; the site
|
||
dimension is asserted unconditionally in the same method and genuinely
|
||
passes). Root cause is a HARNESS scope limit shared with the pre-existing
|
||
PM/PC gate, not a routing defect: closing it for real would mean feeding
|
||
`WalkFrameDriver` genuine per-pose GfxObj/particle content from the installed
|
||
DAT (the production `WalkProductionWorldData` path, not
|
||
`EmptyAlphaDepthWorldData`) — a materially larger apparatus than this chunk's
|
||
bounded scope, flagged here for a future chunk rather than attempted.
|
||
|
||
**§11 result (fix round 1, Sonnet implementer, 2026-09-04):** all items
|
||
M1–M8/A1–A8 from the campaign branch's §11 landed in one commit on top of
|
||
this landing. M1 (blocking) deleted both unreachable-branch throws and
|
||
implemented the particle site's real rows 1/4/5; M3 wired building-detail
|
||
Row 1 into `SubmitToAlphaQueue` with a new single-instance immediate-draw
|
||
path (`DrawImmediateAlphaInstance`/`Rhi`), removing the drain's own detail
|
||
branch (M3c) since detail-eligible content no longer reaches it; M6 wired
|
||
EnvCell's whole transparent shell into the SAME router/queue as one ALPHA
|
||
token per cell when detail was off, disproving this section's own "needs a
|
||
new deferred-replay abstraction" claim above; that round's false
|
||
homogeneous-`0x02` premise and whole-cell replay were then corrected by the
|
||
exact-mask/list-filtered §12 implementation; A1 deleted a mislabelled
|
||
outdoor-root `LandscapeFlush` call retail never makes there (its content now
|
||
joins the pass-end `RenderNormalMode` drain like retail's own outdoor root);
|
||
M5 split the six former `AlphaFlushTranscript_*` Facts into live `AlphaFlushSites_*`
|
||
(unconditional pass) and `AlphaFlushCounts_*` (KnownFailure, three honest
|
||
reasons instead of one) and added a live boundary pin through
|
||
`WalkFrameDriver.Replay`'s own `SortCellExit` arm; M4 deleted the unread
|
||
`IsFirstForList` field (retail's per-DrawMesh, per-list value genuinely
|
||
varies: 9,685 `new=1`, 871 `new=0`; acdream has no one-to-one retained
|
||
producer or Vulkan consumer); M2/A2/M8c retired `AP-34` (restored as
|
||
`~~AP-34~~`, not left deleted), renumbered the colliding `AP-236`/`AP-237` to
|
||
`AP-238`/`AP-239`, and filed `AP-240` for the CLIP-list-for-ordinary-content
|
||
gap M2 found; M7 disproved AP-239's cloud citation and replaced it with a
|
||
real scanned instance; A4 fixed `ApplyScratchRetention`'s source-count
|
||
argument; A7 renamed/redocumented the mesh-router truth-table oracle
|
||
honestly. See the fix-round commit body for every mutation check's actual
|
||
failing-assertion text and the real gate output lines.
|
||
|
||
**§12 result (fix round 2 plus the owner-authorized post-stop repair,
|
||
2026-09-04):** the owner-authorized repair supersedes the earlier §12 result's
|
||
EnvCell exactness, scratch-bound, and allocation claims. The repaired real
|
||
leaf path now excludes deferred non-additive transparent subsets from the
|
||
opaque pass, classifies retained ClipMap presence with `(mask & 0x08) != 0`
|
||
(including legal positive-stipple mask `0x09`), and keeps canonical row 3 at
|
||
`OverrideClipmap=false`. Its CLIP base pipeline is the paired-retail
|
||
`ONE/INVSRCALPHA`, alpha test `GREATER_EQUAL`, reference `100/255` for a
|
||
paletted texture or `200/255` for DDS/non-paletted, with depth test/write on
|
||
and alpha-to-coverage off. Both fragment shaders recognize only those two
|
||
named references (within 1e-6 for GLSL constant folding); arbitrary `0.5`
|
||
falls back to the ordinary `0.05` empty-fragment cutoff. Exact `uParamB=1`
|
||
remains `mesh_detail.vert`'s pre-existing building-category sentinel and also
|
||
uses `0.05`, so the new reference does not erase building detail. Detail-
|
||
active ClipMap replay retains the selected cutoff and a depth-writing clip
|
||
base before the detail contribution. ALPHA remains straight-alpha with depth
|
||
write off and the two subsets do not cross-feed.
|
||
|
||
Rejected EnvCell reservations now roll back the tail cell id while keeping
|
||
the source registered for exactly one flush/end/abort reset. Storm coverage
|
||
uses two sources, 3,000 accepted tokens, and 9,000 rejected attempts; rejected
|
||
pending count returns to zero, retained capacity stays at or below 4,096 (the
|
||
bounded geometric backing for the 3,000-list limit), and rejected payload is
|
||
never prepared or drawn. The allocation claims now execute the real whole-
|
||
leaf route scan, `DrawCellShell`, list-filtered replay and
|
||
`EnvCellRenderer.SubmitRhi`, and the real private particle
|
||
`DrawImmediateParticleSubmissionRhi`, against a preallocated RHI with call
|
||
recording disabled. Both report 0 managed bytes per warmed iteration. This
|
||
replaces the prior static/delegate-only evidence.
|
||
|
||
The exact state is backed by `D3DPolyRender::SetSurface` @0x0059c4d0 and the
|
||
paired executable: @0x0059c72a selects blend ids 2/6
|
||
(`ONE/INVSRCALPHA`), globals 0x00820d8c and 0x00820d90 contain 0x64 and 0xc8,
|
||
@0x0059c821 calls `SetAlphaTestEnable`, @0x0059c838 calls
|
||
`SetAlphaTestFunction` with function 7 (`GREATER_EQUAL`), and @0x0059c866
|
||
passes depth-write byte 1. No Content model, serializer, or package-format
|
||
file changed. AP-238 and AP-240 now state only the repaired production truth;
|
||
the remaining AP-238 divergence is token granularity, while ordinary Wb
|
||
ClipMap A2C remains AP-240 and is unchanged.
|
||
|
||
Real clean-state return matrix:
|
||
|
||
- Release solution build: `Build succeeded`, `0 Warning(s)`, `0 Error(s)`.
|
||
- Hermetic lane: every project green, `16,735 passed / 0 skipped / 0 failed`
|
||
across 14 assemblies; App `6,882/6,882`.
|
||
- InstalledDat: exactly `Passed: 255`, `Failed: 10`, `Skipped: 1`,
|
||
`Total: 266`. The failures are only
|
||
`TowerAscent_StaircaseStaysConeVisible_EveryStep`,
|
||
`MainGameUiAndChatInput_MediaBearingChildrenNowBuildAsRealWidgets`
|
||
(#383), `EveryAuthoredInvisibleWidget_StartsHiddenAcrossAllLayouts`
|
||
(#383), `Oh_doorway_still_first_frame_diff` (#458), and the six
|
||
`AlphaFlushCounts_*`; every `AlphaFlushSites_*` passes.
|
||
- Checked-in SPIR-V was rebuilt with `tools/compile-shaders.ps1`: 24/24;
|
||
shader descriptor/manifest/pack validator filter: `32/32`.
|
||
- Focused queue/router/walk/driver/particle/Wb/EnvCell/PView production
|
||
filter: `239/239`. The explicit real production allocation filter is
|
||
`2/2`, and both pins assert 0 B.
|
||
- Register read: AP-238, AP-239, AP-240, AD-120, and `~~AP-34~~` each have
|
||
exactly one physical row; active physical rows remain AP=159 and AD=92.
|
||
- `git diff --check`: PASS.
|
||
|
||
Evidence-history disclosure: the first hermetic invocation was stopped after
|
||
App exposed two stale test oracles introduced by this repair: the old
|
||
`mesh_modern.frag.spv` SHA (expected
|
||
`b702b644862aca31ce1fb0677adc5872b39c4ea87f595a89363b44d10f2cc50e`, actual
|
||
`e094a966f7653a79a57d1c208f36d3100a8dcb20891584e6c74b4697e95c1950`) and the old
|
||
five-blend cardinality (expected 5, actual 6). Both assertions were corrected
|
||
to the exact new shader/state contract, then the complete lane above ran once
|
||
without an internal retry. The same evidence directory was mistakenly reused,
|
||
so script startup replaced that first invocation's TRX/log; the exact failures
|
||
remain recorded here rather than being presented as a clean first attempt.
|
||
The observed Core.Net PIDs belonged to those two separate script invocations,
|
||
not a project retry: Core.Net passed 1,077 in the stopped invocation and again
|
||
in the clean invocation. The first InstalledDat command also omitted
|
||
`ACDREAM_RUN_INSTALLED_DAT_TESTS=1` and was invalid evidence (161 pass / 8 fail
|
||
/ 97 skip); the documented environment produced the 255/10/1 result above.
|
||
A narrower exploratory focused filter hit the pre-existing global
|
||
`Console.Out` capture race once (`218 passed / 1 failed`,
|
||
`OutdoorRoot_TranscriptFlagOn_PrintsLandscapeThenLandCellThenSortCellThenBuilding_InOrder`,
|
||
"LS must precede LC"); that Fact passed isolated 1/1 and in the broader
|
||
239/239 focused run above. A direct unfiltered `WalkTraceConformanceTests`
|
||
probe also produced its seven documented InstalledDat failures and is not the
|
||
focused clean lane.
|
||
|
||
Actual owner-repair mutation failures (each production mutation was applied,
|
||
run to the named first failure, and exactly reversed before the final gates):
|
||
|
||
1. Restoring the opaque predicate to `!IsAdditive` fails
|
||
`WholeLeaf_MixedCellDrawsOpaqueAtTurnThenClipAndAlphaAtDrain`
|
||
first at draw count: expected 1, actual 3.
|
||
2. Selecting `_alphaPipeline` for CLIP fails
|
||
`WholeLeaf_ClipDrainBindsExactStateAndTextureClassReference` first at the
|
||
bind sequence: expected `[envcell-clip]`, actual `[envcell-alpha]`.
|
||
3. Disabling CLIP depth write fails that same production Theory first at
|
||
`Assert.True(clipPipeline.Depth.Write)`: expected true, actual false.
|
||
4. Swapping the palette/DDS references fails the DDS row first: expected
|
||
`0.784313738`, actual `0.392156869` (and the palette row reports the
|
||
inverse).
|
||
5. Mutating `mesh_modern.frag` from `<` to `<=` (strict `GREATER`) fails
|
||
`ClipShaders_UseGreaterEqualForThePerRangeReference` first at the preceding
|
||
`Assert.Contains("if (color.a < alphaCutoff) discard;")`: the required `<`
|
||
source spelling is absent after the mutation. The later
|
||
`Assert.DoesNotContain` is not the first failure.
|
||
6. Restoring row-3 `OverrideClipmap=true` fails the real-interface clip Theory
|
||
first at `Assert.False`: expected false, actual true.
|
||
7. Deleting failed-append rollback fails all flush/end/abort rejection-storm
|
||
rows at the first bounded pending-count assertion: expected 0, actual
|
||
9,000.
|
||
8. Selecting `_transparentDetailPipeline` for a ClipMap detail contribution
|
||
fails the leaf detail pin's bind sequence: expected second bind
|
||
`envcell-retail-detail-clip`, actual `envcell-retail-detail-alpha`.
|
||
9. Resetting detail `ParamB` to zero fails the same detail pin first at the
|
||
second pushed reference: expected `0.784313738`, actual 0.
|
||
10. Classifying CLIP with exact mask equality excludes legal mask `0x09` and
|
||
fails `WholeLeaf_PositiveStippleClipMaskUsesClipPipelineAndDdsReference`: expected
|
||
`envcell-clip`, actual `envcell-alpha`.
|
||
11. Mapping the new blend to `SRC_ALPHA/INVSRCALPHA` fails
|
||
`AllRetailBlendModesAreRepresentable`: expected
|
||
`(One, OneMinusSrcAlpha)`, actual `(SrcAlpha, OneMinusSrcAlpha)`.
|
||
12. Restoring `mesh_detail.vert`'s former `uParamB > 0.5` category predicate
|
||
fails `ClipShaders_UseGreaterEqualForThePerRangeReference` first because
|
||
`vDetailCategory = uParamB == 1.0` is absent; the DDS reference must remain
|
||
EnvCell rather than masquerading as the building sentinel.
|
||
13. Treating every positive detail `uParamB` as a cutoff fails the same source
|
||
pin first because `isRetailClipReference(uParamB) ? uParamB : 0.05` is
|
||
absent; this is the negative proof that exact building sentinel 1 is not a
|
||
cutoff.
|
||
14. Adding arbitrary `0.5` as an accepted reference to either
|
||
`mesh_modern.frag` or `mesh_detail.frag` fails that source pin first at
|
||
`Assert.DoesNotContain("value - 0.5")`; both shader mutations were run and
|
||
reversed independently.
|
||
|
||
No graphical client was launched. G3/G4 remain unpassed pending the campaign
|
||
branch's fresh build, reviews, and owner-visible graphical/soak gates.
|
||
|
||
## 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` 0x0059c6e4–0x0059c806;
|
||
`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.
|
||
|
||
## 15. Owner-authorized repair review stop (2026-09-04)
|
||
|
||
The owner-authorized implementation is clean and unlanded at
|
||
`a094bf2b77c3061288185f069fa0b5e494ee8540` in `s4-c2-impl`, on top of
|
||
`c4cbc1d0d` / `cc8e5677a` / `048d5b12f`. The lead independently rebuilt the
|
||
Release solution with zero warnings/errors, reproduced the two real 0-B
|
||
allocation pins, recompiled 24/24 shader pairs, checked the three final SPIR-V
|
||
hashes, inspected the 14-assembly 16,735/16,735 hermetic evidence, and
|
||
re-verified `SetSurface` against both the named pseudo-C and paired executable.
|
||
No graphical client was launched.
|
||
|
||
The first sequential retail lens found the repaired behavior retail-faithful:
|
||
whole-leaf opaque exclusion, `0x08`/`0x09` CLIP grouping, row-3
|
||
`overrideClipmap=false`, blend ids 2/6 (`ONE/INVSRCALPHA`), references
|
||
100/200, inclusive `GREATER_EQUAL`, depth write, exact shader-reference versus
|
||
building-sentinel separation, detail CLIP state, ALPHA isolation,
|
||
rollback/reset, particle row 5, AP-238, and AP-240 all passed. Its focused
|
||
checks passed 60/60 and 88/88. It nevertheless returned **FAIL** because §14
|
||
requires every evidence/prose claim to be exact and permits no repair after a
|
||
review finding:
|
||
|
||
1. **MAJOR — commit evidence:** `a094bf2b7` summarizes “14 negative mutations
|
||
restored” instead of naming every mutation and actual first failing
|
||
assertion as §14.5 requires. The packet has the list, but the binding
|
||
requirement says the commit body must carry it.
|
||
2. **MAJOR — mutation truth:** §12 mutation 5 says the `<` → `<=` mutation
|
||
first fails `Assert.DoesNotContain`; the test actually executes and fails
|
||
the preceding `Assert.Contains("if (color.a < alphaCutoff) discard;")`
|
||
first.
|
||
3. **MINOR — address prose:** §12 attributes function 7 / `GREATER_EQUAL` to
|
||
`0x0059c821`; that call is `SetAlphaTestEnable`. The function call is at
|
||
`0x0059c838`, as the implementation commit body correctly records.
|
||
4. **MINOR — stale source prose:** `mesh_detail.vert` still says EnvCell always
|
||
sets and ignores `uParamB=0`; CLIP now passes and consumes 100/255 or
|
||
200/255. `EnvCellRenderer.Rhi.cs` still says the filtered opaque detail
|
||
replay includes ClipMap, which the repaired pass filter excludes.
|
||
`ParticleRenderer.Rhi.cs` still says five pipelines although it creates six.
|
||
5. **MINOR — stale test prose:** `RetailAlphaMeshRouterTests.cs` says ClipMap
|
||
never reaches `MaskFromTranslucencyKind` from production; mesh particles do
|
||
at `ParticleRenderer.cs`, consistent with AP-240.
|
||
|
||
Because the retail lens failed, the production/gate lens was not started.
|
||
Correcting the commit metadata, packet, source comments, and test comment
|
||
would be a post-review fourth repair. §14 explicitly grants no implicit fourth
|
||
round, so the implementation remains unlanded, the campaign renderer remains
|
||
S4-c1 `766f9e749`, and G3/G4 remain unpassed. Resume only by another explicit
|
||
owner process decision.
|
||
|
||
## 16. Owner-authorized evidence/prose repair budget (2026-09-04)
|
||
|
||
The owner replied: “Ok but fix those and finish these. You can try 5 more
|
||
times.” This explicitly authorizes up to five additional bounded
|
||
implementation-plus-sequential-review attempts for S4-c2. It does not weaken
|
||
the retail/binary verification, dual-review, landing, graphical-gate, ledger,
|
||
or no-merge-before-G4 rules. Attempt 1/5 starts from clean unlanded
|
||
`a094bf2b77c3061288185f069fa0b5e494ee8540`; the campaign branch remains on
|
||
S4-c1 until a complete attempt receives retail PASS followed by production/
|
||
gate PASS.
|
||
|
||
### 16.1 Attempt 1/5 contract — evidence and comment truth only
|
||
|
||
Make exactly the retail lens's §15 corrections; no renderer behavior, shader
|
||
instruction, SPIR-V, test assertion, register row, package model, or gate is
|
||
weakened or changed:
|
||
|
||
1. In the §12 result, attribute `SetAlphaTestEnable` to `0x0059c821` and
|
||
`SetAlphaTestFunction(GREATER_EQUAL)` to `0x0059c838`.
|
||
2. Correct mutation 5's actual first failure: after `<` becomes `<=`, the
|
||
preceding `Assert.Contains("if (color.a < alphaCutoff) discard;")` fails
|
||
because the required source spelling is absent. Do not claim the later
|
||
`Assert.DoesNotContain` is first.
|
||
3. Update `mesh_detail.vert`: exact `uParamB=1` selects the building/object
|
||
category; EnvCell zero and CLIP 100/255 or 200/255 select the bound
|
||
environment category, and the fragment shader consumes the CLIP values.
|
||
4. Update `EnvCellRenderer.Rhi.cs`: the opaque environment-detail replay is
|
||
for the already-filtered opaque shell commands; transparent ClipMap is
|
||
excluded and takes its immediate/delayed CLIP path with its own detail
|
||
contribution.
|
||
5. Update `ParticleRenderer.Rhi.cs` from “five pipelines” to the exact six.
|
||
6. Update `RetailAlphaMeshRouterTests.cs`: ordinary Wb reconstruction still
|
||
owns AP-239, while mesh particles genuinely call
|
||
`MaskFromTranslucencyKind`; do not claim production never calls it.
|
||
7. The lead amends the unlanded implementation commit so its body names all
|
||
fourteen owner-repair mutations and each actual first failing assertion,
|
||
using the corrected mutation-5 ordering above. The implementation agent
|
||
returns an uncommitted diff and does not amend or commit.
|
||
|
||
Allowed implementation files are only the four source/test files named above
|
||
plus this packet (five files total). `git diff --check`, Release build, the
|
||
exact focused source/comment
|
||
and behavioral tests, shader/manifest tests, and the two real 0-B allocation
|
||
pins must remain green. The unchanged 16,735/16,735 hermetic and 255/10/1
|
||
InstalledDat evidence may be reused only if the diff remains prose-only;
|
||
otherwise rerun the affected complete lane. No graphical client runs from an
|
||
implementation/review worktree.
|
||
|
||
Review attempt 1 sequentially: retail/evidence lens first, then production/
|
||
gate lens only on PASS. A finding consumes attempt 1 and returns to the lead,
|
||
who writes the next bounded contract against that exact finding; up to four
|
||
further attempts remain. Dual PASS authorizes landing the full S4-c2 stack,
|
||
fresh campaign Release/hermetic/InstalledDat gates, then the graphical and
|
||
stationary-soak gates. G3/G4 remain unpassed until those steps finish.
|
||
|
||
### 16.2 Attempt 1/5 result; attempt 2/5 contract
|
||
|
||
Attempt 1's five-file prose diff is correct and remains uncommitted on clean
|
||
base `a094bf2b7`. Release passed with zero warnings/errors, the affected tests
|
||
passed 37/37, both real allocation pins passed 2/2, and `git diff --check`
|
||
passed. The shader lane correctly failed 31/32:
|
||
`CommittedSpirvIsNotStaleAgainstItsGlslSource` reports that
|
||
`mesh_detail.vert`'s source hash changed after its required comment correction.
|
||
The attempt-1 contract allowed the GLSL comment but forbade the mechanically
|
||
required manifest/SPIR-V refresh. The implementer stopped without weakening
|
||
the freshness test or touching either artifact. This contract conflict
|
||
consumes attempt 1; four attempts remain.
|
||
|
||
Attempt 2/5 retains the exact five-file diff from §16.1 and permits only the
|
||
mechanical shader-artifact closure:
|
||
|
||
1. Run `tools/compile-shaders.ps1` once from `s4-c2-impl`.
|
||
2. Permit changes only to
|
||
`src/AcDream.App/Rendering/Shaders/spv/shaders.manifest.json` and, if the
|
||
deterministic compiler rewrites it, the paired
|
||
`mesh_detail.vert.spv`. No other shader source or SPIR-V may change.
|
||
3. Verify the vertex shader's executable instructions are unchanged: if the
|
||
SPIR-V bytes change, compare/disassemble the before/after modules and prove
|
||
the difference is non-semantic metadata only; otherwise stop instead of
|
||
accepting a shader behavior change.
|
||
4. Run Release build, the complete shader/manifest lane (32/32), the 37
|
||
affected tests, both real allocation pins, `git diff --check`, and a strict
|
||
changed-file audit. The unchanged hermetic/InstalledDat evidence remains
|
||
reusable because the diff is prose plus deterministic shader metadata.
|
||
|
||
The implementation agent still returns an uncommitted diff. The lead verifies
|
||
the artifact closure and amends the unlanded implementation commit with all
|
||
fourteen mutation names/first failures. Then review attempt 2 sequentially,
|
||
retail/evidence first and production/gate second. A finding consumes attempt 2;
|
||
three further attempts remain.
|
||
|
||
## 17. Attempt 2 landing result (2026-09-04)
|
||
|
||
Attempt 2 retained the five evidence/comment fixes from §16.1 and refreshed
|
||
only `src/AcDream.App/Rendering/Shaders/spv/shaders.manifest.json` after the
|
||
one permitted compiler run. `mesh_detail.vert.spv` remained byte-identical:
|
||
SHA-256 `5346247ab7d606046943e19b28888c814e08dc6cb27cd9750096ac055457eb57`,
|
||
Git blob `5ae4f2379167f739f297d2f00189901e29d5e412`. The lead amended the
|
||
implementation evidence to name all fourteen mutations and their actual first
|
||
assertions; final reviewed implementation commit: `daaeab0ba`.
|
||
|
||
The sequential retail/evidence lens PASSED first. It independently confirmed
|
||
the paired PDB/executable GUID `{9e847e2f-777c-4bd9-886c-22256bb87f32}` age 1
|
||
and the required bytes: blend IDs 2/6 at `0x0059C72A`/`0x0059C72F`, alpha-test
|
||
enable at `0x0059C821`, `GREATER_EQUAL` at `0x0059C838`, and depth-write at
|
||
`0x0059C866`. Whole-leaf exclusion, `0x08`/`0x09` CLIP, row-3 override false,
|
||
references/sentinel/detail/ALPHA/rollback/particles/register all passed. The
|
||
production/gate-honesty lens then PASSED: real production reachability,
|
||
pipeline state, bounded 3000/4096 scratch, production 0-B pins, register truth,
|
||
and all fourteen mutations passed. Its fresh gates were Release 0W/0E,
|
||
shader 32/32, affected 37/37, allocation 2/2, production focused 239/239.
|
||
|
||
The stack landed on the campaign branch in order:
|
||
`89f1e2676` (`048d5b12f`), `9ccb61a8e` (`cc8e5677a`), `0aa166aa0`
|
||
(`c4cbc1d0d`), and `252886e84` (`daaeab0ba`). All 43 non-packet files at the
|
||
campaign tip are byte-identical to the reviewed implementation stack.
|
||
|
||
Fresh campaign gates:
|
||
|
||
- Release build: PASS, zero warnings/errors.
|
||
- Shader/manifest 32/32; attempt-2 affected 37/37; real allocation 2/2 at
|
||
0 B; focused production 239/239.
|
||
- Official no-retry 14-assembly hermetic artifact
|
||
`%TEMP%\acdream-s4-c2-campaign-252886e84`: 16,734 pass / 1 fail / 0 skip.
|
||
The sole failure is the unchanged global `Console.Out` capture race in
|
||
`WalkFrameDriverTests.Collect_WeatherTurnFiredMatchesThePrintedOcLineExactly`;
|
||
the exact theory passed 2/2 isolated. The isolated pass does not rewrite the
|
||
original lane verdict.
|
||
- InstalledDat with explicit installed DAT path: 255 pass / 10 documented
|
||
fail / 1 skip. The failures are TowerAscent, two #383 sweeps, #458, and six
|
||
`AlphaFlushCounts_*`; every `AlphaFlushSites_*` row passed.
|
||
|
||
Validation-on graphical evidence is provisional until owner review:
|
||
|
||
- `logs/selfgate-20260904-115818-s4c2-landed-route`: `00-login.png`,
|
||
`01-cathedral-stairs.png`, `02-facility-stairs.png`,
|
||
`03-holtburg-house.png`, `04-holtburg-terrain-leak.png` — PASS. Facility's
|
||
left-panel crop matches the S4-c1 control; only ordinary time/weather drift.
|
||
- `logs/selfgate-20260904-120025-s4c2-landed-g3b`:
|
||
`13-capture-terrace-edge.png`, `14-capture-cathedral-arrival.png`,
|
||
`15-capture-holtburg-doorway.png`, `16-capture-foundry-deep.png` — PASS.
|
||
Pose 15 is the intentional #468 outdoor replacement and the camera is close
|
||
to the translucent self body; owner review remains explicit.
|
||
|
||
The first tip soak
|
||
`logs/connected-r6-soak-20260904-120607.report.json` failed before its first
|
||
sample on known #462 and then reproduced known #461 during abort/logout; keep
|
||
it as a failed attempt. The retry
|
||
`logs/connected-r6-soak-20260904-120756.report.json` passed 9/9 with exit 0
|
||
and graceful teardown. The clean S4-c1 control at `9ba8f013e`, report
|
||
`s4-c1-impl/logs/connected-r6-soak-20260904-121735.report.json`, also passed
|
||
9/9 in the same session. Stationary tip-minus-control averages: CPU p95
|
||
−0.01 ms, GPU p95 +0.16 ms, allocation p50 +1.2 KiB, update p95 −0.12 ms,
|
||
working set −24.6 MiB, private memory −17.7 MiB. Per-destination CPU p95 was
|
||
within ±0.1 ms, GPU p95 within 0.0–+0.4 ms; only Caul/Sawato allocation p50
|
||
rose materially (+5.6/+5.8 KiB).
|
||
|
||
S4-c2 is LANDED and closed. Attempt 1/5 was consumed by the contract conflict;
|
||
attempt 2/5 passed; three attempts remain unused. G3/G4 remain unpassed. A
|
||
fresh landed-source audit then found that the upstream per-cell CYpt order was
|
||
still missing. Execute §18's bounded S4-c3a repair first; only afterward write
|
||
S4-c3b's deletion contract from the repaired code and re-check the
|
||
AP-238/AP-240/`AlphaFlushCounts_*` residuals there.
|
||
|
||
## 18. S4-c3a contract — restore retail's per-cell pre-append order (lead, 2026-09-04)
|
||
|
||
### 18.1 Why §4's deletion guess is not dispatchable yet
|
||
|
||
The landed S4-c2 queue is an exact two-list FIFO, but the fresh source audit
|
||
found that its upstream production order is not yet retail's. This is a missed
|
||
item from the plan's S4 chunk-2 phrase “alpha list records + insertion sort,”
|
||
not new scope:
|
||
|
||
- named retail `RenderDeviceD3D::DrawObjCellForDummies` @`0x005A0760` calls
|
||
`UpdateObjCell`, then calls `CShadowPart::insertion_sort` at `0x005A0786`
|
||
when `num_shadow_parts > 1`, before `DrawObjCell`;
|
||
- outdoor `RenderDeviceD3D::DrawBlock` @`0x005A17C0` performs the same update
|
||
and sort at `0x005A18A3` for every visible land cell before its draw loop;
|
||
- `UpdateObjCell` @`0x005A0690` updates each owning physics object's viewer
|
||
distance, and `CShadowPart::insertion_sort` @`0x006B5130` is stable and
|
||
orders descending `CPhysicsPart::CYpt` (far to near); equal CYpt retains the
|
||
pre-sort shadow-list order;
|
||
- `CPhysicsObj::add_particle_shadow_to_cell` @`0x00514A70` calls
|
||
`CPartArray::AddPartsShadow`, so scene-particle parts participate in that
|
||
same per-cell list rather than forming an unconditional cell-tail block.
|
||
|
||
Production currently reads `ShadowObjectRegistry.GetRetailPartEntriesInCell`
|
||
in registration order, collapses adjacent part rows to one entity record in
|
||
`WalkProductionWorldData.ResolveCellView`, classifies static then dynamic
|
||
records separately, and emits `CellParticles` after both. The only surviving
|
||
sort in `DeferTransparentGroups` is by retained submission ordinal; it
|
||
reconstructs an already-grouped append sequence and never computes CYpt.
|
||
Therefore §4 must not delete `LocalSortCenter` yet. First make the upstream
|
||
cell order real; c3b then deletes facts and parameters proven dead.
|
||
|
||
### 18.2 C1 — one bounded per-cell stable CYpt order
|
||
|
||
For each normal-world outdoor or interior/look-in object-list cell turn:
|
||
|
||
1. compute every eligible object part's CYpt key from its authored GfxObj
|
||
`SortCenter` transformed by that part's current model and the current world
|
||
viewpoint; squared distance is acceptable as the nonnegative monotonic key,
|
||
but do not replace the authored sort center with the entity origin;
|
||
2. stable-sort far to near within that one cell turn only; all surface subsets
|
||
of one part retain authored subset order;
|
||
3. combine static and dynamic object records before the sort—the retail cell
|
||
has one `shadow_part_list`, not two independently sorted lists;
|
||
4. never sort across cells, building turns, landscape/clear/seal barriers, or
|
||
frame scopes. The two `RetailAlphaQueue` lists remain unsorted FIFO lists.
|
||
|
||
Opaque/cutout commands may still be emitted through the ordered draw stream
|
||
and delayed subsets through the alpha submission list, but both projections
|
||
must derive from the same stable part order. A cell with no particles still
|
||
submits its sorted object alpha range. A building shell is not an ordinary
|
||
cell shadow part and keeps its existing `DrawBuilding` alpha mark/detail rule.
|
||
|
||
### 18.3 C2 — merge scene-particle alpha at the same cell turn
|
||
|
||
The existing cell particle event must prepare (not prematurely submit) that
|
||
cell's scene-particle draw records, expose each record's already-computed
|
||
authored CYpt/distance key, and merge them far-to-near with the cell's delayed
|
||
object subset records before either source appends to `RetailAlphaQueue`.
|
||
Particle subsets sharing one part key remain in authored/submission order.
|
||
The merge is stable and allocation-free after warm-up. It must preserve every
|
||
S4-c2 router outcome: billboard ALPHA, mesh CLIP/ALPHA, row-5 immediate opaque
|
||
state, capacity drop, and source-owned rollback. An earlier building barrier
|
||
must still be unable to see a later cell's staged content.
|
||
|
||
Retail's one physical shadow-list insertion ordinal across object and particle
|
||
registrations is not represented by one acdream owner today. For an exactly
|
||
equal cross-source CYpt tie, keep a deterministic stable source order and file
|
||
**AP-242** in this implementation commit; do not invent an “exact” common
|
||
ordinal. Also file **AP-241** for the narrower remaining full-list difference:
|
||
row-5 immediate particle draws and ordinary opaque/cutout object draws still
|
||
use separate Vulkan submission channels, so their relative coplanar depth
|
||
winner is not a literal replay of one interleaved `CShadowPart::draw` loop.
|
||
These rows disclose only the unported consequence after C1/C2, not the delayed
|
||
alpha order C1/C2 now make exact. Increment the register header count and add
|
||
identity/count pins in the same commit.
|
||
|
||
### 18.4 C3 — deletion/truth boundary for c3a
|
||
|
||
- Keep `ObjectRenderData.SortCenter`, `CachedBatch.LocalSortCenter`,
|
||
`WalkClassifiedBatch.LocalSortCenter`, and the per-instance/part equivalent
|
||
needed by C1. c3b deletes only fields proven unused after the exact order is
|
||
live; do not erase the evidence first.
|
||
- Remove a `cameraWorldPosition` parameter only when the replacement CYpt key
|
||
is retained on the staged record and a signature/source pin proves no alpha
|
||
submit API silently recomputes or ignores it. No `_ = cameraWorldPosition`
|
||
tombstone survives c3b.
|
||
- Keep `AlphaSubmissionOrderComparer`: it restores original submission
|
||
ordinal after material grouping and is not the deleted scope-global distance
|
||
sort. Keep building-degrade `ViewerDistanceTo`, portal-BFS distance,
|
||
opaque/private-viewport `SortDistance`, and the immediate off-screen
|
||
`ParticleSubmissionOrdering.Sort`; none is the world-alpha queue sort.
|
||
- Update `WbDrawDispatcher`, `ParticleRenderer`, `GroupKey`,
|
||
`WalkStaticStreamPopulator`, `worldbuilder-inventory.md`, and
|
||
`acdream-architecture.md` prose so world alpha is described as per-cell
|
||
CYpt order feeding two FIFO lists—not one scope-global far-to-near queue.
|
||
|
||
`AlphaFlushCounts_*` remains KnownFailure in c3a. Correct its three reasons:
|
||
(1) the replay world is content-empty; (2) AP-238 coalesces EnvCell to one
|
||
`(cell,list)` token; (3) AP-239/AP-240 alter CLIP-vs-ALPHA membership for the
|
||
named ordinary-Wb cases. Delete the six rows only in a later chunk that first
|
||
supplies a real content-bearing production replay. The broad stale claim
|
||
“acdream appends one entry per instance while retail appends per subset” is
|
||
false for the ordinary Wb/particle paths and must be removed. AP-238/AP-239/
|
||
AP-240 stay active and truthful.
|
||
|
||
### 18.5 Required tests and mutations
|
||
|
||
Use real production seams, not a surrogate list sorter:
|
||
|
||
1. one cell with near-first/far-second translucent object parts appends far
|
||
first; reversing the comparator fails;
|
||
2. equal-CYpt object parts retain input order; replacing the stable algorithm
|
||
with an unstable/tie-reversing one fails;
|
||
3. static and dynamic parts interleave by CYpt instead of forming two blocks;
|
||
4. a multipart entity preserves per-part order and authored subset order;
|
||
5. particle/object delayed records with reversed distances merge into the
|
||
same far-to-near pre-append sequence; restoring the old particle-tail event
|
||
fails;
|
||
6. two cells whose distances disagree globally remain cell-major; a global
|
||
sort mutation fails;
|
||
7. the real queue still drains CLIP then ALPHA FIFO, and the four flush sites,
|
||
0.75 valve, building barrier, EnvCell CLIP state, row-5 immediate particle
|
||
state, rollback, and 3000-entry drop tests remain green;
|
||
8. the production combined-order hot path reports 0 managed bytes per warmed
|
||
iteration; the pin must call the actual driver/particle/dispatcher merge;
|
||
9. source/signature pins distinguish retained CYpt data from deleted dead
|
||
camera threading, and documentation/register pins fail on the old
|
||
“scope-global distance-sorted queue” wording or missing AP-241/AP-242.
|
||
|
||
The commit body names every mutation and its actual first failing assertion.
|
||
No new pin is accepted without its observed failing text.
|
||
|
||
### 18.6 Scope, gates, and review
|
||
|
||
**Allowed production files:** the existing normal-world alpha participants
|
||
under `src/AcDream.App/Rendering/{Walk,Wb}/`, `ParticleRenderer.cs` and
|
||
`.Rhi.cs`, plus the minimum shared alpha record needed for the merge. Tests may
|
||
change only under `tests/AcDream.App.Tests/Rendering/` and the directly
|
||
affected Core dispatcher tests. Documentation changes are limited to this
|
||
packet, `worldbuilder-inventory.md`, `acdream-architecture.md`, and
|
||
`retail-divergence-register.md`.
|
||
|
||
**Must not:** sort inside `RetailAlphaQueue`; merge CLIP and ALPHA; change any
|
||
S4-c2 mask/pipeline/reference/depth decision; move a flush/barrier; sort across
|
||
cells; change building degrade, private/sealed viewport ordering, portal BFS,
|
||
prepared package formats, render-scene ownership, or shadow/collision
|
||
registration; add allocations to the warmed path; run a graphical client from
|
||
the implementation/review worktree.
|
||
|
||
**Automated return:** `git diff --check`; Release solution build 0W/0E;
|
||
focused per-cell/order/queue/particle/Wb/walk/EnvCell/PView tests; real 0-B
|
||
pin; shader/manifest lane; full hermetic lane; InstalledDat with exactly the
|
||
documented global set plus the six retained `AlphaFlushCounts_*`, no new
|
||
failure. The implementer commits one bounded change on a clean scratch
|
||
worktree and returns the commit, changed-file list, gate output, and mutation
|
||
ledger.
|
||
|
||
**Sequential reviews:** (1) retail lens checks the named decomp and paired
|
||
binary at `0x005A0690`, `0x005A0786`, `0x005A18A3`, and
|
||
`0x006B5130..0x006B519D`, per-cell scope, comparator direction/stability,
|
||
part/subset grouping, particle reachability, and every retained deviation;
|
||
(2) production/gate-honesty lens checks real event reachability, barrier
|
||
isolation, two-list FIFO preservation, allocation/bounds/rollback, mutations,
|
||
register count, allowed files, and every gate claim. A failed lens gets one
|
||
bounded fix contract; a third fix round stops and is written up. Dual PASS
|
||
lands c3a; the lead then writes c3b's deletion-only contract from that code.
|
||
|
||
### 18.7 Implementation result (scratch implementation, 2026-09-04)
|
||
|
||
The bounded c3a implementation now builds one combined registry view for each
|
||
ordinary outdoor/interior object-cell turn, transforms each GfxObj's authored
|
||
`SortCenter`, applies a stable descending per-cell insertion sort, and derives
|
||
both opaque/cutout commands and delayed object records from that same order.
|
||
The real particle leaf prepares but does not expose delayed records; the cell
|
||
event merges their retained keys with the object's range before either source
|
||
appends to the unchanged CLIP/ALPHA FIFO lists. Row-5 immediate routing,
|
||
capacity-drop/source rollback, barriers, and building-shell ownership are
|
||
unchanged. Exact equal object/particle keys use the disclosed object-first tie.
|
||
|
||
The paired-binary correction is recorded as AP-243: retail's
|
||
`UpdateObjCell` greater-than-50 m branch at `0x005A06B7..0x005A0720` gives
|
||
all parts one cell CYpt/heading through `CPhysicsObj::UpdateViewerDistance`
|
||
and therefore retains insertion order, while this bounded port always uses
|
||
the more exact per-part authored center. AP-241/AP-242 record the two other
|
||
narrow residuals. The active AP header and physical table are pinned at 162
|
||
rows, with exactly one row for each AP-241/AP-242/AP-243.
|
||
|
||
Lead-approved process-scope clarification: the real-path integration also
|
||
changes exactly `src/AcDream.App/Rendering/RetailPViewPassExecutor.WalkLeaf.cs`
|
||
and `src/AcDream.App/Rendering/RetailPViewPassExecutor.cs`. The literal
|
||
`{Walk,Wb}/` production-file list omitted the existing leaf adapter and the
|
||
thin `PrepareCellParticleAlpha` forwarder required to reach the expressly
|
||
allowed `ParticleRenderer`; relocating that bridge would create an artificial
|
||
seam. These two files contain only the interface adaptation and forwarder—no
|
||
router, queue, mask, pipeline, reference, depth, or flush behavior. The lead
|
||
approved this minimum real-path reachability delta before commit. It is a
|
||
contract-scope clarification, not a retail behavior deviation, so it files no
|
||
additional AP row.
|
||
|
||
Clean-state return matrix (no graphical client was launched):
|
||
|
||
- Initial solution `--no-restore` build was invalid setup evidence: 42
|
||
projects lacked `project.assets.json` (`NETSDK1004`). One solution restore
|
||
followed; the official Release solution build then succeeded with 0
|
||
warnings and 0 errors.
|
||
- Shader descriptor/manifest/SPIR-V validation: 32/32. No shader source,
|
||
checked-in SPIR-V, manifest, Content model, serializer, or package format
|
||
changed.
|
||
- Focused queue/router/particle/Wb/walk/EnvCell/PView production filter:
|
||
210/210. The three real warmed routes (EnvCell whole-leaf SubmitRhi,
|
||
immediate mesh particle RHI, and the new driver/particle/dispatcher merge)
|
||
pass 3/3 and each asserts 0 managed bytes.
|
||
- Official one-shot 14-assembly hermetic gate: 16,743 passed / 0 skipped /
|
||
0 failed. Evidence:
|
||
`%TEMP%/acdream-s4-c3a-impl-20260904-2015`.
|
||
- InstalledDat with explicit `C:\Turbine\Asheron's Call`: 385 passed / 10
|
||
failed / 1 skipped. The failures are exactly TowerAscent, the two #383
|
||
layout sweeps, #458 `Oh_doorway_still_first_frame_diff`, and the six
|
||
retained `AlphaFlushCounts_*`; all six paired `AlphaFlushSites_*` pass.
|
||
Evidence: `%TEMP%/acdream-s4-c3a-installed-20260904-2017`.
|
||
- `git diff --check`: pass.
|
||
|
||
Observed mutation first failures (every mutation was reversed with a patch
|
||
before the return matrix):
|
||
|
||
1. Reverse the CYpt comparator: `PopulateCellObjects_UsesAuthoredSortCenterAndStableFarToNearOrder`
|
||
expected `[202,101]`, actual `[101,202]` at the first sequence assertion.
|
||
2. Move equal keys left (`>=`): `PopulateCellObjects_EqualCyptRetainsEntityPartAndSubsetOrder`
|
||
expected `[11,12,21,22]`, actual `[22,21,12,11]`.
|
||
3. Restore static/dynamic blocks: `PopulateCellObjects_InterleavesStaticAndDynamicOpaquePartsByCypt`
|
||
expected `[2,3,1]`, actual `[3,1,2]`.
|
||
4. Replace authored SortCenter with entity translation: the authored-center
|
||
test first expected `[202,101]`, actual `[101,202]`.
|
||
5. Restore the old object-then-particle tail: `CellTurn_RealParticlePreparationMergesWithObjectAlphaByCypt`
|
||
expected source order `[Wb,Particle,Wb,Particle]`, actual
|
||
`[Wb,Wb,Particle,Particle]` at position 1.
|
||
6. Sort all staged objects scope-globally before replay:
|
||
`SeparateCellTurnsRemainCellMajorWhenLaterCellIsFarther` first expected
|
||
model X `5`, actual `50`.
|
||
7. Restore a dead optional camera parameter on `SubmitWalkAlphaInstance`:
|
||
`WorldAlphaCyptContract_RetainsTheKeyWithoutDeadCameraSubmitThreading`
|
||
first expected parameter count 2, actual 3.
|
||
8. Reinsert “distance-sorts one shared queue” into the inventory:
|
||
`WorldAlphaCyptDocumentationAndRegister_PinPerCellTruthAndThreeResiduals`
|
||
first failed `Assert.DoesNotContain` on that exact phrase.
|
||
9. Rename AP-241 away: that same truth pin first failed the earlier AP-table-
|
||
boundary `Assert.True` because `rowIndex=-1`; the later `Assert.Single` was
|
||
not reached.
|
||
10. Allocate one object in the real cell-merge path:
|
||
`ProductionCellObjectParticleMerge_WarmedPathAllocatesZeroBytes` first
|
||
expected 0, actual 3,072 managed bytes.
|
||
|
||
## 19. S4-c3a fix round 1 — authored particle CYpt and bounded preparation (lead, 2026-09-04)
|
||
|
||
The first retail-faithfulness lens returned **FAIL** on candidate
|
||
`44e2bc227ba74d10074cfe985eee094e10b7f438`. Ordinary object parts are
|
||
correct, but the billboard/mode-2–5 particle path orders by its rendered quad
|
||
center. That center is the vertex-AABB-derived `ParticleGfxInfo.CenterOffset`
|
||
after viewer-facing adjustment, not the GfxObj's authored `sort_center`.
|
||
Retail does not use the rendered center for CYpt:
|
||
`CPhysicsPart::UpdateViewerDistance @ 0x0050E030` reads the current GfxObj's
|
||
`sort_center` at offsets `+0x7C/+0x80/+0x84`, scales it, passes it with the
|
||
part `Position` to `Position::get_offset`, computes the length, and writes
|
||
CYpt. The paired bytes at `0x0050E036..0x0050E0AE` confirm that named-decomp
|
||
sequence. The same lens also found the stale statement that static records
|
||
are never re-sorted downstream.
|
||
|
||
The lead's pre-production audit found two coupled safety holes in the new
|
||
prepared-particle seam. `_preparedCellAlphaScratch` is a new retained list but
|
||
is absent from the alpha scratch accounting/retention bound. More importantly,
|
||
`PrepareForCellAlpha` reserves `_deferredAlpha` payload tokens before the
|
||
driver reaches the queue visibility edge. An exception from a later immediate
|
||
duplicate can strand unregistered source payload; ordinary capacity rejection
|
||
retains payload for entries that can never draw. These contradict §18.3's
|
||
source-owned rollback requirement. They are included in this same bounded
|
||
round rather than deferred to a predictable production-lens failure.
|
||
|
||
### 19.1 F1 — one authored particle sort point, separate from its draw center
|
||
|
||
Retain `GfxObj.SortCenter` explicitly in `ParticleGfxInfo`. Populate it
|
||
directly in `AuthoredParticleGfxInfo`; synthetic texture-only/default
|
||
billboards, which have no GfxObj, use zero. Do not derive it from vertex bounds
|
||
and do not replace or alter the visual `CenterOffset`.
|
||
|
||
For every billboard/mode-2–5 particle, compute the CYpt point before any
|
||
viewer-facing draw-frame adjustment:
|
||
|
||
`particle.Position + Transform(authoredSortCenter * particle.Size, ParticleOrientation)`.
|
||
|
||
Use the squared viewer distance from that point for `ParticleInstance` and
|
||
`ParticleSubmission`. The rendered quad position/axes remain byte-for-byte
|
||
the existing `CenterOffset`/facing result. The full-mesh path already applies
|
||
the equivalent `ObjectRenderData.SortCenter` through its model; keep the two
|
||
paths semantically identical and do not add a second sort.
|
||
|
||
Add a real GfxObj-backed billboard test whose authored SortCenter is distinct
|
||
from both its particle origin and vertex AABB center, with non-unit size and a
|
||
non-identity orientation. Drive the actual cell particle preparation and
|
||
driver merge against ordinary object alpha. It must prove that the authored
|
||
point determines the cross-source order while the captured billboard draw
|
||
center remains the existing visual center. Required mutations: using rendered
|
||
`pos`, using the AABB center, dropping size, or dropping orientation must each
|
||
fail a named first assertion.
|
||
|
||
### 19.2 F2 — reserve only at the queue visibility edge and roll back rejection
|
||
|
||
A prepared particle record retains only the information needed to reconstruct
|
||
its source payload when `Append` is called; preparation must not mutate
|
||
`_deferredAlpha`. At `Append`, reserve one tail token, call
|
||
`RetailAlphaQueue.TryAppend`, and roll back that exact tail token when the
|
||
append returns false or throws. A rejected first-use source must remain
|
||
registered by the queue and receive one flush/end/abort reset, but it owns no
|
||
rejected payload and never prepares or draws it. Accepted token indices remain
|
||
stable. An exception from a later row-5 or clip-immediate draw during
|
||
preparation must leave the source payload count unchanged.
|
||
|
||
Bound `_preparedCellAlphaScratch` by the physical two-list limit: retain no
|
||
more than the first 3,000 delayed candidates for CLIP and the first 3,000 for
|
||
ALPHA. Later candidates for a list cannot be admitted even in an otherwise
|
||
empty frame, so dropping only their prepared records is behavior-equivalent;
|
||
their immediate duplicate, if any, still executes. Include this list in an
|
||
explicit retained-byte/capacity diagnostic or an equivalent dedicated bound.
|
||
After a rejection storm its count is zero at reset/next preparation and its
|
||
retained capacity is no greater than the bounded geometric backing required
|
||
for 6,000 records (8,192 with `List<T>` growth). Do not change either queue's
|
||
3,000-entry capacity, FIFO append order, source registration, CLIP-then-ALPHA
|
||
drain, router decisions, or row-5 immediate state.
|
||
|
||
Pins cover: more than 3,000 candidates for each list; accepted/rejected token
|
||
counts; no rejected prepare/draw; flush, end, and abort cleanup; an injected
|
||
immediate-draw exception after at least one delayed candidate; bounded count,
|
||
capacity, and retained bytes; and the real warmed driver/particle/dispatcher
|
||
merge at 0 managed bytes. Mutations restoring eager reservation, omitting
|
||
false/exception rollback, or removing the per-list preparation cap must fail
|
||
at their first named count/capacity assertion.
|
||
|
||
### 19.3 F3 — prose and register truth
|
||
|
||
Correct `WalkFrameDriver.cs`'s `WalkFrameStaticRecords` comment: records retain
|
||
authored traversal/registration order until the ordinary-cell populator builds
|
||
the combined static/dynamic part list and performs the retail per-cell CYpt
|
||
sort. They are not final stream order. After F1, AP-241's positive authored-
|
||
part-order claim becomes true; AP-241/AP-242/AP-243 otherwise remain unchanged,
|
||
unique, inside the AP table, and the active physical count remains 162. No new
|
||
deviation is introduced by this exact repair.
|
||
|
||
### 19.4 Scope, return, and review order
|
||
|
||
Production edits are limited to `ParticleRenderer.cs`,
|
||
`ParticleSubmissionOrdering.cs`, and the comment-only correction in
|
||
`Walk/WalkFrameDriver.cs`. Tests may change only
|
||
`ParticleRendererRouteTests.cs` and `Walk/WalkFrameDriverTests.cs`; this packet
|
||
records the result. If the implementer proves one additional existing test
|
||
helper is the minimum real-path fixture seam, the lead must approve and record
|
||
it before commit. No router, queue, pipeline, shader, manifest, Content model,
|
||
serializer, package format, building-shell, EnvCell, or PView behavior changes.
|
||
|
||
Return one fix commit on top of `44e2bc227b`: `git diff --check`; Release 0W/0E;
|
||
the focused particle/driver/queue/order/bounds suite; the real 0-B pin; shader
|
||
contract lane; and a mutation ledger naming each actual first failure. No
|
||
graphical launch. The retail lens re-reviews F1, the paired bytes, F3, and the
|
||
unchanged S4-c2 behavior first. Only a retail PASS unlocks the sequential
|
||
production/gate-honesty lens over the entire c3a stack, with special attention
|
||
to F2. A failed re-review gets the one remaining bounded fix round; a further
|
||
finding after that would require a third round and stops the chunk.
|
||
|
||
### 19.5 Fix-round-1 implementation result (Sonnet, 2026-09-04)
|
||
|
||
**IMPLEMENTED — RETAIL RE-REVIEW REQUIRED.** This fix commit retains the
|
||
GfxObj-authored `SortCenter` separately from the rendered AABB-derived
|
||
`CenterOffset`. Billboard/mode-2–5 CYpt now uses the authored point after the
|
||
particle's scale and orientation, while the captured draw center remains the
|
||
existing visual center. The prepared-cell seam now reserves source payload
|
||
only from `Append`, rolls back the exact tail once on either a false return or
|
||
an exception, retains at most the first 3,000 CLIP and 3,000 ALPHA candidates,
|
||
and accounts for the bounded scratch list in its retained-byte diagnostic.
|
||
The row-2 immediate duplicate remains independent of delayed retention. The
|
||
static-record comment now describes the later ordinary-cell combined CYpt
|
||
sort.
|
||
|
||
The lead separately authorized one plan-ledger edit so the S4-c3a row records
|
||
candidate `44e2bc227b`'s retail FAIL and this §19 fix result. That file is
|
||
ledger currency only; it does not widen production scope. AP-241/AP-242/AP-243,
|
||
the active physical count of 162, both retail queues and their capacities,
|
||
router decisions, FIFO order, CLIP-then-ALPHA drain, row-5 immediate state,
|
||
pipelines, shaders, manifest, Content model, serializer, package format,
|
||
building shells, EnvCells, and PView behavior remain unchanged.
|
||
|
||
Automated return:
|
||
|
||
- `dotnet build AcDream.slnx -c Release --no-restore --nologo` — PASS, 0
|
||
warnings / 0 errors.
|
||
- focused `ParticleRendererRouteTests|WalkFrameDriverTests|RetailAlphaQueueTests|RetailParticleGeometryClassifierTests`
|
||
lane — PASS, 95/95, 0 skipped.
|
||
- `WorldAlphaCyptDocumentationAndRegister_PinPerCellTruthAndThreeResiduals`
|
||
— PASS, 1/1; all three residual rows remain unique inside the AP section and
|
||
the physical count remains 162.
|
||
- real warmed `ProductionCellObjectParticleMerge_WarmedPathAllocatesZeroBytes|ProductionImmediateMesh_WarmedDrawImmediateParticleSubmissionRhiDoesNotAllocate`
|
||
lane — PASS, 2/2; both production-path pins observed 0 managed bytes.
|
||
- `VulkanShaderDescriptorContractTests|VulkanShaderManifestTests|RenderPackSpirvValidatorTests`
|
||
— PASS, 32/32, 0 skipped.
|
||
- official one-shot 14-assembly hermetic gate — PASS, 16,751 passed / 0
|
||
skipped / 0 failed. Evidence:
|
||
`%TEMP%/acdream-s4-c3a-fix1-20260904-2215`.
|
||
- InstalledDat with explicit `C:\Turbine\Asheron's Call` and the documented
|
||
ordinary set plus TowerAscent, #458 `Oh_doorway_still_first_frame_diff`, and
|
||
the six retained `AlphaFlushCounts_*` — 385 passed / 10 expected failed / 1
|
||
skipped. The failures are exactly TowerAscent, the two #383 layout sweeps,
|
||
#458, and the six count rows; no new failure appeared. Evidence:
|
||
`%TEMP%/acdream-s4-c3a-fix1-installed-inclusive-20260904-2222`.
|
||
- `git diff --check` — PASS (only the repository's LF-to-CRLF working-copy
|
||
notices).
|
||
|
||
Mutation ledger (each mutation was applied alone, its named test was run once,
|
||
and the production source was restored before the next mutation):
|
||
|
||
1. Use rendered `pos` for billboard CYpt: `CellTurn_GfxObjBillboardUsesScaledOrientedAuthoredSortCenterButKeepsVisualCenter`
|
||
first failed its distance assertion, expected `40`, actual `116`.
|
||
2. Use the AABB-derived `CenterOffset`: the same test first failed its distance
|
||
assertion, expected `40`, actual `116`.
|
||
3. Drop particle size from authored SortCenter: the same test first failed its
|
||
distance assertion, expected `40`, actual `65`.
|
||
4. Drop particle orientation from authored SortCenter: the same test first
|
||
failed its distance assertion, expected `40`, actual `160`.
|
||
5. Restore eager source-payload reservation during preparation:
|
||
`PreparedCellAlpha_ImmediateExceptionAfterDelayedCandidateDoesNotReservePayload`
|
||
first failed `Assert.Empty`; the collection contained one
|
||
`DeferredParticleDraw`.
|
||
6. Omit rollback after `TryAppend` returns false:
|
||
`PreparedCellAlpha_AcceptsStableTokenAndRollsBackRejectedTailOnAbort` first
|
||
failed `Assert.Single`; the collection contained two payloads.
|
||
7. Omit rollback after `TryAppend` throws:
|
||
`PreparedCellAlpha_AppendExceptionRollsBackExactTailToken` first failed
|
||
`Assert.Empty`; the collection contained one payload.
|
||
8. Remove the two per-list preparation caps:
|
||
`PreparedCellAlpha_CapsBothListsAndRejectStormRetainsNoPayloadOrUnboundedScratch`
|
||
first failed the prepared-count assertion, expected `6000`, actual `6002`.
|
||
|
||
Before the return matrix, fixture construction exposed and corrected two
|
||
test-only setup issues: missing `DatReaderWriter.Lib`/`Types` imports plus a
|
||
nonexistent vector comparer caused the first compile attempt to fail, and
|
||
xUnit2013 rejected two count-shaped assertions. Neither failure reached a
|
||
production positive assertion. The first InstalledDat invocation used the
|
||
release guide's ordinary `Status!=KnownFailure` filter and honestly returned
|
||
385 passed / 2 expected failed / 1 skipped; that was incomplete §18.6 evidence
|
||
because it excluded TowerAscent, #458, and the six count rows. It was not
|
||
retried or rewritten: the separate inclusive artifact above is the required
|
||
documented-set gate. No graphical client was launched.
|
||
|
||
## 20. S4-c3a fix round 2 — retain authored metadata without a surface (lead, 2026-09-04; LAST ROUND)
|
||
|
||
The §19 retail re-review returned **FAIL** on candidate `eea5793d2`. The exact
|
||
authored-center formula, the paired-byte argument, all installed September
|
||
2013 content, and every original c3a invariant passed. One universal contract
|
||
edge did not: after `ReadParticleGfxInfo` successfully decodes a real GfxObj,
|
||
`ResolveParticleGfxInfo` replaces the complete result with
|
||
`ParticleGfxInfo.Default` whenever `SurfaceId == 0`. That discards the real
|
||
GfxObj's `SortCenter`, axes, bounds-derived visual center, and degrade mode.
|
||
Retail `CPhysicsPart::UpdateViewerDistance @ 0x0050E030` reads GfxObj
|
||
`sort_center` independently of surface/material presence. Packet §19.1 also
|
||
explicitly permits a zero authored center only for synthetic/default
|
||
billboards with no GfxObj. The existing production-path fixture supplied a
|
||
synthetic in-memory Surface and therefore did not exercise the bad branch.
|
||
|
||
The lens scanned the installed domain: 2,051 emitter records reference 360
|
||
distinct GfxObjs and every one has a nonzero first Surface DID. That lowers
|
||
current installed exposure to zero but does not make the implementation or
|
||
its universal claim correct. The same lens found one evidence-only wording
|
||
error: the in-memory `NoopDatReaderWriter` fixture is GfxObj-backed and drives
|
||
the real production path, but is not “real DAT-backed.”
|
||
|
||
### 20.1 F1 — decoded GfxObj metadata survives `SurfaceId == 0`
|
||
|
||
When a real GfxObj decodes successfully, preserve its complete
|
||
`ParticleGfxInfo` regardless of Surface presence. Acquire a texture slot only
|
||
when `SurfaceId != 0`; otherwise return the decoded record unchanged with its
|
||
unassigned slot. A missing/unreadable GfxObj or a descriptor with no GfxObj
|
||
may still use `ParticleGfxInfo.Default`. Do not synthesize a surface, change
|
||
procedural/untextured draw behavior, alter material/additive routing, or
|
||
special-case installed DIDs.
|
||
|
||
Extend the existing production-path GfxObj-backed CYpt fixture with a
|
||
no-surface row (or a separate equally real-path row): nonzero authored
|
||
SortCenter; vertex AABB center different from it; non-unit size and nonidentity
|
||
orientation; no Surface entry/DID. It must prove the same authored distance
|
||
and object/particle merge order while retaining the existing untextured visual
|
||
fallback. Restoring `SurfaceId == 0 ? ParticleGfxInfo.Default : ...` must first
|
||
fail a named authored-distance or cross-source-order assertion. Correct the
|
||
fixture comment to “production-path GfxObj-backed synthetic DAT records”; do
|
||
not call it installed or real DAT-backed.
|
||
|
||
### 20.2 Final-round production audit before return
|
||
|
||
This is c3a's second and last fix round. Before commit, re-read every §19 F2
|
||
path rather than relying only on the existing green tests: preparation must
|
||
hold no source payload; `Append` must reserve once; false and exception paths
|
||
must roll back the same tail exactly once; a rejected first-use source must
|
||
remain registered for reset; accepted tokens must remain stable; the first
|
||
3,000 candidates per list must be the only retained candidates; later row-2
|
||
immediate duplicates must still draw; flush/end/abort and next-preparation
|
||
cleanup must converge; the retained capacity and byte diagnostics must remain
|
||
bounded; the real warmed merge must remain 0 B. If that source audit exposes
|
||
any defect, fix and pin it inside this same round and record it explicitly in
|
||
the result—there is no later repair round.
|
||
|
||
### 20.3 Scope and return
|
||
|
||
Production edits are limited to `ParticleRenderer.cs`. Test edits are limited
|
||
to `Walk/WalkFrameDriverTests.cs`; this packet and the S4-c3a plan-ledger row
|
||
record the result. No other file changes without lead approval. AP-241/242/243,
|
||
queue/router/pipeline/shader/manifest/package behavior, and all installed
|
||
content remain unchanged.
|
||
|
||
Return one fix commit on top of `eea5793d2`: targeted no-surface positive and
|
||
mutation; the complete §19 95-test focused lane; AP boundary/count pin; both
|
||
real 0-B pins; shader/manifest lane; Release 0W/0E; `git diff --check`; honest
|
||
changed-file list and source-audit statement. The retail lens re-reviews the
|
||
no-surface branch and evidence wording first. Only PASS unlocks the sequential
|
||
production/gate-honesty lens over the complete c3a stack. Any further code,
|
||
test, register, or evidence correction would be a third fix round: stop the
|
||
chunk and write it up; do not land or graphically gate it.
|
||
|
||
### 20.4 Final-fix implementation result (Sonnet, 2026-09-04)
|
||
|
||
**IMPLEMENTED — FINAL RETAIL REVIEW REQUIRED.** A successfully decoded GfxObj
|
||
now retains its complete `ParticleGfxInfo` when `SurfaceId == 0`; texture
|
||
acquisition alone remains conditional on a nonzero Surface DID. Missing or
|
||
unreadable GfxObjs and descriptors without a GfxObj retain the existing
|
||
`Default` behavior. The production-path synthetic GfxObj test supplies no
|
||
Surface DID or entry, a nonzero authored center distinct from its vertex-AABB
|
||
center, size 2, and a nonidentity orientation. It proves authored distance²
|
||
40, ordinary-object-then-particle merge order against distance² 49, the
|
||
unchanged visual center `(10,4,0)`, and an unassigned texture slot. The
|
||
evidence comment now calls both fixtures “production-path GfxObj-backed
|
||
synthetic DAT records,” not real or installed DATs.
|
||
|
||
Required §20.2 final-round source audit found no additional defect:
|
||
|
||
- `PrepareForCellAlpha` clears and rebuilds only reconstruction records; it
|
||
does not add source payload to `_deferredAlpha`.
|
||
- `PreparedParticleAlphaSubmission.Append` calls
|
||
`ReservePreparedDispatchDeferredParticle` exactly once at the visibility
|
||
edge, then calls `TryAppend` once.
|
||
- A false return rolls back that exact tail once outside the `try`; an
|
||
exception rolls it back once in the `catch` and rethrows. The rollback
|
||
method rejects any non-tail token, so an accepted earlier token cannot be
|
||
renumbered or removed.
|
||
- `RetailAlphaQueue.TryAppend` registers the source before its capacity
|
||
return. A rejected first-use source therefore still participates in the
|
||
next flush/end/abort reset while owning no rejected payload. Accepted token
|
||
indices remain stable.
|
||
- Independent retained counters admit only the first 3,000 CLIP and first
|
||
3,000 ALPHA candidates from the already stable particle order. The row-2
|
||
immediate action is computed independently of retention, so candidate
|
||
3,001 still draws immediately.
|
||
- Flush, EndFrame, and AbortFrame reset `_deferredAlpha`, prepared RHI count,
|
||
and `_preparedCellAlphaScratch`; the next preparation also clears the
|
||
scratch before any early return or rebuild. The immediate-exception path
|
||
holds no source payload and converges on that next preparation/abort.
|
||
- The prepared list can retain at most 6,000 records and therefore at most the
|
||
8,192-slot `List<T>` geometric backing pinned by the diagnostic. Its bytes
|
||
remain included in `RetainedAlphaScratchBytes`.
|
||
- The real warmed driver/particle/dispatcher merge and the immediate-particle
|
||
RHI path both still measure zero managed bytes.
|
||
|
||
Mutation ledger: restoring candidate `eea5793d2`'s
|
||
`SurfaceId == 0 ? ParticleGfxInfo.Default : ...` ternary made
|
||
`CellTurn_GfxObjBillboardWithoutSurfaceRetainsAuthoredSortCenterAndUntexturedFallback`
|
||
first fail its authored-distance assertion: expected `40`, actual `100`.
|
||
The mutation was restored before the return matrix.
|
||
|
||
Automated return:
|
||
|
||
- targeted no-surface production path — PASS, 1/1 after mutation restore;
|
||
- unchanged §19 focused baseline (excluding the separately executed new
|
||
target) — PASS, 95/95, 0 skipped;
|
||
- AP-241/AP-242/AP-243 boundary/count pin — PASS, 1/1;
|
||
- real production allocation pins — PASS, 2/2, both asserting 0 B;
|
||
- shader/manifest/SPIR-V lane — PASS, 32/32;
|
||
- Release solution build — PASS, 0 warnings / 0 errors;
|
||
- `git diff --check` — PASS (only the repository's LF-to-CRLF working-copy
|
||
notices).
|
||
|
||
Only `ParticleRenderer.cs`, `WalkFrameDriverTests.cs`, this packet, and the
|
||
S4-c3a plan-ledger row changed. AP rows, queue/router/pipeline/shader/manifest/
|
||
package behavior, and installed content remain unchanged. No graphical client
|
||
was launched.
|
||
|
||
## 21. Owner-authorized evidence-only exception (2026-09-04)
|
||
|
||
The owner explicitly authorized one correction beyond the five-attempt/
|
||
third-round stop: fix the sole false mutation-first-failure sentence and run
|
||
a narrow confirmation. This does not reopen renderer implementation or any
|
||
other evidence claim.
|
||
|
||
The exact correction is §18.7 mutation 9. Renaming AP-241 makes
|
||
`register.IndexOf("| AP-241 |")` return `-1`; the first failure is the AP-table
|
||
boundary `Assert.True` in
|
||
`WorldAlphaCyptDocumentationAndRegister_PinPerCellTruthAndThreeResiduals`, not
|
||
the later `Assert.Single`. Replace only that statement. The correction commit
|
||
body must explicitly supersede the same false mutation-9 sentence in initial
|
||
candidate commit `44e2bc227b`; do not rewrite that historical commit.
|
||
|
||
Allowed files: this packet and the S4-c3a plan-ledger row only. No production,
|
||
test, register, handoff, architecture, inventory, shader, manifest, or package
|
||
file changes. The narrow gate is:
|
||
|
||
1. temporarily rename the AP-241 table row, run only
|
||
`WorldAlphaCyptDocumentationAndRegister_PinPerCellTruthAndThreeResiduals`,
|
||
and record the actual first failure/message;
|
||
2. restore the row exactly, rerun the same test and require 1/1 PASS;
|
||
3. `git diff --check` and exact changed-file inspection;
|
||
4. one narrow independent gate-honesty re-review of this exception diff only.
|
||
|
||
No full renderer rerun is required: the final retail and production lenses
|
||
already found no other correction-worthy item and the correction cannot affect
|
||
compiled source or tests. A narrow PASS unlocks landing the already-reviewed
|
||
c3a stack; a narrow FAIL returns to STOPPED UNLANDED.
|
||
|
||
### 21.1 Evidence-exception implementation result (Sonnet, 2026-09-04)
|
||
|
||
**CORRECTED — NARROW REVIEW PENDING.** Temporarily renaming the AP-241 row and
|
||
running only
|
||
`WorldAlphaCyptDocumentationAndRegister_PinPerCellTruthAndThreeResiduals`
|
||
first failed the boundary assertion at line 329 with the actual message:
|
||
`AP-241 row must be inside the AP table before the TS section; rowIndex=-1,
|
||
AP=[275116,751256).` The later `Assert.Single` was not reached. The register row
|
||
was restored exactly and the same isolated test then passed 1/1. `git diff
|
||
--check` passed, and exact inspection found only this packet and the S4-c3a
|
||
plan-ledger row changed. No production, test, register, shader, manifest, or
|
||
package file remains modified; no graphical client was launched. This text
|
||
supersedes only §18.7 mutation 9 and the corresponding historical claim in
|
||
candidate `44e2bc227b`; it changes no other c3a evidence.
|
||
|
||
### 21.2 Narrow review and campaign landing result (2026-09-04)
|
||
|
||
**PASS — LANDED.** The independent narrow gate-honesty re-review found no
|
||
blocking, major, or minor issue. It reproduced an in-memory AP-241 rename and
|
||
the exact first boundary failure (`rowIndex=-1`, AP range
|
||
`[275116,751256)`), confirmed that the later `Assert.Single` was not reached,
|
||
then confirmed the restored isolated pin at 1/1. The AP-register Git blob is
|
||
byte-identical at the exception base, correction commit, and clean scratch
|
||
worktree: `bf8758705a17b9415888b1a437e673826b6777e2`. The exception diff is
|
||
exactly this packet plus the plan row; `git diff --check` passed. Commit
|
||
`9cfddf301` explicitly supersedes the false sentence in historical
|
||
`44e2bc227b` without rewriting it.
|
||
|
||
The reviewed scratch stack landed on the campaign branch as:
|
||
|
||
1. `a86ec73ec` (`44e2bc227b`) — stable authored per-cell object/particle order;
|
||
2. `8e0c6fb14` (`b6bf6c131`) — bounded fix-round-1 contract;
|
||
3. `01674bcc7` (`eea5793d2`) — authored particle CYpt preparation and bounds;
|
||
4. `8bd75ba31` (`14397b14c`) — bounded final fix contract;
|
||
5. `b6b015604` (`359061b82`) — surfaceless Gfx metadata preservation;
|
||
6. `316193043` (`255194e90`) — owner-authorized narrow exception contract;
|
||
7. `67c76026e` (`9cfddf301`) — corrected mutation evidence.
|
||
|
||
The stop commit `06b986622` remains immediately before that stack as the
|
||
truthful historical record of the then-binding rule. The owner exception,
|
||
narrow PASS, and this landing supersede its operational disposition; history
|
||
was not rewritten.
|
||
|
||
Fresh campaign verification after integration: Release solution build PASS,
|
||
0 warnings / 0 errors; focused particle/driver/queue/classifier lane 96/96;
|
||
targeted no-surface path 1/1; AP boundary/count pin 1/1; both real production
|
||
allocation pins 2/2 at 0 B; shader/manifest/SPIR-V lane 32/32; `git diff
|
||
--check` clean. The campaign `src`/`tests` tree is byte-identical to reviewed
|
||
scratch commit `9cfddf301`. No graphical client was launched. c3b is now
|
||
unlocked; G3 remains locked until the deletion-only c3b chunk lands.
|
||
|
||
## 22. S4-c3b contract — delete the superseded alpha-order sidecars (lead, 2026-09-04)
|
||
|
||
### 22.1 Retail and landed-code boundary
|
||
|
||
This chunk changes no retail-visible renderer behavior. Named retail
|
||
`D3DPolyRender::AddMeshToAlphaList @0x0059C230` accepts mesh/subset/surface and
|
||
list-state flags but no camera or distance argument; it appends into one of two
|
||
fixed arrays. `FlushAlphaList @0x0059D2E0` replays those arrays by index.
|
||
Retail's only relevant distance step is earlier and per cell:
|
||
`CShadowPart::insertion_sort @0x006B5130..0x006B519D`, before the resulting
|
||
parts call `DrawMesh`. The paired bytes and the named pseudo-C agree on those
|
||
facts; §§17–21 contain the earlier byte/review record.
|
||
|
||
Landed c3a now owns the needed key on
|
||
`WalkClassifiedBatch.LocalSortCenter`/`SortDistanceSq` and on the prepared
|
||
particle record before the two FIFO lists see it. A separate classic grouped
|
||
dispatcher sidecar survives only as dead storage and diagnostic hash input:
|
||
`CachedBatch.LocalSortCenter`, `InstanceGroup.LocalSortCenters`, and their
|
||
append/cache plumbing. Two additional tombstones pass a camera position into
|
||
`DeferTransparentGroups` and `BuildTransparentSubmissionDigest`, then discard
|
||
it. None feeds a draw, route, list choice, queue record, flush, or barrier.
|
||
|
||
### 22.2 D1 — remove the dead grouped sort-center sidecar
|
||
|
||
Delete `CachedBatch.LocalSortCenter` and
|
||
`InstanceGroup.LocalSortCenters`, including constructor arguments, cache-hit
|
||
delegate/plumbing, append parameters, per-frame clear/release calls, and the
|
||
unused field in `AddSubmissionInstance`'s diagnostic digest. The resulting
|
||
classic grouped path retains matrices, exact submission ordinal, clip slot,
|
||
lights, indoor/detail/opacity/selection state, and every material key.
|
||
|
||
This deletion must not touch these live retail keys:
|
||
|
||
- `ObjectRenderData.SortCenter`;
|
||
- `WalkClassifiedBatch.LocalSortCenter` and `SortDistanceSq`;
|
||
- `WalkStaticStreamPopulator`'s transformed authored-center calculation and
|
||
stable descending per-cell insertion sort;
|
||
- `ParticleRenderer`'s authored GfxObj sort center, prepared distance, and
|
||
object/particle merge;
|
||
- building-degrade `ViewerDistanceTo`, opaque `InstanceGroup.SortDistance`,
|
||
portal-flood distance, private-viewport sorting, or off-screen particle
|
||
ordering.
|
||
|
||
The `CurrentRenderDispatcherSubmission` digest deliberately stops hashing the
|
||
deleted non-rendered sidecar. That is diagnostic cleanup, not a world-render
|
||
change; submission order and every rendered field remain hashed.
|
||
|
||
### 22.3 D2 — remove the dead alpha camera-parameter chain
|
||
|
||
Remove `cameraWorldPosition` from
|
||
`DeferTransparentGroups`, `BuildTransparentSubmissionDigest`,
|
||
`CreateDispatcherSubmission`, `ObserveCurrentDispatcherSubmission`, and
|
||
`ObserveClassifiedDispatcherSubmission`, plus all callers/tests. No
|
||
`_ = cameraWorldPosition` tombstone may remain.
|
||
|
||
Keep the camera output from `BeginEntityDispatch`, the camera argument to
|
||
`PartitionInstanceGroups`, `InstanceGroup.SortDistance`, and
|
||
`CompareOpaqueSubmissionOrder`: that is the still-live opaque/private grouped
|
||
path and is outside the alpha deletion.
|
||
|
||
### 22.4 D3 — truth cleanup and explicit non-changes
|
||
|
||
The six `AlphaFlushCounts_*` rows remain evaluated KnownFailures. Their exact
|
||
three reasons are: (1) the replay world is content-empty; (2) AP-238 coalesces
|
||
EnvCell work to one `(cell,list)` token; (3) AP-239/AP-240 alter list
|
||
membership for the named ordinary-Wb cases. Remove any surviving broad
|
||
“per instance versus per subset” explanation; ordinary Wb and particle paths
|
||
otherwise append per real subset. The live `AlphaFlushSites_*` rows remain.
|
||
|
||
Static deletion verification must find no executable `RetailAlphaOrdering`,
|
||
`FlushFartherThan`, alpha-submit `viewerDistance`, portal punch depth bias,
|
||
`#129` eye-span cap, or stencil-mark pass. Do not delete generic RHI stencil
|
||
support, change `PortalDepthMaskRenderer`, touch shaders/SPIR-V, or change
|
||
AD-119/AP-238/AP-239/AP-240/AP-241/AP-242/AP-243. The historical mutation
|
||
comments that quote the deleted old API may remain when clearly past tense.
|
||
|
||
### 22.5 Required tests and mutation evidence
|
||
|
||
Extend the existing production-facing tests, not a surrogate implementation:
|
||
|
||
1. reflection/source shape proves `CachedBatch` and `InstanceGroup` have no
|
||
`LocalSortCenter(s)` sidecar while `WalkClassifiedBatch` still has
|
||
`LocalSortCenter` and `SortDistanceSq`;
|
||
2. reflection/source shape proves the five D2 methods have no dead camera
|
||
parameter and neither tombstone remains, while `PartitionInstanceGroups`
|
||
still accepts and uses its camera position for opaque `SortDistance`;
|
||
3. existing cache-hit composition, transparent submission-order digest,
|
||
group-clear, per-cell object order, particle merge, queue, allocation, and
|
||
shader/state pins remain green;
|
||
4. a source-truth pin keeps the three `AlphaFlushCounts_*` reasons and rejects
|
||
the false broad explanation;
|
||
5. a deletion pin rejects any production resurrection of
|
||
`RetailAlphaOrdering`, `FlushFartherThan`, or an alpha-submit
|
||
`viewerDistance`, without rejecting unrelated building/opaque/portal
|
||
distance owners.
|
||
|
||
Every new pin gets a real sabotage. At minimum, record the actual first
|
||
failure after independently restoring: (a) `InstanceGroup.LocalSortCenters`;
|
||
(b) `CachedBatch.LocalSortCenter`; (c) the discarded camera parameter/tombstone
|
||
on `DeferTransparentGroups`; (d) the discarded camera parameter on the
|
||
transparent digest; (e) the false broad count explanation; and (f) one deleted
|
||
alpha-order symbol. Restore each mutation exactly before the clean return.
|
||
|
||
### 22.6 Scope, gates, and review
|
||
|
||
Allowed production files:
|
||
`src/AcDream.App/Rendering/Wb/CachedBatch.cs`,
|
||
`WbDrawDispatcher.cs`, and comment-only cleanup in
|
||
`WbDrawDispatcher.WalkClassify.cs`. Tests may change only
|
||
`tests/AcDream.App.Tests/Rendering/Wb/InstanceGroupClearTests.cs`,
|
||
`tests/AcDream.App.Tests/Rendering/Walk/WalkStaticStreamPopulatorTests.cs`, and
|
||
the directly affected existing rendering test file if compile fallout requires
|
||
it. Documentation is limited to this packet,
|
||
`docs/architecture/worldbuilder-inventory.md`, and
|
||
`docs/architecture/acdream-architecture.md`. No register edit is expected; if
|
||
source truth disproves that, stop and return the fact instead of silently
|
||
changing scope.
|
||
|
||
Must not change queue/router/pipeline/list membership, capacity, flush/barrier,
|
||
particle preparation, per-cell sort/merge, package/content/RHI/shader state,
|
||
or graphical behavior. No client launch from the implementation/review
|
||
worktree.
|
||
|
||
Automated return: `git diff --check`; Release solution 0W/0E; focused Wb
|
||
group/cache/digest + walk per-cell/order + queue/particle/router suite; both
|
||
real production 0-B pins; shader/manifest/SPIR-V 32/32; hermetic lane; and
|
||
InstalledDat with exactly the documented global set plus the six retained
|
||
`AlphaFlushCounts_*`, no new failure. The implementer commits one bounded
|
||
change on a clean worktree and returns exact files, counts, and mutation-first-
|
||
failure text.
|
||
|
||
Sequential reviews: first, retail/deletion fidelity verifies the named decomp
|
||
and paired bytes, that only pre-append per-cell CYpt survives, and that every
|
||
live distance owner above was preserved. Second, production/gate honesty checks
|
||
call reachability, diagnostic-digest consequences, cache/reset/storage
|
||
lifecycle, allocation, allowed scope, every mutation claim, and all gate
|
||
counts. A failed lens gets one bounded fix contract; a third fix round stops
|
||
and is written up. Dual PASS lands c3b and unlocks G3.
|
||
|
||
### 22.7 S4-c3b implementation result (implementer, 2026-09-04)
|
||
|
||
PASS for the bounded implementation return. The classic grouped dispatcher no
|
||
longer carries `CachedBatch.LocalSortCenter` or
|
||
`InstanceGroup.LocalSortCenters`; their constructor/cache-hit/append/reset/
|
||
release and diagnostic-hash plumbing is gone. The discarded alpha camera
|
||
parameter is also absent from `DeferTransparentGroups`,
|
||
`BuildTransparentSubmissionDigest`, `CreateDispatcherSubmission`,
|
||
`ObserveCurrentDispatcherSubmission`, and
|
||
`ObserveClassifiedDispatcherSubmission`, with no camera tombstone remaining.
|
||
The diagnostic transparent digest therefore hashes only rendered state plus the
|
||
live submission ordinal, as intended.
|
||
|
||
Production-facing reflection/source pins prove the deletion and retain the
|
||
separate live owners: `WalkClassifiedBatch.LocalSortCenter`/
|
||
`SortDistanceSq`, the transformed authored-center per-cell stable descending
|
||
sort, and `PartitionInstanceGroups(cameraWorldPosition)` feeding opaque
|
||
`InstanceGroup.SortDistance`. Existing cache-hit matrix composition,
|
||
transparent submission-order digest, group lifecycle, walk/particle merge,
|
||
queue/router, allocation, and shader/state tests remain green. The
|
||
`AlphaFlushCounts_*` source-truth pin keeps exactly the content-empty replay,
|
||
AP-238 `(cell,list)` coalescing, and AP-239/AP-240 list-membership reasons and
|
||
explicitly preserves the fact that the former broad “per instance versus per
|
||
subset” explanation was false. Static production truth rejects resurrection of
|
||
`RetailAlphaOrdering`, `FlushFartherThan`, alpha-submit `viewerDistance`, or a
|
||
discarded camera tombstone.
|
||
|
||
Automated return:
|
||
|
||
- The first `dotnet build AcDream.slnx -c Release --no-restore` invocation did
|
||
not reach compilation because the fresh worktree had no
|
||
`obj/project.assets.json` files (`NETSDK1004`, 57 projects). One
|
||
`dotnet restore AcDream.slnx` populated those assets; the Release rerun then
|
||
passed with 0 warnings / 0 errors. This was dependency preparation, not a
|
||
product retry.
|
||
- focused App
|
||
`InstanceGroupClearTests|WalkStaticStreamPopulatorTests|ParticleRendererRouteTests|WalkFrameDriverTests|RetailAlphaQueueTests|RetailParticleGeometryClassifierTests`
|
||
— PASS, 132/132; focused Core
|
||
`WbDrawDispatcherBucketingTests|EntityClassificationCacheTests` — PASS,
|
||
29/29 (161/161 aggregate);
|
||
- the four new deletion/truth pins — PASS, 4/4 after every mutation restore;
|
||
- real warmed
|
||
`ProductionCellObjectParticleMerge_WarmedPathAllocatesZeroBytes|ProductionImmediateMesh_WarmedDrawImmediateParticleSubmissionRhiDoesNotAllocate`
|
||
— PASS, 2/2, both observing 0 managed bytes;
|
||
- `VulkanShaderDescriptorContractTests|VulkanShaderManifestTests|RenderPackSpirvValidatorTests`
|
||
— PASS, 32/32; no shader, SPIR-V, manifest, RHI, or pipeline file changed;
|
||
- official no-retry 14-assembly hermetic gate — PASS, 16,755 passed / 0
|
||
skipped / 0 failed; evidence
|
||
`artifacts/s4-c3b-hermetic-20260904`;
|
||
- InstalledDat with explicit `C:\Turbine\Asheron's Call`, inclusive of the
|
||
retained KnownFailures — 385 passed / 10 expected failed / 1 skipped. The
|
||
failures were exactly TowerAscent, the two #383 layout sweeps,
|
||
`Oh_doorway_still_first_frame_diff` (#458), and the six
|
||
`AlphaFlushCounts_*`; the skip remained `Sweep_the_lookin_gate_decodes_against_the_street_fixture`.
|
||
No new failure appeared; evidence
|
||
`artifacts/s4-c3b-installed-inclusive-20260904`.
|
||
|
||
Artifact provenance: both official artifact sets above ran before the
|
||
implementation commit, on the restored but still uncommitted c3b tree whose
|
||
HEAD was parent `a0523e6057af206126a09874bf8664206ff7d9a1`. Accordingly,
|
||
both embedded summaries truthfully record that parent and
|
||
`WorktreeDirty=true`, rather than implementation tip `4eca2a4f`. The two
|
||
`SHA256SUMS.txt` manifests each verify all 30 entries with zero missing or
|
||
mismatched files.
|
||
|
||
Both artifact environments list
|
||
`WalkTraceConformanceTests.AlphaDepthTranscript.cs` as dirty. That entry was
|
||
transient mutation-worktree dirtiness left by applying and restoring mutation
|
||
5, not an active prose mutation during either official gate: the hermetic TRX
|
||
records
|
||
`AlphaFlushCountKnownFailure_StatesOnlyTheThreeExactReasons` as `Passed`, and
|
||
the transcript has the identical Git blob
|
||
`c755c1379feeba5fe5382fa0b0db243e7169b4e9` at parent `a0523e605`,
|
||
implementation tip `4eca2a4f`, current contract HEAD, and the current
|
||
worktree. The final implementation diff therefore correctly excludes that
|
||
file while the pre-commit artifacts continue to describe their actual capture
|
||
state.
|
||
|
||
Mutation ledger (each mutation was applied alone and restored by patch before
|
||
the next; the restored pin set passed 4/4):
|
||
|
||
1. Restoring `InstanceGroup.LocalSortCenters` first failed
|
||
`ClassicGroupedShapes_DeleteDeadSortCenterSidecarsButRetainWalkCyptKey` at
|
||
its second `Assert.Null`: expected null; actual
|
||
`List<Vector3> LocalSortCenters`.
|
||
2. Restoring `CachedBatch.LocalSortCenter` first failed the same pin at its
|
||
first `Assert.Null`: expected null; actual `Vector3 LocalSortCenter`.
|
||
3. Restoring the `DeferTransparentGroups(Vector3, Matrix4x4)` parameter and
|
||
tombstone first failed
|
||
`AlphaSubmissionShapes_DeleteDeadCameraChainButRetainOpaqueCameraDistance`:
|
||
`Assert.Equal` expected `[Matrix4x4]`, actual `[Vector3, Matrix4x4]`.
|
||
4. Restoring `cameraWorldPosition` on
|
||
`BuildTransparentSubmissionDigest` first failed the same pin's next
|
||
`Assert.DoesNotContain`: the parameter collection contained
|
||
`Vector3 cameraWorldPosition` at position 1.
|
||
5. Replacing the exact three-reason prose with a false broad fourth reason
|
||
first failed
|
||
`AlphaFlushCountKnownFailure_StatesOnlyTheThreeExactReasons` at
|
||
`Assert.Contains`: the required `former broad "per instance versus per
|
||
subset" explanation was false.` substring was absent.
|
||
6. Restoring an executable `RetailAlphaOrdering` symbol first failed
|
||
`ClassicGroupedAlphaSourceTruth_DeletesDeadOrderingChainAndPreservesLiveOwners`
|
||
at `Assert.DoesNotContain`: substring `RetailAlphaOrdering` was found.
|
||
|
||
The implementation changes only the three allowed production files, the two
|
||
named App test files, the one directly affected Core rendering test file, and
|
||
this result. AD-119 and AP-238 through AP-243, queue/router/list membership,
|
||
capacities, barriers, particles, per-cell ordering, building/private/portal
|
||
distances, shaders/RHI, package/content, and graphical behavior are unchanged.
|
||
No graphical client was launched.
|
||
|
||
## 23. S4-c3b gate-provenance fix contract (2026-09-04)
|
||
|
||
The production/gate-honesty lens found no code, test, renderer, scope, or gate
|
||
defect. It found one evidence-provenance omission in §22.7: both official gate
|
||
artifact sets were captured on the restored, uncommitted c3b implementation
|
||
tree before the implementation commit, so their embedded identity names parent
|
||
`a0523e605` and `WorktreeDirty=true` rather than tip `4eca2a4f`. The dirty-file
|
||
inventory also names
|
||
`WalkTraceConformanceTests.AlphaDepthTranscript.cs`, although that file is
|
||
byte-identical at base and tip and is absent from the final diff.
|
||
|
||
Make one packet-only correction to §22.7. State the artifact timing and identity
|
||
explicitly; state that the transcript entry was transient mutation-worktree
|
||
dirtiness, not an active mutation during either official gate; and ground that
|
||
statement in the hermetic TRX passing
|
||
`AlphaFlushCountKnownFailure_StatesOnlyTheThreeExactReasons` plus the exact
|
||
base/tip/current blob identity. Do not change production, tests, register,
|
||
architecture, inventory, handoff, plan, memory, or artifact files, and do not
|
||
rerun either full gate or launch a client.
|
||
|
||
Narrow verification: verify both cited summaries contain parent
|
||
`a0523e605`/`WorktreeDirty=true`; verify both SHA manifests; verify the transcript
|
||
blob is identical at base, tip, and current worktree; verify the hermetic TRX
|
||
records the source-truth pin PASS; run `git diff --check`. Commit the packet-only
|
||
correction and return the exact evidence. The lead then performs one narrow
|
||
gate-honesty re-review; no additional retail review is required because retail
|
||
and renderer behavior are untouched.
|
||
|
||
## 24. S4-c3b landing (2026-09-04)
|
||
|
||
S4-c3b is LANDED. Reviewed scratch implementation `4eca2a4f` maps to campaign
|
||
commit `26e97ba41`; provenance contract `8074a6b4d` and packet-only correction
|
||
`92f9b4bbb` map to `5110bf676` and `3f2f00c9f`.
|
||
|
||
The retail/deletion lens returned PASS with no finding after checking the named
|
||
decomp and paired executable/PDB: `AddMeshToAlphaList @0x0059C230` has no
|
||
camera/distance input, `FlushAlphaList @0x0059D2E0` replays CLIP then ALPHA in
|
||
FIFO index order, and `CShadowPart::insertion_sort @0x006B5130..0x006B519D`
|
||
is strict-descending and stable for equal keys. The removed grouped centers fed
|
||
only dead storage and a diagnostic hash. Walk CYpt, particle authored-center
|
||
distance, opaque `SortDistance`, building/private/portal distances, queue and
|
||
router behavior, barriers, and generic stencil state remain live and unchanged.
|
||
|
||
The production/gate-honesty lens found no code, test, allocation, lifecycle,
|
||
scope, mutation, or gate defect. Its sole MAJOR was §22.7's omission of the
|
||
pre-commit artifact identity. Fix round 1 changed only this packet. Both
|
||
artifact summaries name parent `a0523e605` and `WorktreeDirty=true`; both
|
||
30-entry SHA manifests verify; the transcript blob is
|
||
`c755c1379feeba5fe5382fa0b0db243e7169b4e9` at base, implementation tip,
|
||
contract, fix, and current worktree; and the hermetic TRX records the exact
|
||
source-truth pin PASS. The narrow re-review returned PASS and closed the finding.
|
||
|
||
Fresh campaign verification at `3f2f00c9f`: Release solution build PASS with
|
||
0 warnings / 0 errors; focused App 132/132; focused Core 29/29; real warmed
|
||
allocation pins 2/2 at 0 B; shader/manifest/SPIR-V 32/32. The campaign worktree
|
||
was clean after integration. No client was launched for c3b. G3 is now unlocked;
|
||
G4 remains unpassed and nothing may merge to main.
|
||
|
||
## 25. G3 lead self-gate (2026-09-04, provisional until owner review)
|
||
|
||
**PROVISIONAL PASS** on clean campaign commit `9ca82bfc8`. Release was built
|
||
green before the first launch. ACE was listening on UDP 9000 as PID 13340;
|
||
before every launch no acdream or retail client was running. Each runner command
|
||
launched exactly one client and closed only that client through the scripted
|
||
graceful path.
|
||
|
||
1. `route-g3.txt` — PASS, exit 0, graceful logout confirmed, 13/13 PNGs:
|
||
`logs/selfgate-20260904-151811-s4c3b-g3/artifacts/screenshots/00-login.png`,
|
||
`01-cathedral-stairs.png`, `02-facility-stairs.png`,
|
||
`03-holtburg-house.png`, `04-holtburg-terrain-leak.png`,
|
||
`05-cathedral-south-0106.png`, `06-cathedral-south-0104.png`,
|
||
`07-cathedral-stairs-0107.png`, `08-cathedral-stairs-0112.png`,
|
||
`09-cathedral-terrace-edge.png`, `10-facility-015E.png`,
|
||
`11-facility-015F.png`, and `12-nanto-falls.png`.
|
||
2. `route-g3b.txt` — PASS, exit 0, graceful logout confirmed, 4/4 PNGs:
|
||
`logs/selfgate-20260904-152347-s4c3b-g3b/artifacts/screenshots/13-capture-terrace-edge.png`,
|
||
`14-capture-cathedral-arrival.png`, `15-capture-holtburg-doorway.png`, and
|
||
`16-capture-foundry-deep.png`. The Holtburg frame matches the prior accepted
|
||
band, including the arrival-state translucent player/effect.
|
||
3. `route-g3c.txt` first attempt — FAIL before the route, zero PNGs:
|
||
`logs/selfgate-20260904-152725-s4c3b-g3c/client.log`. The initial
|
||
`wait world-visible 180000` stalled in `0xA9B40176` before the Nanto
|
||
teleport, exactly the registered #462 login-reveal flake; graceful logout
|
||
was confirmed. This did not exercise renderer acceptance.
|
||
4. `route-g3c.txt` retry 1 — PASS, exit 0, graceful logout confirmed, 3/3 PNGs:
|
||
`logs/selfgate-20260904-153350-s4c3b-g3c-retry1/artifacts/screenshots/12-nanto-falls.png`,
|
||
`12b-nanto-falls-east.png`, and `12c-nanto-falls-west.png`. The falls are
|
||
present at the authored view and east quarter-turn; scenery/house occlusion
|
||
is intact, and the west frame correctly faces away from the falls.
|
||
|
||
Lead inspection found the player whole, expected walls/slabs/actors/effects
|
||
present, no new terrain bleed, no wall-textured beam, and no obvious alpha/depth
|
||
ordering regression in the captured frames. This remains provisional until the
|
||
owner inspects the PNGs. G3 also still owes the owner-only cathedral wall actor
|
||
(two clients), exterior ramp (no coordinates), Tusker, and two ordinary-dungeon
|
||
rows. No renderer fix is implied by #462; it remains outside S4/S5.
|