acdream/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md

125 KiB
Raw Blame History

Campaign OVERHAUL v2 — S5 consumers, material, and closeout packet

Status: S5-c1 through S5-c3 LANDED + REVIEW-CLOSED with lead graphical gates PROVISIONAL PASS; S5-c4 is contracted under §22. 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, one bounded OpenAI implementation agent changes only that contract, the lead verifies every retail claim against the named pseudo-C and the paired executable/PDB, and independent sequential OpenAI review lenses run before landing. Per the owner's 2026-09-04 overrides, no remaining campaign step uses Claude Code, Anthropic models, or Anthropic credentials, and a chunk may receive at most ten review passes. Each code finding still receives a bounded contract; documentation-only findings may be corrected directly by the lead. The chunk stops before an eleventh review. 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:

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:

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.

8. Pre-review gate correction — retired-row count

The first official hermetic lane is retained as a failed artifact: 16,759 of 16,760 tests passed. The only failure is WalkStaticStreamPopulatorTests.WorldAlphaCyptDocumentationAndRegister_PinPerCellTruthAndThreeResiduals: its literal expected 162 active AP rows, while this chunk correctly retires AP-117 and leaves 161. This is a coupled documentation-test correction, not a renderer finding and not a review fix round.

The bounded correction may change only tests/AcDream.App.Tests/Rendering/Walk/WalkStaticStreamPopulatorTests.cs, replacing the stale active-row count with 161. Do not add a fabricated register row and do not change the three AP-241/AP-242/AP-243 assertions. Run the exact failed test first, then a fresh official hermetic lane under a new artifact name and the required InstalledDat lane. Preserve the original failed artifact and record both identities in the implementer return.

9. S5-c1 implementation result — 2026-09-04

The bounded implementation publishes WalkFrameDriver.VisitedLandscapeCellIds as the typed landscape product, retains it transactionally in the particle visibility owner, and applies the retail cell-family virtual: membership for land cells, constant true for non-null EnvCells. The null-root terrain reconstruction and the dead point-light drawable-cell feedback chain are deleted. AP-117 is retired; AP-85 and AD-21 now describe the surviving code.

The real warmed allocation pin initially exposed that enumerating the retained SortedSet<int> of world-simulation handles allocated on every Apply. The owner is now a sorted List<int> maintained at lifecycle mutation time, so the production Apply loop preserves stable handle order and measures 0 B without changing queue, router, draw, or particle tick behavior. This is an implementation-mechanism correction, not a retail behavior deviation.

Focused returns before the official lanes: Core VFX 111/111, App particle / frame / renderer / terrain 146/146, and the real warmed production allocation pin 1/1 at 0 B. Release built with 0 warnings / 0 errors. The first official hermetic artifact, artifacts/s5-c1-hermetic-20260904, is deliberately preserved at 16,759/16,760: its sole failure was the stale 162-row test literal after AP-117's retirement. Section 8 authorized only that coupled test correction; the exact failed pin then passed 1/1 with the truthful 161-row header and physical count. The one-shot corrected official lane at artifacts/s5-c1-hermetic-corrected-20260904 then passed 16,760/16,760, 0 skipped, across 14 assemblies. The inclusive InstalledDat lane at artifacts/s5-c1-installed-20260904 produced the documented global set: 385 passed, 10 failed, 1 skipped. The failures are TowerAscent, the two #383 layout sweeps, #458 Oh_doorway_still_first_frame_diff, and the six AlphaFlushCounts_* transcript Facts; the skip is Sweep_the_lookin_gate_decodes_against_the_street_fixture. No new failure or skip identity appeared.

Independent mutation ledger (each mutation restored exactly before the next):

  1. EnvCell eligibility made set-dependent: ApplyRetailView_UsesLandscapeMembershipButEnvCellConstantVirtual first failed Assert.True, expected true / actual false, at ParticleSystemTests.cs:553.
  2. Outdoor eligibility made constant true: the same test first failed Assert.False, expected false / actual true, at ParticleSystemTests.cs:559.
  3. Renderer fed the diagnostic union: PViewWorld_PublishesOnlyLandscapeCellsToParticleVisibility first failed the HashSet equality at WorldSceneRendererTests.cs:279, expected [16842755], actual [16843008, 16842755].
  4. A production CollectVisibleCells symbol was restored: Production_source_has_no_reconstructed_particle_visibility_feedback first failed at TerrainParticleCellVisibilityTests.cs:37, naming TerrainModernRenderer.cs.
  5. A production ObserveDrawableCells symbol was restored: the same source guard first failed at line 37, naming WorldRenderFrameBuilder.cs.
  6. The inclusive boundary was changed from <= to <: ApplyRetailView_UsesOwnerVisibilityAndInclusiveAuthoredDistance first failed Assert.True, expected true / actual false, at ParticleSystemTests.cs:519.

10. Sequential review 1 — retail lens and fix round 1

The retail lens found no behavioral retail-fidelity defect. It independently matched the paired executable/PDB identity and bytes for ShouldDrawParticles, UpdateParticles, both cell-family virtuals, the previous-completed-frame transaction, the low-word discriminator, examination bypass, x87 distance edges, AP-116, the exact landscape handoff, and unchanged particle draw/queue/tick behavior. The lens returned FAIL on comment truth only:

  1. ParticleVisibilityController.UseWorldView still says an outdoor fallback can publish the authoritative product, although S5-c1 deleted it.
  2. WalkFrameDriver.CopyVisibleCellsTo still calls the diagnostics union the complete CObjCell::IsInView answer and says particles, lights, and shadows consume it. Particles now consume only the landscape half, EnvCell particle eligibility is constant true, point lights use the resident registry, and directional shadows remain S5-c2.
  3. ParticleSystem calls the sorted-list lifecycle insertion/removal cost binary even though only the insertion search is binary and list shifts / removal are linear. Its adjacent blanket O(log E) lifecycle sentence must remain scoped to the SortedSet indexes rather than the new list.

Fix round 1 is comment-only. It may change exactly ParticleVisibilityController.cs, WalkFrameDriver.cs, and ParticleSystem.cs, plus this packet's result section. Do not change behavior, tests, register rows, architecture prose, or any other file. Correct the three descriptions to the surviving ownership/cost model, run git diff --check and the same focused retail-review classes (47 Core particle tests, 38 App visibility/terrain/frame/renderer tests, and 3 AP-116 settings/live-object tests), commit once, then return to a narrow retail comment-truth re-review. The production/gate-honesty lens remains undispatched until that re-review passes. A third fix round still stops the chunk.

10.1 Fix-round-1 implementation result

The three stale descriptions are corrected without behavior or assertion changes. CopyVisibleCellsTo describes a diagnostic union and names the distinct particle, point-light, and future directional-shadow consumers. ParticleSystem scopes the logarithmic lifecycle statement to its SortedSet indexes and records the sorted list's binary-search plus linear-shift insertion and linear search/compaction removal costs. Focused gate results: Core ParticleSystemTests 47/47, App visibility/terrain/frame/renderer 38/38, and AP-116 settings/live-object 3/3; git diff --check is clean. The first narrow re-review found the UseWorldView result sentence still misstated null-root transaction state; fix round 2 below supersedes that sentence.

11. Retail narrow re-review — fix round 2 (last allowed)

The narrow retail re-review passed the four-file scope, behavior/test/register invariance, diagnostic-union wording, sorted-list cost wording, diff check, and the focused 47 + 41 tests. It found one remaining MINOR comment-truth error: ParticleVisibilityController.UseWorldView and §10.1 say the null-root safety draw omits/excludes the completed product. Production begins visibility before root resolution and calls UseWorldView for every non-login built frame, so a null-root safety frame completes hasCompletedView=true with an empty landscape set. Login/portal frames carry hasCompletedView=false. This distinction is already the bound §3 behavior: null-root invents no fallback cells.

Fix round 2 is the last allowed round and is prose-only. It may change exactly the UseWorldView XML comment in ParticleVisibilityController.cs and this packet's result prose. State that non-login world frames participate in the completed transaction; the retail walk publishes its exact landscape set when present, while null-root completes an empty set without reconstruction. Do not change code behavior, tests, register/architecture prose, or any other file. Run git diff --check, Core particle 47/47, and the combined App/AP-116 41/41; commit once and return to the same narrow retail lens. Any further finding that would require a third fix round stops S5-c1 and is written up.

11.1 Fix-round-2 implementation result

UseWorldView now states the production transaction exactly: every non-login world frame participates; a PView walk contributes its exact landscape set, while a null-root safety frame completes hasCompletedView=true with an empty set and no reconstructed fallback. Login and portal-space frames retain hasCompletedView=false. No behavior or assertion changed. Core particle tests passed 47/47, the combined App visibility/terrain/frame/renderer plus AP-116 lane passed 41/41, and git diff --check is clean.

12. Owner-authorized documentation/evidence exception — 2026-09-04

The final production/gate-honesty lens found no production-code or test defect but returned FAIL after fix round 2 on two correction-worthy truth gaps:

  1. architecture and AD-21 say null-root publishes no cell-visibility answer, while production completes hasCompletedView=true with an empty landscape set; and
  2. the official lane summaries identify dirty bases, but the packet does not independently bind those dirty source deltas to implementation commit 9aadc917a.

Per the campaign rule, S5-c1 stopped and the campaign branch recorded that stop at efb075619. The owner then explicitly authorized a documentation/evidence-only exception: "correct docs and continue." The stop and both failed-lens results remain in history.

The exception is bounded to:

  • truth-correcting the null-root sentence in docs/architecture/acdream-architecture.md;
  • truth-correcting AD-21 in docs/architecture/retail-divergence-register.md;
  • recording this exception and its evidence in this packet; and
  • updating only the S5-c1/S5 ledger rows in docs/plans/2026-09-01-campaign-overhaul-world-solidity.md.

No production code, tests, other register row, architecture section, or prior artifact may change. The correction must state that every non-login world frame participates, a walk contributes its exact landscape set, and null-root completes an empty set without reconstruction; login/portal remain false.

After the documentation correction is committed, create fresh official evidence from that clean exact commit (not a dirty pre-commit tree):

  • artifacts/s5-c1-exception-hermetic-20260904 — hermetic lane;
  • artifacts/s5-c1-exception-installed-20260904 — InstalledDat lane.

Both summaries must record the correction commit and WorktreeDirty=false; their manifests must verify completely. The older dirty-base artifacts remain preserved as historical evidence but are superseded for landing provenance. One narrow independent production/gate-honesty re-review verifies only the authorized documentation diff, exact clean artifact identity/counts/hashes, and absence of code/test changes. PASS permits landing and the graphical gate; any behavioral change or further correction-worthy finding stops again.

12.1 Exception implementation result — clean evidence complete

The authorized documentation correction aligns the architecture and AD-21 with production's existing transaction without changing code or tests: every non-login normal-world frame participates, the walk contributes its exact landscape set when present, and null-root completes hasCompletedView=true with an empty set and no reconstruction; login and portal-space retain hasCompletedView=false.

The pre-exception official artifacts remain preserved as historical evidence, including their dirty-base identities. They do not become clean commit-bound evidence by prose assertion. Both replacement lanes ran from exact correction commit d6592d3ac56bc400bfdaab7cff59306319b5b96d with WorktreeDirty=false and now supersede the older dirty artifacts for landing provenance:

  • artifacts/s5-c1-exception-hermetic-20260904 — PASS, 16,760 passed, 0 failed, 0 skipped across 14 assemblies. Its 32-entry SHA-256 manifest verifies with zero missing or mismatched files.
  • artifacts/s5-c1-exception-installed-20260904 — 385 passed, the same 10 documented failures, and the same 1 documented skip across 14 assemblies. Its 30-entry SHA-256 manifest verifies with zero missing or mismatched files. Compare-Object over every non-passing TRX identity against the historical inclusive artifact returned zero differences.

