From 5c9da6fc25a72b5c984c3a9711fafb7f094b2384 Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 4 Sep 2026 12:42:01 +0200 Subject: [PATCH] docs(overhaul): define S4 c3 upstream order repair --- ...-09-01-campaign-overhaul-world-solidity.md | 2 +- .../2026-09-04-s4-handoff.md | 16 +- .../s4-depth-alpha-packet.md | 175 +++++++++++++++++- 3 files changed, 183 insertions(+), 10 deletions(-) diff --git a/docs/plans/2026-09-01-campaign-overhaul-world-solidity.md b/docs/plans/2026-09-01-campaign-overhaul-world-solidity.md index 11dbd232..5927a003 100644 --- a/docs/plans/2026-09-01-campaign-overhaul-world-solidity.md +++ b/docs/plans/2026-09-01-campaign-overhaul-world-solidity.md @@ -678,7 +678,7 @@ Update immediately when a slice changes state. Chat is not the ledger. | S4-c2 stop | **STOPPED UNLANDED 2026-09-04** — lead final-round contract `ac74fbd84`; evidence commit `c4cbc1d0d` in `s4-c2-impl` on `cc8e5677a`/`048d5b12f`; campaign renderer remains S4-c1 `766f9e749` | G3/G4 UNPASSED | Both sequential final lenses FAIL, so the required repair is the forbidden THIRD round. EnvCell transparent/ClipMap batches still draw in the opaque pass before FIFO submission and then redraw; CLIP/detail-immediate replay binds StraightAlpha with depth-write off rather than retail clip-test/depth-writing state; tests omit the preceding opaque call and pipeline descriptors. Source-owned EnvCell lists are unbounded under queue rejection, the claimed scan/filter/RHI 0-B evidence bypasses those paths, and AP-238/AP-240/result truth is false. Full file:line and gate record: S4 packet §13. No chunk cherry-pick, graphical gate, or soak. Resume only on explicit owner process change. | | S4-c2 owner repair | **STOPPED UNLANDED 2026-09-04** — owner-authorized implementation `a094bf2b7` is clean in `s4-c2-impl`; packet §15 is the review record | G3/G4 UNPASSED | The repaired renderer behavior passed the retail lens: exact whole-leaf pass membership, `0x08`/`0x09` CLIP, row-3 override, blend/reference/depth state, sentinel separation, detail state, rollback, allocation, AP-238/AP-240. The lens still returned FAIL: commit body omitted the required per-mutation first failures, packet mutation 5 names the wrong first assertion/address, and four source/test comments are stale. Sequential production lens therefore did not run. Correcting those items is a post-review fourth repair, which §14 does not authorize. Nothing landed or graphically gated; resume only by explicit owner process decision. | | S4-c2 attempts 1–5 | **ATTEMPT 1/5 CONSUMED; ATTEMPT 2/5 PASSED AND LANDED 2026-09-04** — reviewed implementation `daaeab0ba`; campaign stack `89f1e2676` → `9ccb61a8e` → `0aa166aa0` → `252886e84`; packet §17 | G3/G4 UNPASSED | Sequential retail/evidence then production/gate-honesty PASS. Fresh: Release 0W/0E; shader 32/32; affected 37/37; real allocation 2/2 at 0 B; production 239/239. Official no-retry hermetic 16,734/1: sole unchanged global `Console.Out` capture race, exact theory 2/2 isolated. InstalledDat 255/10 documented/1. Validation routes `selfgate-20260904-115818-s4c2-landed-route` and `selfgate-20260904-120025-s4c2-landed-g3b` PASS provisional. First soak failed on known #461/#462; retry and S4-c1 control both 9/9 graceful; stationary averages CPU p95 −0.01 ms, GPU p95 +0.16 ms, alloc p50 +1.2 KiB, update p95 −0.12 ms. Three attempts remain unused. | -| S4-c3 | **CONTRACT NEXT** — write from landed `252886e84`; delete surviving old alpha queue/sort/distance residue, replace `AlphaFlushCounts_*` only with a real content-bearing gate, re-check AP-238/AP-240 and EnvCell/CLIP residue | G3/G4 UNPASSED | Packet §4 is an old guess, not the dispatch contract. S4-c2 renderer is closed; G3 runs only after c3 review/landing. | +| S4-c3a | **CONTRACT READY — packet §18**. Fresh landed-source audit found the S4 chunk-2 “insertion sort” item was not actually implemented: production feeds the correct two-list FIFO in registry/static-then-dynamic/particle-tail order, while named retail `UpdateObjCell` + `CShadowPart::insertion_sort` orders each cell's object and particle parts by stable descending CYpt before append (`0x005A0690`, `0x005A0786`, `0x005A18A3`, `0x006B5130`) | G3/G4 UNPASSED | Port one per-cell pre-append CYpt order and object/particle delayed merge without sorting inside the FIFO or crossing a barrier; file the two narrow residuals AP-241/AP-242 in the same commit; keep sort-center facts until live. Then c3b deletes only proven dead residue and corrects `AlphaFlushCounts_*` truth. Old packet §4 is not dispatchable. | | S5 | — | G4 | fill | --- diff --git a/docs/research/2026-09-01-overhaul/2026-09-04-s4-handoff.md b/docs/research/2026-09-01-overhaul/2026-09-04-s4-handoff.md index 91904470..f23642b3 100644 --- a/docs/research/2026-09-01-overhaul/2026-09-04-s4-handoff.md +++ b/docs/research/2026-09-01-overhaul/2026-09-04-s4-handoff.md @@ -105,7 +105,8 @@ The reviewed implementation is `daaeab0ba`; the complete campaign stack is preceded production/gate-honesty PASS. Fresh campaign build, focused, shader, allocation, graphical, and same-session stationary A/B gates pass as recorded below and in packet §17. Three of the five additional attempts remain unused. -S4-c2 is closed; next is a fresh S4-c3 deletion contract from landed code. +S4-c2 is closed. Next is packet §18's S4-c3a upstream-order repair, +followed by a fresh S4-c3b deletion contract from the repaired landed code. **Historical state before the final round (kept for audit; do not execute its landing procedure):** @@ -155,11 +156,14 @@ memory −17.7 MiB. G3/G4 remain unpassed. ## 4. After chunk 2 -1. **S4 chunk 3 — deletions** (packet §4): whatever of the old queue/sort/ - distance residue survives, the `AlphaFlushCounts_*` Facts if a real - content-bearing gate replaces them, the two `EnvCell`/CLIP residual rows' - re-check. Write the contract from the LANDED code, not from §4's 2026-09-03 - guess. +1. **S4 chunk 3 — corrected into c3a order + c3b deletions.** The fresh landed + audit found the plan's chunk-2 `CShadowPart::insertion_sort` item is missing: + production feeds the correct FIFO in registry/static-then-dynamic/particle- + tail order, not stable per-cell CYpt order. Packet §18 is c3a's binding + contract: port the upstream object/particle order first. Only after dual + review and landing does the lead write c3b to delete proven dead camera/ + sort-center residue and re-check `AlphaFlushCounts_*` plus AP-238/AP-240. + Packet §4's 2026-09-03 deletion guess is explicitly not dispatchable. 2. **G3 — S4's owner gate:** the lead runs `route-g3.txt` (13 matrix shots), `route-g3b.txt` (the capture poses; pose 15 now outdoors), `route-g3c.txt` (Nanto ×3, 300 s waits) with `pwsh -File tools/overhaul-selfgate/run-selfgate.ps1 -Label -Route ` diff --git a/docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md b/docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md index df19fb0f..ca664988 100644 --- a/docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md +++ b/docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md @@ -1176,6 +1176,175 @@ 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. Next: -write S4-c3's bounded deletion contract from the landed code, not §4's old -guess, and re-check the AP-238/AP-240/`AlphaFlushCounts_*` residuals there. +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.