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 2a71e436..3b2e1c2c 100644 --- a/docs/plans/2026-09-01-campaign-overhaul-world-solidity.md +++ b/docs/plans/2026-09-01-campaign-overhaul-world-solidity.md @@ -681,7 +681,8 @@ Update immediately when a slice changes state. Chat is not the ledger. | 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. | | S5-c1 | **LANDED 2026-09-04 after the owner-authorized documentation/evidence exception.** Mandatory stop `efb075619` remains in history; final campaign tip `1718832e2`, reviewed scratch tip `b2d56f9e3`. | G4 UNPASSED | Narrow exception re-review PASS. Clean evidence: hermetic 16,760/16,760; inclusive InstalledDat 385 pass / the same documented 10 fail / 1 skip; both exact `d6592d3ac`, `WorktreeDirty=false`, manifests fully verified. Fresh campaign Release 0W/0E, Core 111/111, visibility 38/38, allocation/AP-116 4/4. Lead graphical portal-haze gate PROVISIONAL PASS, exit 0/graceful, 10 PNGs under `logs/selfgate-20260904-171137-s5c1-particle-visibility`; owner inspection pending. | -| S5 | IN FLIGHT — c1 landed/provisionally self-gated; c2 directional-shadow consumption NEXT; c3–c5 and closeout remain | G4 | Packet §§7, 12, and 13 are binding; never merge main before G4. | +| S5-c2 | **CONTRACTED 2026-09-04; Sonnet implementation next.** Exact prior-completed landscape visibility selects opt-in IA-24 terrain/world shadow casters through S2 CELLARRAY/building placement facts; pack-off remains retail and untouched. | G4 UNPASSED | Packet §14 binding: one borrowed set, zero fallback, arbitrary-instance exactness, no retained topology rebuild on camera-only change, 0-B warmed path, dual sequential review. | +| S5 | IN FLIGHT — c1 landed/provisionally self-gated; c2 contracted; c3–c5 and closeout remain | G4 | Packet §§7 and 12–14 are binding; never merge main before G4. | --- diff --git a/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md b/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md index 1fa17488..003d398c 100644 --- a/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md +++ b/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md @@ -1,6 +1,7 @@ # Campaign OVERHAUL v2 — S5 consumers, material, and closeout packet -**Status:** S5-c1 IMPLEMENTED 2026-09-04; sequential review pending. +**Status:** S5-c1 LANDED + lead graphical gate PROVISIONAL PASS 2026-09-04; +S5-c2 CONTRACTED below. **Branch:** `claude/campaign-w-retail-frame-walk`. **Gate:** G4 remains unpassed. Nothing merges to `main` before G4. @@ -535,3 +536,199 @@ materialization particles at 400 ms, the particle effect clears normally by the later frames, and Facility/Holtburg geometry and actors remain intact with no obvious visibility regression. This is not owner acceptance. G4 remains unpassed, nothing may merge to `main`, and S5-c2 is next. + +## 14. S5-c2 contract — exact landscape visibility for the opt-in shadow pack + +### 14.1 Retail and deviation boundary (lead-verified 2026-09-04) + +This chunk ports one retail **input**, not a retail shadow-map algorithm. +Retail has no cascaded real-time directional shadow map; acdream's selected +atmospheric pack is the explicit IA-24 deviation. Pack-off remains the retail +path and must not build, select, upload, or draw directional-shadow work. + +The retail input is the completed landscape `in_view` product: + +- named `LScape::draw_check_blocks @0x00505F80` writes a non-`OUTSIDE` block + result and calls `LScape::landcell_check @0x005050A0`; the latter stamps each + `CLandCell::in_view` from the same portal-view interval walk; +- named `CLandCell::IsInView @0x00532CB0` returns that field at `+0x104`; +- the paired Sept-2013 executable is SHA-256 + `006FFEADC5D679C871497112A5BD1F87714D0E273E2166BAE5052DDE369297B1`. + Its CodeView GUID `{9E847E2F-777C-4BD9-886C-22256BB87F32}`, age 1, matches + the PDB, and its relevant bytes are `8B 81 04 01 00 00 C3` at + `0x00532CB0`; `landcell_check` begins `55 8B EC 83 EC 1C 53 56` at + `0x005050A0`. The ICF body used by the `CEnvCell::IsInView` vtable remains + `B8 01 00 00 00 C3` at `0x005269F0`. + +Because the directional-shadow prepass runs after enhanced-world preparation +but before the current frame's PView walk, it consumes the **previous +successfully completed** landscape product, exactly as S5-c1's retained owner +already exposes to update-time consumers. An aborted frame preserves that +product; completion replaces it; reset removes it. A first/login/portal-space +frame has no completed world view. A completed null-root safety frame has an +empty set and may not manufacture a resident/frustum fallback. + +IA-24 must be amended in the implementation commit to state this selection +adaptation plainly: the opt-in non-retail shadow map borrows retail's prior +completed landscape visibility and exact S2 object membership. That amendment +does not make the shadow map retail behavior and does not authorize a new +fallback or a pack-off change. + +### 14.2 C1 — borrow the one completed visibility product + +Publish a typed one-frame `RetailLandscapeVisibilityFrame` (name may vary only +to fit existing conventions) from the existing completed visibility owner. It +contains: + +- the exact completed `HashSet`/`IReadOnlySet` by reference, with + no copy, union, sort, reconstruction, or second retained set; and +- the completed-world-view flag needed to distinguish an authoritative empty + answer from no answer. + +`WorldRenderFrameBuilder` captures that borrowed fact before the current frame +can complete and attaches it to `WorldRenderFrame` as a pack-only input. The +reference remains valid through the shadow prepass and is not retained after +the prepared world is consumed/cancelled. Do not rename the product into a +current-camera claim: on camera-only movement it is deliberately one completed +frame behind. + +The membership side of the selector borrows S2's existing +`ShadowObjectRegistry.TryGetRetailCellArray`; do not copy the registry rows +into the frame and do not add a render-owned cell dictionary. A narrow typed +read seam over that owner is allowed so tests need not construct `PhysicsEngine`. + +### 14.3 C2 — exact terrain and object selection + +Build one reusable, allocation-free per-frame selection over the retained +shadow topology: + +1. If `HasCompletedWorldView` is false, select zero terrain commands and zero + world casters. An authoritative empty landscape set also selects zero. +2. A loaded terrain slot is selected iff at least one of its authored 8x8 + outdoor land-cell ids occurs in the exact completed set. Scan the borrowed + set/slot facts directly; no visible-landblock `HashSet` is permitted. +3. A non-building caster is selected iff its non-empty retail CELLARRAY from + `TryGetRetailCellArray(LocalEntityId)` contains at least one outdoor land + cell in the exact completed set. A missing/empty registry product fails + closed. `ParentCellId`, `EffectCellId`, render bounds, origin cell, resident + landblock, and camera frustum are not substitutes. +4. Building shells are intentionally absent from `ShadowObjectRegistry` in + retail's building channel. Select a shell by its exact outdoor placement + cell, `RenderSourceMetadata.EffectCellId`; do not test its EnvCell + `BuildingShellAnchorCellId`. Zero/non-land placement fails closed. +5. Multi-cell objects select once, stable retained caster order is preserved, + and a visibility-only change does not touch membership, render-scene + registration, caster classification, material classification, mesh lookup, + or transform-journal ownership. + +Reusable bool/generation-mark arrays keyed by existing caster/terrain slots +are selection scratch, not a second visibility answer, and are allowed. +Another `HashSet`, dictionary keyed by cell, LINQ materialization, or +per-frame collection allocation is not. + +### 14.4 C3 — project visibility without rebuilding retained topology + +`DirectionalShadowCasterFrame.BuildSequence` and the prepared +material/mesh-topology `DirectionalShadowPreparedDraws.BuildSequence` remain +keyed only by their existing scene/mesh/fade topology inputs. A camera-only +visibility change must leave both sequences unchanged and report zero topology +classification/mesh-resolution work. + +Project the selection into reusable active draw products instead. For world +draws, arbitrary selected/unselected instances inside one prepared material +group must be represented exactly. A permitted implementation keeps the +retained transform array and emits allocation-free contiguous selected runs +with adjusted `BaseInstance`/`InstanceCount`, duplicating the already-classified +batch metadata for split runs. Equivalent retained-index/mask machinery is +acceptable only if GPU tests prove unselected instances cannot reach the +depth map. Merely changing one group's prefix count while leaving interleaved +unselected instances addressable is incorrect. + +The active command/batch/run product gets its own per-frame selection sequence +for GPU publication. Rebuilding or re-uploading that bounded indirect product +is not a topology rebuild; re-running `TryBegin` classification, mesh lookup, +or changing the topology build sequence is. Preserve the one N.5 transform +address space and all existing dynamic-transform journal/replay semantics. +Terrain may rebuild its bounded indirect command list from selected retained +slots each frame, but must not rebuild/upload terrain geometry or slot +topology. + +Diagnostics must distinguish resident/prepared topology counts from active +selected caster/instance/command counts. Existing celestial direction, +cascade fit/quality, day/night/indoor/portal gates, cutout/translucency/fade, +foliage wind, transform churn, and two-frame topology-deferral policy remain +unchanged. + +### 14.5 Allowed files and explicit non-changes + +Production changes are limited to the directly affected owners: + +- `Rendering/Vfx/ParticleVisibilityController.cs`; +- `Rendering/WorldRenderFrameBuilder.cs` and composition compile fallout; +- `Rendering/Scene/DirectionalShadowCasterFrame.cs` (selection only; existing + topology admission and revision semantics stay fixed); +- `Rendering/Wb/WbDrawDispatcher.DirectionalShadows.cs`; +- `Rendering/TerrainModernRenderer.DirectionalShadows.cs`; +- `Rendering/DirectionalSunShadowRenderer.cs`; +- the built-in and declared directional-shadow pack graphs. + +Tests may change only in the corresponding frame-builder, visibility, +directional-shadow caster/prepared/GPU/terrain/pack test files and compile- +fallout fakes. Documentation is limited to this packet, the S5 ledger row, +the architecture statement if its shared visibility-owner wording requires a +truth correction, and IA-24. If exact selection requires a production owner +outside this list, a shader/pipeline-layout change, a new divergence, or any +change to `ShadowObjectRegistry`, stop and return the fact before expanding. + +Do not change `WalkLandscape`, PView ordering/products, terrain/world ordinary +draws, S2 membership mutation, render-scene indices, streaming, portal/depth/ +alpha, particle/light behavior, shadow source/quality/cascade math, shader ABI, +RHI contracts, DAT/package formats, or any pack-off pixels/work. No graphical +client is launched from implementation or review worktrees. + +### 14.6 Tests, mutations, automated return, and reviews + +Production-facing tests must prove: + +1. the frame builder borrows the exact prior completed set reference and flag; + current Begin does not turn it into a current-camera product; +2. complete/abort/reset and first/login/portal/null-root cases have the stated + transaction semantics; +3. exact CELLARRAY intersection selects multi-cell outdoor static, dynamic, + and child casters once, while missing membership and ParentCell-only impostors + fail closed; +4. a building shell selects by outdoor `EffectCellId`, not its EnvCell anchor; +5. terrain selects only loaded slots reached by exact land cells; +6. alternating visible/invisible instances in one material group produce only + the correct active instance ranges and stable order; +7. camera-only visibility changes alter active output while both retained + topology build sequences, classification counts, mesh lookups, geometry, + and dynamic-transform mappings remain unchanged; +8. topology rebuild, transform journal refresh, fade/mesh-availability retry, + generation reset, and the existing two-frame deferral still converge; +9. built-in and declared packs consume the same typed selector; pack-off does + no shadow work; +10. the warmed production selection path allocates 0 managed bytes and retained + scratch remains streaming-bounded. + +At minimum sabotage and restore exactly: replace CELLARRAY with ParentCell; +select all resident terrain; use building anchor instead of effect cell; admit +missing membership; feed current building scratch instead of the completed +product; change a visibility-only frame so it advances the retained topology +sequence; and collapse an alternating group into a prefix `InstanceCount`. +Record each exact first failure in the implementer commit body. + +Implementer return: `git diff --check`; Release solution build 0W/0E; focused +visibility/frame/shadow caster/prepared/GPU/terrain/pack tests; the real warmed +0-B pin; official hermetic lane; inclusive InstalledDat lane with exactly the +documented global failure/skip identities; one clean commit and exact file/ +count/mutation report. + +Sequential review 1 — retail/deviation fidelity: re-check §14.1 against the +named decomp and paired executable/PDB, prior-completed timing, CELLARRAY and +building-channel sources, IA-24 truth, and pack-off non-participation. +Sequential review 2 — architecture/GPU/gate honesty: one borrowed set, no cell +reconstruction, arbitrary-instance correctness, no topology rebuild on camera +motion, transform/GPU flight safety, 0-B steady state, lifecycle/deferral, +allowed scope, counts, and at least three mutation claims. A failed lens gets +one bounded fix contract; a third fix round stops and is written up.