The first clean InstalledDat invocation omitted ACDREAM_RUN_INSTALLED_DAT_TESTS=1; 97 live-DAT tests therefore self-skipped with their explicit opt-in message. That invalid evidence is preserved at artifacts/s5-c1-exception-installed-invalid-missing-env-20260904 (291 passed / 8 failed / 97 skipped) and is not used for acceptance. The canonical invocation pinned both ACDREAM_RUN_INSTALLED_DAT_TESTS=1 and ACDREAM_DAT_DIR=C:\\Turbine\\Asheron's Call; it produced the exact documented identity above without a product change or product retry.

Production and tests remain byte-identical to the authorized contract parent. The plan ledger therefore advances to clean evidence complete, with only the narrow independent production/gate-honesty review pending before landing and the graphical gate.

13. S5-c1 landing and lead graphical gate — 2026-09-04

S5-c1 is LANDED. The mandatory stop remains in campaign history at efb075619; the owner-authorized continuation was not used to rewrite it. Reviewed scratch commits 9aadc917aafaebcad674a2e4c48ed8200664a28384d80b7a7eb9e2d6592d3acb2d56f9e3 map to campaign commits 94a6b5ef3282fe87fb4d11108123f17c91316bbb9e11736569c0b0ad115141a1718832e2. The integrated tree is byte-identical to reviewed scratch tip b2d56f9e3.

The one narrow independent exception re-review returned PASS with no finding. It verified the exact four-document authorized scope, the corrected architecture/AD-21 transaction, no src/ or tests/ diff, both clean summary identities and counts, hermetic 32/32 plus InstalledDat 30/30 manifest verification, zero non-passing-identity difference from the historical inclusive InstalledDat artifact, and honest exclusion of the missing-opt-in attempt.

Fresh campaign verification at 1718832e2: Release solution build PASS with 0 warnings / 0 errors; Core VFX 111/111; focused particle-visibility/frame 38/38; warmed production particle-view allocation plus AP-116 settings/live object 4/4. The worktree was clean before launch.

The lead graphical gate is PROVISIONAL PASS pending owner inspection. Before launch, ACE was listening on UDP 9000 as PID 13340 and neither acdream nor retail client was running. One Release client ran tools/overhaul-selfgate/route-portal-haze.txt from clean 1718832e2, exited 0, confirmed graceful logout, and left no client process. Evidence root: logs/selfgate-20260904-171137-s5c1-particle-visibility.

All ten PNGs were captured:

  • artifacts/screenshots/h00-before.png;
  • Facility sequence: h01-arrive-0ms.png, h02-arrive-400ms.png, h03-arrive-1000ms.png, h04-arrive-2000ms.png, h05-arrive-4000ms.png;
  • Holtburg sequence: h11-arrive-0ms.png, h12-arrive-400ms.png, h13-arrive-1000ms.png, h14-arrive-2000ms.png.

Lead inspection: both arrival sequences show the authored magenta 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<uint>/IReadOnlySet<uint> 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<uint>, 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.

14.7 S5-c2 implementation result — clean evidence complete; fix round 1 implemented

The bounded implementation is complete for review. The selected atmospheric pack now borrows the existing visibility controller's exact prior-completed set and completed-view flag by reference. The frame captures that fact before the current transaction begins and borrows S2's retained CELLARRAY owner through a typed read-only adapter. No second visibility set, cell index, or fallback was added.

The retained caster and terrain products now have separate active-selection projections. Ordinary casters intersect their non-empty retail CELLARRAY with the completed landscape set; building shells use outdoor EffectCellId; missing membership and no/empty completed views fail closed. The established outdoor family remains low != 0 && low < 0x0100 (including 0x41), while a terrain slot scans only its authored 1..64 cells. Arbitrary selected instances inside one material command are emitted as exact contiguous BaseInstance/InstanceCount runs. Active indirect publication advances its own sequence; caster, prepared-draw, and terrain topology sequences remain unchanged on visibility-only frames. Terrain snapshot publication also marks an aborted build invalid so the next frame retries rather than accepting a partially written snapshot.

Built-in and declared directional-shadow graphs call the same typed selector and pass the same prior product into terrain selection. The existing production pack-off integration remains unchanged and proves no active pack runtime, shadow resource, or shadow work. IA-24 now states the prior-view/S2 selection adaptation and keeps the shadow map explicitly non-retail.

Pre-commit automated evidence:

  • Release solution build: PASS, 0 warnings / 0 errors.
  • focused visibility/frame/caster/prepared/GPU/terrain/built-in/declared/ pack-off/long-cycle lane: 137 passed, 0 failed, 0 skipped;
  • warmed production selection: caster selector, arbitrary-run projection, and terrain projection each measured 0 managed bytes while retained scratch and topology build sequences stayed stable;
  • git diff --check: PASS.

The required mutations were each built, run against the named production pin, and restored exactly. Their actual first failures were:

  1. CELLARRAY → ParentCellId: PriorLandscapeSelection_UsesExactCellArrayAndBuildingEffectCell, first Assert.Equal expected [201, 202, 203, 205], actual [204, 205].
  2. Select every resident terrain range: PriorLandscapeSelection_ScansExactAuthoredEightByEightCells, first Assert.Single found 3 commands.
  3. Building anchor → placement effect cell: PriorLandscapeSelection_UsesExactCellArrayAndBuildingEffectCell, first Assert.Equal expected [201, 202, 203, 205], actual [201, 202, 203, 206].
  4. Admit missing membership: the same caster pin's first Assert.Equal expected [201, 202, 203, 205], actual [201, 202, 203, 204, 205].
  5. Publish current building scratch instead of the completed product: BorrowedLandscapeFrame_TracksOnlyCompletedTransactionsByReference, first Assert.True expected HasCompletedWorldView=true, actual false after the completed empty frame.
  6. Advance retained caster topology during selection: PriorLandscapeSelection_UsesExactCellArrayAndBuildingEffectCell, first topology Assert.Equal expected BuildSequence=1, actual 2.
  7. Collapse alternating selection into one prefix instance count: AlternatingCasterSelection_EmitsExactContiguousInstanceRuns, first active-command-count Assert.Equal expected 3, actual 1.

The bounded implementation is commit 603d4bbb05ebc3e840b5d6e66a20a4c9d3cecc8a. All three official summaries name that exact commit and record WorktreeDirty=false; their existing SHA-256 manifests verify without a missing or mismatched file:

  • artifacts/s5-c2-hermetic-20260904 — 16,768 passed, 0 failed, 0 skipped; manifest 32/32 present and matching.
  • artifacts/s5-c2-installed-20260904 — the first, deliberately preserved broader run used the literal Lane=InstalledDat filter and produced 468 passed, 10 failed, 1 skipped; manifest 30/30 present and matching. It is valid additional evidence, but it is not renamed or presented as the canonical comparison.
  • artifacts/s5-c2-installed-canonical-20260904 — the distinct canonical comparison used the same accepted S5-c1 project filter, Lane=InstalledDat&Purpose!=Diagnostic, and produced 385 passed, 10 failed, 1 skipped; manifest 30/30 present and matching.

Both S5-c2 InstalledDat artifacts contain the same 11 nonpassing TRX identities as the accepted S5-c1 canonical artifact. The broad-versus-S5-c1 and canonical-versus-S5-c1 Compare-Object comparisons each returned zero differences. Their different passing totals remain explicit because the two intentional filters are not interchangeable.

Sequential retail/deviation review returned PASS without a production correction. Sequential architecture/GPU/gate-honesty review found the code, architecture, GPU-flight safety, lifecycle, allocation, and implementation scope otherwise passing, but returned FAIL because this result and the campaign plan still described clean evidence as pending and named only the broader InstalledDat run. Fix round 1 changes only those two evidence/status documents and is implemented pending narrow re-review. The stationary three-buffer per-frame publication is real, explicitly permitted by §14.4, and bounded by Vulkan's two-flight retirement fence; it is a performance note, not a correction and not the #350 mechanism.

15. S5-c2 production-review fix round 1 — evidence provenance only

Retail/deviation review passed the exact implementation commit 603d4bbb05ebc3e840b5d6e66a20a4c9d3cecc8a without a correction. The subsequent architecture/GPU/gate-honesty review found no production-code, test, lifecycle, allocation, GPU-flight, or scope defect. It returned FAIL on one documentation-only truth gap: §14.7 and the plan still say clean evidence is pending and name only the first, broader InstalledDat run, while two clean InstalledDat artifacts now exist with different intentional filters.

This is fix round 1. It is bounded to evidence provenance and status text:

  1. Change §14.7's heading and tail from pending/future tense to the exact clean results already on disk. Name the implementation commit and WorktreeDirty=false.
  2. Record the hermetic artifact artifacts/s5-c2-hermetic-20260904: 16,768 passed, 0 failed, 0 skipped; SHA-256 manifest 32/32 present and matching.
  3. Preserve and explain the first InstalledDat artifact rather than hiding, renaming, replacing, or calling it canonical: artifacts/s5-c2-installed-20260904 ran the literal filter Lane=InstalledDat and produced 468 passed, 10 failed, 1 skipped; manifest 30/30 present and matching.
  4. Name the distinct canonical comparison artifact artifacts/s5-c2-installed-canonical-20260904. It ran the same accepted project filter used by S5-c1, Lane=InstalledDat&Purpose!=Diagnostic, and produced 385 passed, 10 failed, 1 skipped; manifest 30/30 present and matching.
  5. State that both S5-c2 InstalledDat artifacts have the same 11 nonpassing identities as the accepted S5-c1 canonical artifact and that both exact Compare-Object comparisons returned no differences. Do not collapse the two passing counts into one claim.
  6. Record both sequential review outcomes honestly: retail PASS; production FAIL on this evidence-text defect only, with code/architecture/GPU-flight otherwise passing. The stationary three-buffer per-frame publication is real, explicitly permitted by §14.4, and bounded by Vulkan's two-flight retirement fence; it is a performance note, not a correction or #350 mechanism.
  7. Update only the S5-c2/S5 status text in the campaign plan to say fix round 1 is documentation-only and implemented/pending narrow re-review. Do not mark the chunk landed, review-closed, self-gated, or user-accepted.

Allowed files are exactly this packet and docs/plans/2026-09-01-campaign-overhaul-world-solidity.md. No source, test, register, architecture, artifact, manifest, filter, or client change is authorized. Do not rerun a lane or launch the graphical client. Return one clean docs-only commit, git diff --check, exact file/count report, and prove every named artifact/manifest/count/filter directly from its existing files.

One narrow independent production/gate-honesty re-review then checks only the two corrected documents against the three clean artifact directories and the two recorded review verdicts. A new correction-worthy finding would be fix round 2; a third fix round still stops S5-c2 and is written up.

16. S5-c2 review closeout, landing, and lead graphical A/B — 2026-09-04

The narrow independent production/gate-honesty re-review returned PASS with no finding. It checked the two-document fix-round scope, all three clean artifact directories and manifests, both InstalledDat filters and counts, the two unchanged nonpassing-identity comparisons, and the recorded sequential review verdicts. No production or test file changed in fix round 1.

The reviewed scratch stack maps to the campaign branch as follows:

  • implementation 603d4bbb05e -> a4de2efc4;
  • lead fix-round contract 0025bb2c097 -> 048027e71;
  • evidence/status correction 521f5edda54 -> ef819eedf.

The integrated campaign tree at ef819eedf is byte-identical to reviewed scratch tip 521f5edda54. Fresh campaign verification passed: Release solution build 0 warnings / 0 errors and the affected 137-test lane 137/137. The official clean evidence remains §14.7's hermetic 16,768/16,768, broader InstalledDat 468 pass / 10 documented fail / 1 skip, and canonical InstalledDat 385 pass / the same 10 documented fail / 1 skip, with all manifests and nonpassing identities verified.

