66 KiB
Campaign OVERHAUL — retail world construction and render solidity
Status: READY TO EXECUTE (plan requested by owner 2026-09-01; implementation has not started).
Campaign code: OH.
Worktree (binding):
C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-blackburn-5333f0
Branch (binding): claude/campaign-w-retail-frame-walk.
Plan-start HEAD: e8808602 (fix(render): restore landscape objects and walk alpha order), 27 commits ahead of the remote when this plan was written.
Known accepted historical anchor: b8befded (checkpoint: preserve user-gated FW closeout fixes). This is a rollback reference, not permission to
discard the work after it.
Dirty-tree rule: the worktree already contains a large, valuable set of uncommitted rendering, geometry, physics-shadow, lighting, diagnostics, test, and prepared-package changes. Nothing may reset, overwrite, clean, stash-pop, or wholesale replace that state. OH0 must classify and preserve it before the first behavioral edit.
Predecessor evidence: Campaign FW and the cathedral review corpus remain authoritative evidence, but Campaign OVERHAUL supersedes FW as the execution ledger for world-construction and world-render solidity work.
One-sentence goal: recreate retail's single coherent world-cell graph and its exact per-frame world walk up to a narrow Vulkan translation boundary, so walls, terrain, buildings, objects, particles, transparency, and portal transitions remain stable at every camera position without scene-specific suppression, guessed tolerances, or corrective overdraw.
1. Why this campaign exists
Campaign FW successfully replaced the legacy production visibility product with a retail-derived frame walk, fixed the original cathedral through-wall actor defect, restored outdoor particles, and corrected several object and terrain lifetime regressions. It did not make the complete world pipeline retail-identical.
The current client still reconstructs relationships that retail owns directly:
- prepared cell meshes are separate from portal topology;
- building shells are separate from building portal ownership;
- render projections are separate from physics
CELLARRAYmembership; - static visual membership is rebuilt from visual bounds;
- terrain is submitted as a complete slice before per-cell object turns;
- alpha uses a modern scope-global queue rather than retail's exact cell/list ownership;
- the interior depth clear is emitted unconditionally even though the retail
decomp establishes an outside-view block and a previous-frame
portalsDrawnCountlatch; - CellStruct face selection still uses the registered AP-234
NoPosproxy rather than the surface-type decision retail actually makes; - some accepted object parts are duplicated through Vulkan clip slots, a translation whose exact correspondence to the built-mesh retail leaf has not been proved for every content category.
These differences explain why local fixes oscillate between opposite failure modes: prevent one leak and walls disappear; restore a wall and a portal-view artifact returns; cull one cell and a valid stair or ramp vanishes. The campaign therefore changes the unit of work from "fix this visible triangle" to "port and prove this retail-owned world invariant."
2. Definition of success
Campaign OVERHAUL is complete only when all of the following are true.
- One authoritative, generation-scoped cell graph supplies portal topology, building ownership, drawable CellStruct identity, and render/physics cross-cell part membership. No production consumer rebuilds a competing answer.
- CellStruct mesh extraction selects sides and subsets from the same authored data retail uses, including exact surface-type handling. AP-234 is retired.
- The per-frame transcript matches retail for the same root and camera pose: landscape visits, portal views, building calls, cell order, object-list turns, frame-stamp boundaries, depth events, and alpha flushes.
- Every leaf category has a proven retail contract: EnvCell shell, building shell, landblock static, indoor static, dynamic object, particle, terrain, punch, seal, and transparent subset.
- Vulkan receives an ordered list of already-decided retail draw operations. Vulkan may encode and batch adjacent compatible work, but it does not decide visibility, ownership, ordering, clipping, or depth-phase membership.
- Scene-specific suppression, shell lifts, bias values, fallback floods, corrective redraws, and behavior-changing diagnostic flags do not remain in production.
- The owner acceptance matrix passes in the cathedral, Facility Hub, Nanto, Tusker Island, Holtburg, ordinary dungeons, and ordinary outdoor terrain.
- The complete Release suite, installed-DAT conformance lane, connected lifecycle route, R6 route, and performance checkpoint pass on the exact owner-gated binary.
- Architecture, inventory, divergence register, launch options, campaign memory, and milestone ledgers describe the code that actually ships. No document may claim a conditional clear while production emits an unconditional one, or claim exact cell extraction while AP-234 remains.
"Looks fixed at one camera angle" is never a completion condition.
3. Scope and non-goals
In scope
- CellStruct/EnvCell render-geometry construction.
- The canonical cell/building/portal/part-membership graph.
- Static and dynamic cross-cell render membership.
- Retail
PViewportal-view ownership and draw-leaf contracts. - Landscape, building, cell-shell, object, particle, depth, and alpha ordering.
- Portal punch and exit-seal lifecycle/state.
- Retail landscape
in_viewproduction and its particle/light/shadow consumers. - Material behavior necessary for solid world composition, including the transparent-detail AP-232 residual.
- Exact instrumentation and retail/acdream transcript comparison.
- Deletion of the superseded reconstruction and diagnostic apparatus.
- Documentation and regression coverage for the finished pipeline.
Explicitly out of scope
- Replacing Vulkan with retail's graphics API.
- Recreating C++ pointer layouts, allocator behavior, or COM objects.
- Changing the asynchronous streaming strategy, publication budgets, reveal radii, prepared-package mmap model, or GPU resource lifetime—except for a schema/version migration strictly required by exact prepared geometry.
- Increasing draw distance or hiding defects with additional residency.
- A general lighting redesign. Lighting must remain stable through the overhaul; independent lighting findings enter only if they prove a world-ownership or draw-order dependency.
- Physics behavior not required to produce exact cell/part membership.
- New graphics features, visual enhancements, or non-retail occlusion systems.
- Removing the user-requested Extended particle-range option. The Retail option must be exact; a deliberate user-selected range multiplier remains a documented preference rather than being confused with visibility parity.
4. Binding engineering rules
- Retail makes every world decision. Modern code may represent a result differently, but may not invent an additional visibility, membership, ordering, clipping, or depth decision.
- Evidence before code. Every behavioral slice begins with a written retail contract containing named functions, addresses, inputs, state writes, branch senses, call order, and observable output. No implementation starts from a screenshot theory.
- Named retail first. Search
docs/research/named-retail/acclient_2013_pseudo_c.txtandacclient.hbefore fresh decompilation. - Ghidra arbitrates branch sense. Binary Ninja pseudo-C is a navigation aid. Any condition whose polarity affects admission, clipping, depth, ordering, or lifetime must be cross-checked in Ghidra before implementation.
- DAT identity is exact. Aggregate owner IDs do not identify rendered content. A trace must reach landblock/static/server owner → Setup → part → GfxObj → polygon/surface before assigning a visual carrier.
- No symptom-site fixes. A cell ID, building ID, GfxObj ID, camera pose, cathedral-only branch, extra shell draw, or suppression flag may be used for diagnosis only. It cannot ship as behavior.
- No silent drop. During a slice, every rejected cell/view/part/mesh must have a diagnostic reason available. Production diagnostics are removed or made strictly print-only at slice close.
- No competing production owner. A cutover slice deletes the route it replaces. A temporary comparator may live within one slice but cannot cross the slice boundary as a second authority.
- Whole-mechanism fixes. Do not change a downstream draw call when retail owns the decision upstream in graph construction, portal traversal, shadow registration, or stage ordering.
- Build before launch. Every launched candidate is a green Release build
produced from a recorded commit/worktree state.
dotnet runwithout a successful build is forbidden. - Exact binary for gates. The commit/hash, package schema, environment flags, and log path are recorded before every owner gate.
- Client process safety. Never kill the client. Use graceful in-client closure only when the owner has authorized control; otherwise wait for the owner to close it.
- Preserve unrelated work. No destructive git command, broad checkout, reset, or clean. Every rollback is a normal revert of a named campaign commit or a return to a recorded checkpoint.
- Register discipline. A newly discovered deliberate deviation is filed in the same commit. A retired deviation is removed in the same commit as the exact port and its tests.
- Docs are tested truth. If the architecture text and production code disagree, the slice is not closed until one is corrected with evidence.
5. The required Plan → Implement → Review loop
Every numbered slice follows the same state machine:
PLANNED
→ EVIDENCE COMPLETE
→ IMPLEMENTED
→ REVIEWED (architecture + retail fidelity)
→ FINDINGS FIXED
→ NARROW RE-REVIEW
→ AUTOMATED GATE GREEN
→ OWNER GATE, only when assigned
→ CLOSED + rollback recorded
5.1 Plan packet required before implementation
Each slice receives a short research packet under
docs/research/2026-09-01-overhaul/ containing:
- the exact question being answered;
- named retail functions and addresses;
- struct fields and offsets used;
- caller/callee order;
- all branch senses that change behavior;
- retail state before and after the call;
- current acdream source locations;
- a retail-vs-acdream difference table;
- the smallest production ownership change that closes the difference;
- tests that fail before and pass after;
- performance/allocation risk;
- rollback boundary;
- whether an owner gate is required and why automation cannot settle it.
No packet may say "probably," "roughly," or "retail-shaped" at the behavior being implemented. Unresolved facts block only that sub-slice; they do not license an approximation.
5.2 Implementation discipline
- Implement one retail invariant at a time.
- Keep the diff local to the named ownership boundary.
- Add the deterministic failing test or comparator before changing production behavior whenever practicable.
- Preserve retail ordering even if it temporarily produces more draw calls. Adjacent-run batching is a later, separately reviewed optimization.
- Do not mix diagnostic experiments with the final implementation commit.
- Remove the replaced production route and its tests in the cutover commit.
- Build focused projects after every meaningful edit; build the full solution before review.
5.3 Two mandatory review lenses
Architecture review asks:
- Is there exactly one owner for this fact?
- Did a render cache or projection become a second world model?
- Do graphical and physics consumers borrow the same generation/identity?
- Are publication and teardown atomic at the existing boundary?
- Is fallback behavior explicit, bounded, and retail-supported?
- Did the change leak App/Vulkan types into Core/Content/Runtime?
- Can a retry, cancellation, recenter, or late upload create mixed generations?
Retail-fidelity review asks:
- Is every behavioral branch tied to a named retail function?
- Were ambiguous conditions Ghidra-arbitrated?
- Are list order, iteration direction, stamps, latches, and flush sites exact?
- Are built-mesh and non-built-mesh retail branches distinguished?
- Are polygon sides and Surface types interpreted from the correct owner?
- Does the implementation preserve retail quirks rather than normalize them?
- Does the test assert the retail mechanism, not merely the desired screenshot?
Review findings are recorded as Blocker/Major/Minor. Blocker and Major findings must be fixed before the slice gate. The changed surface receives a narrow re-review; a review is not closed by author explanation alone.
5.4 Commit shape
Prefer this sequence for each slice:
docs(render): define OHx retail contract— evidence packet and fixtures.fix(render): port OHx <mechanism>orrefactor(render): cut over OHx <owner>— behavior and focused tests.docs(render): close OHx review— review disposition, measured gates, register/doc reconciliation.
A very small slice may combine 1 and 2, but the evidence must still predate the
behavioral decision in the diff history. Every closed slice records its commit
and git revert <commit> anchor in this file.
6. Evidence hierarchy and oracle products
When sources disagree, use this order:
- Installed retail binary behavior captured at named functions.
- Named retail PDB/header identity and Ghidra-arbitrated decompilation.
- Byte-exact installed DAT structure and geometry.
- Existing retail cdb/oracle traces in
docs/research/2026-08-30-fw-walk-oracle/posed/. - Deterministic acdream replay of the same input.
- Render/API captures for confirming submitted geometry and state.
- acdream diagnostic logs.
- Visual observation, used to discover symptoms and accept final pixels—not to infer object identity or branch logic.
6.1 Canonical frame transcript
OH1 defines a versioned, line-oriented transcript. At minimum it records:
- frame number, frame stamp, previous/current
portalsDrawnCount; - camera pose, resolved camera root, player cell, outdoor/interior root kind;
- PView identity (
rootversus building look-in),draw_landscape, and outside-view count; - each portal-view polygon after every clip, including exact ordered vertices;
- todo insertion/pop order and cell draw-list append order;
- landscape landcell order and
in_viewresult; - building entry, degrade gate, look-in portal pass, alpha barrier, punch, and shell draw;
- EnvCell shell draw stamp and mesh identity;
- object-list cell turn and every admitted part, with membership source;
- particle owner turn and degradation decision;
- alpha enqueue list, insertion key, queue identity, and flush site;
- full-depth clear, far-Z punch, and true-depth seal state;
- exact final draw-leaf sequence.
Retail and acdream use the same semantic schema. Pointer values, Vulkan handles, and allocation addresses are excluded from equality.
6.2 Canonical geometry manifest
For every audited CellStruct polygon:
cellStructId
polygonIndex
sides_type / CullMode
NoPos / NoNeg
positiveSurfaceId / negativeSurfaceId
positiveSurface.Type / negativeSurface.Type
selected side(s)
subset classification
emitted/skipped reason
vertex IDs and final winding
The manifest is required for cathedral cells 0xF4180100, 0101, 0104,
0106, 0107, 0112, 0113, and 0114, plus the Facility Hub stair cells
around 0x8A02015E/015F. Installed-DAT catalog tests sample additional ordinary
dungeons so the solution cannot overfit those two buildings.
6.3 Canonical part-membership manifest
For each static/dynamic object part:
owner identity and owner kind
Setup ID / part index / GfxObj ID
root transform and part transform
retail drawing sphere and/or part bounds
resident cell
every crossed shadow cell, in retail insertion order
parent/child inheritance source
render membership
physics membership
fallback reason, if any
The production invariant is that one canonical registration transaction
produces retail's typed outputs: per-part render-shadow cells and object-level
physics CELLARRAY/broadphase cells. Those outputs may differ where retail's
algorithms differ, but no consumer may recalculate either one independently.
7. Target architecture
The final design keeps modern immutable storage but restores retail ownership. Names below are descriptive; OH1 may refine names without weakening the contract.
Prepared DAT assets
├─ exact CellStruct mesh/subset records
├─ exact portal/topology records
├─ exact building shell/portal ownership
└─ exact Setup/GfxObj part records
│
▼
WorldCellGraphSnapshot (one generation, one authority)
├─ CellNode[]
│ ├─ drawable shell identity
│ ├─ ordered portals/neighbours
│ ├─ owning building
│ ├─ ordered static part shadows
│ └─ ordered dynamic part shadows
├─ BuildingNode[]
├─ PartRenderShadowMembership[]
├─ ObjectPhysicsCellMembership[]
└─ exact stable indices/identities
│
├─────────────► physics adapter (borrowed)
├─────────────► render preparation adapter (borrowed)
└─────────────► RetailFrameWalk (borrowed topology)
│
▼
Retail semantic draw transcript
│
▼
Vulkan encoder / adjacent batching
Required properties
- Core/shared records are BCL-only and contain no Vulkan handles.
- Mesh payloads remain Content/App resources referenced by stable IDs/ranges.
- The existing generation/publication transaction remains the publication boundary; this campaign does not invent a second streamer.
- A complete graph snapshot becomes visible atomically.
- Render and physics adapters never mutate canonical topology/membership.
- Dynamic membership updates replace one object's membership transactionally and preserve exact object incarnation/generation identity.
- Child objects inherit the retail root object's
CELLARRAYthrough one canonical rule. - The walk owns temporary per-frame portal views, todo lists, draw lists, stamps, and latches. These are not persisted in render projections.
- The Vulkan encoder receives clip/depth/order data but cannot enlarge the visible set or reorder across a semantic boundary.
8. Stage overview and owner-gate budget
| Stage | Purpose | Owner gate |
|---|---|---|
| OH0 | Preserve/classify the current state and establish baseline evidence | No |
| OH1 | Define the exact retail world contract and upgrade the oracle | Only if a missing retail capture requires owner action |
| OH2 | Exact CellStruct geometry and prepared-package representation | Gate G1 after automated world-geometry checks |
| OH3 | One canonical cell graph and exact part-shadow membership | Fold into G1 if no second launch is needed; otherwise a short G1b |
| OH4 | Exact PView views and leaf admission/clipping contracts | No standalone owner gate |
| OH5 | Exact landscape/building/cell/object interleave | No standalone owner gate |
| OH6 | Exact depth epoch, clear latch, punches, seals, and frame stamps | Gate G2 for opaque-world solidity |
| OH7 | Exact alpha ownership, ordering, and flushes | No standalone owner gate |
| OH8 | Exact landscape in_view and particle/light/shadow consumers |
Gate G3 together with OH7/OH9 |
| OH9 | Building/material/degrade leaf fidelity required for composition | Fold into G3 |
| OH10 | Delete duplicate owners, fallbacks, experiments, and stale claims | No |
| OH11 | Full regression, performance, connected routes, docs, final acceptance | Gate G4 final matrix |
The owner should normally see four builds during the campaign, not one build per code slice. A new owner gate is added only when the automated oracle cannot settle a real visual/feel question or a prior gate exposes a regression.
9. Detailed stages
OH0 — safety baseline and dirty-tree classification
Goal: make the current state recoverable and comprehensible before any overhaul behavior changes.
Plan
- Record HEAD, upstream, status, staged/unstaged/untracked files, submodules, package schema, shader manifest hash, and installed-DAT identity.
- Classify every current dirty file into:
- accepted prior fix;
- current cathedral/facility investigation;
- exact retail depth-state port;
- diagnostic-only apparatus;
- tests for one of those changes;
- unrelated/user-owned change.
- Record the runtime flags that change behavior, especially every
ACDREAM_PROBE_CATHEDRAL_*switch, and prove they are unset in normal launch state. - Build the current state in Release and run the focused walk/geometry/depth tests. Record failures honestly; do not edit production to make OH0 green.
- Write
docs/research/2026-09-01-overhaul/oh0-baseline.mdwith the complete inventory and the exact recovery procedure. - Create a normal checkpoint commit containing only classified campaign work after confirming no unrelated user change is swept into it. If unrelated changes cannot be separated safely, leave them dirty and record hashes; never force a checkpoint by overwriting them.
Implement
OH0 changes documentation, evidence tooling, and checkpoint history only. It does not change draw behavior.
Review
- Confirm every pre-existing dirty file is accounted for.
- Confirm the accepted
b8befdedanchor and current HEAD are both recorded. - Confirm no behavioral probe is silently enabled by a default.
- Confirm the checkpoint can be reverted without reverting user-owned work.
Automated gate
- Release solution build result recorded.
- Focused walk/depth/geometry test results recorded.
git diff --checkclean for new OH files.- Recovery recipe reviewed from a fresh
git statussnapshot.
Owner gate
None. OH0 should not consume owner time.
Exit artifacts
oh0-baseline.md- first entry in the execution ledger
- checkpoint/recovery anchor
OH1 — retail world contract and oracle completion
Goal: replace prose such as "retail-shaped" with an executable contract for world construction and every frame leaf.
Plan
Produce focused, Ghidra-arbitrated notes for these symbol families:
- Construction/ownership
CEnvCell::init_static_objectsCPhysicsObj::calc_cross_cells_staticCPartArray::AddPartsShadowCPhysicsObj::add_shadows_to_cells- child-list propagation and cell removal counterparts
- Portal traversal
PView::InitCellPView::InsCellTodoListPView::ClipPortalsPView::AddViewToPortalsPView::ConstructViewRender::copy_view,Render::set_view,Render::obj_view_setRender::viewconeCheck
- Landscape/building order
LScape::draw_check_blocksLScape::landcell_checkLScape::grab_visible_cellsLScape::drawRenderDeviceD3D::DrawBuilding
- Cell/object leaves
PView::DrawCellsRenderDeviceD3D::DrawEnvCellRenderDeviceD3D::DrawObjCellForDummiesCPhysicsPart::Drawand its built/non-built branches
- Geometry/material/alpha
D3DPolyRender::ConstructMeshD3DPolyRender::DrawMeshD3DPolyRender::AddMeshToAlphaListD3DPolyRender::FlushAlphaListCShadowPart::insertion_sort
- Depth lifecycle
- the complete
PView::DrawCellsoutside-view block; - the source, reset, and previous-frame consumption of
portalsDrawnCount; - the mid-frame frame-stamp increment;
- far-Z portal punches and true-depth exit seals.
- the complete
The result must explicitly answer:
- Which built meshes are submitted whole after a Boolean sphere test?
- Which geometry is actually polygon-clipped by the installed portal view?
- Does a surviving object view cause multiple built-mesh draws or only repeated admission tests before a draw stamp suppresses duplicates?
- Which frame stamp applies to landscape look-ins versus the interior root?
- Which list owns transparent EnvCell subsets?
- What exactly increments
portalsDrawnCount, and when is it cleared? - What is the exact relationship between cell traversal order and part-shadow insertion order?
Implement
- Define the canonical transcript schema and serializers in test/tooling code.
- Extend retail capture templates only for missing fields.
- Add acdream transcript emission behind one print/file diagnostic that does not alter behavior.
- Convert the existing posed FW oracle into semantic fixtures consumable by equality tests.
- Add geometry and membership manifest generation to
A8CellAuditor a narrowly named successor tool; do not add DAT parsing to App.
Review
- Retail review verifies every transcript field is observable at the cited retail site.
- Architecture review verifies tooling does not become a second production visibility owner.
- A fixture review verifies pointers/addresses are normalized while ordering, float bits, IDs, and branch outcomes remain exact.
Automated gate
- Existing posed traces parse without loss.
- Round-trip transcript serialization is byte-stable.
- Synthetic ordering/latch fixtures detect deliberate one-event mutations.
- Installed-DAT manifests are deterministic across two runs.
- No production draw result changes.
Owner gate
Only if a retail capture lacks a fact that cannot be recovered statically. The request must name the exact location, pose, action, capture duration, and expected output; no open-ended "run around and report" gate.
Exit artifacts
oh1-retail-world-contract.md- versioned transcript schema
- versioned geometry/membership manifest schema
- retail/acdream replay fixtures
OH2 — exact CellStruct geometry and subset construction
Goal: retire AP-234 and make cell-wall geometry a byte/data-derived fact.
Plan
- Trace
DrawEnvCell → DrawMesh(arg4=1)andConstructMeshthrough Surface lookup and subset creation. - Pin the meaning of
sides_type,NoPos,NoNeg, positive/negative surface IDs, untextured surfaces, clip maps, and reversed winding. - Produce before-state manifests for all canonical cathedral and Facility Hub cells and a statistically useful installed-DAT sample.
- Identify every prepared-package record affected by adding exact surface identity/type to the extraction decision.
- Define package version/migration behavior before changing the codec.
Implement
- Thread the real positive/negative
Surface.TypeintoPrepareCellStructMeshDatabefore emit/skip selection. - Apply retail's exact side/subset rule; remove the
NoPosapproximation and its explanatory exception. - Preserve original polygon/vertex order and float bits.
- Update the prepared payload schema and strict codec if necessary.
- Update bake equivalence, migration catalog, launcher package validation, and corruption tests together.
- Rebuild only the required prepared package through the supported bake flow; never patch the package by hand.
- Delete AP-234 in the same behavior commit.
Tests
- Unit matrices for all
sides_type × NoPos × NoNeg × Surface.Typecombinations. - Positive/negative side winding and material identity tests.
- CellStruct manifest goldens for canonical scenes.
- Installed-DAT comparison over all available CellStruct records, reporting every changed polygon and why.
- Prepared-package encode/decode/corruption/version tests.
- Render-batch tests proving an untextured subset is skipped and a textured
NoPosedge case follows retail rather than the old proxy.
Review
- Retail reviewer checks the exact subset decision against the decomp.
- Data reviewer checks no ordinary GfxObj rule was accidentally applied to CellStructs or vice versa.
- Architecture reviewer checks the Surface lookup remains in Content/bake, not a render-thread DAT read.
Automated gate
- Content, Bake, Launcher.Core, and focused App suites green in Release.
- Installed-DAT manifest produces no unexplained difference.
- Full solution Release build green.
- No per-frame allocation or DAT lookup added.
Owner gate G1a — geometry integrity
One exact build, normal settings, all behavior-changing probes unset:
- cathedral exterior ramp and all floating stair slabs;
- cathedral walls at the known
0x104/0106and0x107/0112seams; - Facility Hub bottom/top stairs and doorway walls;
- two ordinary dungeons with solid-color and textured cell surfaces;
- Holtburg/Nanto building shells.
Pass means no missing/new wall faces, no invisible ramp/slab, and no gross material substitution. Camera-dependent occlusion is not adjudicated until OH6.
Rollback
One normal revert of the OH2 behavior/schema commit plus restoration of the previous prepared package version through the supported launcher migration.
OH3 — canonical world-cell graph and exact part-shadow membership
Goal: one graph owns the relationships retail stores on CEnvCell,
CBuildingObj, CPhysicsObj, CPartArray, and CShadowPart.
OH3a — graph contract and read-only construction
Plan: map every existing source of cell topology, building ownership, static membership, dynamic membership, and child inheritance. Define stable keys and generation lifetime.
Implement: build WorldCellGraphSnapshot alongside existing owners from
the same accepted publication input. It is initially read-only and diagnostic;
no consumer changes behavior.
Review: reject any field that is a renderer cache rather than world truth; verify Core/shared layering and atomic lifetime.
Gate: exhaustive equality between graph topology and source publication; zero production pixel change.
OH3b — static AddPartsShadow parity
Plan: port exact part bounds/shape, cell-crossing, insertion order, and removal rules for indoor statics, building parts, landblock statics, scenery, and non-colliding decorations.
Implement: populate one ordered membership vector per visual part. Retain the old render index as a comparator only inside OH3b. Cut render lookup to the canonical membership after exact comparison is green.
Tests: cathedral ramp/stairs/walls, Facility stairs, a large outdoor object crossing a 24 m cell edge, a landblock-edge object, a non-colliding decoration, and a multi-part Setup whose individual parts cross different cells.
Delete: the superseded visual-AABB index builder and duplicate cell buckets after cutover.
OH3c — dynamic and child membership parity
Plan: port add_shadows_to_cells, removal, movement update, and child-list
inheritance as one transaction tied to exact runtime entity incarnation.
Implement: one dynamic registration transaction produces the distinct retail render-shadow and physics-cell outputs, and the corresponding adapters borrow those typed results. Visual-only effects use a separately named, retail-supported owner rule rather than silently falling back to root position.
Tests: local player, remote player, NPC, projectile, spell worldobject, equipped child, contained child, crossing an indoor portal, crossing outdoors, and teardown/reconnect.
OH3d — consumer cutover and deletion
Cut the following consumers to the canonical graph in one controlled series:
- indoor static render lookup;
- outdoor static render lookup;
- dynamic render lookup;
- physics broadphase projection;
- particle owner-cell lookup;
- point-light owner-cell lookup;
- directional-shadow caster reachability.
After every consumer agrees, delete duplicate dictionaries, origin-cell fallbacks for prepared content, and independent render membership builders.
Review
- Architecture: exactly one membership authority; retry/recenter/reset safe.
- Retail: crossed cells and insertion order match
AddPartsShadowfamily. - Lifecycle: no stale incarnation or old generation can retain membership.
- Performance: no per-frame graph rebuild; updates are proportional to changed objects.
Automated gate
- Exact membership comparator reports zero mismatch across the installed-DAT canonical routes.
- Render-shadow and physics-cell projections each match their typed expected output from the same canonical registration transaction; any intentional difference between the two is explicit and fixture-covered.
- Cancellation, generation replacement, landblock retirement, reconnect, and child detach converge to zero retained rows.
- Full Release solution and connected headless lifecycle route green.
Owner gate G1b — membership stability
Use G1a's same binary if practical; otherwise launch once after OH3d:
- stand on and move around cathedral floating stairs/ramp;
- move/rotate at Facility Hub stairs;
- circle dense Tusker groups while turning the camera;
- observe remote player and NPC across the cathedral wall cells;
- cast and complete several spells, confirming no lingering visual owners.
Pass means static geometry never disappears merely because its origin cell or camera-facing cell changes, dynamics do not vanish at membership transitions, and retired effects leave no render rows.
OH4 — exact PView state and draw-leaf contract
Goal: prove and port what each installed portal view does to each content category. This stage resolves the current GPU clip-slot uncertainty.
Plan
For EnvCell shells, building shells, indoor statics, outdoor statics, dynamic objects, and particles, record separately:
- number of
portal_viewiterations; viewconeCheckinputs/result;- draw-stamp read/write;
Render::set_view/obj_view_setcalls;- built versus immediate polygon path;
- whether the final mesh is whole, CPU clipped, or later raster clipped;
- whether multiple surviving views cause multiple submissions;
- which view remains installed at the draw call.
The already-proved EnvCell rule is binding: the built cell shell is stamped and submitted whole once. The old "first view clips the shell" hypothesis is retired and may not return without contradictory binary evidence.
Implement
- Make
WalkPViewown the exact mutable per-frame state retail owns: portal-view lists, view/update counts, todo ordering, draw list, and stamps. - Retain exact screen/homogeneous portal polygons as the semantic view.
- Apply the retail leaf contract per content category:
- whole mesh once where retail does so;
- Boolean drawing-sphere admission where retail does so;
- exact polygon clipping only where retail does so;
- repeated submission only where retail does so.
- Remove Vulkan clip slots from any category for which they add clipping not present in retail.
- Where a retail polygon clip genuinely must reach Vulkan, translate the already-decided clipped polygon/planes exactly once and pin conventions with CPU/GPU equivalence tests.
- Delete comments/tests asserting the disproved generic rule that every accepted cell/static/dynamic mesh must render through the same clip slot.
Review
- One table row per content category with a retail call chain.
- Ghidra verification of every stamp/view loop branch.
- Shader review of clip-space sign, y inversion, W plane, max plane count, and scissor interaction for the remaining translated categories.
- Ensure clip slots cannot become a second admission mechanism.
Automated gate
- Retail/acdream leaf transcript equality for posed cathedral frames.
- Tests distinguish whole-shell once, Boolean part admission, and actual polygon clipping.
- Camera pan/zoom replay does not change membership or draw count except at the same retail view boundary.
- No unexplained duplicate draw of a stamped part.
Owner gate
Deferred to G2 after frame ordering and depth lifecycle are exact. Testing OH4 alone would produce ambiguous pixels and waste an owner round.
OH5 — exact landscape, building, cell, and object interleave
Goal: make the frame event sequence equal to retail rather than drawing terrain as a preliminary block.
Plan
- Recover the exact
LScape::draw/grab_visible_cellsiteration direction, sorting keys, and per-landcell call order. - Define the exact relationship between:
- terrain cell draw;
- building draw;
- landcell object list;
- building look-in flood;
- outdoor statics and particles;
- pre-clear alpha drain;
- interior root cell-shell/object-list passes.
- Record all degrade gates and their location relative to alpha barriers.
- Design terrain draw ranges that allow per-landcell turns without changing terrain geometry or texture blending.
Implement
- Replace
DrawTerrainSliceas a whole-stage event with ordered landcell terrain events. - Give
TerrainModernRendererstable per-landcell ranges/commands. - Emit terrain, buildings, and object lists in retail far-to-near order.
- Reproduce
DrawBuildingas one semantic sequence: degrade gate → full alpha barrier → portal/look-in work → punch → own shell. - Preserve the separate interior
DrawCellstwo-pass order: all shells in reverse draw-list order, then all object lists in reverse draw-list order. - Permit Vulkan to merge only adjacent compatible terrain/draw commands with no intervening semantic event.
- Remove the source comment and implementation that acknowledge "all terrain first" simplification.
Tests
- Synthetic three-landcell scene with buildings/objects between terrain cells; exact event-string golden.
- Equal-distance tie ordering.
- Building with and without drawable degrade slot.
- Look-in building embedded between two outdoor cells.
- Interior root with landscape views and without them.
- Outdoor root with no interior clear.
- Renderer command-buffer test proving an alpha/depth boundary prevents an otherwise legal adjacent merge.
Review
- Retail call-order audit against trace and decomp.
- Performance review ensures command count increase is measured, not hidden by reordering.
- Architecture review ensures terrain does not acquire a competing visibility list.
Automated gate
- Frame transcript order exact for all posed fixtures.
- Terrain pixels/mesh counts unchanged when no building/object interleave is present.
- Dense outdoor CPU/GPU p50/p99 captured as an informational checkpoint; no optimization is permitted to alter order.
Owner gate
Deferred to G2.
OH6 — exact depth epoch, clear latch, portal punches, seals, and stamps
Goal: reproduce retail's complete depth lifecycle, not merely the punch pipeline state.
Plan
- Reconstruct the full
PView::DrawCellscontrol flow aroundoutside_view.view_count, the landscape block, alpha flush, frame-stamp increment, conditional clear, and exit seals. - Identify the sole producers/reset sites of
portalsDrawnCountand prove whether the clear consumes the previous frame's value before or after reset. - Confirm look-in PViews (
draw_landscape=0) never execute the root landscape clear/seal block. - Confirm which 0xFFFF portals are sealed, their iteration order, installed view, polygon orientation, and true-depth draw.
- Retain the already-ported exact Vulkan state: depth test ALWAYS, depth write ON, color write OFF, no stencil; far-Z for punch, true clip-space depth for seal.
Implement
- Add one explicit frame-persistent latch owner corresponding to retail's
portalsDrawnCount; no renderer-local heuristic. - Gate the complete landscape→flush→stamp→clear→seal block exactly as retail.
- Remove
WalkFrameDriver's unconditional interior clear. - Place the mid-frame stamp transition exactly; allow straddling parts to draw in both retail scopes when retail re-arms them.
- Generate exit seals from the exact current walk views and retail cell order.
- Ensure building look-ins cannot advance or consume the root latch.
- Delete obsolete stencil/bias tests and any diagnostic skip path once the causal assertions are covered.
Tests
- Truth table over root kind,
draw_landscape, outside-view count, previous/current portal count, and expected clear/seal/stamp events. - Two consecutive frames proving the latch is genuinely cross-frame.
- Multiple building look-ins proving isolation from the root PView.
- Coincident cathedral exits at y≈24, y=48, and y=72.
- Recording GPU tests for exact punch/seal pipeline and draw count.
- Negative tests: outdoor root never clears interior depth; zero-view interior root does not execute a fabricated landscape block.
Review
- Retail reviewer traces every state write from producer to next-frame consumer.
- GPU reviewer checks pipeline state and clip-depth calculation only after the scheduling transcript is exact.
- Architecture reviewer checks the latch has one frame owner and deterministic reset on session/world generation changes.
Automated gate
- Exact depth-event transcript equality for posed fixtures.
- Focused walk/depth suites green.
- Full Release build and hermetic App suite green.
- Cathedral replay contains no behavior-changing probe.
Owner gate G2 — opaque-world solidity
The owner receives one exact binary with a short prescribed route:
- Cathedral
0xF4180106 ↔ 0xF4180104: move both directions, zoom, rotate; player remains whole and walls remain opaque. - Cathedral
0xF4180107 ↔ 0xF4180112floating stairs: ascend/descend, pan, zoom, stand at top and bottom; no wall-textured beam, missing slab, exterior terrain bleed, or chopped player. - Cathedral exterior ramp: visible from all meaningful exterior angles.
- Remote player parked at
0xF4180112: hidden from0x104,0x101, and outdoors wherever retail has no sightline; visible only through valid openings. - Facility Hub stairs at
0x8A02015E/015F: stairs and player remain whole at bottom, side, ascent, top, and all retail zoom extents. - Tusker/Nanto/Holtburg: rotate in place; terrain, buildings, and opaque objects remain stable.
Any failure reopens the owning OH4/OH5/OH6 slice based on transcript evidence. No new camera-specific suppression is allowed.
OH7 — exact alpha lists, per-cell order, and flush boundaries
Goal: retire AP-34 by reproducing retail's alpha ownership and order.
Plan
- Map the two retail alpha lists, their owners, insertion sites, insertion keys, equal-key behavior, and flush/reset lifecycle.
- Recover
CShadowPart::insertion_sortexactly, including direction and ties. - Pin every full flush:
DrawBuilding(... FlushAlphaList(0f));DrawCellspre-clear;- final normal-mode flush.
- Pin
DrawBlock's 0.75 pressure-valve semantics and prove it does not become a global distance sort. - Determine the queue ownership of transparent EnvCell shell subsets.
Implement
- Replace the scope-global CYpt sort with explicit retail queue/list records.
- Enqueue transparent parts at their cell/object turn after retail per-cell insertion ordering.
- Route transparent EnvCell subsets through the correct queue/flush behavior.
- Preserve FIFO at flush; do not sort the finished list globally.
- Preserve blend-mode boundaries without reordering entries. Adjacent compatible entries may batch only if their FIFO positions remain adjacent.
- Implement the 0.75 pressure valve exactly.
- Retire AP-34 in the behavior commit.
Tests
- Multiple translucent objects in one cell with reversed distance/insertion orders.
- Equal CYpt stable tie.
- Two cells whose global distance sort would disagree with retail traversal.
- Particle, translucent object, and transparent EnvCell overlap.
- DrawBuilding 0f full flush.
- Pre-clear flush and final flush.
- 0.75 partial flush/pressure valve.
- Alternating blend modes prove order retention across Vulkan batches.
Review
- Retail list/order review from insertion to flush.
- Vulkan review for blend/depth state without semantic reorder.
- Allocation review: queue storage is retained/reused, with no per-entry boxes.
Automated gate
- Alpha transcript exact on synthetic and posed fixtures.
- AP-34 deleted.
- Particle/mesh shared-alpha tests green.
- Dense particle field performance captured.
Owner gate
Fold into G3 after OH8/OH9 so particles, in_view, and material combine are
tested together.
OH8 — exact landscape in_view and visibility consumers
Goal: make terrain visibility, outdoor particle updating, light admission, and shadow reachability consume retail state instead of a modern approximation.
Plan
- Port and fixture
LScape::draw_check_blocks,landcell_check,get_clip_height, andblock_checkfrom named retail/Ghidra. - Establish exact grid pitch, interval math, corner order, view union, previous-frame stamping, and outside/inside enum meanings.
- Pin
CLandCell::IsInViewprevious-frame behavior andCEnvCell::IsInView's constantPARTIALLY_INSIDEbehavior. - Map the update-time and draw-time particle gates separately.
- Define the complete visibility answer as typed products, not one ambiguous set: visited EnvCells, in-view landscape cells, drawable object parts, and particle-update cells.
Implement
- Produce the exact retail landcell
in_viewset during the landscape walk. - Replace frustum/AABB reconstruction for retail
IsInViewconsumers. - Feed exact state to particle update/degrade, point-light snapshots, and directional-shadow selection.
- Keep EnvCell preparation scoped to visited EnvCells; do not union unrelated outdoor cells into shell preparation.
- Preserve the explicit user-selectable Extended particle range after the exact retail visibility gate. Retail mode applies no multiplier.
- Retire or narrow AP-117 based on the exact port.
Tests
- Landcell boundary grazing and multiple portal-view union.
- Previous-frame
CLandCell::IsInViewtiming. - Constant interior EnvCell particle cell test plus distance gate.
- Nanto waterfalls turning at
0xE43D001E. - Cathedral waterfall owner range
0xCF418000..13. - Tusker scenery/creature visibility while rotating.
- Point light and shadow consumer equality with canonical typed sets.
Review
- Retail math and one-frame timing review.
- Consumer audit proves no remaining frustum/AABB visibility reconstruction.
- Settings review isolates Extended range as a deliberate post-retail option.
Automated gate
- Installed-DAT terrain visibility comparisons green.
- Particles/lights/shadows report no independent cell-set decisions.
- Full Core/App focused suites green.
OH9 — building/material/degrade leaf fidelity
Goal: close remaining composition differences that can look like missing or bleeding world geometry even when traversal is correct.
Plan
- Audit
DrawBuildingdegrade selection and no-geometry behavior. - Audit building/EnvCell detail texture setup and transparent subset combine.
- Resolve AP-232 by pinning retail's single fixed-function stage result, including output alpha.
- Confirm cull mode, negative-side rendering, clip-map discard, fog, depth write, and blend state per world subset class.
- Separate material defects from lighting differences; this stage changes lighting only when named retail material state requires it.
Implement
- Make building degrade selection and complete body gate exact.
- Reproduce retail's single-result detail combine for translucent subsets, either in one Vulkan shader path or a mathematically proven equivalent that produces the same framebuffer result.
- Preserve exact opaque detail behavior.
- Normalize world subset state through one audited policy table so building, EnvCell, and ordinary GfxObj paths cannot silently disagree.
- Retire AP-232 when pixel-equivalence tests cover translucent detail.
Tests
- Opaque, clip-map, alpha, inverse-alpha, additive, luminous, and detail-bearing world subsets.
- Translucent detail over dark and bright backgrounds.
- Building degrade slot absent/present.
- Positive/negative side and cull-state matrix.
- Fogged transparent detail identity.
Review
- Retail material-stage review.
- Shader algebra review with framebuffer-equivalence fixtures.
- Pipeline-state review for depth/cull/blend consistency.
Automated gate
- AP-232 deleted.
- Offscreen framebuffer tests match the retail formula.
- World material suites and full Release build green.
Owner gate G3 — transparency, particles, and material composition
One combined route:
- cathedral waterfalls, lake mist, torches, floating stairs, walls, exterior ramp, lifestone/portal effects, and remote actors;
- Nanto waterfalls while rotating at the recorded position;
- Holtburg lifestone behind houses and NPCs;
- Tusker spell casting, projectile completion, corpses, dense creatures, and scenery;
- Facility Hub point lights and transparent/magenta-lit surfaces at multiple zoom levels;
- at least one ordinary dungeon with transparent/detail-bearing material.
Pass means correct occlusion, no lingering effects, no particle disappearance, no transparency exchange across cells, and no camera-dependent material bleed.
OH10 — delete reconstruction residue and enforce the architecture
Goal: ensure the exact path is the only path that can ship.
Plan
Inventory every class/field/flag made obsolete by OH2–OH9. Search by type, constructor, interface, environment variable, log prefix, test name, and docs.
Implement
Delete or retire:
- competing cell/part membership dictionaries;
- origin-cell and visual-AABB fallbacks for prepared world content;
- generic per-view GPU clip rules disproved by OH4;
- whole-stage terrain events superseded by per-landcell interleave;
- unconditional clear code and stale comments;
- scope-global alpha ordering superseded by retail queues;
- behavior-changing cathedral skip flags and carrier-discriminator code;
- obsolete shell lift, bias, stencil, corrective redraw, or suppression tests;
PortalVisibilityBuilderresearch code if no test/research owner still needs it; otherwise move it out of production assemblies and mark it non-authority;- stale launch-option rows and retired diagnostics;
- architecture claims contradicted by the final code.
Add architectural guards:
- production call graph has one
WalkPView/world-cell graph owner; - renderer cannot query DAT directly;
- consumers cannot construct independent visibility sets;
- Vulkan submitter cannot sort across semantic event boundaries;
- no production reference to behavior-changing OH diagnostic symbols;
- divergence rows retired in their owning commits.
Review
- Dead-code/call-graph review.
- Architecture dependency review.
- Retail review of every deletion to ensure no real mechanism was mistaken for patch apparatus.
- Documentation consistency review.
Automated gate
rgguards and dependency tests green.- No OH behavior-changing probe remains.
- Full Release build and hermetic suites green.
git diff --checkclean.
Owner gate
None; pixels must be unchanged from the accepted G3 binary. If cleanup changes pixels, it is a failed deletion and the owning slice reopens.
OH11 — performance, regression, final owner acceptance, and closeout
Goal: prove the exact architecture survives ordinary play and becomes the documented shipping state.
Automated closeout
- Full Release solution build.
- Focused suites:
- App Walk/PView/frame-driver/depth/alpha/render tests;
- Content CellStruct/Surface/prepared-package tests;
- Core cell-transit/shadow/membership tests;
- Runtime lifetime/placement tests touched by shared membership;
- Launcher package migration tests.
- Hermetic solution lane:
Lane!=InstalledDat&Lane!=Linux&Lane!=Manual&Lane!=Timing&Lane!=Live&Lane!=PreparedPackage. - Supported installed-DAT lane, with unsupported/known exclusions listed rather than hidden.
- Two clean deterministic geometry and membership manifest runs with equal hashes.
- Retail/acdream frame transcript equality over all canonical fixtures.
- Capped and uncapped lifecycle/reconnect routes.
- R6 nine-stop route.
- Portal-in and portal-out presentation route, including long destination preparation.
- Graceful shutdown with zero retained graph/membership/alpha rows.
Performance checkpoint
Measure the exact final candidate in Release:
- dense Arwic capped and uncapped;
- Tusker dense-creature scene;
- cathedral interior/floating stairs;
- Facility Hub interior;
- CPU/GPU p50 and p99, FPS, draw/dispatch counts, managed allocation/frame, working/private memory, graph/membership retained bytes, and alpha queue high water.
Correctness comes first, but a regression greater than 20% against the recorded pre-OH baseline triggers an explicit optimization slice before final gate. Optimization may merge adjacent compatible commands or reuse storage; it may not reorder, cull, or weaken the retail transcript. Every optimization must pass transcript equality before performance is remeasured.
Owner gate G4 — final acceptance matrix
The final user gate repeats G1–G3 on one clean exact binary and adds ordinary travel:
- cathedral complete route and two-client wall occlusion;
- Facility Hub stair circuit;
- Nanto waterfalls and town buildings;
- Tusker Island combat/casting/camera rotation;
- Holtburg town/building/lifestone route;
- at least two ordinary dungeons selected without code changes;
- portal to/from each world type;
- zoom/pan/rotation at seams;
- ten minutes of free movement looking for spontaneous terrain/object loss.
The owner verdict is recorded per row as PASS/FAIL with location and symptom. A failure reopens the responsible slice. The final binary is not rebuilt after owner acceptance except for documentation-only changes; if code or shader bytes change, the affected gate repeats.
Documentation closeout
- Update
docs/architecture/acdream-architecture.mdwith the actual canonical graph and frame pipeline. - Update
docs/architecture/worldbuilder-inventory.mdwith the exact boundary: asset extraction/preparation only, never world visibility ownership. - Reconcile
docs/architecture/retail-divergence-register.md. - Update
docs/launch-options.mdafter probe deletion. - Close/supersede the relevant FW ledger sections without deleting history.
- Update roadmap, milestones, and
project_frame_walk_campaign.mdor its successor memory with current truth at the top. - Record final commits, package version, test counts, connected artifacts, performance numbers, user verdict, and reverts.
Campaign close condition
Only after G4 passes and docs match code does Status change to
CLOSED — USER ACCEPTED.
10. Canonical scene and symptom matrix
| Scene | Fixed coordinates/state | Required invariant | Primary stages |
|---|---|---|---|
| Cathedral south transition | 0xF4180106 [37.181568 46.790077 169.804993] ↔ 0xF4180104 [37.310383 48.895710 169.804993] |
Player and walls remain whole; no wand/body depth inversion | OH4–OH6 |
| Cathedral wall actor | Observer 0x104, 0x101, outdoors; remote in 0xF4180112 [36.299465 18.594580 169.804993] |
Actor visible only through a retail-valid sightline | OH3–OH6 |
| Cathedral floating stairs | 0xF4180107 [38.311169 24.270454 177.423584] ↔ 0xF4180112 [38.333950 23.704699 177.868729] |
Every slab stable; no moving wall-textured triangles/rays | OH2–OH6 |
| Cathedral exterior ramp | Stand directly on the formerly invisible ramp | Exact authored shell/member always renders | OH2–OH5 |
| Facility Hub stairs | 0x8A02015E [60.971485 -42.752495 -4.121752], 0x8A02015F [58.815380 -49.425373 -0.857726] |
Stairs/player stable at bottom, side, ascent, top, zoom | OH2–OH6 |
| Nanto waterfalls | 0xE43D001E [93.826614 126.522484 120.005005] |
Falls do not vanish while rotating; houses occlude effects/NPCs | OH7–OH9 |
| Tusker Island | Owner's dense combat route | Terrain/scenery/actors stable; completed spell objects retire | OH3, OH5, OH8 |
| Holtburg | Town route | Buildings intact; particles/lifestone obey opaque depth | OH5–OH9 |
| Ordinary dungeons | At least two selected before code changes | No cathedral-specific overfit; stairs/walls/portals stable | All |
The matrix is append-only during the campaign. New symptoms receive a row and are assigned to an existing invariant before any fix is attempted.
11. Test and command policy
Standard build
dotnet build AcDream.slnx -c Release
Focused project families
dotnet test tests\AcDream.Content.Tests\AcDream.Content.Tests.csproj -c Release --no-build
dotnet test tests\AcDream.Core.Tests\AcDream.Core.Tests.csproj -c Release --no-build
dotnet test tests\AcDream.Runtime.Tests\AcDream.Runtime.Tests.csproj -c Release --no-build
dotnet test tests\AcDream.App.Tests\AcDream.App.Tests.csproj -c Release --no-build
dotnet test tests\AcDream.Launcher.Core.Tests\AcDream.Launcher.Core.Tests.csproj -c Release --no-build
Use focused --filter expressions during implementation, but a stage cannot
close on focused tests alone. Record exact commands and counts in the ledger.
Launch discipline
Normal owner-gate launch, from the binding worktree after a green Release build:
$env:ACDREAM_DAT_DIR="$env:USERPROFILE\Documents\Asheron's Call"
$env:ACDREAM_LIVE="1"
$env:ACDREAM_TEST_HOST="127.0.0.1"
$env:ACDREAM_TEST_PORT="9000"
$env:ACDREAM_TEST_USER="testaccount"
$env:ACDREAM_TEST_PASS="testpassword"
dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Release
All behavior-changing probes remain unset for acceptance. A trace gate lists its print-only flags explicitly. Never reuse an old running client after a rebuild; record the launched binary hash and process start time.
12. Instrumentation lifecycle
Every new probe is declared in the owning research packet before code:
- question it answers;
- exact emission site;
- fields and identity chain;
- print-only versus behavior-changing;
- expected maximum volume;
- environment flag;
- deletion stage.
Rules:
- Prefer deterministic file transcripts to console tail interpretation.
- Print only on state change or bounded frame windows unless a capture explicitly requires every event.
- Never use aggregate owner IDs as geometry identity.
- Behavior-changing probes may exist only inside the active investigation and must be visibly announced at startup.
- A behavior-changing probe can identify a mechanism; it cannot become the mechanism.
- OH10 removes all Campaign OVERHAUL behavior-changing probes.
13. Rollback and recovery policy
- No history rewrite.
- Every closed behavior slice records a normal
git revertanchor. - Schema migrations record both code revert and package restoration steps.
- A failed owner gate reverts only the candidate slice if the cause is known; otherwise preserve logs/artifacts and return to the latest accepted campaign checkpoint.
- Never revert the entire dirty starting tree to
b8befded; that commit is a historical baseline, not a substitute for OH0 classification. - Failed experiments are either reverted immediately or committed on an explicitly quarantined branch. They do not remain mixed into the next candidate.
- The owner must always be told which exact client binary is running.
Rollback ledger
| Slice | Implementation commit(s) | Last accepted gate | Revert command/notes |
|---|---|---|---|
| Starting history | b8befded, 4808d4d1, 4683ac6f, e8808602 |
FW/Tusker gates recorded in predecessor plan | Historical anchors only; OH0 classifies dirty successor work |
| OH0 | b3b7d922 |
n/a | Recovery checkpoint only; git revert b3b7d922 removes the preserved investigation state. This commit is not a retail/visual acceptance claim. |
| OH1 | — | n/a | Fill during execution |
| OH2 | — | G1a | Fill during execution |
| OH3 | — | G1b | Fill during execution |
| OH4 | — | G2 combined | Fill during execution |
| OH5 | — | G2 combined | Fill during execution |
| OH6 | — | G2 | Fill during execution |
| OH7 | — | G3 combined | Fill during execution |
| OH8 | — | G3 combined | Fill during execution |
| OH9 | — | G3 | Fill during execution |
| OH10 | — | pixels unchanged | Fill during execution |
| OH11 | — | G4 | Fill during execution |
14. Risk register
R1 — rebuilding retail's object graph as a second scene graph
Risk: WorldCellGraphSnapshot becomes a mirror that can drift from Runtime
or publication state.
Control: graph records own only canonical topology/membership facts; mesh and entity state remain borrowed by stable identity. Atomic generation tests and consumer deletion are part of OH3, not deferred cleanup.
R2 — over-porting mutable C++ mechanics
Risk: copying retail pointer/list implementation creates unnecessary allocation and lifetime hazards.
Control: port observable ordering, ownership, stamps, and state transitions; represent them with retained arrays/indexes. Equality is judged by semantic transcript, not pointer layout.
R3 — Vulkan batching changes semantic order
Risk: performance optimization regroups cells/materials after the exact walk is built.
Control: ordered stream is immutable; only adjacent compatible runs merge. Tests deliberately place merge-compatible draws around alpha/depth boundaries.
R4 — prepared-package schema churn
Risk: exact CellStruct surface data invalidates existing packages or creates launcher/client skew.
Control: OH2 owns one explicit version bump, strict rejection/migration, rollback, corruption tests, and launcher coverage.
R5 — retail oracle incompleteness
Risk: an unobserved built-mesh branch causes another confident but wrong generic clipping rule.
Control: OH1 explicitly separates each leaf category and blocks OH4 until the built/non-built behavior is settled. No approximation is allowed to bridge the gap.
R6 — scene overfitting
Risk: cathedral IDs leak into production logic or tests validate only one DAT structure.
Control: production guards reject scene IDs; installed-DAT sampling and ordinary-dungeon gates are mandatory.
R7 — performance collapse from per-cell commands
Risk: exact interleave increases draw calls and CPU overhead.
Control: correctness-first transcript; then adjacent-run merging and retained storage only. The 20% stop rule requires an explicit optimization slice, never a semantic shortcut.
R8 — stale documentation drives the next wrong fix
Risk: architecture/plan claims remain inconsistent with code.
Control: OH10 includes grep/document consistency checks; OH11 cannot close until the architecture description is reviewed against production call sites.
R9 — too many owner gates
Risk: implementation degenerates into repeated manual trial-and-error.
Control: four planned gate builds only. Every build arrives after evidence, implementation, two-lens review, fixes, and automated gates.
15. Execution ledger
Update this table immediately when a slice changes state. Do not keep the real status only in chat.
| Slice | Status | Evidence packet | Implementation | Reviews | Automated gate | Owner gate | Notes |
|---|---|---|---|---|---|---|---|
| OH0 | CLOSED | docs/research/2026-09-01-overhaul/oh0-baseline.md |
b3b7d922 recovery checkpoint |
Read-only dirty-tree classification; every path accounted for | Release build green; focused gates 319 passed / 1 skipped; OH docs pass git diff --check |
n/a | No production behavior changed by OH0; no unrelated semantic files found; candidate state is explicitly unaccepted |
| OH1 | IN PROGRESS | oh1-retail-world-contract.md plus construction, built-view, alpha-list, and depth packets |
strict Core schema/codec and output-only App recorder in review | retail synthesis re-review passed after two blockers were corrected; final alpha/tooling review active | Core codec focused gate green before schema-expansion review | not required so far | No production draw decision may change; legacy FW semantic importer and recorder equivalence gate remain |
| OH2 | PLANNED | — | — | — | — | G1a | Retire AP-234 |
| OH3a | PLANNED | — | — | — | — | folded | Read-only canonical graph |
| OH3b | PLANNED | — | — | — | — | folded | Static membership |
| OH3c | PLANNED | — | — | — | — | folded | Dynamic/child membership |
| OH3d | PLANNED | — | — | — | — | G1b if needed | Consumer cutover/deletion |
| OH4 | PLANNED | — | — | — | — | folded into G2 | Per-leaf portal-view contract |
| OH5 | PLANNED | — | — | — | — | folded into G2 | Full landscape interleave |
| OH6 | PLANNED | — | — | — | — | G2 | Exact depth lifecycle |
| OH7 | PLANNED | — | — | — | — | folded into G3 | Retire AP-34 |
| OH8 | PLANNED | — | — | — | — | folded into G3 | Retire/narrow AP-117 |
| OH9 | PLANNED | — | — | — | — | G3 | Retire AP-232 |
| OH10 | PLANNED | — | — | — | — | n/a | Deletions and guards |
| OH11 | PLANNED | — | — | — | — | G4 | Final closeout |
16. First execution actions
When the owner says to begin execution, do exactly this:
- Start OH0; do not edit rendering behavior.
- Produce the dirty-tree classification and recovery anchor.
- Build and record the current baseline.
- Start OH1's retail contract with the two facts most likely to invalidate
current code:
- object built-mesh behavior under
set_view/obj_view_set; - complete
portalsDrawnCountproducer/consumer/reset lifecycle.
- object built-mesh behavior under
- In parallel only after OH0 safety is complete, prepare OH2's CellStruct surface manifest; it is independent of frame scheduling.
- Review the OH1/OH2 evidence before the first behavior change.
- Implement OH2, review it, fix findings, and run G1a.
No new cathedral visual discriminator is the first action of this campaign.