Bind S5 packet section 27 for issue 470. The contract preserves the shared absolute transform index while making every live per-submission sidecar local, requires a nonzero-prefix production recording and offscreen pixel witness, and keeps receiver selection plus issue 469 out of scope.
136 KiB
Campaign OVERHAUL v2 — S5 consumers, material, and closeout packet
Status: S5-c1 through S5-c4 LANDED + REVIEW-CLOSED with lead graphical
gates PROVISIONAL PASS; #470, #469, S5-c5, closeout, and G4 remain.
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/LandCellCheckportLScape::draw_check_blocks @0x00505F80andLScape::landcell_check @0x005050A0;WalkVisibilityMathowns the portedget_clip_height/block_checkmath;WalkFrameDriver.VisitedLandscapeCellIdsis 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 @0x00532CB0returns the 32-bit field at+0x104. The paired body is exactlymov eax,[ecx+0x104]; ret. Landscape drawing stamps that field, so particle update consumes the previous completed render frame's landscape answer.CEnvCell::IsInViewis the PDB-vtable slot at0x007C8D00, pointing to the ICF-folded body0x005269F0. The paired body is exactlymov eax,1; ret. Thus an indoor cell with a non-null owner is alwaysPARTIALLY_INSIDEfor 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.csif 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:
- an outdoor emitter is admitted only by the exact completed landscape set;
- an EnvCell emitter remains update-eligible at authored range even when no indoor cell is in that set;
- zero cell and no completed world view reject both cell families;
- inclusive/unordered/raw-distance behavior and AP-116 Retail/Extended multipliers remain unchanged;
WorldSceneRendererhands onlyRetailPViewFrameResult's landscape set to the particle owner, never the EnvCell set or diagnostic union;- abort/complete/reset preserve the previous-frame transaction;
- no production
CollectVisibleCells,TerrainVisibleCellIds,ObserveDrawableCells, orClearDrawableCellssymbol remains; - point-light snapshots still include resident lights regardless of the removed feedback set;
- 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
CollectVisibleCellsproduction symbol; - restore one
ObserveDrawableCellsproduction 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
- 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.
- S5-c3: retail
DrawBuildingdegrade selection and complete-body null gate. - S5-c4: translucent detail single-stage framebuffer equivalence; retire AP-232.
- S5-c5: delete Facility probes, production
PortalVisibilityBuilderresidue, obsolete fallbacks/flags/tests/claims; add architecture guards. - 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):
- EnvCell eligibility made set-dependent:
ApplyRetailView_UsesLandscapeMembershipButEnvCellConstantVirtualfirst failedAssert.True, expected true / actual false, atParticleSystemTests.cs:553. - Outdoor eligibility made constant true: the same test first failed
Assert.False, expected false / actual true, atParticleSystemTests.cs:559. - Renderer fed the diagnostic union:
PViewWorld_PublishesOnlyLandscapeCellsToParticleVisibilityfirst failed the HashSet equality atWorldSceneRendererTests.cs:279, expected[16842755], actual[16843008, 16842755]. - A production
CollectVisibleCellssymbol was restored:Production_source_has_no_reconstructed_particle_visibility_feedbackfirst failed atTerrainParticleCellVisibilityTests.cs:37, namingTerrainModernRenderer.cs. - A production
ObserveDrawableCellssymbol was restored: the same source guard first failed at line 37, namingWorldRenderFrameBuilder.cs. - The inclusive boundary was changed from
<=to<:ApplyRetailView_UsesOwnerVisibilityAndInclusiveAuthoredDistancefirst failedAssert.True, expected true / actual false, atParticleSystemTests.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:
ParticleVisibilityController.UseWorldViewstill says an outdoor fallback can publish the authoritative product, although S5-c1 deleted it.WalkFrameDriver.CopyVisibleCellsTostill calls the diagnostics union the completeCObjCell::IsInViewanswer 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.ParticleSystemcalls the sorted-list lifecycle insertion/removal cost binary even though only the insertion search is binary and list shifts / removal are linear. Its adjacent blanketO(log E)lifecycle sentence must remain scoped to theSortedSetindexes 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:
- architecture and AD-21 say null-root publishes no cell-visibility answer,
while production completes
hasCompletedView=truewith an empty landscape set; and - 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-Objectover 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 9aadc917a → afaebcad6 → 74a2e4c48 →
ed8200664 → a28384d80 → b7a7eb9e2 → d6592d3ac → b2d56f9e3
map to campaign commits 94a6b5ef3 → 282fe87fb → 4d1110812 →
3f17c9131 → 6bbb9e117 → 36569c0b0 → ad115141a → 1718832e2.
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 @0x00505F80writes a non-OUTSIDEblock result and callsLScape::landcell_check @0x005050A0; the latter stamps eachCLandCell::in_viewfrom the same portal-view interval walk; - named
CLandCell::IsInView @0x00532CB0returns 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 are8B 81 04 01 00 00 C3at0x00532CB0;landcell_checkbegins55 8B EC 83 EC 1C 53 56at0x005050A0. The ICF body used by theCEnvCell::IsInViewvtable remainsB8 01 00 00 00 C3at0x005269F0.
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:
- If
HasCompletedWorldViewis false, select zero terrain commands and zero world casters. An authoritative empty landscape set also selects zero. - 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
HashSetis permitted. - 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. - Building shells are intentionally absent from
ShadowObjectRegistryin retail's building channel. Select a shell by its exact outdoor placement cell,RenderSourceMetadata.EffectCellId; do not test its EnvCellBuildingShellAnchorCellId. Zero/non-land placement fails closed. - 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.csand 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:
- the frame builder borrows the exact prior completed set reference and flag; current Begin does not turn it into a current-camera product;
- complete/abort/reset and first/login/portal/null-root cases have the stated transaction semantics;
- exact CELLARRAY intersection selects multi-cell outdoor static, dynamic, and child casters once, while missing membership and ParentCell-only impostors fail closed;
- a building shell selects by outdoor
EffectCellId, not its EnvCell anchor; - terrain selects only loaded slots reached by exact land cells;
- alternating visible/invisible instances in one material group produce only the correct active instance ranges and stable order;
- camera-only visibility changes alter active output while both retained topology build sequences, classification counts, mesh lookups, geometry, and dynamic-transform mappings remain unchanged;
- topology rebuild, transform journal refresh, fade/mesh-availability retry, generation reset, and the existing two-frame deferral still converge;
- built-in and declared packs consume the same typed selector; pack-off does no shadow work;
- 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:
- CELLARRAY →
ParentCellId:PriorLandscapeSelection_UsesExactCellArrayAndBuildingEffectCell, firstAssert.Equalexpected[201, 202, 203, 205], actual[204, 205]. - Select every resident terrain range:
PriorLandscapeSelection_ScansExactAuthoredEightByEightCells, firstAssert.Singlefound 3 commands. - Building anchor → placement effect cell:
PriorLandscapeSelection_UsesExactCellArrayAndBuildingEffectCell, firstAssert.Equalexpected[201, 202, 203, 205], actual[201, 202, 203, 206]. - Admit missing membership:
the same caster pin's first
Assert.Equalexpected[201, 202, 203, 205], actual[201, 202, 203, 204, 205]. - Publish current building scratch instead of the completed product:
BorrowedLandscapeFrame_TracksOnlyCompletedTransactionsByReference, firstAssert.TrueexpectedHasCompletedWorldView=true, actualfalseafter the completed empty frame. - Advance retained caster topology during selection:
PriorLandscapeSelection_UsesExactCellArrayAndBuildingEffectCell, first topologyAssert.EqualexpectedBuildSequence=1, actual2. - Collapse alternating selection into one prefix instance count:
AlternatingCasterSelection_EmitsExactContiguousInstanceRuns, first active-command-countAssert.Equalexpected 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 literalLane=InstalledDatfilter 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:
- 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. - Record the hermetic artifact
artifacts/s5-c2-hermetic-20260904: 16,768 passed, 0 failed, 0 skipped; SHA-256 manifest 32/32 present and matching. - Preserve and explain the first InstalledDat artifact rather than hiding,
renaming, replacing, or calling it canonical:
artifacts/s5-c2-installed-20260904ran the literal filterLane=InstalledDatand produced 468 passed, 10 failed, 1 skipped; manifest 30/30 present and matching. - 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. - 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-Objectcomparisons returned no differences. Do not collapse the two passing counts into one claim. - 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.
- 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-abat cleanef819eedf.
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
GraphicsPerformancebias; - 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:
- selected GfxObj id zero: return after entry publication; no alpha barrier, portal walk, look-in draw, or shell;
- selected id nonzero: emit the existing alpha barrier first;
- 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;
- 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:
- direct base Gfx and ladder selections carry exact id/BSP/level/mode;
- 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;
- the prior-20 FPS ordering and the complete 30-slot
CalcDegLevelformula, stability gate, clamp, manual arm, warmup, and settings transitions match fixed expected sequences—not implementation self-comparison; - 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;
- 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;
- a synthetic Setup building draws only transformed part zero and uses the identical composed transform for distance, portal clip, and shell;
- Config's three rows are live-colored, persist exact values, and the one composed controller instance is borrowed by both renderer and FPS panel;
- publish/retire/revisit/reset and first/login/portal/null-root frames neither duplicate nor recreate the controller and leave existing building lifecycle behavior intact;
- the installed census equals §17.2 exactly; and
- 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:
SceneTool::UpdateFPSCounter @0x0043E510sums the 20 stored single-precision frame durations in x87 precision and divides before narrowing once at the published FPS store. Accumulating into a C#floatis not equivalent. Use a wider accumulator that exactly sums the 20 binary32 inputs, perform the division wide, then narrow once tofloat. Restore retail's physical history direction: shift old slots0..18to1..19, then store the just-finished binary32 duration at slot 0. The prior-20-before-insert order remains unchanged.Render::CalcDegLevel @0x0054CAF0evaluates 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 qword0.01, not0.01f. Keep the existing shift-before-evaluate and final current-multiplier store order.GfxObjDegradeInfo::get_degrade @0x0051E4B0stores the effective distance afterabs(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 tofloatbefore 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] × 10publishes bits0x43A6AAAB(333.333344f), not the candidate's0x43A6AAAC; CalculateCandidate(14f, 0f)publishes bits0x3BB2BC0A, not0x3BB2BC0B;- with ideal/max
24f/48f, multiplier0.0020020019728690386f, and effective distance24.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 publish0x3CA3D70A; the current combined store publishes0x3CA3D70B.
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:
- exclude the retail zero sentinel and deduplicate ladder IDs, including any
overlap with retained base
MeshRefs; - 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; - 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;
- preserve selected-only submission: an unavailable selected mesh remains a skipped shell, never a resident-base fallback; and
- 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
_missRequestedat each successfulBeginWalkPartFrame, 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 425083–425303),
RenderMeshSubset @0x0059CA10 (lines 425382–425450),
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 isabut whose stage-1CURRENTalpha 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:
MeshExtractorcomputes it from the resolved sourceSurfacefor ordinary GfxObj and CellStruct batches using the existingOpacityFromSurfaceTranslucencyrule;TextureBatchData, its deterministic serializer, andObjectRenderBatchpreserve 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:
- 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;
- set the detail slot/tiling and draw that source subset exactly once through its original base pipeline family;
- 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
- 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:
- 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²froma*qA,base.a*a*qA², and today's two draws; - pure/paletted/DDS CLIP values immediately below, equal to, and above the
final-
Xreference plusTranslucent|CLIP's disabled-test override; - 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;
- 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;
- 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;
- real EnvCell opaque, Alpha, Additive, and both CLIP-reference recordings with the same one-draw/state/order proof;
- production ordered sequence ordinary → opaque building detail → ClipMap building detail → ordinary with exact one-draw adjacency and no added terrain flush, closing #471;
- active/inactive atmospheric receiver shader/pipeline recordings proving identical material equations while leaving #470's separate general repair boundary explicit;
- 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
- 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:
- production collapses raw
Additive,Alpha|Additive, andInvAlpha|Additiveinto oneTranslucencyKind.Additive/ VulkanSRCALPHA,ONEpipeline. Retail instead usesONE,ONE,SRCALPHA,ONE, andINVSRCALPHA,ONErespectively. EnvCell additionally chooses its rawIsAdditivebucket before the already-resolved translucent override and owns no inverse pipeline, so both ordinary inverse alpha andTranslucent|ClipMap|Additivecan reach the wrong base state; - building/Wb commands never set push
ParamB, so a detail-active ClipMap fragment falls back to0.05rather than retail's final-Xreference of100/255for paletted input or200/255for DDS/non-paletted input. The command also lacks the state needed for ClipMap combined with another blend family; and - 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 425083–425303 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_EQUALwith the palette/DDS reference while retaining a pre-existing blend family, except that a pure ClipMap suppliesONE,INVSRCALPHA; - the later Translucent branch forces every
Translucent|ClipMapcombination 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-paletted200/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, andInvAlpha|Additive; - each applicable family with ClipMap, with both paletted and DDS reference
classes and final
Ximmediately below/equal/above the reference; Translucent,Translucent|Additive,Translucent|InvAlpha, and at leastTranslucent|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:
- collapse raw Additive back to
SRCALPHA,ONE; - collapse InverseAlpha+Additive to either existing additive pipeline;
- remove EnvCell's inverse-family selection;
- restore raw
IsAdditiveprecedence over the Translucent+ClipMap override; - zero Wb
ParamBfor a paletted row and separately substitute0.05for a DDS row; - remove alpha testing from an Alpha+ClipMap combined row;
- always fog a raw-Additive row; and
- 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 @0x0059C4D0first selects the framebuffer blend family. Its ClipMap arm at0x0059C724..0x0059C761retains an already-selected blend family, except for the pure-ClipONE,INVSRCALPHAcase, and enablesGREATER_EQUALalpha testing with the palette/DDS reference;- after the later Translucent override, the normal depth-state arm at
0x0059C7EE..0x0059C801selects depth-write1whenever alpha testing is still enabled or blending is disabled, otherwise depth-write0; SetSurface @0x0059C85E..0x0059C866passes that byte toRenderDeviceD3D::SetDepthBufferMode @0x005A2D10; the callee at0x005A2D4B..0x005A2D6Estores the third argument asm_State.DepthWriteEnableand programs D3D render state0x0E; 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|ClipMapis 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:
- Wb
StraightAlpha,AlphaAdditive, rawAdditive,InverseAlpha, andInverseAdditive, across both backbuffer/offscreen sample counts and the ordinary/atmospheric receiver pipeline sets; and - 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|ClipMapselects 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:
- collapse one Wb blended+Clip row back to its depth-write-OFF variant;
- collapse a different EnvCell blended+Clip family to depth-write off;
- incorrectly select depth-write ON for the corresponding non-Clip blend; and
- incorrectly make the late
Translucent|ClipMapoverride 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:
- when the current command has no active detail material, bind
pipelines.AlphaBlendregardless of itsTranslucencyKindor carried raw SetSurface state; - restore the prior coalescing rule for consecutive non-detail transparent
commands: do not split a run merely because
TranslucencyKindchanges; when detail is enabled, the next detail-bearing command remains a boundary; - 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 - 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:
- with detail disabled, one Additive and one InvAlpha ordinary instance each
bind
wb-mesh-alpha-1xand issue exactly one physical MDI; - with the detail category unavailable, the same two rows retain that result;
- adjacent same-cull Alpha -> Additive -> InvAlpha detail-off commands remain one outer material run/MDI range rather than three blend-family runs;
- detail enabled with an eligible command still selects its exact carried detail-active material pipeline and arms slot/tiling/reference/fog once;
- non-detail -> detail -> non-detail adjacency does not leak detail state and preserves the two required boundaries; and
- 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:
- restore
PipelineForBlend(pipelines, blend)on the non-detail arm; - restore the
TranslucencyKindequality run split while leaving the pipeline arm correct; and - 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.
26. S5-c4 landing, review closeout, and lead graphical gate — 2026-09-05
S5-c4 is LANDED + REVIEW-CLOSED. The reviewed scratch stack maps to the campaign branch as follows:
- one-pass detail material
91fb80de6->75664805f; - resolved SetSurface material state
70751ef0e->15ed57a1e; - alpha-tested blended depth-write variants
472dc4fb7->d5cfd1c91; and - classic/private detail-off restoration
db8136448->03a108ffa.
Retail/material pass 3/10 returned PASS after independently checking the named decomp, paired executable/PDB bytes, all five blend families, Clip references, Translucent override, fog, depth-write rule, real descriptors, register truth, and three mutations. Full production pass 4/10 found only §25's reachable classic/private detail-off regression. Fix round 3 changed exactly one production method plus its real-path transcript tests. Narrow production pass 5/10 reproduced all three mutations and returned PASS with no finding. C4's frame-aware ordered receiver selection/binding is retained; #470 is narrowed, not closed, because the ordinary shader's local-sidecar index is still wrong.
The campaign src/tests tree at 03a108ffa is byte-identical to reviewed
scratch db8136448. Fresh campaign verification passed: Release solution build
0 warnings / 0 errors; focused App material/ordered/EnvCell/shader suite
245/245; focused Content extraction/serialization/package suite 71/71. The
authoritative scratch artifacts remain exact, clean db8136448: hermetic
16,971/16,971 with manifest 32/32; InstalledDat 469 pass / the unchanged ten
accepted failures / one accepted skip with manifest 32/32.
Because the existing self-gate package was recipe 8, the lead did not launch
against stale prepared content or overwrite it. A separate full recipe-10 bake
from the campaign Release binary completed in 30.8 seconds with zero failures:
2,237,865 keys, 786,891 physical blobs, 597,482,264 bytes, SHA-256
4E0FA6C589ECE12E13099A56385077964961EC52F888BC9161C6F5D34829B59B.
It is
artifacts/s5-c4-recipe10-full-20260905/acdream.pak; header format 2 / recipe
10, TOC count 2,237,865. The gate session points only at this separate package.
The lead graphical gate is PROVISIONAL PASS pending owner inspection.
Before launch, ACE was listening on UDP 9000 as ACE.Server.exe PID 13340;
neither acdream nor retail client was running; the campaign worktree was clean;
and the Release build above was green. Exactly one Release client ran
tools/overhaul-selfgate/route-g3.txt with Building Detail Textures enabled
and the High atmospheric pack. It exited 0 through the route's own
close-client, logged graceful logout confirmed, and left no client process.
The log contains no fatal, unhandled, device-lost, or validation failure.
Evidence root:
logs/selfgate-20260905-020703-s5c4-onepass-detail.
All 13 requested 1024x768 PNGs were produced:
artifacts/screenshots/00-login.png;artifacts/screenshots/01-cathedral-stairs.png;artifacts/screenshots/02-facility-stairs.png;artifacts/screenshots/03-holtburg-house.png;artifacts/screenshots/04-holtburg-terrain-leak.png;artifacts/screenshots/05-cathedral-south-0106.png;artifacts/screenshots/06-cathedral-south-0104.png;artifacts/screenshots/07-cathedral-stairs-0107.png;artifacts/screenshots/08-cathedral-stairs-0112.png;artifacts/screenshots/09-cathedral-terrace-edge.png;artifacts/screenshots/10-facility-015E.png;artifacts/screenshots/11-facility-015F.png; andartifacts/screenshots/12-nanto-falls.png.
Lead inspection finds detailed cathedral, Facility, Holtburg, terrain, and
waterfall surfaces present; the player and expected shells/slabs/props remain
whole; and no new double-draw ghost, alpha/depth inversion, stale detail arm,
terrain bleed, or missing waterfall is visible. The separate known #469
lighting transition and #470 local-sidecar defect remain G4 blockers and are
not waived by this scope gate. #471 is closed by the ordered one-pass arm.
Nothing has merged to main.
27. S5-#470 contract — split shared transform and local sidecar indices
27.1 Lead-verified production boundary
This is a modern Vulkan ownership/indexing repair, not a new retail algorithm. No AC-specific material, lighting, visibility, or ordering fact changes. The named-retail facts already carried by the existing light/opacity/selection ports remain untouched; the paired retail binary has no analogue for acdream's shared Vulkan frame-ring layout.
The production defect is exact and bounded:
PrepareOrderedStreamwrites this stream's transforms throughWriteWorldTransformSection, which appends them to the shared directional-shadow/world transform arena and returns a possibly nonzerotransformBaseInstance.WriteIndirectCommandsadds that prefix to every indirect command'sBaseInstance, andDrawOrderedRangepublishes the same prefix inGpuPushConstants.TextureIndexB.- The alpha, selection-lighting, per-instance light-set, indoor, detail, and dormant clip-slot sections are separate ring sections whose descriptor offsets already point at element zero for this ordered submission.
mesh_atmospheric.verttherefore correctly names two indices: absolutetransformIndex = gl_BaseInstanceARB + gl_InstanceID, and localinstanceIndex = transformIndex - int(uTextureIndexB). It reads only the transform with the former and every live per-instance sidecar with the latter.mesh_modern.vertinstead uses the absolute value asinstanceIndexfor both domains. Any nonzero transform prefix therefore reads beyond or into unrelated local sidecar elements. This affects the ordinary ordered path; S5-c4 already repaired and proved atmospheric receiver selection/binding.
The batch array is a third, already-correct domain indexed by
uDrawIDOffset + gl_DrawIDARB; the global-light array is indexed by values
stored in the local light-set sidecar. The clip-slot buffer is still bound and
written but no world shader reads it after S3; do not reintroduce a clip read
or use its dead payload to justify wider work.
27.2 Bounded production repair
Make mesh_modern.vert use the same explicit split as
mesh_atmospheric.vert:
- add/read the existing push member as
uniform uint uTextureIndexB; - compute absolute
transformIndexfrom base-instance plus instance-id; - compute local
instanceIndexby subtractinguTextureIndexB; - index
Instances[]only withtransformIndex; and - index alpha, selection lighting, indoor, the eight-entry light-set, and
detail category only with
instanceIndex.
Correct the two shaders' comments so they describe the shared-transform/local- sidecar ownership rather than claiming that every buffer uses an identical index. Recompile the committed shader set and update only the generated SPIR-V and manifest/hash pins that the source change requires.
Do not change PrepareOrderedStream, ring-allocation ownership, descriptor
offsets, indirect command construction, push-constant ABI/size/offsets,
pipeline choice, atmospheric receiver binding, render-pack policy, SetSurface
state, detail equations, alpha queues/FIFO order, walk stages, batching, cull,
depth, blend, fog, transforms, sidecar contents, texture/batch indices,
geometry, DAT/package recipe, #469 lighting direction, or any unrelated
renderer. Do not add a second data owner, copy the local sidecars into the
shared transform arena, zero the transform prefix, special-case atmospheric
mode, or add a per-frame allocation. No divergence-register row is expected:
this restores intended production indexing without changing retail-visible
policy. If any wider production change proves necessary, stop and return the
exact dependency before expanding scope.
Allowed production scope is the ordinary vertex shader plus regenerated shader outputs. Tests may add the smallest production-path recording and offscreen proof needed below. The implementer changes no packet, plan, issue, architecture, package, gate artifact, or campaign memory file.
27.3 Discriminating proof and review return
Add permanent proof that fails on the pre-fix shader and exercises the real ordered preparation/draw seam:
- deliberately consume enough shared frame-ring transform space before
PrepareOrderedStreamthat its transform prefix is nonzero; - record two ordered instances with deliberately distinct transform, alpha, selection-lighting, light-set, indoor, and detail values;
- assert the uploaded indirect commands carry the nonzero absolute
BaseInstance, the push block carries that exact prefix, and each local sidecar descriptor section still begins at its own element zero; - compile/inspect the production ordinary SPIR-V and prove the source/ABI has one absolute transform lookup and local lookup for every live sidecar;
- add an offscreen pixel witness through the production ordinary shader at a nonzero transform prefix. Its two instances must encode distinguishable sidecar-driven output so using the absolute index for either domain changes the readback; a source-string-only or parallel-policy oracle is not this witness; and
- prove active and inactive directional-shadow receiver states still select and bind the same ordinary/atmospheric pipelines as before.
Apply and independently restore at least these mutations, recording the first discriminating failure for each in the commit body:
- make the transform lookup use local
instanceIndex; - make at least one live local sidecar lookup use absolute
transformIndex; - omit or zero the pushed transform prefix while keeping the shader split;
- force the inactive receiver state onto the atmospheric pipeline, then force the active receiver state onto the ordinary pipeline; and
- point the offscreen witness at a copied/test shader instead of the committed production ordinary SPIR-V.
Return one clean implementation commit atop this contract; exact changed-file
and line counts; all mutation first failures; both git diff --check forms;
Release solution build with zero warnings/errors; focused ordered-stream,
receiver, shader ABI/manifest/SPIR-V, offscreen, allocation, material, and
render-pack tests; official hermetic lane; and inclusive InstalledDat with all
accepted nonpassing identities named. Recipe 10 and prepared content are
unchanged, so no bake is required. No graphical client launch.
Review stays sequential. Retail/behavior pass 1/10 first verifies that no retail-visible algorithm or state changed, the existing named-retail sidecar meanings remain intact, and the proof actually distinguishes both index domains. Only after PASS does production/gate-honesty pass 2/10 inspect the complete data/descriptor/push/SPIR-V path, reproduce at least three mutations, and rule on gate sufficiency. A failed pass receives a bounded fix contract; the owner-authorized ceiling is ten review passes. Nothing lands or launches graphically before both lenses pass.