The first graphical run at logs/selfgate-20260904-182320-s5c2-shadow-selection captured all seven transition PNGs and reached its checkpoint without a fatal log entry, but its route omitted close-client. GLFW exposes no main-window handle to the runner, so the runner's graceful external close could not succeed. The owner was away from the computer and explicitly directed the lead to close it; after the graceful path was exhausted, the lead terminated only the verified campaign PID. This run is retained as visual evidence but its teardown is FAIL, not the valid c2 gate.

The lead then added an out-of-tree A/B route with an in-client close-client step and built exact parent 5c106bcdf in detached worktree s5-c2-ab-parent (Release 0 warnings / 0 errors). Before each run ACE was UP on UDP 9000 as PID 13340 and no graphical client was running. Exact evidence:

  • parent: s5-c2-ab-parent/logs/selfgate-20260904-183815-s5c2-parent-shadow-ab;
  • candidate: logs/selfgate-20260904-183925-s5c2-candidate-shadow-ab at clean ef819eedf.

Both runs produced all seven PNGs, exited 0, logged graceful logout confirmed, left no client process, and contained no fatal/unhandled/device-lost/validation match. Candidate metadata shows exact active selection rather than retained topology fallback: 2,500 selected casters on the first high frame and 3,087 after re-enable, with four cascades and 26 draws; pack-off reports zero pack work. Terrain, buildings, actors, UI, weather transitions, resize, and pack off/on recovery remain present. The lead verdict for S5-c2's own scope is PROVISIONAL PASS pending owner inspection.

The A/B also proves a conspicuous darkening on atmospheric re-enable is pre-existing: exact parent and candidate both reproduce it. The receiver shaders switch outdoor directional lighting from authored -uLights[0].dirAndRange to uShadowLightDirectionAndSource whenever the shadow flag becomes nonzero; the shadow-strength weight does not blend that lighting-direction change. This is not an S5-c2 regression, but it is not silently accepted as a solid-renderer result: issue #469 records it and IA-24 now names the gate-visible discontinuity. It must be resolved or explicitly owner-accepted before G4. S5-c3 is next; G4 remains unpassed and nothing may merge to main.

17. S5-c3 contract — exact building degrade selection and complete-body gate

This chunk is deliberately bounded to the building part-0 path named by S5. It replaces the capture-specific fixed +0.99 selection, preserves the selected GfxObj identity separately from its optional drawing BSP, draws that selected shell, and makes the three already-authored Config preferences live. It does not add generic entity LOD, change S5-c1 particle visibility, change S5-c2 shadow selection, or implement the fixed-function material work reserved for c4.

17.1 Lead-verified retail and paired-binary facts

The paired executable is C:\Users\erikn\Downloads\acclient.exe, SHA-256 006FFEADC5D679C871497112A5BD1F87714D0E273E2166BAE5052DDE369297B1. Its CodeView record remains GUID {9E847E2F-777C-4BD9-886C-22256BB87F32}, age 1, matching refs/acclient.pdb. Fresh read-only Ghidra output was checked against the named pseudo-C. Exact function byte ranges are:

Function VA / file offset / length SHA-256
SceneTool::UpdateFPSCounter 0x0043E510 / 0x0003E510 / 176 4B49B883F2F03284F08BAF70716F2AFFAA6591EAD4142D8D5A68879F79CA9DA2
CPhysicsPart::Draw 0x0050D7A0 / 0x0010D7A0 / 192 965E1E6208DF662EE3466AA455CFF57BBDEA8AA3751E4DE2F5FD30C3842661FA
CPhysicsPart::UpdateViewerDistance 0x0050E030 / 0x0010E030 / 384 30F0EEA8829728497E1D00E0D9737DF9EB112CC6643A24ED6150F1350D29D49D
GfxObjDegradeInfo::get_degrade 0x0051E4B0 / 0x0011E4B0 / 400 E0FE4A2BC79F108985B84DDBA44460B8B80809AE81088779D02C2FEF6CCDD8B7
Render::SetDegradeLevelInternal 0x0054C3C0 / 0x0014C3C0 / 240 9A59895EC901ABA75584EA5B059222C00CC9CF2B7AF54F5FB7C2A2CF444D83E4
Render::CalcDegLevel 0x0054CAF0 / 0x0014CAF0 / 736 607DC8B8DBAAB9498C163241CE535E14751378A7EC06DFFD724BB68910C7BB08
RenderDeviceD3D::DrawBuilding 0x0059F2A0 / 0x0019F2A0 / 177 0FEC14C65D32DACEA0344A9F347937A2588CE3D14694AC658607BDFE5ACDE125

RenderDeviceD3D::DrawBuilding @0x0059F2A0 always publishes the building's outdoor portal list and calls UpdateViewerDistance(parts[0]). Its complete body is gated only by parts[0]->gfxobj[parts[0]->deg_level] != nullptr. Inside that gate retail sets building/detail state, calls FlushAlphaList(0f), calls CPhysicsPart::Draw(part0, 1) for the portal-only walk, sets the building flag, calls CPhysicsPart::Draw(part0, 0) for the selected shell, clears the flag, and clears detail state. A non-null selected GfxObj whose drawing_bsp is null therefore still crosses the alpha barrier and draws its shell; only the portal-only sub-walk naturally emits nothing. The current acdream if (bsp is null) return conflates those facts and is wrong.

CPhysicsPart::Draw @0x0050D7A0 normalizes its local level to zero when the part has no degrade descriptor or its stored level is outside the loaded Gfx array, then indexes gfxobj[level]. A null selected GfxObj returns; a non-null one reaches DrawMesh. UpdateViewerDistance @0x0050E030 measures from the viewer to the base GfxObj's sort center after component-wise part scale, stores CYpt and heading, selects level zero/mode one for a missing ladder or the player, otherwise calls get_degrade(CYpt / gfxobj_scale.z), and calculates a draw frame only when the selected GfxObj is non-null.

GfxObjDegradeInfo::get_degrade @0x0051E4B0 uses max(0, abs(distance) - Render::s_rDegradeDistance). With automatic degrades enabled it uses Render::deg_mul; otherwise it uses Render::s_rUserSuppliedDegradeBias. For a nonnegative multiplier the strict threshold is ideal - (ideal - max) * multiplier; for a negative multiplier it is ideal + (ideal - min) * multiplier. The first strict effective < threshold match wins; equality advances; no match selects the last level. degrades_disabled forces level zero and that level's mode; a forced level is clamped to the last slot. This chunk has no production force-level or global disable control, but its pure selector must keep those two explicit inputs so the retail branches are pinned and no future caller must fork the algorithm.

The binary statics are s_rDegradeDistance=50, max_framerate=20, min_framerate=8, ideal_framerate=10, auto_update_deg_mul=1, manual bias 0, and initial deg_mul=0. The Config UI's authored defaults are separately automatic=false, bias=0, distance=50; production follows the persisted UI preference, not a capture's transient multiplier.

SceneTool::UpdateFPSCounter @0x0043E510 sums the prior 20 frame-duration slots, publishes FPS as zero when the sum is not strictly greater than 0.000199999995f, otherwise publishes 20/sum, then shifts the history and inserts the just-finished duration. Preserve this retail one-sample ordering, the 20-slot warmup contents, and single-precision behavior.

Render::CalcDegLevel @0x0054CAF0 first shifts its 30-slot candidate history. With automatic degrades off it stores the unchanged current automatic multiplier and returns. With automatic degrades on it evaluates retail's exact five-weight piecewise formula from current FPS and the 8/10/20 rates, adds the current multiplier, clamps to [-1,+1], and calls SetDegradeLevelInternal(candidate) only after all 30 prior history slots are within the strict retail abs(slot-candidate) < 0.01 band; it finally stores the resulting current multiplier. Port this body as one testable pure routine from the named function and paired bytes. A proportional controller, moving average substitute, time-based debounce, modern clamp, or reordered history is not equivalent.

Render::SetDegradeLevelInternal @0x0054C3C0 also derives retail object, particle, static-light, and dynamic-light budgets. S5-c3 changes only the building consumer of deg_mul: TS-15, AP-116, and AP-85 already own the surviving non-building LOD, particle-range, and light-pool differences and must be amended in the same implementation commit to name that uncoupled adaptive-budget fact. Do not perturb those already-landed policies here.

Finally, CBuildingObj::makeBuilding @0x006B53A0 calls InitPartArrayObject(model, 1). That path accepts either a direct GfxObj or a Setup, but DrawBuilding still uses only parts[0]. A Setup-backed building therefore resolves the existing SetupMesh.Flatten/Resting placement part zero and its transform; it never flattens every Setup part into the building shell draw. The installed-DAT census below contains no Setup building, so this branch is a synthetic structural pin, not an installed-population claim.

17.2 Installed-DAT population pin

The lead scanned the installed land/cell/portal DATs through the legal DatCollection reader before this contract. Record and reproduce these exact facts in an InstalledDat test or an existing InstalledDat census surface:

  • 1,639 landblocks contain 6,979 building instances across 398 distinct models;
  • all 6,979 installed building models are direct GfxObjs; zero are Setup or another type;
  • all 6,979 resolve part-zero GfxObj data; none are missing;
  • 6,760 instances have degrade ladders, containing 27,859 level slots across 350 distinct ladder models;
  • every one of those 6,760 ladders has exactly one zero-id slot and it is the final slot; no nonzero slot is missing and all 21,099 nonzero slots have a drawing BSP;
  • level-count histogram: 2→196, 3→216, 4→4,964, 5→1,341, 6→43;
  • there are no duplicate building-anchor groups.

Thus the complete-body null-selected-Gfx path is real and widespread, while the non-null-Gfx/null-BSP path requires a synthetic pin even though its retail behavior is unambiguous. Do not “repair” the authored final zero slots, clamp to the last nonzero slot, or use BSP presence as a body-existence proxy.

17.3 One typed selection, one shared degrade owner

Replace BSP-only selection with one value that carries at least the selected GfxObj id, nullable drawing BSP, degrade level, and degrade mode. The base direct-Gfx path carries its own GfxObj id even with no ladder. Ladder entries carry the authored GfxObj id and mode as well as min/ideal/max and the optional BSP. A selected GfxObj id of zero is the exact complete-body failure. A nonzero id with null BSP is an admitted complete body with no portal walk. HasGeometry, the fixed DefaultDegradeMultiplier=0.99, and the erroneous default distance 100 are deleted, not retained as fallback truths.

Create one renderer-lifetime degrade owner, passed/borrowed through normal composition: no static mutable global, service locator, duplicate UI mirror, or second ticker. It owns the 20 frame-time slots, 30 candidate slots, current automatic multiplier, exact rolling FPS, and the current persisted settings view. It advances exactly once per accepted graphical render callback using that callback's real delta; world replacement/portal travel does not recreate or double-tick it. Settings changes are observed on the next frame:

  • automatic=false → building selection and the FPS panel's DEG field use the persisted manual GraphicsPerformance bias;
  • automatic=true → they use the exact current automatic multiplier;
  • both modes use the persisted DegradeDistance;
  • the FPS panel's FPS field borrows this same retail rolling-FPS value, not a second cadence, while its authored show/hide option remains unchanged.

The controller must define and pin initial/warmup behavior, zero and tiny deltas, NaN/infinity input, settings toggle transitions, and exact float ordering. It may fail closed or sanitize only where the retail x87 comparison would do so identically; any modern safety divergence must receive a register row in this same commit. No allocation is permitted after warmup.

17.4 Exact building body, portal, and selected-shell execution

