docs(overhaul): contract S5 typed visibility consumers

This commit is contained in:
Erik 2026-09-04 15:52:55 +02:00
parent 170a807aad
commit 00f134f9e4
2 changed files with 261 additions and 1 deletions

View file

@ -680,7 +680,8 @@ Update immediately when a slice changes state. Chat is not the ledger.
| 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-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-c3a | **LANDED 2026-09-04 after the owner-authorized §21 evidence exception.** Reviewed scratch stack `44e2bc227b``b6bf6c131``eea5793d2``14397b14c``359061b82``255194e90``9cfddf301`; campaign cherry-picks `a86ec73ec``8e0c6fb14``01674bcc7``8bd75ba31``b6b015604``316193043``67c76026e`. The earlier stop remains in history at `06b986622`. | G3/G4 UNPASSED | Final retail lens PASS; production behavior/lifecycle/allocation/scope clean. The narrow independent gate-honesty re-review PASS reproduced the exact first failure (AP-table-boundary `Assert.True`, `rowIndex=-1`, before `Assert.Single`), restored AP-241 byte-identically, and passed the pin 1/1. Fresh campaign: Release 0W/0E; focused class lane 96/96; no-surface 1/1; AP pin 1/1; real allocation 2/2 at 0 B; shader 32/32; `git diff --check` clean. No client launched. NEXT: write c3b's deletion-only contract from the landed code; G3 stays locked until c3b lands. | | S4-c3a | **LANDED 2026-09-04 after the owner-authorized §21 evidence exception.** Reviewed scratch stack `44e2bc227b``b6bf6c131``eea5793d2``14397b14c``359061b82``255194e90``9cfddf301`; campaign cherry-picks `a86ec73ec``8e0c6fb14``01674bcc7``8bd75ba31``b6b015604``316193043``67c76026e`. The earlier stop remains in history at `06b986622`. | G3/G4 UNPASSED | Final retail lens PASS; production behavior/lifecycle/allocation/scope clean. The narrow independent gate-honesty re-review PASS reproduced the exact first failure (AP-table-boundary `Assert.True`, `rowIndex=-1`, before `Assert.Single`), restored AP-241 byte-identically, and passed the pin 1/1. Fresh campaign: Release 0W/0E; focused class lane 96/96; no-surface 1/1; AP pin 1/1; real allocation 2/2 at 0 B; shader 32/32; `git diff --check` clean. No client launched. NEXT: write c3b's deletion-only contract from the landed code; G3 stays locked until c3b lands. |
| S4-c3b | **LANDED 2026-09-04** — implementation `26e97ba41`, provenance contract `5110bf676`, packet-only correction `3f2f00c9f`; packet §22§25. Dead classic-group `LocalSortCenters`/`CachedBatch.LocalSortCenter` storage and the alpha camera-parameter/digest chain are deleted. Live per-cell/particle CYpt keys, opaque `SortDistance`, building/private/portal distances, two FIFO lists, all state/barriers, and AP/AD rows remain. | **G3 LEAD SELF-GATE PROVISIONAL PASS; owner acceptance/owner-only rows pending. G4 UNPASSED.** | Retail/deletion lens PASS. Production lens found no code defect and one artifact-provenance omission; packet-only fix round 1 passed its narrow re-review. Fresh campaign: Release 0W/0E; App 132/132; Core 29/29; allocation 2/2 at 0 B; shader 32/32. G3: route 1 13/13, route 2 4/4, route 3 retry 3/3, all exit 0/graceful. The first route-3 attempt stopped before Nanto on registered #462. Exact PNG paths: packet §25. | | S4-c3b | **LANDED 2026-09-04** — implementation `26e97ba41`, provenance contract `5110bf676`, packet-only correction `3f2f00c9f`; packet §22§25. Dead classic-group `LocalSortCenters`/`CachedBatch.LocalSortCenter` storage and the alpha camera-parameter/digest chain are deleted. Live per-cell/particle CYpt keys, opaque `SortDistance`, building/private/portal distances, two FIFO lists, all state/barriers, and AP/AD rows remain. | **G3 LEAD SELF-GATE PROVISIONAL PASS; owner acceptance/owner-only rows pending. G4 UNPASSED.** | Retail/deletion lens PASS. Production lens found no code defect and one artifact-provenance omission; packet-only fix round 1 passed its narrow re-review. Fresh campaign: Release 0W/0E; App 132/132; Core 29/29; allocation 2/2 at 0 B; shader 32/32. G3: route 1 13/13, route 2 4/4, route 3 retry 3/3, all exit 0/graceful. The first route-3 attempt stopped before Nanto on registered #462. Exact PNG paths: packet §25. |
| S5 | — | G4 | fill | | S5-c1 | **CONTRACTED 2026-09-04; implementation pending.** Packet `s5-consumers-material-closeout-packet.md` §§16. Exact landscape land-cell publication is separated from EnvCells; particle update ports `CLandCell::IsInView` vs constant-true `CEnvCell::IsInView`; AP-117's null-root frustum/AABB reconstruction and the dead point-light feedback seam are deleted; AP-85/AD-21 are corrected in the same implementation commit. | G4 UNPASSED | Lead verified the named pseudo-C and paired executable/PDB (GUID `{9E847E2F-777C-4BD9-886C-22256BB87F32}`, age 1): `ShouldDrawParticles @0x0050FE60`, `UpdateParticles @0x0051D180`, `CLandCell::IsInView @0x00532CB0`, and the CEnvCell vtable's ICF body `0x005269F0`. Directional shadows, building degrade, AP-232, probes, and closeout are later bounded chunks. |
| S5 | IN FLIGHT — c1 contracted; c2c5 and closeout remain | G4 | Packet §7 is the bounded decomposition; never merge main before G4. |
--- ---

