docs(overhaul): define S4 c3 upstream order repair

This commit is contained in:
Erik 2026-09-04 12:42:01 +02:00
parent d8c88adeb0
commit 5c9da6fc25
3 changed files with 183 additions and 10 deletions

View file

@ -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 15 | **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 |
---

View file

@ -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 <l> -Route <file>`

View file

@ -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.