At DrawBuilding entry retain the unconditional BLD transcript event and portal-list publication. Then select part zero once and use that same immutable selection for every downstream action:

  1. selected GfxObj id zero: return after entry publication; no alpha barrier, portal walk, look-in draw, or shell;
  2. selected id nonzero: emit the existing alpha barrier first;
  3. if the selection's BSP is non-null, run the existing pass-1/pass-2 portal walk through each active view; if null, emit no portal work but continue;
  4. submit the shell after the portal walk using exactly the selected GfxObj id.

Thread the typed selection through OnBuildingShellTurn and the production world/populator/dispatcher seam. Do not mutate the retained RenderProjectionRecord, rebuild retained topology, clone a record per frame, or silently keep the base shell's MeshRefs. Classification must preserve the retained building's scene/lifecycle identity, root transform, material/ surface overrides, detail state, effect/anchor membership, and picking facts, while replacing the part-zero GfxObj with the selected one. Direct-Gfx models use identity part transform. Setup models use exactly the precomputed part-zero placement/default-scale transform, and portal projection, sort-center distance, and shell submission must agree on the same composed part-zero frame.

The building path submits exactly one selected part-zero mesh. If its render mesh is not resident, request/load that selected id through the existing asynchronous mesh seam and draw no shell for that frame; never fall back to the base GfxObj, block on DAT access, or query DAT from the renderer. Retry on the following frame through existing residency behavior. Zero retained shell records during a streaming boundary remains an empty shell turn; multiple matching retained shell records for one committed building is a fail-loud ownership error. No new dictionary, cell scan, or linear model search may run per building per frame.

17.5 Config and deviation truth

Render_AutomaticDegrades, Render_GraphicsPerformance, and Render_DegradeDistance become live rows and must no longer receive storeOnly:true or cite AP-198. Update the exact Config dim-set test and all comments/counts that pin it. AP-198 narrows from its current residual set by those three rows; do not disturb the already-live landscape-radius and building-detail controls. Keep AD-78's count and description mechanically consistent with the actual controller test.

Narrow TS-15 explicitly to non-building parts. Amend AP-85 to say its fixed one-list light cap is not driven by SetDegradeLevelInternal's multiplier, and AP-116 to say the explicit Retail/Extended particle-range choice is not the adaptive multiplier's object/particle distance budget. Those existing rows cover every intentionally uncoupled SetDegradeLevelInternal consumer; add no duplicate row. If implementation discovers another surviving deviation, add or correct its row in the same commit. The active-row total must change only if a row is actually added or retired; narrowing does not change it.

17.6 Allowed scope and explicit nonchanges

Allowed production scope is the existing building walk/factory/registry, frame-driver world-data/populator/dispatcher classification seam, the one renderer/frame-root composition seam needed for the shared controller, the FPS retained-UI binding, DisplaySettings comments, and the Config row dimming flags. One focused App-layer controller file may be added. Tests may change only for those surfaces, the exact retail math, installed census, composition identity, residency retry, lifecycle, and allocation. The only authorized documentation file in the implementation commit is docs/architecture/retail-divergence-register.md.

Do not change portal admission, BSP traversal, alpha FIFO routing, material blend/state, particle update/range, point-light selection, terrain/shadow selection, streaming radii, generic entity/scenery/creature LOD, DAT reader, RHI/shaders, login/network/runtime gameplay, self-gate scripts, artifacts, or this packet/plan. Do not add a base-shell fallback. No graphical client is launched by the implementer.

17.7 Required automated proof, mutations, and return

Focused tests must prove at minimum:

  1. direct base Gfx and ladder selections carry exact id/BSP/level/mode;
  2. positive and negative multiplier arms, strict threshold equality, last slot, disable, forced-level clamp, scaled sort-center/CYpt, zero/negative/ NaN/infinity inputs match a literal independent retail oracle;
  3. the prior-20 FPS ordering and the complete 30-slot CalcDegLevel formula, stability gate, clamp, manual arm, warmup, and settings transitions match fixed expected sequences—not implementation self-comparison;
  4. zero selected Gfx emits BLD only; nonzero/null-BSP emits BLD → alpha barrier → selected shell with no portal events; nonzero/BSP preserves BLD → barrier → portal passes/look-ins → selected shell;
  5. a far selected LOD changes the submitted GfxObj id while all retained ownership, transform, surface/detail, effect-cell, picking, and ordering facts remain exact; no base fallback occurs while the selected mesh is unavailable, and the same selection appears after residency succeeds;
  6. a synthetic Setup building draws only transformed part zero and uses the identical composed transform for distance, portal clip, and shell;
  7. Config's three rows are live-colored, persist exact values, and the one composed controller instance is borrowed by both renderer and FPS panel;
  8. publish/retire/revisit/reset and first/login/portal/null-root frames neither duplicate nor recreate the controller and leave existing building lifecycle behavior intact;
  9. the installed census equals §17.2 exactly; and
  10. the warmed selection/controller/classification path allocates 0 managed bytes and does not advance retained topology or materialize records.

Sabotage and restore at least these exact mutations, recording each first failing test/assertion in the implementation commit body: use BSP-null as the complete-body gate; clamp the final zero slot to the prior nonzero slot; use the base GfxObj for shell submission; change strict < to <=; feed the manual bias while automatic is enabled; update FPS after inserting the current sample; allow one stable history slot instead of all 30; fall back to base when the selected mesh is unavailable; and recreate the shared owner for the FPS binding. Include an allocation sabotage that constructs or clones per building and prove the 0-B pin catches it.

Implementer return: git diff --check; Release solution build 0W/0E; focused building/walk/driver/dispatcher/settings/UI/composition tests; exact math and 0-B lanes; official hermetic lane; inclusive InstalledDat lane with the campaign's accepted exclusions and explicit documented global identities; one clean commit; exact file/count/mutation report; no client run.

Sequential review 1 — retail/deviation fidelity: re-check every §17.1 byte/ named fact, the §17.2 census, selection math, FPS/auto controller, complete- body gate/order, Setup part zero, selected shell, Config/register truth, and all mutations. Sequential review 2 — architecture/production/gate honesty: one shared owner/tick, one typed selection, no retained mutation/base fallback/ renderer DAT read/topology rebuild, async residency, transform/material/ lifecycle identity, allocation, allowed scope, build/lane provenance, and at least three reproduced sabotage claims. Reviews run sequentially. A failed lens gets one bounded fix contract. Under the owner override, S5-c3 may use at most ten review passes and stops before an eleventh; documentation-only findings may be corrected directly by the lead.

18. S5-c3 fix round 1 — x87 store schedule and register truth

The first sequential OpenAI retail/deviation review returned FAIL on the uncommitted scratch implementation: one MAJOR exact-arithmetic defect and one MINOR pre-existing register-truth defect. Everything else in §17 passed. This is the first bounded fix round; it does not reopen selection ownership, building traversal, residency, Config wiring, or any S5-c1/S5-c2 behavior.

The reviewer independently re-confirmed the executable SHA, CodeView GUID/age, all seven §17.1 byte-range hashes, the named-decomp semantics, the complete §17.2 census, the complete-body order, Setup part zero, selected-shell identity and surface preservation, no base fallback, scope, lifecycle wiring, the other register edits, and every required mutation. Its clean focused return was 64/64, and the scratch state was restored exactly.

18.1 F1 — preserve retail's x87/store boundaries

The candidate currently rounds arithmetic too early in three places. Repair only these exact boundaries, allocation-free:

  1. SceneTool::UpdateFPSCounter @0x0043E510 sums the 20 stored single-precision frame durations in x87 precision and divides before narrowing once at the published FPS store. Accumulating into a C# float is not equivalent. Use a wider accumulator that exactly sums the 20 binary32 inputs, perform the division wide, then narrow once to float. Restore retail's physical history direction: shift old slots 0..18 to 1..19, then store the just-finished binary32 duration at slot 0. The prior-20-before-insert order remains unchanged.
  2. Render::CalcDegLevel @0x0054CAF0 evaluates its five membership weights, weighted numerator/denominator, addition, and clamp in x87 precision except at the explicit binary32 stores visible in the named function. Re-express the pure calculation with wide intermediates fed by the exact binary32 constants (-0.150000006f, -0.02f, 0.01f, 0.1f) and narrow only at retail's candidate store. The stability comparison promotes each binary32 history slot and candidate and compares against the executable's qword 0.01, not 0.01f. Keep the existing shift-before-evaluate and final current-multiplier store order.
  3. GfxObjDegradeInfo::get_degrade @0x0051E4B0 stores the effective distance after abs(distance)-DegradeDistance, but evaluates each positive/negative threshold in x87 precision and compares the stored binary32 effective value against that wide threshold. Do not round the threshold to float before the strict comparison. Disable/force precedence, strict <, equality advance, final slot, modes, and NaN/infinity behavior stay unchanged.

Add bit-exact independent assertions for all three proven witnesses:

  • FPS history [0.001f, 0.005f] × 10 publishes bits 0x43A6AAAB (333.333344f), not the candidate's 0x43A6AAAC;
  • CalculateCandidate(14f, 0f) publishes bits 0x3BB2BC0A, not 0x3BB2BC0B;
  • with ideal/max 24f/48f, multiplier 0.0020020019728690386f, and effective distance 24.04804801940918f (0x41C06267), retail's wide threshold remains strictly greater and selects the first level.

Also pin the qword stability edge directly and the slot direction without reflection-only self-comparison. Each of these changes needs a named mutation and actual first failing assertion: restore float FPS accumulation; restore float CalcDeg intermediates or 0.01f; restore a rounded selector threshold; reverse the FPS slot direction. Restore every mutation before return.

18.2 F2 — correct AP-198's already-live landscape radius

AP-198 is stale independently of this chunk: Render_LandscapeDrawDistance already feeds RuntimeSettingsController's live far radius, and the Config controller maps its persisted default 8 to the selected Medium entry. Remove that control from AP-198, change every six-row statement to five, and delete the obsolete no-highlight sub-note. Keep the actual Config dim set at 16/27; S5-c3 still changes only Automatic Degrades, Graphics Performance, and Degrade Distance from store-only to live. No row is added or retired, so active table counts do not change. Add or update a truth pin that fails on the old six-row wording or the obsolete no-highlight statement.

18.3 Scope, return, and review order

Production edits are limited to BuildingDegradeController.cs and Walk/WalkBuilding.cs. Test edits are limited to their existing focused test files plus the existing Config/register truth pin if required. The only documentation edit in the implementation remains docs/architecture/retail-divergence-register.md. Do not change controller ownership/tick placement, selection/result shapes, building factory or transforms, portal walk/order, shell classification, residency, materials, surface overrides, UI wiring, RHI/shaders, DAT readers, or any other register row. No graphical client.

Return the exact changed-file list; git diff --check; Release solution build 0W/0E; the bit-exact math/selector/controller and Config/register focused lanes; the original S5-c3 focused lane; official hermetic lane; inclusive InstalledDat lane with exactly the documented global identities; and the new mutation ledger. Do not commit—the lead owns the reviewed landing commit under the owner's OpenAI-only process override.

The same OpenAI retail lens narrowly re-reviews F1/F2 and regression evidence first. Only its PASS unlocks the sequential OpenAI architecture/production/ gate-honesty review over the entire S5-c3 stack. Each further code finding receives its own bounded contract; S5-c3 stops before an eleventh review pass. Documentation-only findings may be corrected directly by the lead.

19. S5-c3 fix round 2 — CalcDegLevel's four intermediate stores

OpenAI retail review pass 2/10 returned FAIL on one remaining MAJOR F1 defect. Fix round 1 otherwise passed: the FPS witness is 0x43A6AAAB, the 14-FPS candidate is 0x3BB2BC0A, the selector boundary stays at level zero, the qword 0.01 edge and physical FPS slot direction pass, and AP-198 now states the exact five-row residual while AD-78 is corrected to 16/27. The reviewer also re-confirmed the paired executable/PDB identity, clean allowed scope, the exact installed census, and the official evidence identities.