View file

@ -0,0 +1,259 @@
# Campaign OVERHAUL v2 — S5 consumers, material, and closeout packet
**Status:** S5-c1 CONTRACTED 2026-09-04; implementation not yet landed.
**Branch:** `claude/campaign-w-retail-frame-walk`.
**Gate:** G4 remains unpassed. Nothing merges to `main` before G4.
This packet decomposes plan S5 into bounded chunks. The lead writes each
contract, a Sonnet implementer changes only that contract, the lead verifies
every retail claim against the named pseudo-C and the paired executable/PDB,
and the sequential review lenses run before landing. A chunk that needs a
third fix round stops and is written up. Every surviving deviation is entered
or corrected in the divergence register in the same implementation commit.
## 1. Current boundary after S4
S4-c3b is landed and the lead G3 matrix is a provisional PASS; owner inspection
and the owner-only G3 rows remain. S5 must not reopen the green walk, portal
depth, or two-FIFO alpha ports without new evidence.
The landscape half is already present and exact:
- `WalkLandscape.CheckBlocks` / `LandCellCheck` port
`LScape::draw_check_blocks @0x00505F80` and
`LScape::landcell_check @0x005050A0`;
- `WalkVisibilityMath` owns the ported `get_clip_height` / `block_check` math;
- `WalkFrameDriver.VisitedLandscapeCellIds` is populated by the same one walk
that emits the retail-ordered terrain/object stream.
S5-c1 therefore changes the consumers and deletes the competing fallback. It
does not rewrite the landscape calculation.
## 2. Retail facts for S5-c1 (lead-verified 2026-09-04)
The executable is `C:\Users\erikn\Downloads\acclient.exe`. Its CodeView record
is GUID `{9E847E2F-777C-4BD9-886C-22256BB87F32}`, age 1, matching
`refs/acclient.pdb`.
### 2.1 `ShouldDrawParticles` is distance AND the cell virtual
Named pseudo-C at `CPhysicsObj::ShouldDrawParticles @0x0050FE60` reads:
```text
if examination: true
if CYpt > degrade_distance: false
if cell == null: false
if cell->IsInView() == 0: false
true
```
The paired bytes are the same: `fld [ecx+0x24]`, `fcomp [esp+4]`, the x87
`test ah,0x41` gate, null-check of `[ecx+0x90]`, then the virtual call through
vtable slot `+0x68`. `ParticleEmitter::UpdateParticles @0x0051D180` calls that
function at `0x0051D1A1`; false enters the `SetNoDraw(1)` / `degraded_out=1`
arm, while true clears that state and updates/emits particles.
Preserve the existing x87-compatible comparison, including inclusive equality,
unordered admission, raw negative/zero/NaN/infinity authored distances, and the
deliberate AP-116 range multiplier (`Retail=1`, default `Extended=2`).
### 2.2 outdoor and indoor cells have different `IsInView` semantics
- `CLandCell::IsInView @0x00532CB0` returns the 32-bit field at `+0x104`.
The paired body is exactly `mov eax,[ecx+0x104]; ret`. Landscape drawing
stamps that field, so particle update consumes the previous completed
render frame's landscape answer.
- `CEnvCell::IsInView` is the PDB-vtable slot at `0x007C8D00`, pointing to the
ICF-folded body `0x005269F0`. The paired body is exactly `mov eax,1; ret`.
Thus an indoor cell with a non-null owner is always `PARTIALLY_INSIDE` for
the update-time check; its particle drawing remains separately controlled
by the cell walk.
AC cell identity already has a production-pinned discriminator:
`low = cellId & 0xFFFF`; outdoor land cells have `0 < low < 0x0100`, EnvCells
have `low >= 0x0100`, and zero is no cell.
### 2.3 point lights do not consume the camera walk
Retail collects point lights from the DBObj-load/flush-bounded resident
`CEnvCell::visible_cell_table`, not from the current camera portal flood.
Current `LightManager.BuildPointLightSnapshot(playerWorldPos)` likewise uses
the resident registry. `RuntimeWorldFrameEnvironmentPreparation`'s
`ObserveDrawableCells` / `ClearDrawableCells` methods are now no-ops, while
AP-85 still describes the deleted last-frame filter. The methods and the stale
claim are tombstones, not behavior.
### 2.4 the null-root terrain reconstruction is not a retail answer
In-world retail has a viewer-cell root. acdream's null-root path is the AD-21
streaming-gap/debug safety draw. `TerrainModernRenderer.CollectVisibleCells`
manufactures 64 land-cell ids per retained landblock from camera-frustum AABBs
and publishes them through `TerrainVisibleCellIds`. That is the only remaining
AP-117 reconstruction. A safety draw with no walk product must publish no
outdoor `IsInView` answer; it must not invent one.
## 3. S5-c1 contract — typed `IsInView` consumers and fallback deletion
### 3.1 C1 — publish the landscape half explicitly
Extend the borrowed `RetailPViewFrameResult` with the exact landscape land-cell
set from `WalkFrameDriver.VisitedLandscapeCellIds`. Keep `DrawableCells` for
EnvCell shell preparation and keep the existing union `VisibleCells` only for
diagnostics that compare the two products. Do not re-filter, re-walk, sort, or
derive the landscape set from projection/entity ids.
Rename the particle handoff to make the type visible in the API, for example
`MarkVisibleLandscapeCells`. It accepts only outdoor land-cell ids and copies
them into the controller's building frame. Passing zero or an EnvCell id is a
contract violation, not something to silently reinterpret.
The completed frame remains the sole retained owner. `AbortFrame` preserves
the prior completed product, `CompleteFrame` publishes the new product, and
`Reset` removes both generations. The update thread continues to call `Apply`
before the next render, preserving retail's previous-frame timing.
### 3.2 C2 — evaluate the correct virtual by cell family
Change `ParticleSystem.ApplyRetailView` so a world-policy emitter is eligible
only when all of the following are true:
```text
hasCompletedView
ownerCellId != 0
(owner is EnvCell OR exact completed landscape set contains ownerCellId)
retail x87-compatible distance predicate
```
EnvCell means `low >= 0x0100`; landscape means `0 < low < 0x0100`.
Examination and dedicated-pass policies keep their existing bypass. This is an
update/degrade correction only: do not alter emitter-own-cell draw membership,
per-cell particle turns, cone admission, queue routing, alpha order, lifetime,
or tick order.
A completed null-root safety frame has an empty landscape set. EnvCell owners
still see their constant virtual result; outdoor owners fail closed. Login and
portal-space frames still carry `hasCompletedView=false` and reject ordinary
world-policy emitters.
### 3.3 C3 — delete AP-117's remaining reconstruction
Delete the complete `TerrainModernRenderer.CollectVisibleCells` route,
including `_visibleCellIds`, `VisibleCellIds`, `BeginVisibilityFrame`,
`IWorldScenePassExecutor.TerrainVisibleCellIds`, the null-root publication in
`WorldSceneRenderer`, and the reconstruction-only tests. The flat terrain draw
itself remains; only its fabricated visibility side channel goes.
After this deletion, AP-117 is retired: the walk path publishes the ported
landscape product, and frames without that product publish none. Update AD-21
in the same commit so it no longer claims the login screen shows live sky and
states that the safety draw cannot publish cell visibility.
### 3.4 C4 — delete the dead point-light feedback seam
Delete `ObserveDrawableCells` and `ClearDrawableCells` from
`IWorldRenderFrameBuilder`, `IWorldFrameEnvironmentPreparation`, their runtime
implementations, all calls, fakes, and tests. Keep point-light snapshot
selection exactly resident-registry based. Correct AP-85 in the same commit to
the code that actually remains: one resident, player-nearest 128-cap pool
instead of retail's separate 7-dynamic/40-static pools and DBObj-granular
residency. AP-68's owner-approved always-lit-interior policy is unchanged.
### 3.5 Explicit non-changes
S5-c1 must not change:
- `WalkLandscape`, `WalkVisibilityMath`, block/cell order, landscape event
order, terrain draws, membership, portal flood, depth, alpha, shaders, RHI,
DAT/package code, or streaming ownership;
- point-light capacity, sort anchor, curves, cell/object selection, or AP-68;
- directional-shadow selection (S5-c2 owns that consumer and its retained
topology/per-frame visibility design);
- building degrade/complete-body selection (later S5 chunk);
- translucent-detail material combine/AP-232 (later S5 chunk);
- Facility probe and broader cleanup inventory (later S5 cleanup chunk).
No graphical client is launched from the implementation or review worktree.
## 4. Allowed files
Production changes are limited to the directly affected files:
- `src/AcDream.Core/Vfx/ParticleSystem.cs`;
- `src/AcDream.App/Rendering/Vfx/ParticleVisibilityController.cs`;
- `src/AcDream.App/Rendering/RetailPViewRenderer.cs`;
- `src/AcDream.App/Rendering/WorldSceneRenderer.cs`;
- `src/AcDream.App/Rendering/WorldScenePassExecutor.cs`;
- `src/AcDream.App/Rendering/WorldRenderFrameBuilder.cs`;
- `src/AcDream.App/Rendering/TerrainModernRenderer.cs`;
- comment-only truth correction in `WalkFrameDriver.cs` if required.
Tests may change in the directly affected Core/App VFX, renderer, frame-builder,
and terrain-visibility files, plus compile-fallout fakes for the deleted
interfaces. Documentation is limited to this packet, the plan ledger,
`acdream-architecture.md`, `oh1-construction-landscape-contract.md`, and the
divergence register. If implementation requires another production owner or a
new deviation, stop and return the fact before expanding scope.
## 5. Tests and mutation evidence
Extend production-facing tests to prove:
1. an outdoor emitter is admitted only by the exact completed landscape set;
2. an EnvCell emitter remains update-eligible at authored range even when no
indoor cell is in that set;
3. zero cell and no completed world view reject both cell families;
4. inclusive/unordered/raw-distance behavior and AP-116 Retail/Extended
multipliers remain unchanged;
5. `WorldSceneRenderer` hands only `RetailPViewFrameResult`'s landscape set to
the particle owner, never the EnvCell set or diagnostic union;
6. abort/complete/reset preserve the previous-frame transaction;
7. no production `CollectVisibleCells`, `TerrainVisibleCellIds`,
`ObserveDrawableCells`, or `ClearDrawableCells` symbol remains;
8. point-light snapshots still include resident lights regardless of the
removed feedback set;
9. the warmed production particle-view path allocates 0 managed bytes.
Every new pin gets a real sabotage and exact first failure in the implementer
commit body. At minimum mutate independently and restore exactly:
- make EnvCell eligibility depend on set membership;
- make outdoor eligibility constant true;
- feed the union instead of the landscape set at the renderer call site;
- restore one `CollectVisibleCells` production symbol;
- restore one `ObserveDrawableCells` production symbol;
- invert or exclude the inclusive authored-distance boundary.
## 6. Automated return and reviews
Implementer return:
- `git diff --check`;
- Release solution build, 0 warnings / 0 errors;
- focused Core VFX and App particle/frame/renderer/terrain tests;
- the real warmed 0-B particle-view pin;
- official hermetic lane;
- InstalledDat lane with exactly the documented global failure/skip set and no
new failure;
- one clean commit, exact files/counts, and all mutation first failures.
Sequential review 1 — retail fidelity: re-check the named pseudo-C and paired
bytes above, the CEnvCell vtable/ICF identity, previous-frame timing, cell-id
discriminator, and every preserved x87/AP-116 edge. Review 2 — architecture,
production, and gate honesty: prove one retained product, typed call-site
reachability, no reconstructed/null-root answer, no point-light behavior
change, reset/abort/lifecycle correctness, 0-B steady state, allowed scope, all
register prose, all gate counts, and at least three mutation claims. A failed
lens receives one bounded fix contract; a third fix round stops the chunk.
## 7. Remaining S5 decomposition after c1
1. S5-c2: exact landscape visibility consumption by directional-shadow caster
selection without creating a second set or rebuilding retained topology on
every camera-only change.
2. S5-c3: retail `DrawBuilding` degrade selection and complete-body null gate.
3. S5-c4: translucent detail single-stage framebuffer equivalence; retire
AP-232.
4. S5-c5: delete Facility probes, production `PortalVisibilityBuilder`
residue, obsolete fallbacks/flags/tests/claims; add architecture guards.
5. S5 closeout: full automated/lifecycle/performance program, G4 owner matrix,
documentation closeout, then and only then merge to `main`.