19.1 R2-F1 — reproduce every executable-visible numerator store

The remaining defect is only BuildingDegradeController.CalculateCandidate. Its combined float weightedNumerator narrows once after all five terms. The paired Render::CalcDegLevel @0x0054CAF0 bytes instead store the evolving numerator to binary32 four times: after w0 at 0x0054CC14, after the negative w1 term at 0x0054CC61, after the zero-weight w2 term at 0x0054CCA6, and after the positive w3 term at 0x0054CCEB. Retail then promotes that fourth stored value, adds the w4 term wide at 0x0054CD3F, divides wide, adds/clamps wide, and narrows only at the final candidate store.

Implement that literal schedule allocation-free. Each of the first four stages must be an explicit float store followed by promotion for the next stage; do not algebraically combine, reassociate, or eliminate the +0*w2 store. Feed every term with the existing exact binary32 coefficient. Keep the five membership weights, denominator, history/stability behavior, clamp, exceptional-value behavior, and every other fix-round-1 change untouched.

Add an independent bit-exact assertion:

  • CalculateCandidate(16.25f, 0f) must publish 0x3CA3D70A; the current combined store publishes 0x3CA3D70B.

Sabotage by recombining the five terms into one store and record this witness as the first failure, then restore it. Re-run the three §18 witnesses, qword edge, FPS slot-direction pin, complete controller/selector lane, original S5-c3 focused surface, allocation lane, official hermetic lane, and inclusive InstalledDat lane with the same documented nonpassing identities.

19.2 Scope and review order

Production scope is exactly src/AcDream.App/Rendering/BuildingDegradeController.cs; test scope is exactly tests/AcDream.App.Tests/Rendering/BuildingDegradeControllerTests.cs. No other production, test, register, packet, plan, UI, renderer, RHI, shader, DAT, or lifecycle behavior changes. No graphical client and no commit; the lead owns landing.

Return the exact two-file diff, git diff --check, Release solution build 0W/0E, every lane above, and the mutation's first failure. The same OpenAI retail lens performs narrow review pass 3/10 over §19 first. Only its PASS unlocks the sequential full architecture/production/gate-honesty review.

20. S5-c3 fix round 3 — ladder ownership, retry rearm, and tick proof

OpenAI retail review pass 3/10 returned PASS after independently pairing the exact executable and PDB and confirming the literal four-store CalcDeg schedule. The sequential OpenAI architecture/production/gate-honesty review pass 4/10 returned FAIL on two production lifecycle defects and one non-discriminating test. Typed selection, complete-body gating/order, selected transform and surface borrowing, Config wiring, exact installed census, allocation-free controller/selector/classifier paths, and the restored retail math witnesses otherwise passed. This bounded round does not reopen retail selection math or rendering policy.

20.1 R3-A — own every nonzero building ladder mesh

Selected non-base degrade meshes are requested through WbMeshAdapter.EnsureLoaded, but asynchronous publication is admitted only while ObjectMeshManager sees an ownership reference. Landblock registration owns retained base MeshRefs and prepared EnvCell geometry, not the nonzero GfxObj IDs in building degrade ladders. A selected ladder ID can therefore remain permanently non-drawable unless an unrelated owner happens to hold it.

Carry the unique nonzero ladder GfxObj IDs derived from the worker-built EnvCellLandblockBuild.WalkBuildings through the existing landblock publication/lifetime transaction as ordinary mesh ownership, distinct from prepared EnvCell IDs. Requirements:

  1. exclude the retail zero sentinel and deduplicate ladder IDs, including any overlap with retained base MeshRefs;
  2. acquire them through the existing IncrementRefCount/ordinary desired and held path before readiness can complete; do not treat them as prepared EnvCell pins and do not acquire them from the per-frame classifier;
  3. balance ownership across initial publication, Far-to-Near promotion, Near-to-Far retirement, full unload, replacement, partial publication failure, reset, and same-location revisit, without duplicate increments;
  4. preserve selected-only submission: an unavailable selected mesh remains a skipped shell, never a resident-base fallback; and
  5. keep the carrier precomputed/immutable and the frame walk allocation-free.

Add a production-path proof using the real ObjectMeshManager and WbMeshAdapter, without direct ObjectRenderData injection: a non-base selected ladder dependency becomes owned, its valid prepared result reaches upload/publication, and a later frame can submit it. Add focused lifecycle proofs for balanced release, cancellation/partial failure, reset, and revisit. Sabotage by dropping ladder dependency publication and by dropping one release edge; record the first failing assertions and restore both mutations.

20.2 R3-B — rearm mesh-miss requests at the real walk-frame boundary

WbDrawDispatcher clears _missRequested only from the legacy flat/entity dispatch boundary. Normal PView walk frames use BeginWalkPartFrame, so a once-missed selected ID remains suppressed across later frames and after cancellation, eviction, or revisit.

Clear _missRequested once at the successful BeginWalkPartFrame boundary, after its double-open guard has accepted the new frame. Preserve _missLogged as the once-per-lifetime diagnostic set. Prove that the same ID requested twice in one frame emits one preparation request, the next accepted frame can request it again, and cancellation/eviction/revisit converge without an unbounded request-dedup set. Sabotage by deleting the frame-boundary clear and record the first failure, then restore it.

20.3 R3-C — make exactly-once tick and ordering discriminating

The production orchestrator contains one accepted-frame degrade tick, but its test uses constant 0.05 samples and checks only eventual 20 FPS; duplicating the production tick survives that proof.

Strengthen the orchestrator lane with an independent call-count and order recorder: each accepted nonzero-area render frame ticks the one shared owner exactly once, a zero-area/rejected frame ticks zero times, and the tick occurs before BeginFrame and downstream walk work. Use a nonuniform, hard-coded duration sequence with exact expected published FPS bits so a duplicate or shifted sample changes the result. Sabotage by duplicating the tick and independently moving it after BeginFrame; both mutations must fail at named assertions and then be restored.

20.4 Lead-owned documentation corrections

The lead may directly repair the Config controller prose to describe the three now-live degrade controls; pin AP-198's five residual rows; correct the Config dim set and AD-78 count to 16/27; change both portal-gate diagnostic effective- distance calculations to use the selected distance 50 rather than 100; and add a Config-test aggregate pin that exactly 16 rows remain store-only.

20.5 Scope, return, and review order

Production scope is limited to the worker-built ladder dependency carrier, the landblock publication receipt and ordinary/prepared ownership split through GpuWorldState/LandblockSpawnAdapter, the successful walk-frame boundary, and the existing render orchestrator seam needed for a discriminating order test. Tests may extend the corresponding focused build, publication, dispatcher, classifier, and orchestrator suites. Do not change retail degrade math, selector thresholds, complete-body logic, transforms, surfaces, fallback policy, RHI/shaders, DAT readers, or unrelated lifecycle owners. No client, commit, campaign-doc edit, or subagent; the lead owns those actions.

Return the exact changed-file list, git diff --check, Release solution build 0W/0E, the focused ownership/lifecycle/retry/order lanes, all prior S5-c3 math/selection/census/allocation lanes, official hermetic lane, inclusive InstalledDat lane with every documented nonpassing identity, and the five required mutation failures. The same OpenAI production lens performs narrow review pass 5/10 over §20 and the full corrected stack. Its PASS, together with retail pass 3, unlocks lead integration and the clean-HEAD graphical self-gate; any further code finding receives another bounded contract, with a hard stop before review pass 11.

21. S5-c3 review closeout, landing, and lead graphical gate — 2026-09-04

OpenAI production narrow re-review pass 5/10 returned PASS with no finding. The reviewer independently reproduced all five §20 mutations, named the first failed assertion for each, restored all 41 changed paths byte-for-byte, and re-ran Release plus focused ownership/publication evidence. OpenAI retail pass 3/10 remains the independent paired-executable/PDB verdict for the exact x87 schedule and building-selection semantics.

The reviewed scratch implementation is 01e5a15d0b4efc73882634899bf5af500168fafe; it landed on the campaign branch as c673f767e968a85a898b4a3aebb03781060efe06. Fix round 3 now:

  • carries every unique nonzero ladder GfxObj as ordinary landblock-lifetime ownership, distinct from prepared EnvCell ownership, with balanced publication, replacement, retirement, failure, reset, and revisit edges;
  • clears only _missRequested at each successful BeginWalkPartFrame, after the double-open guard, so a miss deduplicates within one frame and rearms on the next; and
  • proves one degrade tick per accepted nonzero-area frame, zero on a rejected zero-area frame, before BeginFrame, using nonuniform samples.

Fresh clean-HEAD campaign evidence at c673f767e:

  • Release solution build: 0 warnings / 0 errors;
  • exact focused campaign lane: 101/101;
  • official hermetic artifact artifacts/s5-c3-campaign-hermetic-20260904: 16,811/16,811, zero fail/skip, WorktreeDirty=false, exact commit/branch, manifest 30/30;
  • inclusive InstalledDat artifact artifacts/s5-c3-campaign-installed-inclusive-20260904: 469 pass / the same documented 10 fail / 1 skip, WorktreeDirty=false, exact commit/branch, manifest 30/30. The nonpassing identities are unchanged: TowerAscent, the main-game/chat-input and invisible-widget fixture drifts, Oh doorway first- frame drift, and the six documented AlphaFlushCounts; the sweep look-in gate remains the one documented skip.

Before the lead launch, ACE was UP on UDP 9000 as PID 13340 and no acdream or retail graphical client was running. Exactly one Release self-gate command ran and closed its own client gracefully:

logs/selfgate-20260904-223345-s5c3-building-degrade

It produced 00-login.png, 01-cathedral-stairs.png, 02-facility-stairs.png, 03-holtburg-house.png, and 04-holtburg-terrain-leak.png, exited 0, confirmed graceful logout, logged no fatal/unhandled/device-lost error, and left no client process. Cathedral, Facility, Holtburg shell geometry, and the terrace hill are intact. The c3 selected-building scope is therefore PROVISIONAL PASS pending owner inspection.

The Holtburg screenshot is not a controlled old/new pixel comparison: the old frame is retail/off at 1760x990 while this run starts with the persisted High atmospheric pack at 1024x768, and neither records the exact camera eye. Static DAT inspection nevertheless disproves a c3 part-zero explanation: cell 0xA9B4013F's 16 props are independent EnvCell statics and ordinary cell records never receive buildingSelection.

That audit found a separate pre-existing production defect: ordered draws use an absolute shared-arena transform base with the ordinary shader's locally based alpha/selection/light sidecars and omit the active atmospheric receiver pipeline/bindings. It exists at least at S4-c2 252886e84, is filed as #470, and must be repaired before renderer-solid/G4. S5-c4 is next; #469/#470, c5, the closeout program, and G4 remain. Nothing merges to main before G4.

22. S5-c4 contract — exact one-pass detail material and ordered production closure

This chunk replaces the acdream-only base-plus-mesh_detail replay with the single fragment retail emits when the hardware single-pass detail path is available. It applies to detail-active building and EnvCell subsets in every current world submission path: classic grouped, walk-ordered, immediate alpha, deferred alpha, and EnvCell opaque/transparent replay. One source subset must produce one physical draw and one (rgb, alpha) result while retaining that subset's existing queue position, blend family, alpha-test/depth state, cull, geometry, transform, material overrides, fog policy, sampler, and mip chain.

The production audit found that the walk-ordered path currently uploads building detail categories and forces them into solo runs but issues only the base draw. That omission is filed as #471 and is part of this chunk: the new one-pass detail result must be armed on that existing base draw. Do not add a blended overlay after the run. An overlay would preserve AP-232, create a new terrain/StreamMark flush obligation, and remain unlike retail.

22.1 Lead-verified retail and paired-binary facts

The paired executable is C:\Turbine\Asheron's Call\acclient.exe, SHA-256 006FFEADC5D679C871497112A5BD1F87714D0E273E2166BAE5052DDE369297B1. Its CodeView identity remains GUID {9E847E2F-777C-4BD9-886C-22256BB87F32}, age 1, matching the named PDB. The named pseudo-C and fresh paired-executable disassembly agree on these exact ranges:

Fact VA range / length SHA-256
SetSurface detail stages 0x0059C4D0..0x0059C5B5 / 229 090E24BE542E9DA4F77B547D091F5C2E676109495919BEA70027AD2B89E11426
SetSurface blend/alpha/depth state 0x0059C6C5..0x0059C866 / 417 1F077DA1BB09FBAC0EAF7522E125C716AAF499DFA8763DD3DDF29CCC6A76C382
RenderMeshSubset single-pass arm 0x0059CA10..0x0059CAF0 / 224 64A988D4B1611CEEA6DE135FF52CDF30FE1AFDAAFF5E3B76751FFA7FC833CC53
DrawMesh detail/alpha routing 0x0059D4A0..0x0059D5A5 / 261 20B1E5D1E90C9E19C62047AF521F817CF6700B5FEA68CE78C7404CD238862CB3

Named anchors are D3DPolyRender::SetSurface @0x0059C4D0 (acclient_2013_pseudo_c.txt lines 425083425303), RenderMeshSubset @0x0059CA10 (lines 425382425450), DrawMesh @0x0059D4A0, RenderDeviceD3D::DrawEnvCell @0x0059F170, and DrawBuilding @0x0059F2A0. The live capability result remains the VM2 CDB record in 2026-08-22-vm2-retail-detail-path-cdb.md: retail takes the single-pass path, not its fallback.

Let B be the sampled base RGB, D the active diffuse/lighting RGB, a the active diffuse/material alpha, and Q=(q,qA) the sampled detail texel. At 0x0059C51C/52B/53A/549 retail programs:

  • stage 0 colour C0 = B * D;
  • stage 0 alpha PREMODULATE(DIFFUSE,DIFFUSE), whose visible stage-0 result is a but whose stage-1 CURRENT alpha is premultiplied by the next texture, a*qA;
  • stage 1 colour BLENDCURRENTALPHA(TEXTURE,CURRENT); and
  • stage 1 alpha MODULATE(TEXTURE,CURRENT).

Therefore the exact pre-fog fragment is:

w = a * qA
C = q * w + (B * D) * (1 - w)
X = a * qA * qA

The square in X is mandatory. Base texture alpha does not participate in the detail-active final alpha. Fog is applied to C after the combine wherever the subset's fixed-function policy enables fog; it never changes X.

SetBlendFunction @0x005A2B90 writes one colour/alpha factor set, so the framebuffer equations for destination F are:

Raw family Result RGB Result alpha
Alpha C*X + F.rgb*(1-X) X*X + F.a*(1-X)
Alpha + Additive C*X + F.rgb X*X + F.a
Additive without Alpha C + F.rgb X + F.a
InverseAlpha C*(1-X) + F.rgb*X X*(1-X) + F.a*X
InverseAlpha + Additive C*(1-X) + F.rgb X*(1-X) + F.a
pure CLIP survivor C + F.rgb*(1-X) X + F.a*(1-X)

Pure CLIP rejects iff X < r, with r=100/255 for paletted and r=200/255 for DDS/non-paletted input; equality survives. CLIP combined with an Alpha/Additive/Inverse family keeps that family's factors and applies the same test. The later TRANSLUCENT branch at 0x0059C767..0x0059C7A6 then matters: ordinary T and T|Alpha are straight-alpha; T|Additive and T|InverseAlpha retain their respective family unless the skip arm applies; every T|CLIP combination is forced to straight-alpha and CLIP is disabled. Do not replace that table with a universal straight-alpha assumption.

a is the active material alpha, including authored 1-Surface.Translucency on a Translucent surface and the current object/part fade multiplier. The lead's installed Surface census found 261/261 Translucent-flagged surfaces carry nonzero authored translucency, including real 0.25, 0.5, 0.75, and 1.0 values. Treating a as always one is disproven. Current prepared Wb payloads discard that scalar while the decoded base image bakes it into base alpha; because retail detail excludes base alpha, it cannot be recovered from the sampled texel. The implementation must carry authored surface opacity explicitly from extraction through the prepared payload and GPU batch data, multiply it by the existing live instance opacity, and use the product as a. Guessing from texture alpha, querying DAT from the renderer, or using base.a is forbidden.

22.2 One draw, one material result

Implement the combine in the ordinary and atmospheric world-mesh fragment families, sharing one source include or otherwise proving their arithmetic textually and numerically identical. The base texture remains the batch-owned array sample. A detail-active exact command supplies the category texture slot and tiling in the existing push fields; zero tiling is the unarmed value. The per-draw GPU batch record supplies authored surface opacity. The vertex stage passes that scalar without interpolation; the fragment multiplies it by the existing instance-opacity varying to obtain a.

The prepared contract must gain the scalar without ambiguity:

  • MeshExtractor computes it from the resolved source Surface for ordinary GfxObj and CellStruct batches using the existing OpacityFromSurfaceTranslucency rule;
  • TextureBatchData, its deterministic serializer, and ObjectRenderBatch preserve it exactly;
  • this is a prepared-payload schema change, so advance the bake-tool recipe identity and update every recipe/round-trip/compatibility pin in the same commit; an old recipe must be rejected clearly, never misread; and
  • the GPU batch ABI carries it explicitly with layout/stride tests for both built-in shader families. Do not introduce a renderer-side surface table, per-frame dictionary, or DAT lookup.

For a detail-active fragment, compute (C,X) before the current discard/fog tail. Alpha testing uses X, not sampled base alpha. For detail-off fragments, preserve the current byte-for-byte logical path: base-alpha discard/reference, RGB lighting/fog, and base.a * instanceOpacity output alpha. The debug-light mode remains a deliberate diagnostic bypass and must not sample detail.

At each production draw site:

  1. arm detail only when the existing Building Detail Textures option is on, the correct category binding is resident, tiling is nonzero, and the exact command/subset belongs to the building or EnvCell detail category;
  2. set the detail slot/tiling and draw that source subset exactly once through its original base pipeline family;
  3. preserve its original queue position, blend, depth test/write/reference, alpha test, cull, geometry, draw-id offset, absolute transform base, local sidecars, selected building GfxObj, palette/original-texture override, lighting, fog enable, and atmospheric receiver choice; and
  4. restore neutral detail push fields before the next non-detail draw.

Delete every now-unreachable RetailDetail/RetailDetailTransparent pipeline, GpuBlendMode.RetailDetail, DrawBuildingDetailRangeRhi-style replay helper, mesh_detail.vert/.frag, compiled SPIR-V entries, manifest entries, and stale two-draw comments/tests. Keep CPU detail-category ownership only where it still selects exact eligible commands. Do not delete or weaken the building-detail setting, category textures, repeat/linear sampler, full mip chain, S4's two FIFO queues, AD-120 immediate placement, AP-238 token granularity, AP-239 raw mask residual, or AP-240 ordinary-GfxObj ClipMap placement.

The ordered-path repair for #471 is a one-pass arm on the existing solo base run. It adds no second draw and therefore leaves WalkFrameDriver's opaque/no-blended-overlay StreamMark terrain-flush premise true. Tests must prove that premise rather than adding a compensating terrain flush.

22.3 Audited policy table and explicit nonchanges

Add one data-driven policy test/table spanning Building and EnvCell × Opaque, Alpha, Additive, InverseAlpha, paletted CLIP, and DDS CLIP × detail on/off. For each row pin physical draw count, source order/FIFO, pipeline blend/depth/alpha test/reference, detail arm, emitted (C,X), and framebuffer result on a nontrivial destination. Add raw Translucent combinations sufficient to pin the later override described in §22.1. Existing AP-238/AP-239/AP-240 facts remain visible in the table instead of being silently relabelled exact.

This chunk does not change FIFO classification/token granularity, portal or terrain ordering, building-degrade selection, visibility/membership, directional-shadow caster selection, #469's lighting-direction transition, or #470's general ordered atmospheric sidecar/receiver defect. It must implement the same material arithmetic in the atmospheric shader so the later #470 repair cannot expose a second result. No graphical client is launched by the implementer.

Allowed production scope is the prepared mesh batch/extractor/serializer and bake-recipe identity; world GPU batch ABI and built-in ordinary/atmospheric mesh shaders; Wb/EnvCell detail draw/pipeline ownership; shader compiler outputs/manifest; and the smallest render-pack ABI pins required by those shader changes. Tests may change for those surfaces, deterministic prepared round trips, state/pixel equations, command transcripts, allocation, shader ABI, and package compatibility. The only authorized documentation file in the implementation commit is docs/architecture/retail-divergence-register.md: strike AP-232 with the exact new mechanism/evidence and amend counts; add or correct a row in the same commit for every discovered surviving deviation. Do not edit this packet, the plan, issues, architecture prose, scripts, or generated evidence reports.

22.4 Required proof, mutations, and return

Focused proof must include at least:

  1. independent CPU fixtures over nontrivial base/detail RGBA, diffuse colour, authored opacity, live fade, fog, destination RGBA, and every §22.1 state; they must distinguish a*qA² from a*qA, base.a*a*qA², and today's two draws;
  2. pure/paletted/DDS CLIP values immediately below, equal to, and above the final-X reference plus Translucent|CLIP's disabled-test override;
  3. extraction and prepared serialization round trips for opacity 1, 0.75, 0.5, 0.25, and 0, a bumped recipe identity, deterministic bytes, and clear rejection of recipe 8 by the recipe-9 build;
  4. GPU ABI pins proving the batch scalar reaches both ordinary and atmospheric fragments, detail-off never samples the category texture, and debug-light mode stays independent;
  5. real Wb classic, walk-ordered, immediate-alpha, and delayed-alpha command recordings proving one detail-active subset draw, original pipeline state, exact slot/tiling/material alpha, no replay, and no stale detail arm on an adjacent ordinary draw;
  6. real EnvCell opaque, Alpha, Additive, and both CLIP-reference recordings with the same one-draw/state/order proof;
  7. production ordered sequence ordinary → opaque building detail → ClipMap building detail → ordinary with exact one-draw adjacency and no added terrain flush, closing #471;
  8. active/inactive atmospheric receiver shader/pipeline recordings proving identical material equations while leaving #470's separate general repair boundary explicit;
  9. setting-off and unavailable-category identity, selected-surface override, sampler/mip, fog-after-combine, draw-id/transform-prefix, cull, and lifecycle/reset/revisit preservation; and
  10. warmed extraction-free draw/classification paths at 0 managed bytes after warmup, with no per-frame material lookup/table/allocation.

Sabotage and restore at least these mutations, recording the first failing test/assertion for each in the implementation commit body: change X to a*qA; multiply X by base alpha; test CLIP against base alpha or 0.05; restore any second detail draw; bind straight alpha instead of the original subset family; omit the walk-ordered detail arm; omit the atmospheric combine; drop authored opacity during prepared serialization; and leave the detail push fields armed for the following ordinary draw. Include one allocation sabotage that builds a per-frame surface map and prove the 0-B pin catches it.

Implementer return: one clean commit; exact changed-file and line-count list; all mutation first failures; git diff --check; Release solution build 0W/0E; shader compilation plus manifest/SPIR-V validation; focused content/serializer, renderer/state/pixel/command/allocation suites; official hermetic lane; and an inclusive InstalledDat lane with every accepted nonpassing identity named. If the package recipe changes, also return the exact deterministic bake command, artifact identity/size, and compatibility result. No client run.

Sequential review 1 — retail/material/deviation fidelity: re-check the named and paired bytes, PREMODULATE semantics, squared alpha, every framebuffer and CLIP/Translucent row, authored opacity provenance, fog placement, AP-232 retirement, AP-238/239/240 preservation, and all retail-facing mutations. Sequential review 2 — architecture/production/gate honesty: one physical draw, all five production paths including #471, prepared-schema compatibility, no renderer DAT lookup or per-frame map, shader/pack ABI, state/order/reset, allocation, build/lane/artifact provenance, and at least three independently reproduced sabotages. Reviews run sequentially. Every code finding receives a bounded fix contract and narrow re-review; documentation-only findings may be corrected directly by the lead. At most ten c4 review passes may run; stop before an eleventh. Nothing lands or launches graphically until both lenses pass.

23. S5-c4 fix round 1 — production SetSurface state reaches the one-pass draw

23.1 Review result and independently re-verified retail boundary

Retail/material review pass 1/10 returned FAIL on clean implementation tip 91fb80de6e0f536819100890ebc218169070aadc. The shared one-pass material equation is correct, but three production-state gaps make several §22 rows model-only rather than rendered truth:

  1. production collapses raw Additive, Alpha|Additive, and InvAlpha|Additive into one TranslucencyKind.Additive / Vulkan SRCALPHA,ONE pipeline. Retail instead uses ONE,ONE, SRCALPHA,ONE, and INVSRCALPHA,ONE respectively. EnvCell additionally chooses its raw IsAdditive bucket before the already-resolved translucent override and owns no inverse pipeline, so both ordinary inverse alpha and Translucent|ClipMap|Additive can reach the wrong base state;
  2. building/Wb commands never set push ParamB, so a detail-active ClipMap fragment falls back to 0.05 rather than retail's final-X reference of 100/255 for paletted input or 200/255 for DDS/non-paletted input. The command also lacks the state needed for ClipMap combined with another blend family; and
  3. both one-pass fragment families always apply fog, although retail disables fixed-function fog whenever the raw Additive bit is present, including a row whose later Translucent branch changes its blend family.

The existing RetailDetailTextureContractTests policy table did not expose these failures: it omitted Additive-without-Alpha and InverseAlpha-with-Additive, computed framebuffer results only through a CPU oracle, and returned expected pipeline values without invoking extraction or a production draw owner. EnvCellAlphaDrawSourceTests also synthesized IsAdditive from the collapsed TranslucencyKind, unlike real extraction.

The lead independently re-read named D3DPolyRender::SetSurface @0x0059C4D0 lines 425083425303 and re-hashed the paired executable and all four §22 ranges. The executable remains SHA-256 006FFEADC5D679C871497112A5BD1F87714D0E273E2166BAE5052DDE369297B1; the four range hashes remain exactly those in §22.1. Paired bytes and named pseudo-C agree:

  • the Alpha arm selects SRCALPHA,(Additive ? ONE : INVSRCALPHA);
  • the neither-Alpha-nor-InvAlpha arm selects ONE,(Additive ? ONE : ZERO);
  • the InvAlpha arm selects INVSRCALPHA,(Additive ? ONE : SRCALPHA);
  • ClipMap enables GREATER_EQUAL with the palette/DDS reference while retaining a pre-existing blend family, except that a pure ClipMap supplies ONE,INVSRCALPHA;
  • the later Translucent branch forces every Translucent|ClipMap combination to straight alpha and disables its alpha test, but otherwise retains an established Additive or InvAlpha family; and
  • the raw Additive bit disables fixed-function fog independent of that later blend override.

For the review's nontrivial §22 fixture, X=0.11532 and C=(0.3534682,0.2330118,0.5438054). Against F.rgb=(0.17,0.37,0.71), retail raw Additive produces (0.5234682,0.6030118,1.2538054), while the collapsed current pipeline produces approximately (0.21076195,0.39687092,0.77271164); InverseAlpha+Additive produces approximately (0.48270625,0.57614088,1.19109376). The current 0.05 Wb ClipMap fallback also lets X=0.11532 survive where retail rejects it at both real references. The installed portal Surface census contains real Additive-only and Alpha+Additive families, so the distinction is not synthetic.

23.2 Bounded production repair

Carry one immutable, deterministic resolved SetSurface material state from the resolved source Surface at extraction time through TextureBatchData, recipe-9 serialization, ObjectRenderBatch, grouping/ordered-command data, and the exact Wb/EnvCell draw command. It must distinguish at least:

  • opaque; straight alpha; alpha-additive (SRCALPHA,ONE); raw additive (ONE,ONE); inverse alpha (INVSRCALPHA,SRCALPHA); inverse-additive (INVSRCALPHA,ONE); and pure ClipMap (ONE,INVSRCALPHA);
  • alpha test disabled, paletted 100/255, or DDS/non-paletted 200/255; and
  • fixed-function fog enabled versus raw-Additive-disabled.

Resolve the complete precedence once from raw Surface.Type, actual texture presence/palette class, and the later Translucent rule. Do not infer it later from TranslucencyKind, IsAdditive, sampled alpha, texture-table identity, or a renderer-side DAT lookup. TranslucencyKind remains the existing queue/list-membership classification; the new state must not change the two FIFO queues, AP-239 raw-mask residual, AP-240 ordinary-Gfx ClipMap placement, or terrain/portal ordering.

For a detail-active Wb or EnvCell command, select the pipeline for that resolved family, including new ONE,ONE and INVSRCALPHA,ONE Vulkan variants; arm ParamB with the resolved final-X alpha-test reference when enabled; and bypass post-combine fog exactly when the resolved state says raw Additive disabled it. One explicit existing deviation remains binding: a pure-ClipMap ordinary-Gfx/building Wb command keeps AP-240's immediate opaque/A2C pipeline and placement while gaining the correct final-X ParamB; only EnvCell uses retail's pure-ClipMap ONE,INVSRCALPHA pipeline. EnvCell must otherwise use the resolved family rather than raw IsAdditive precedence and must have a real inverse path. Combined ClipMap families retain their blend factors and use the same final-X comparison; the Translucent+ClipMap override uses straight alpha with the test disabled. The ordinary and atmospheric shaders must implement the same fog decision.

Keep the §22.2 detail-off fragment arithmetic and its existing production selection unchanged. If the smallest implementation cannot restrict a newly exact state transition to the detail-active path without altering detail-off rendering, stop and return the exact call/data reason rather than silently expanding this fix round. Any now-proven detail-off raw-state mismatch that therefore remains must receive a precise active deviation-register row in the same implementation commit. AP-232 may retire only the old two-draw overlay and the exact detail-active mechanism actually proved; remove its current overclaim of complete framebuffer/ClipMap closure and none residual unless the production evidence truly supports those words.

Do not change the correct shared w=a*qA, C, or X=a*qA*qA equations; authored/live opacity multiplication; one-draw placement; #471's ordered arm; geometry, transform, local sidecars, cull, selection, lighting, sampler/mips, or debug-light bypass. Do not repair #469 or #470 here. Do not add a surface dictionary, per-frame map/allocation, DAT query, second draw, overlay, terrain flush, queue kind, or new ordering owner. Recipe identity remains 9 unless the serialized byte shape must change incompatibly; if it does, advance the recipe and every migration/compatibility pin together and return a fresh deterministic bake.

Allowed production scope is the §22 prepared material chain and serializer; the smallest exact material-state type; Wb/EnvCell batch/group/ordered data and pipeline selection; GPU blend enum/mapping and required pipeline variants; ordinary/atmospheric fragment state input; compiled SPIR-V and manifest; and the directly affected render-pack validator/ABI. Tests may change only for those production surfaces. The only documentation allowed in the implementation commit is docs/architecture/retail-divergence-register.md, including every required correction/new row. Do not edit this packet, plan, issues, handoff, evidence, or unrelated architecture prose.

23.3 Discriminating proof and mutation return

Replace the model-only claim with production extractor-to-command recordings for both Building/Wb and EnvCell, detail on and off, covering at minimum:

  • Opaque, Alpha, Alpha|Additive, Additive without Alpha, InvAlpha, and InvAlpha|Additive;
  • each applicable family with ClipMap, with both paletted and DDS reference classes and final X immediately below/equal/above the reference;
  • Translucent, Translucent|Additive, Translucent|InvAlpha, and at least Translucent|ClipMap|Additive, proving the late override and independent fog disable; and
  • ordinary versus atmospheric selection with an adjacent non-detail command, proving no stale blend/reference/fog state.

Each detail-active row must prove one physical draw, source FIFO/order, concrete production pipeline blend factors, depth write/test, alpha-test enable/reference in push data, detail slot/tiling, emitted (C,X), fog choice, and framebuffer result on the §23.1 destination. Each detail-off row must prove the current logical path was not changed. Use a real extracted fixture or the same production construction seam extraction uses; do not set IsAdditive or the resolved state from the expected TranslucencyKind in the fixture. Round-trip and equality tests must prove every new state bit survives prepared serialization and reaches both ObjectRenderBatch consumers.

Apply and independently restore at least these additional mutations, recording the first failure in the fix commit body:

  1. collapse raw Additive back to SRCALPHA,ONE;
  2. collapse InverseAlpha+Additive to either existing additive pipeline;
  3. remove EnvCell's inverse-family selection;
  4. restore raw IsAdditive precedence over the Translucent+ClipMap override;
  5. zero Wb ParamB for a paletted row and separately substitute 0.05 for a DDS row;
  6. remove alpha testing from an Alpha+ClipMap combined row;
  7. always fog a raw-Additive row; and
  8. disable fog from a non-Additive row.

The original ten §22 mutations remain green and restored. Return one clean fix commit atop 91fb80de6; exact file/line counts; git diff --check; Release solution 0W/0E; shader compilation and manifest/SPIR-V validation; focused content/serialization, production renderer/state/pixel/command/allocation and GPU mapping suites; the official hermetic lane; and inclusive InstalledDat with every accepted nonpassing identity named. No client launch.

Retail/material narrow re-review is pass 2/10 and must independently reproduce the raw-state mappings, CLIP reference, fog rule, register truth, and at least three new mutations. Only after it passes may the full production/gate-honesty lens run. Nothing lands or launches graphically before both lenses pass.

24. S5-c4 fix round 2 — alpha-tested blend families write depth

24.1 Retail/material re-review pass 2/10

Retail/material re-review of clean fix-round-1 tip 70751ef0e81200282323c0b08c6c52f40036ecd9 returned FAIL on one production state and one documentation-only correction. The reviewer and lead independently reproduced the code finding against the named retail decomp and paired executable:

  • D3DPolyRender::SetSurface @0x0059C4D0 first selects the framebuffer blend family. Its ClipMap arm at 0x0059C724..0x0059C761 retains an already-selected blend family, except for the pure-Clip ONE,INVSRCALPHA case, and enables GREATER_EQUAL alpha testing with the palette/DDS reference;
  • after the later Translucent override, the normal depth-state arm at 0x0059C7EE..0x0059C801 selects depth-write 1 whenever alpha testing is still enabled or blending is disabled, otherwise depth-write 0;
  • SetSurface @0x0059C85E..0x0059C866 passes that byte to RenderDeviceD3D::SetDepthBufferMode @0x005A2D10; the callee at 0x005A2D4B..0x005A2D6E stores the third argument as m_State.DepthWriteEnable and programs D3D render state 0x0E; and
  • therefore Alpha+Clip, Alpha+Additive+Clip, raw Additive+Clip, InvAlpha+Clip, and InvAlpha+Additive+Clip all retain their blend factors and alpha reference with depth writes ON. The corresponding non-Clip blended rows write no depth. Translucent|ClipMap is also depth-write off because retail's late override disables its alpha test. Opaque and pure Clip remain depth-write on.

Fix round 1 instead creates all five blended Wb pipeline families with depthWrite:false in WbDrawDispatcher.Rhi.cs and selects only by blend family; EnvCell repeats the same collapse. Its three production-transcript oracles also encode the false rule that only Opaque/pure Clip writes depth. The result has the right blend, final-X cutoff, fog decision, and single-draw position, but accepted blended+Clip fragments do not populate depth as retail does.

Everything else audited in fix round 1 passed: the shared PREMODULATE RGB and X=a*qA*qA result; 100/255 versus 200/255 final-X references; raw-Additive fog suppression; Translucent precedence; actual texture/palette provenance; recipe-10 state packing; Wb/EnvCell ordered state and reset; detail-off invariance; and AP-238/AP-239/AP-240/AP-244 preservation. Clean exact-tip evidence was also verified: focused App 242, Content 92, and Launcher 8 tests; hermetic 16,959/16,959; inclusive InstalledDat 469 pass / the same documented 10 fail / 1 skip; and byte-identical 3/8-worker recipe-10 bakes with SHA-256 0D3194A3B834DC1E0DCF67647402723B30BD758A268B8E909EC737369B911FA7. The register header in the fix commit says 160 active AP rows even though the physical table and existing recount establish 161, and its AP-232 correction temporarily overclaims exact combined-Clip state despite this depth mismatch.

24.2 Bounded production repair

On top of 70751ef0e, add/select a depth-write-ON variant of every blended SetSurface family used by a detail-active alpha-tested command:

  1. Wb StraightAlpha, AlphaAdditive, raw Additive, InverseAlpha, and InverseAdditive, across both backbuffer/offscreen sample counts and the ordinary/atmospheric receiver pipeline sets; and
  2. the same five families in EnvCell.

Select the depth-writing variant from the already-carried RetailSetSurfaceMaterialState.AlphaTestEnabled, not from raw Clip bits, TranslucencyKind, queue identity, a DAT lookup, or a second state owner. A blend family with alpha testing disabled keeps its existing depth-write-OFF pipeline. Preserve Wb pure Clip on AP-240's opaque/A2C pipeline and EnvCell pure Clip on its existing ONE,INVSRCALPHA, depth-write-ON pipeline. Preserve the late Translucent|ClipMap override on straight alpha, test disabled, depth write off. Depth compare remains the existing world compare; this round changes only the write-enable bit.

Do not change extraction, raw-state resolution, recipe-10 bytes, grouping or FIFO membership, draw count/order, ParamB, detail slot/tiling, fog flag, shared material equations, shader discard/equality behavior, geometry, transforms, local sidecars, cull, lighting, sampler/mips, #469, or #470. Do not add a per-frame allocation, map, DAT query, second draw, or overlay. Dispose every new pipeline in all ordinary/atmospheric and sample-count owners, with the existing partial-construction rollback behavior intact.

Correct the AP header to the physical 161-row count and narrow the AP-232 correction so it does not claim combined-Clip depth exactness until this fix is present. No new deviation row is needed: this is a required correction, while AP-240 and AP-244 remain the disclosed placement/detail-off residuals. The only documentation permitted in the implementation commit remains docs/architecture/retail-divergence-register.md.

Allowed production scope is Wb/EnvCell pipeline-set construction, exact material-pipeline selection and disposal. Tests may change only for the directly affected production pipeline/state transcripts. No shader/SPIR-V, prepared-data, recipe, queue, routing, or unrelated documentation change is authorized; if one proves necessary, stop and return the exact reason.

24.3 Discriminating proof and review return

Correct the three false depth-write oracles and prove actual production pipeline descriptors, not a parallel policy model, for both Wb and EnvCell:

  • all five blended families with ClipMap/paletted or DDS alpha testing select their exact blend factors, existing cutoff, and depth-write ON;
  • the same five families without alpha testing select the same factors and depth-write OFF;
  • Translucent|ClipMap selects straight alpha, test disabled, depth-write OFF;
  • Wb pure Clip still selects its opaque/A2C, depth-write-ON AP-240 path, while EnvCell pure Clip still selects premultiplied ONE,INVSRCALPHA, depth-write ON; and
  • ordinary versus atmospheric Wb and an adjacent non-detail command select the same write rule without stale pipeline/reference/fog state.

Apply and independently restore at least these mutations, recording each first discriminating failure in the fix commit body:

  1. collapse one Wb blended+Clip row back to its depth-write-OFF variant;
  2. collapse a different EnvCell blended+Clip family to depth-write off;
  3. incorrectly select depth-write ON for the corresponding non-Clip blend; and
  4. incorrectly make the late Translucent|ClipMap override write depth.

Return one clean fix-round-2 commit atop 70751ef0e; exact file/line counts; git diff --check; Release solution 0W/0E; focused Wb/EnvCell material, pipeline-descriptor, ordered/atmospheric, disposal/rollback, allocation, shader invariance, and register-count tests; official hermetic lane; and inclusive InstalledDat with every accepted nonpassing identity named. The recipe remains 10, so no fresh bake is required unless an unauthorized prepared-data change is discovered. No graphical client launch.

Retail/material narrow re-review is pass 3/10 and must independently reproduce the depth-write rule from the paired binary, inspect real production pipeline descriptors, verify AP truth, and reproduce at least three new mutations. Only after it passes may the full production/gate-honesty lens run over the complete S5-c4 stack. Nothing lands or launches graphically before both lenses pass.

25. S5-c4 fix round 3 — restore classic/private detail-off state

25.1 Full production review pass 4/10

Retail/material re-review pass 3/10 returned PASS on clean fix-round-2 tip 472dc4fb7fd246a6efe6ed4ed20ffc26419c9ffa. It independently re-derived the Clip/depth-write rule from named D3DPolyRender::SetSurface @0x0059C4D0 and paired bytes, inspected all ordinary/atmospheric Wb and EnvCell pipeline descriptors, reproduced three mutations, and found no retail/material issue.

The subsequent full production/gate-honesty review returned FAIL on one P2 regression and no other code finding. Before c4, DrawImmediateTransparentRhi always bound pipelines.AlphaBlend for the classic grouped path's non-detail transparent commands and coalesced adjacent non-detail commands without a blend-family split. C4 instead binds PipelineForBlend(pipelines, blend) and adds Translucency equality to that run boundary. This changes detail-disabled/unavailable Additive and InvAlpha compositing and splits a previously coalesced run.

This is reachable production behavior, not a dead compatibility arm: PrivateEntityViewportRenderer.Draw calls the classic dispatcher without a collecting world-alpha queue, which reaches ExecuteClassifiedGroups -> SubmitRhi -> DrawImmediateTransparentRhi. The reviewer drove that exact path with detail disabled and one ordinary instance. Additive expected wb-mesh-alpha-1x but recorded wb-mesh-additive-1x; InvAlpha expected wb-mesh-alpha-1x but recorded wb-mesh-inverse-1x. Each case issued exactly one physical MDI. Temporarily changing only the false arm back to pipelines.AlphaBlend made both witnesses pass, and the reviewer restored the worktree byte-exactly afterward.

The rest of the complete-stack audit passed: opacity and immutable material state reach recipe-10 publication and every consumer; the 16-byte GPU batch ABI, shared shaders, one-pass equations, overlay deletion, #471 ordered arm, all five depth-write pairs, disposal/rollback, allocation, migration and artifact provenance are sound. Restored focused suites passed App 265/265, Content 92/92, and Launcher 8/8. The exact-tip hermetic artifact is 16,964/16,964 with manifest 32/32; InstalledDat is the unchanged documented 469 pass / 10 accepted fail / 1 accepted skip with manifest 30/30. The scratch worktree returned clean at 472dc4fb7.

The review also corrected the chunk boundary: c4 necessarily repairs the receiver half of #470 by selecting the frame-aware atmospheric ordered pipeline and binding its receiver resources. That is valid support for the required atmospheric one-pass path and must remain. #470 stays open because mesh_modern.vert still uses the absolute transform index for locally based alpha/selection/light/detail sidecars. Describe #470 as narrowed at landing; do not claim c4 left all of it untouched or closed it.

25.2 Bounded production repair

On top of 472dc4fb7, restore the pre-c4 detail-off behavior in DrawImmediateTransparentRhi only:

  1. when the current command has no active detail material, bind pipelines.AlphaBlend regardless of its TranslucencyKind or carried raw SetSurface state;
  2. restore the prior coalescing rule for consecutive non-detail transparent commands: do not split a run merely because TranslucencyKind changes; when detail is enabled, the next detail-bearing command remains a boundary;
  3. keep each detail-active command on the exact PipelineForMaterial(pipelines, materialState, pipelines.Opaque) result, armed once on its existing physical draw, with neutral push state restored afterward; and
  4. preserve cull-run splitting inside DrawIndirectRangeRhi; this repair restores only the outer material-run boundary that c4 changed.

Do not generalize this into a detail-off retail correction. AP-244 remains the truthful disclosure for the existing detail-off Wb/EnvCell collapses. Do not change deferred-alpha submission, ordered-stream submission, EnvCell, extraction, recipe 10, GPU batch ABI, shaders/SPIR-V/manifest, blend enums or pipeline construction, alpha-test/depth/fog/reference state, queue membership, FIFO order, transforms/sidecars, lighting, allocation ownership, #469, or the remaining #470 sidecar-index repair. In particular, retain c4's frame-aware ordered receiver selection/bindings.

Allowed production change: only src/AcDream.App/Rendering/Wb/WbDrawDispatcher.Rhi.cs. Tests may change only in the directly affected existing Wb production-transcript suite. No register change is expected because this restores the disclosed prior behavior; if a new deviation or wider production dependency is discovered, stop and return the exact fact before expanding scope. No packet, plan, issue, architecture, package, artifact, or evidence file is changed by the implementer.

25.3 Discriminating proof and return

Add permanent tests through the actual classic production path, without a collecting alpha queue:

  1. with detail disabled, one Additive and one InvAlpha ordinary instance each bind wb-mesh-alpha-1x and issue exactly one physical MDI;
  2. with the detail category unavailable, the same two rows retain that result;
  3. adjacent same-cull Alpha -> Additive -> InvAlpha detail-off commands remain one outer material run/MDI range rather than three blend-family runs;
  4. detail enabled with an eligible command still selects its exact carried detail-active material pipeline and arms slot/tiling/reference/fog once;
  5. non-detail -> detail -> non-detail adjacency does not leak detail state and preserves the two required boundaries; and
  6. existing deferred-alpha, ordered ordinary/atmospheric, EnvCell, depth-pair, disposal/rollback, allocation, shader/ABI and recipe-10 pins remain green.

Apply and independently restore these mutations, recording the first failing test/assertion for each:

  1. restore PipelineForBlend(pipelines, blend) on the non-detail arm;
  2. restore the TranslucencyKind equality run split while leaving the pipeline arm correct; and
  3. force the detail-active command onto pipelines.AlphaBlend.

Return one clean fix-round-3 commit atop 472dc4fb7; exact changed-file and line counts; mutation first failures; both git diff --check forms; Release solution build 0W/0E; focused classic/private material and complete affected Wb/EnvCell/ordered/content/launcher suites; exact-tip clean official hermetic and inclusive InstalledDat artifacts with manifests and every accepted nonpassing identity named. Recipe 10 is unchanged, so no bake is required. No graphical client launch.

Because this repair restores a production-only frozen detail-off path and changes no retail/material fact, the next review is the narrow production/ gate-honesty pass 5/10 over this finding and its non-change boundary; no new retail lens is required. A PASS unlocks landing the complete c4 stack and its lead graphical gate. A FAIL receives another bounded contract within the owner-authorized ten-pass limit. Nothing lands or launches before that result.