731 lines
52 KiB
Markdown
731 lines
52 KiB
Markdown
# Campaign OVERHAUL — retail world construction and render solidity
|
||
|
||
**Status:** ACTIVE — **v2 rescope 2026-09-02.** Five production slices replace
|
||
the twelve-stage v1 plan. S1 is the current slice. See §13 for the ledger and
|
||
§15 for what v2 changed and why.
|
||
|
||
**Campaign code:** `OH`.
|
||
|
||
**Worktree (binding):**
|
||
`C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-blackburn-5333f0`
|
||
|
||
**Branch (binding):** `claude/campaign-w-retail-frame-walk`. This is the
|
||
long-lived renderer integration branch. It carries all of Campaign FW (101
|
||
commits over `origin/main` at `e102fb36`). **Nothing merges to `main` until
|
||
the final gate passes**; `origin/main` is merged INTO this branch at every
|
||
slice boundary so it never drifts.
|
||
|
||
**v2 base:** `5d907ae9` (`docs(render): define OH1 retail world contract`),
|
||
tree clean. The uncommitted OH1/T3 evidence grammar (~32K lines) is parked
|
||
verbatim on `quarantine/oh1-evidence-grammar-2026-09-02` (see its
|
||
`QUARANTINE-README.md`). Do not merge that branch.
|
||
|
||
**Recovery anchors:** `b3b7d922` is the checkpoint that committed the
|
||
pre-overhaul investigation candidates, including the Facility Hub stair fix
|
||
(recipe 7 authored drawing sphere, static render-shadow membership, per-part
|
||
stamps). `b8befded` is the user-gated FW closeout. Both are history, not
|
||
permission to discard later work. No history rewrite, ever.
|
||
|
||
**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 replaced the legacy visibility product with a retail-derived frame
|
||
walk and fixed several defects. It did not make the world pipeline
|
||
retail-identical. The client still reconstructs relationships 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 `CELLARRAY` membership;
|
||
- static visual membership is rebuilt from visual bounds in an App-owned model
|
||
that competes with the physics registry;
|
||
- 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 unconditional although retail latches it on the
|
||
previous frame's `portalsDrawnCount`;
|
||
- CellStruct face selection uses the AP-234 `NoPos` proxy rather than the
|
||
surface-type decision retail makes;
|
||
- some accepted object parts are duplicated through Vulkan clip slots without
|
||
proof that retail clips them.
|
||
|
||
These explain why local fixes oscillate between opposite failure modes. The
|
||
precedent is physics: incremental collision patching never converged; the
|
||
faithful retail port did. The renderer gets the same treatment.
|
||
|
||
Owner-observed symptom family: cathedral walls/wall-textured triangles over
|
||
floating stairs; stair slabs appearing/disappearing by camera angle; the
|
||
cathedral exterior ramp absent; textures bleeding through opaque surfaces; the
|
||
local character chopped at cathedral and Facility Hub seams; remote actors and
|
||
particles through walls; waterfalls vanishing by angle; outdoor groups
|
||
disappearing after small turns; landscape draw-range regressions; spell
|
||
effects lingering.
|
||
|
||
---
|
||
|
||
## 2. Definition of success
|
||
|
||
1. 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.
|
||
2. CellStruct mesh extraction selects sides and subsets from the same authored
|
||
data retail uses, including exact surface-type handling. AP-234 is retired.
|
||
3. The per-frame transcript matches retail's captured transcript for the same
|
||
root and camera pose at the depth the capture records: landscape/building
|
||
order, portal views, cell order, object-list turns, shell/part draws,
|
||
depth events, alpha inserts and flushes.
|
||
4. Every leaf category has a proven retail contract: EnvCell shell, building
|
||
shell, landblock static, indoor static, dynamic object, particle, terrain,
|
||
punch, seal, transparent subset.
|
||
5. Vulkan receives an ordered list of already-decided retail draw operations.
|
||
It may batch adjacent compatible work; it decides nothing.
|
||
6. No scene-specific suppression, shell lift, bias, fallback flood, corrective
|
||
redraw, or behavior-changing diagnostic flag remains in production.
|
||
7. The owner acceptance matrix (§10) passes.
|
||
8. The complete Release suite, installed-DAT lane, connected lifecycle route,
|
||
R6 route, and performance checkpoint pass on the exact gated binary.
|
||
9. Architecture, inventory, divergence register, launch options, memory, and
|
||
milestone ledgers describe the code that ships.
|
||
|
||
"Looks fixed at one camera angle" is never a completion condition.
|
||
|
||
---
|
||
|
||
## 3. Scope and non-goals
|
||
|
||
**In scope:** CellStruct/EnvCell geometry construction; the canonical
|
||
cell/building/portal/part-membership graph; static and dynamic cross-cell
|
||
render membership; retail `PView` view ownership and leaf contracts; landscape,
|
||
building, cell-shell, object, particle, depth, and alpha ordering; portal punch
|
||
and exit-seal lifecycle; retail landscape `in_view` and its particle/light/
|
||
shadow consumers; material behavior needed for solid composition (AP-232
|
||
residual); minimal per-slice instrumentation; deletion of superseded
|
||
reconstruction and diagnostic apparatus; docs and regression coverage.
|
||
|
||
**Out of scope:** replacing Vulkan; recreating C++ pointer layouts; changing
|
||
streaming strategy, budgets, reveal radii, the mmap package model, or GPU
|
||
resource lifetime except the S1 recipe bump; increasing draw distance; a
|
||
lighting redesign; physics not required for exact membership; new graphics
|
||
features; removing the user-requested Extended particle-range option.
|
||
|
||
---
|
||
|
||
## 4. Binding engineering rules
|
||
|
||
1. **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.
|
||
2. **A slice ships a production behavior change or it is not a slice.**
|
||
Evidence tooling is built inside the slice that consumes it, to the depth
|
||
that slice needs, never as its own stage.
|
||
3. **Evidence before code, contract already written.** The OH1 research
|
||
contracts (§6) and the retail capture (§7) are the evidence. No slice
|
||
starts from a screenshot theory; no slice builds a new evidence language.
|
||
4. **Named retail first; Ghidra arbitrates branch sense.** Any condition whose
|
||
polarity affects admission, clipping, depth, ordering, or lifetime is
|
||
cross-checked in Ghidra (`patchmem`, port 8081) before implementation.
|
||
5. **DAT identity is exact.** A trace reaches owner → Setup → part → GfxObj →
|
||
polygon/surface before assigning a visual carrier. Aggregate owner IDs do
|
||
not identify content.
|
||
6. **No symptom-site fixes.** Cell/building/GfxObj IDs and camera poses are
|
||
for diagnosis only.
|
||
7. **No silent drop.** Every rejected cell/view/part/mesh has a diagnostic
|
||
reason available during a slice; production diagnostics are removed or made
|
||
print-only at slice close.
|
||
8. **No competing production owner.** A cutover slice deletes the route it
|
||
replaces within the slice.
|
||
9. **Whole-mechanism fixes.** Never patch a downstream draw when retail owns the
|
||
decision upstream.
|
||
10. **Build before launch; exact binary for gates.** Commit hash, package
|
||
recipe, flags, and log path are recorded before every owner gate.
|
||
11. **Client process safety.** Never kill the client.
|
||
12. **Preserve unrelated work.** No `reset --hard`, `checkout --`, `clean`, or
|
||
bare `stash`. Rollback is a normal revert of a named commit.
|
||
13. **Register discipline.** Deviations filed/retired in the same commit.
|
||
14. **Docs are tested truth.** Architecture text and code agree at slice close.
|
||
15. **Time-box.** A chunk that needs a third fix round stops and goes to the
|
||
user with its evidence. No agent decides it needs more infrastructure.
|
||
|
||
---
|
||
|
||
## 5. Working model
|
||
|
||
The v1 failure was one agent given the whole campaign for eighteen hours. v2
|
||
keeps the lead in the loop at every chunk.
|
||
|
||
| Role | Who | Does | Never |
|
||
|---|---|---|---|
|
||
| Lead / architect | the main session (Fable) | writes each chunk contract (files, retail functions + addresses, acceptance tests); dispatches one bounded chunk; verifies every claim against source; runs gates; commits; merges main in at slice boundaries | hands off "complete the slice" |
|
||
| Implementer | Sonnet, one dispatch per chunk | one file cluster + its tests; build and test green is the return condition; returns a diff summary and open questions | commits; adds evidence infrastructure; starts a third fix round; touches files outside its contract |
|
||
| Retail reviewer | Opus, one pass per slice on the production port | checks each ported branch against the named decomp with addresses; findings as file:line + decomp citation | reviews tooling |
|
||
| Architecture reviewer | Opus, only at the two cutover slices (S2, S5) | one owner per fact; layering; lifetime; performance shape | |
|
||
| Finding verification | the lead, against the source | each reviewer finding is checked by the lead against the decomp/contract/code before it is acted on; at most one Opus skeptic, and only for a blocking finding the lead cannot settle | spawns a skeptic per finding (the S1 review fanned out to ~30 agents this way on 2026-09-02; never again) |
|
||
|
||
**Agent budget per slice:** implementers as needed (one per chunk, serial for
|
||
coupled files); reviewers two (retail lens, and the architecture lens only at
|
||
S2/S5); skeptics at most one per blocking finding. Anything that would spawn
|
||
more than five agents in one step is wrong and stops.
|
||
|
||
Chunk contracts state explicit stop conditions: build red after two attempts →
|
||
return; contract ambiguity → return with the question; any need for a third
|
||
round → return. Coupled files go to one agent serially against a pinned
|
||
contract; only genuinely independent chunks run in parallel worktrees.
|
||
Agents write incremental output to disk; a silent agent is stopped and
|
||
inspected, not waited on.
|
||
|
||
---
|
||
|
||
## 6. Evidence hierarchy and products
|
||
|
||
When sources disagree, in this order:
|
||
|
||
1. Live retail binary behavior captured at named functions (§7).
|
||
2. Named retail PDB/header identity and Ghidra-arbitrated decompilation.
|
||
3. Byte-exact installed DAT structure and geometry.
|
||
4. Existing FW0 cdb traces in `docs/research/2026-08-30-fw-walk-oracle/`.
|
||
5. Deterministic acdream replay of the same input.
|
||
6. Render/API captures.
|
||
7. acdream diagnostic logs.
|
||
8. Visual observation — to discover symptoms and accept final pixels, never to
|
||
infer identity or branch logic.
|
||
|
||
**Research contracts already written (committed at `5d907ae9`, binding):**
|
||
`oh1-retail-world-contract.md`, `oh1-construction-landscape-contract.md`,
|
||
`oh1-built-mesh-view-contract.md`, `oh1-alpha-list-contract.md`,
|
||
`oh1-depth-lifecycle.md`, `oh2-cellstruct-surface-contract.md`, and the
|
||
corrected `2026-08-30-fw-flood-pseudocode-appendix.md`. The retail facts the
|
||
v1 T3 reviews established are carried in
|
||
`2026-09-02-campaign-overhaul-handoff.md` §5.3 and are binding inputs to S3/S4.
|
||
|
||
**Evidence products, minimal by design:**
|
||
|
||
| Product | Form | Used by |
|
||
|---|---|---|
|
||
| Geometry conformance | installed-DAT scans + synthetic fixtures + a two-run SHA-256 over the emitted CellStruct subset records | S1 |
|
||
| Membership conformance | typed expected cell lists per fixture object + installed-DAT comparator between the canonical graph and the old builders (comparator lives and dies inside S2) | S2 |
|
||
| Frame transcript | the FW0 line format (`F/P/LS/BLD/DI/DC`) extended with the OH line kinds the capture scripts emit; parsed by the existing test-side `WalkOracleTrace` parser, extended in place; acdream emits the same lines behind ONE print-only flag inside the slice that needs it | S3, S4 |
|
||
| Framebuffer equivalence | offscreen fixture renders compared to the retail formula | S5 |
|
||
|
||
Pointer values, Vulkan handles, and allocation addresses are excluded from
|
||
equality. No canonical JSONL, no semantic validator: structure is checked in
|
||
the parser, semantics in the port and in the compare against retail.
|
||
|
||
---
|
||
|
||
## 7. Retail capture session (owner action, before S3)
|
||
|
||
The one owner action in the campaign apart from gates. Scripts live in
|
||
`tools/walk-oracle/oh/` (recon, three capture templates, runner, README).
|
||
|
||
| Pose | Root | Why |
|
||
|---|---|---|
|
||
| holtburg-doorway-still | interior `a9b4013f` | the flap scene; three consecutive look-in punches of one cell |
|
||
| terrace-edge | outdoor | the #456 pose; far building drawn and depth-covered |
|
||
| cathedral-arrival | interior `f4180106` | interior root, landscape through the exit view, culled roster |
|
||
| foundry-deep | interior `a9b40176` | deep chain with `ov=1`; landscape and 12 buildings drawn from the basement |
|
||
|
||
Per pose, three short attaches in order, each auto-detaching after its frame
|
||
budget: **walk** (cell granularity: FW0 lines plus `DrawEnvCell` and object-cell
|
||
turns, 5 frames), **parts** (`CPhysicsPart::Draw` candidates and
|
||
`DrawMeshInternal` actual draws with GfxObj ids, 3 frames), **alpha/depth**
|
||
(`AddMeshToAlphaList`, `FlushAlphaList` with site, depth-clear latch and
|
||
`portalsDrawnCount`, 5 frames). Still poses repeat bit-for-bit per frame
|
||
(FW0 finding 6), so few frames suffice and the ACE-timeout risk from
|
||
per-hit `.printf` stays bounded. Budget: one hour.
|
||
|
||
Procedure: recon attach first (no breakpoints; `dt`/`x` dumps verify every
|
||
offset the templates assume); PDB pairing check before every attach; `qd` only
|
||
at top level after the terminal-hit fall-through. Logs land in
|
||
`docs/research/<date>-oh-walk-oracle/` and become S3/S4 fixtures.
|
||
|
||
If a static fact is later found unrecoverable from these captures, request one
|
||
more exact capture with pose, action, duration, and expected trace. Never an
|
||
open-ended "run around and report".
|
||
|
||
---
|
||
|
||
## 8. Target architecture (unchanged from v1)
|
||
|
||
```text
|
||
DAT + prepared package
|
||
└─ S1 CellStruct subset construction (surface-index owned, recipe 8)
|
||
World-cell graph (generation-scoped, S2)
|
||
├─ portal topology, building ownership, drawable cell identity
|
||
├─ static part-shadow membership (init_static_objects/AddPartsShadow)
|
||
└─ dynamic/child membership (add_shadows_to_cells, one transaction)
|
||
Frame walk (per frame, S3)
|
||
├─ LScape::draw order → DrawBuilding sequence → look-ins
|
||
├─ PView views/todo/draw-list/stamps → DrawCells two-pass
|
||
└─ leaf admission per category (whole-once / Boolean sphere / real clip)
|
||
Depth + alpha (S4)
|
||
├─ portalsDrawnCount latch, conditional clear, punches, seals, mid-frame stamp
|
||
└─ retail alpha lists, per-cell insertion, FIFO flush sites, 0.75 valve
|
||
Consumers (S5)
|
||
└─ landcell in_view → particles/lights/shadows; material/degrade policy
|
||
Vulkan encoder: ordered immutable stream; merges adjacent compatible runs only
|
||
```
|
||
|
||
Required properties: render and physics adapters never mutate canonical
|
||
topology/membership; dynamic updates replace one object's membership
|
||
transactionally with exact incarnation identity; children inherit the root's
|
||
`CELLARRAY` by one rule; the walk owns per-frame views/todo/draw lists/stamps/
|
||
latches and never persists them in projections; the encoder cannot enlarge the
|
||
visible set or reorder across a semantic boundary.
|
||
|
||
---
|
||
|
||
## 9. The five slices
|
||
|
||
Each slice: plan packet (already written or one short note) → implementation
|
||
in bounded chunks → retail review (+ architecture review at S2/S5) → fix →
|
||
automated gate → owner gate where listed → ledger update → merge `origin/main`
|
||
in.
|
||
|
||
### S1 — Geometry: exact CellStruct construction (was OH2)
|
||
|
||
**Spec:** `oh2-cellstruct-surface-contract.md`, sections 3, 8, 9, 10, 12 are
|
||
the implementation contract verbatim. Retail anchors: `CEnvCell::UnPack`
|
||
`0x0052D470`, `CPolygon::UnPack` `0x00538650`, `copyVert` `0x0059C080`,
|
||
`D3DPolyRender::ConstructMesh` `0x0059DFA0`, `D3DPolyRender::DrawMesh`
|
||
`0x0059D4A0`, `RenderDeviceD3D::DrawEnvCell` `0x0059F170`.
|
||
|
||
**Behavior change:** side candidates come only from `sides_type`; `NoPos`/
|
||
`NoNeg` mean UV absence only; subsets are owned and ordered by source surface
|
||
index; built-EnvCell admission is `(Surface.Type & 6) != 0` after surface
|
||
resolution; authored `sides_type` is not GPU cull. AP-234 retired.
|
||
|
||
**Chunks:**
|
||
1. Core side-candidate descriptor (pure, allocation-free) + `MeshExtractor.
|
||
PrepareCellStructMeshData` rewrite against it + §10.1/§10.2 tests.
|
||
2. Prepared subset record fields (source surface index, raw type, retail mask,
|
||
fixed cell-shell cull) + `ObjectMeshDataSerializer` round-trip +
|
||
`PakFormat.CurrentBakeToolVersion = 8`, launcher recipe 8, `7 → 8`
|
||
FullRebuild step + §10.5 tests. Container format stays 2, with a test
|
||
saying so.
|
||
3. `CellMesh.Build` routed through the same descriptor or its render role
|
||
deleted; full installed-DAT scan with every admission delta explained by
|
||
`Surface.Type & 6`; two-run deterministic hash; §10.3 canonical pins
|
||
(`0xF4180104`: eight `ST_DOUBLE` clip-map polygons, 44 drawable side
|
||
calls); AP-234 row deleted with addresses; inventory/architecture text.
|
||
|
||
**Review:** retail lens on the descriptor, mask, winding, and admission; data
|
||
lens that no ordinary-GfxObj rule leaked into cells or vice versa; Surface
|
||
lookup stays in Content/bake.
|
||
|
||
**Automated gate:** Content, Bake, Core, Launcher.Core, focused App suites
|
||
green in Release; installed-DAT scan reports zero unexplained deltas; full
|
||
solution build green; no per-frame allocation or DAT lookup added.
|
||
|
||
**Package:** rebuild the dev pak (`Documents\Asheron's Call\acdream.pak`) to
|
||
recipe 8 through the supported bake flow; keep the recipe-7 file beside it as
|
||
`acdream.recipe7.pak`. Note the launcher-installed pak under
|
||
`%LOCALAPPDATA%\acdream\pak` is still recipe 6; it is not the gate binary's
|
||
pak.
|
||
|
||
**Owner gate G1 — geometry integrity.** One exact build: cathedral exterior
|
||
ramp and every floating stair slab; cathedral walls at the `0x104/0106` and
|
||
`0x107/0112` seams; Facility Hub bottom/top stairs and doorway walls; two
|
||
ordinary dungeons with solid-color and textured surfaces; Holtburg/Nanto
|
||
shells. Pass = no missing/new wall faces, no invisible ramp/slab, no gross
|
||
material substitution. Camera-dependent occlusion is not adjudicated here.
|
||
|
||
**Rollback:** revert the S1 behavior/schema commits; restore
|
||
`acdream.recipe7.pak`.
|
||
|
||
### S2 — World graph: one membership owner (was OH3)
|
||
|
||
**Spec:** `oh1-construction-landscape-contract.md` §construction/ownership;
|
||
retail: `CEnvCell::init_static_objects`, `CPhysicsObj::calc_cross_cells_static`,
|
||
`CPartArray::AddPartsShadow`, `CPhysicsObj::add_shadows_to_cells`,
|
||
`find_bbox_cell_list`, child-list propagation and removal counterparts.
|
||
Starting point: the `b3b7d922` candidates (`WalkProductionWorldData` render
|
||
index, `ShadowShapeBuilder.FromStaticRenderParts`,
|
||
`ShadowObjectRegistry.ComputeStaticRenderCells`, the Facility stair pin
|
||
`FacilityStairAssembly_RegisterAcross015FTo015EWithoutCollisionRows`). They
|
||
use retail's mechanism in the wrong owner; S2 moves them, it does not delete
|
||
the mechanism.
|
||
|
||
**Behavior change:** one generation-scoped `WorldCellGraphSnapshot` owns
|
||
portal topology, building ownership, drawable cell identity, and typed
|
||
per-part render-shadow plus object-level physics `CELLARRAY` outputs from one
|
||
registration transaction. Every consumer borrows it; the App-owned render
|
||
index, visual-AABB fallbacks, origin-cell fallbacks, and duplicate cell buckets
|
||
are deleted.
|
||
|
||
**Chunks (revised 2026-09-02 from the ownership trace in
|
||
`s2-membership-ownership-map.md`):**
|
||
1. Retail CELLARRAY from the whole part array (per part: physics sphere else
|
||
drawing sphere, part box) computed in `ShadowObjectRegistry` at the same
|
||
registration call as today's collision flood, retained as a new product
|
||
beside `_entityToCells`, plus per-cell part entries (entity, part, GfxObj,
|
||
cell frame, clip-planes-required) in registration order. Nothing consumes
|
||
it yet; a comparator over installed-DAT fixtures reports retail vs current
|
||
collision vs current render cells. Zero pixel change.
|
||
2. Render statics cut over to the registry's per-cell part entries; delete
|
||
`ResolveStaticRenderCells`, `ComputeStaticRenderCells`, the fingerprint
|
||
cache, and App's `FromStaticRenderParts` use. Fixtures: cathedral
|
||
ramp/stairs/walls, Facility stairs, a 24 m cell-edge crosser, a
|
||
landblock-edge object, a non-colliding decoration, a multi-part Setup whose
|
||
parts cross different cells.
|
||
3. Collision cut over: `_entityToCells`/`_cells` from the same CELLARRAY.
|
||
Physics suites, placement/collision replay fixtures, connected nine-stop
|
||
route.
|
||
4. Dynamics and children: `add_shadows_to_cells` recursion at registration and
|
||
movement; particles own-cell; delete the render-side parent-chain walk.
|
||
Fixtures: local/remote player, NPC, projectile, spell world object,
|
||
equipped child, contained child, indoor portal crossing, outdoor crossing,
|
||
teardown/reconnect.
|
||
5. Consumer cutover and deletion: remaining `WalkProductionWorldData` buckets
|
||
become borrowed views, particle owner union reads the same, duplicate
|
||
dictionaries and origin-cell/visual-AABB fallbacks are deleted. Lights and
|
||
directional shadows stay for S5. Topology triplication (`LoadedCell` /
|
||
`WalkCell` / flat asset) is consolidated with S3's `WalkPView` state, not
|
||
here.
|
||
|
||
**Review:** architecture (one authority; retry/recenter/reset safe; no
|
||
per-frame rebuild) and retail (crossed cells and insertion order match the
|
||
`AddPartsShadow` family; `CellTransit` prune change affects collision too and
|
||
is reviewed as such).
|
||
|
||
**Automated gate:** comparator zero mismatch on installed-DAT canonical routes;
|
||
render-shadow and physics projections each match typed expectations from the
|
||
same transaction; cancellation, generation replacement, landblock retirement,
|
||
reconnect, child detach converge to zero rows; full Release solution and
|
||
connected headless lifecycle route green.
|
||
|
||
**Owner gate G2 — membership stability.** Cathedral floating stairs/ramp;
|
||
move/rotate at Facility Hub stairs; circle dense Tusker groups while turning;
|
||
remote player and NPC across cathedral wall cells; cast several spells. Pass =
|
||
static geometry never vanishes because its origin or camera-facing cell
|
||
changes; dynamics do not vanish at transitions; retired effects leave no rows.
|
||
|
||
### S3 — Walk: exact PView views, leaf admission, and interleave (was OH4 + OH5)
|
||
|
||
**Spec:** `oh1-built-mesh-view-contract.md`, `oh1-retail-world-contract.md`,
|
||
the flood appendix, handoff §5.3 facts, and the §7 capture fixtures.
|
||
Retail: `PView::InitCell`, `InsCellTodoList`, `ClipPortals`,
|
||
`AddViewToPortals`, `ConstructView`, `DrawCells`, `Render::copy_view`,
|
||
`set_view`, `obj_view_set`, `viewconeCheck`; `LScape::draw_check_blocks`,
|
||
`landcell_check`, `grab_visible_cells`, `draw`, `calc_draw_order`;
|
||
`RenderDeviceD3D::DrawBuilding`, `DrawEnvCell`, `DrawObjCellForDummies`,
|
||
`CShadowPart::insertion_sort`, `CPhysicsPart::Draw`, `DrawMesh`,
|
||
`DrawMeshInternal`.
|
||
|
||
**Binding already-proved facts:** the built cell shell is stamped and
|
||
submitted whole once after Boolean admission; portal polygons, not built
|
||
meshes, are polygon-clipped; `DrawCells` draws all shells then all object
|
||
lists, both in reverse draw-list order, views ascending; device, cell-shell,
|
||
and part stamps persist with the local-player bypass. The "first view clips
|
||
the shell" hypothesis is retired.
|
||
|
||
**Behavior change:** `WalkPView` owns retail's exact per-frame state
|
||
(portal-view lists, view/update counts, todo order, draw list, stamps); each
|
||
content category follows its retail leaf rule (whole-once / Boolean sphere /
|
||
actual polygon clip / repeated submission) and Vulkan clip slots are removed
|
||
from categories where retail does not clip; terrain is emitted as ordered
|
||
landcell events interleaved with buildings and object lists in retail
|
||
far-to-near order; `DrawBuilding` is one semantic sequence (degrade gate → full
|
||
alpha barrier → look-in work → punch → own shell); the "all terrain first"
|
||
simplification is deleted.
|
||
|
||
**Chunks:** (1) transcript emitter for the OH line kinds behind one print-only
|
||
flag + parser extension + fixture import of the §7 logs; (2) exact PView
|
||
state and per-category leaf contract with CPU/GPU equivalence pins for any
|
||
category that still translates a clip to Vulkan; (3) landscape/building/cell/
|
||
object interleave with per-landcell terrain ranges; (4) delete disproved
|
||
generic clip rules and the whole-stage terrain event.
|
||
|
||
**Review:** retail lens on every stamp/view loop branch (Ghidra) and on the
|
||
call order against capture and decomp; shader review of clip-space sign, y
|
||
inversion, W plane, plane count, scissor for remaining translated categories;
|
||
performance review that command count increase is measured, not hidden by
|
||
reordering.
|
||
|
||
**Automated gate:** transcript equality with the §7 captures at the captured
|
||
depth for all four poses plus the FW0 still fixtures; tests distinguish
|
||
whole-shell-once, Boolean part admission, and actual polygon clipping;
|
||
pan/zoom replay changes membership/draw count only at a retail view boundary;
|
||
no duplicate draw of a stamped part; terrain pixels/mesh counts unchanged when
|
||
no interleave is present; dense-outdoor p50/p99 recorded.
|
||
|
||
**Owner gate:** none standalone; folds into G3.
|
||
|
||
### S4 — Depth and alpha: latch, punches, seals, stamps, lists, flushes (was OH6 + OH7)
|
||
|
||
**Spec:** `oh1-depth-lifecycle.md`, `oh1-alpha-list-contract.md`, the §7
|
||
alpha/depth captures. Retail: the complete `PView::DrawCells` outside-view
|
||
block, `portalsDrawnCount` producer/reset/consumer, the mid-frame stamp
|
||
increment (`@0x005A4886`), far-Z punches, true-depth exit seals;
|
||
`D3DPolyRender::AddMeshToAlphaList`, `FlushAlphaList`,
|
||
`CShadowPart::insertion_sort`, `DrawBlock`'s 0.75 pressure valve.
|
||
|
||
**Behavior change:** one frame-persistent latch owner for `portalsDrawnCount`;
|
||
the landscape → flush → stamp → clear → seal block gated exactly as retail;
|
||
`WalkFrameDriver`'s unconditional interior clear deleted; the mid-frame stamp
|
||
placed exactly so straddling parts draw in both retail scopes; exit seals from
|
||
the exact current views and cell order; look-ins cannot touch the root latch.
|
||
The scope-global CYpt sort is replaced by explicit retail list records with
|
||
per-cell insertion order, FIFO flush, exact full-flush sites, and the 0.75
|
||
valve; transparent EnvCell subsets routed to their retail list. AP-34 retired.
|
||
Vulkan keeps the already-ported state: depth ALWAYS, write ON, color OFF, no
|
||
stencil; far-Z punch, true clip-space seal.
|
||
|
||
**Chunks:** (1) latch owner + conditional block + seal generation + truth-table
|
||
tests; (2) alpha list records + insertion sort + flush sites + valve +
|
||
ordering tests; (3) delete obsolete stencil/bias/skip paths and the CYpt sort.
|
||
|
||
**Tests:** truth table over root kind, `draw_landscape`, outside-view count,
|
||
previous/current portal count → clear/seal/stamp events; two consecutive
|
||
frames proving the latch is cross-frame; multiple look-ins isolated from the
|
||
root; coincident cathedral exits at y≈24/48/72; outdoor root never clears
|
||
interior depth; multiple translucent objects in one cell with reversed
|
||
distance/insertion orders; equal-key stable tie; two cells where a global sort
|
||
disagrees with traversal; particle/object/transparent-cell overlap;
|
||
`DrawBuilding 0f` flush; pre-clear and final flush; 0.75 partial flush;
|
||
alternating blend modes across Vulkan batches.
|
||
|
||
**Review:** retail lens tracing every state write from producer to next-frame
|
||
consumer, and every list from insertion to flush; GPU lens on pipeline state
|
||
after the transcript is exact; architecture lens that the latch has one frame
|
||
owner and resets on generation change.
|
||
|
||
**Automated gate:** depth-event and alpha transcripts exact against §7
|
||
captures; focused walk/depth/alpha suites and full Release build green; AP-34
|
||
deleted; no behavior-changing probe in the cathedral replay.
|
||
|
||
**Owner gate G3 — opaque solidity and transparency.** Cathedral
|
||
`0xF4180106 ↔ 0xF4180104` both directions with zoom/rotate; floating stairs
|
||
`0xF4180107 ↔ 0xF4180112` ascend/descend/pan/zoom; exterior ramp from all
|
||
angles; remote player at `0xF4180112` seen only through valid openings from
|
||
`0x104`, `0x101`, outdoors; Facility Hub stairs at all zoom extents; cathedral
|
||
waterfalls, mist, torches, lifestone/portal effects; Tusker/Nanto/Holtburg
|
||
rotate in place. Pass = player whole, walls opaque, no wall-textured beam or
|
||
missing slab, no terrain bleed, correct transparency order, no effect through
|
||
walls.
|
||
|
||
### S5 — Consumers, material, cleanup, closeout (was OH8 + OH9 + OH10 + OH11)
|
||
|
||
**Spec:** `oh1-construction-landscape-contract.md` §landscape; retail
|
||
`LScape::draw_check_blocks`, `landcell_check`, `get_clip_height`,
|
||
`block_check`, `CLandCell::IsInView` (previous-frame), `CEnvCell::IsInView`
|
||
(constant `PARTIALLY_INSIDE`); `DrawBuilding` degrade selection; the
|
||
fixed-function material stage for translucent detail (AP-232).
|
||
|
||
**Behavior change:** the landscape walk produces the exact retail landcell
|
||
`in_view` set; frustum/AABB reconstruction is replaced for every `IsInView`
|
||
consumer (particle update/degrade, point-light snapshots, directional-shadow
|
||
selection); the Extended particle range remains a deliberate post-retail
|
||
option, Retail mode applies no multiplier; AP-117 retired or narrowed. Building
|
||
degrade selection and complete-body gate exact; translucent detail combine
|
||
reproduces retail's single stage result with framebuffer-equivalence
|
||
fixtures; one audited world-subset state policy table; AP-232 retired. Then
|
||
delete every obsolete owner, fallback, flag, probe, and stale claim, add the
|
||
architectural guards, and run the full closeout.
|
||
|
||
**Cleanup inventory (delete or retire):** competing membership dictionaries;
|
||
origin-cell and visual-AABB fallbacks; disproved generic per-view clip rules;
|
||
whole-stage terrain events; unconditional clear code; scope-global alpha
|
||
ordering; `ACDREAM_PROBE_CATHEDRAL_*` skip flags and the carrier-discriminator
|
||
code; `ACDREAM_PROBE_FACILITY_STAIRS` and `WbDrawDispatcher.FacilityStairProbe`
|
||
with its call sites in `RetailPViewRenderer`, `WalkPView`,
|
||
`WalkProductionWorldData`, `WalkStaticStreamPopulator`,
|
||
`WbDrawDispatcher.OrderedStream/WalkClassify`; obsolete shell-lift, bias,
|
||
stencil, corrective-redraw, suppression tests; `PortalVisibilityBuilder`
|
||
research code out of production; stale launch-option rows; architecture
|
||
claims contradicted by code. Guards: one `WalkPView`/graph owner in the
|
||
production call graph; renderer cannot query DAT; consumers cannot construct
|
||
independent visibility sets; the submitter cannot sort across semantic
|
||
boundaries; no production reference to OH diagnostic symbols.
|
||
|
||
**Automated closeout:** full Release build; focused App/Content/Core/Runtime/
|
||
Launcher suites; hermetic lane
|
||
`Lane!=InstalledDat&Lane!=Linux&Lane!=Manual&Lane!=Timing&Lane!=Live&Lane!=PreparedPackage`;
|
||
installed-DAT lane with exclusions listed; two deterministic geometry/
|
||
membership runs with equal hashes; transcript equality over all fixtures;
|
||
capped/uncapped lifecycle/reconnect routes; R6 nine-stop; portal in/out with
|
||
long destination prep; graceful shutdown with zero retained rows.
|
||
|
||
**Performance checkpoint:** dense Arwic capped/uncapped, Tusker dense scene,
|
||
cathedral floating stairs, Facility Hub; CPU/GPU p50/p99, FPS, draw counts,
|
||
allocation/frame, memory, retained graph/membership bytes, alpha high water. A
|
||
regression over 20% against the recorded pre-OH baseline triggers an explicit
|
||
optimization slice (merge adjacent runs, reuse storage; never reorder, cull,
|
||
or weaken the transcript).
|
||
|
||
**Owner gate G4 — final matrix.** Repeats G1–G3 on one clean binary and adds:
|
||
two-client cathedral wall occlusion; Facility Hub stair circuit; Nanto
|
||
waterfalls and town; Tusker combat/casting/rotation; Holtburg town/building/
|
||
lifestone; two ordinary dungeons chosen without code changes; portal to/from
|
||
each world type; zoom/pan/rotate at seams; ten minutes of free movement. Per
|
||
row PASS/FAIL with location and symptom. The final binary is not rebuilt after
|
||
acceptance except for documentation-only changes.
|
||
|
||
**Documentation closeout:** architecture doc (actual graph and pipeline),
|
||
inventory (asset extraction only, never visibility ownership), divergence
|
||
register reconciliation, launch options after probe deletion, FW ledger
|
||
superseded not deleted, roadmap/milestones, campaign memory. Then merge to
|
||
`main`. Status changes to `CLOSED — USER ACCEPTED` only after G4 and docs match
|
||
code.
|
||
|
||
---
|
||
|
||
## 10. Canonical scene and symptom matrix
|
||
|
||
| Scene | Fixed coordinates/state | Required invariant | Slices |
|
||
|---|---|---|---|
|
||
| Cathedral south transition | `0xF4180106 [37.181568 46.790077 169.804993]` ↔ `0xF4180104 [37.310383 48.895710 169.804993]` | Player and walls whole; no wand/body depth inversion | S3–S4 |
|
||
| Cathedral wall actor | Observer `0x104`, `0x101`, outdoors; remote in `0xF4180112 [36.299465 18.594580 169.804993]` | Actor visible only through a retail-valid sightline | S2–S4 |
|
||
| 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; the exterior-wall slab through the stair chamber MATCHES retail's (retail axiom 2026-09-03, `logs/oh-capture/cathedral-leak.retail.png`) — same slab, same extent, not absent | S1–S4 |
|
||
| Cathedral exterior ramp | Stand on the formerly invisible ramp | Authored shell/member always renders | S1–S3 |
|
||
| 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 | S1–S4 |
|
||
| Nanto waterfalls | `0xE43D001E [93.826614 126.522484 120.005005]` | Falls do not vanish while rotating; houses occlude | S4–S5 |
|
||
| Tusker Island | Owner's dense combat route | Terrain/scenery/actors stable; spell objects retire | S2, S3, S5 |
|
||
| Holtburg | Town route | Buildings intact; particles/lifestone obey depth | S3–S5 |
|
||
| Ordinary dungeons | Two, chosen before code changes | No cathedral overfit; stairs/walls/portals stable | all |
|
||
|
||
Append-only; a new symptom gets a row and an existing invariant before any fix.
|
||
|
||
---
|
||
|
||
### Self-gate poses (owner-supplied 2026-09-02)
|
||
|
||
The lead may run owner gates itself: launch the Release client at a recorded
|
||
commit through a session config (direct character login, no select screen),
|
||
teleport with the server command below (`/teleloc <cell> <x> <y> <z> <qw> <qx>
|
||
<qy> <qz>`), screenshot each pose into the automation artifact directory, read
|
||
the PNGs, and record PASS/FAIL per pose in §13. The owner double-checks in the
|
||
morning; a self-passed gate stays provisional until then.
|
||
|
||
| Pose | Command |
|
||
|---|---|
|
||
| Cathedral floating stairs | `/teleloc F4180112 38.999477 23.470444 178.053741 -0.980785 0.000000 0.000000 -0.195090` |
|
||
| Facility Hub stairs | `/teleloc 8A02015E 60.251431 -38.848198 -5.995000 0.995004 0.000000 0.000000 -0.099833` |
|
||
| Holtburg house interior | `/teleloc A9B4013F 134.555893 11.423566 94.005005 0.996917 0.000000 0.000000 -0.078459` |
|
||
|
||
Add the §10 matrix coordinates and the four retail capture poses
|
||
(`docs/research/2026-08-30-fw-walk-oracle/posed/`, `P` lines: cell, origin
|
||
xyz, quaternion) as further stops when a gate needs them.
|
||
|
||
---
|
||
|
||
## 11. Test and command policy
|
||
|
||
```powershell
|
||
dotnet build AcDream.slnx -c Release
|
||
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
|
||
```
|
||
|
||
Focused `--filter` runs are for iteration; a slice closes on the full families
|
||
above plus the hermetic lane. Record exact commands and counts in §13.
|
||
|
||
**Launch discipline:** every launched candidate is a green Release build from a
|
||
recorded commit; all behavior-changing probes unset; the owner is told the
|
||
exact commit, recipe, and log path; the owner closes the client.
|
||
|
||
---
|
||
|
||
## 12. Instrumentation lifecycle
|
||
|
||
- One print-only transcript flag for the frame walk, introduced in S3 chunk 1,
|
||
documented in `docs/launch-options.md` in the same commit, output-only,
|
||
never read by any draw decision.
|
||
- Slice-local comparators (S2 old-vs-new membership) live and die inside the
|
||
slice.
|
||
- Existing `ACDREAM_PROBE_CATHEDRAL_*` / `ACDREAM_PROBE_FACILITY_STAIRS` flags
|
||
stay unset and untouched until S5 deletes them.
|
||
- No agent adds a probe outside its chunk contract.
|
||
|
||
---
|
||
|
||
## 13. Execution ledger
|
||
|
||
Update immediately when a slice changes state. Chat is not the ledger.
|
||
|
||
| Slice | Status | Spec | Implementation | Reviews | Automated gate | Owner gate | Notes |
|
||
|---|---|---|---|---|---|---|---|
|
||
| v1 OH0 | CLOSED | `oh0-baseline.md` | `b3b7d922` | read-only classification | Release build green; 319 focused / 1 skip | n/a | historical; candidates it committed are S1/S2 seeds |
|
||
| v1 OH1 | SUPERSEDED | research contracts committed at `5cd4fd2c`/`5d907ae9` (kept, binding) | T0–T3 evidence grammar parked on `quarantine/oh1-evidence-grammar-2026-09-02` | reviews found the grammar a false oracle three times | n/a | n/a | see §15 |
|
||
| S1 Geometry | **CLOSED — G1 PASSED 2026-09-02** | `oh2-cellstruct-surface-contract.md` (§3.5 arbitrated on the binary) | chunk A `acf17246`; chunk B `b681717c`; hygiene `0840d5fb`; review fixes `e2543d0e`; G1 regression fix `8c6563ca` (segment/batch pairing) + its pin test (next commit) | lead verified both chunks against the named pseudo-C and the paired binary; two Opus lens reviews, 8 findings all verified by the lead and fixed; the review round's own upload-order change desynchronized cell-shell index segments from batches (first G1 launch: magenta/stretched/missing walls in every dungeon) and was root-caused and fixed by the lead before the re-gate | build 0/0; Content 213/213 (incl. PreparedPackage on the recipe-8 pak); Core 4,948/4,948 (one load-sensitive allocation test outside S1 passes alone); Bake 21/21; Launcher.Core 365/365; Runtime 1,884/1,884; App hermetic 6,757/6,757 | **G1 PASS**: Facility Hub stairs/doorways, Holtburg house interior, ordinary dungeon, town portal network all whole with correct materials on `8c6563ca` + recipe 8; cathedral shows the ORIGINAL symptom family (neighbor-cell walls drawn through portals over the room), explicitly outside G1 and carried to S3/S4 | dev pak recipe 8 (597,369,112 B; `acdream.recipe7.pak` kept); TOC delta explained; corpus scan old-only 3,197 (all untextured), new-only 0, unexplained 0 |
|
||
| Capture | READY | §7 + `tools/walk-oracle/oh/README.md` | scripts committed `ebaa41df` + `14d8fe64`; lead resolved DBObj::m_DID=+0x28 and the cdecl alpha-function conventions; recon attach re-confirms | — | recon dt/x/uf dumps at session start | owner session ~1 h | before S3 |
|
||
| S2 World graph | CLOSED — G2 PASSED (owner, 2026-09-03): Facility Hub PASS, Holtburg house PASS, cathedral leak unchanged/not worse (S3/S4 target), portal haze FIXED by chunk 6 and owner-confirmed; the terrain doorway-punch finding is carried to S4; the chunk-6 retail-lens review (Opus) returned no blocking finding; its one MAJOR (a cell reached through two portals got two particle turns per frame) and the minor items are fixed in the follow-up commit: frame-scoped particle-turn dedupe beside the shell dedupe, zero-emitter cells cost one count check, the scope-cost counter maintained on the cell path, the dead `OutdoorSceneParticleEntityIds` stub chain deleted through the composition root, AD-117 item 4 names the owner-cell substitution and the absent per-emission `AddPartToShadowCells`, and a sink-level pin that an emitter's cell membership is the owner's pose cell and survives the projection-visibility switch (the review's F7 one-frame eligibility lag is the per-frame view pass, documented in the pin). RETAIL AXIOM (owner, 2026-09-03, at the capture session, 2013 v11.4186 client on local ACE): standing on the cathedral stairs, RETAIL ITSELF shows part of the same artifact — the outside structure leaking into the interior — CONFIRMED in BOTH the 2013 v11.4186 client and the 2015 EoR client (owner switched clients to check), so the cathedral leak is retail behavior S3/S4 must REPRODUCE, not remove; the retail transcript at that pose is captured as `logs/oh-capture/cathedral-leak.{walk,parts,alphadepth}.log` (walk 5 frames with LC/SC landscape order, parts 3 frames, alpha-depth 5 frames, recon-verified offsets); owner's retail screenshot at the pose: an exterior wall slab cutting diagonally through the stair chamber over the interior ramps (`logs/oh-capture/cathedral-leak.retail.png`, owner-saved) | `s2-membership-ownership-map.md` (`e7ad25a7`) + Contracts A/B; closeout evidence §8/§9 | chunk 1a `059b8883`; chunk 1b `5a2792d6`; chunk 2 `707d2803` (render statics borrow the registry's retail array; render flood deleted); chunk 3 `afbd2410` (one flood per registration feeds collision rows and render entries; staged SetPosition carries both products); chunk 4 `75ea269d` (movement publishes from the transition's cells; children inherit at registration); chunk 5 + closeout `c94a1a40` (borrowed per-cell views, render-only registration, sweeps/fallbacks deleted; reflood forwards the part array; NON-COLLIDING DAT STATICS register render-only from both publishers; the dual-review fix batch: Suspend clears the retail product, attach/detach advance the mutation revision, an attached child never floods on its own, RemoveLandblock/RetireOwnerFromLandblock prune retail rows, render-only owners move with their destination cell (retail's zero-sphere `find_cell_list` 0x0052b4e0, verified statically 2026-09-03 — AD-117 item 1 dropped), empty part array == null, per-move closures removed, EnvCell shells out of the entity-id index, index predicate compares the id, dead per-cell scene indices deleted) | lead corrected 1a's route decision before landing; chunk 2 verified by the lead; chunk 5's agent report missed the non-colliding-static population (found by the self-gate PIXEL DIFF, not by eye: Facility wall panels grey); S2 dual review (arch + retail lens, Opus) produced 12 + 7 findings, every one lead-verified against the source before an edit; the four BLOCKING/MAJOR lifetime gaps were real | at `c94a1a40`: Core 4,984/4,984; Content 214/214; Runtime 1,884/1,884; App hermetic lane 6,760/6,760; App InstalledDat 217 pass / 1 skip / 2 pre-existing #383; App Windows 1/1 | G2 PROVISIONAL PASS. Self-gate runs (kit `ea546f38`, pwsh): `logs/selfgate-20260902-231426-baseline-g1-binary` (reference), `…231642-s2-chunk3`, `…233845-s2-chunk4` (identical), `logs/selfgate-20260903-002632-s2-chunk5-reflood` (FAIL: Facility wall panels grey, left-wall mean RGB 29,26,23 vs baseline 65,17,21 — missing non-colliding statics), `logs/selfgate-20260903-010022-s2-review-fixes-3` (candidate: panels back at 79,20,25 = chunk-3/4; cathedral 13.6% / Facility 15.0% / house 13.4% px differ vs baseline, the chunk-3/4 band; graceful logout, zero exceptions). Membership-probe run `logs/selfgate-20260903-003013-s2-chunk5-membership-probe`: `[walk-membership]` fired only on two transient Holtburg login frames, never in Facility Hub or the cathedral. Connected R6 soak on the chunk-4 build `6717a3e5` (`logs/connected-r6-soak-20260902-234016.report.json`): 9 destinations in 511 s, zero invariant failures, graceful exit — route PASS (its `-CollisionShadowEvery` referee is the obsolete I5 graph-vs-flat comparator; retire in S5). Connected R6 soak on the FINAL S2 build (`logs/connected-r6-soak-20260903-010403.report.json`, binary matches source, exit 0, graceful=True): 9 canonical checkpoints, 0 failures, 10 warnings (server-side population drift + DAT VFX table messages), 522 s — route PASS. OWNER G2 CHECK 2026-09-03 (client at `4b0b29e4`): Facility Hub PASS, Holtburg house PASS; cathedral: the original leak unchanged, NOT worse (S3/S4 target, G2 bar met); TWO NEW OWNER FINDINGS block G2 closure — (a) parts of buildings leak through terrain outdoors in Holtburg — owner screenshot shows doorway-sized fragments of the houses on the terrace BELOW showing through the hill; mechanism identified: `PortalDepthMaskRenderer` draws every visited cell's `OtherCellId == 0xFFFF` portal fan (`RetailPViewPassExecutor` `DrawDepthFan`) with depth compare `Always` + depth write, so a building doorway BEHIND terrain still punches far depth through the hill and the interior draws through the hole; retail's far punch cannot be `Always` against terrain — the exact z-func is S4's first question (the #117 punch stencil is already on S4's delete list; the retail-world contract §5.4 wording must be re-read at the capture). Pre-existing (not an S2 regression), assigned to S4; (b) the purple portal-exit haze on the character no longer appears on arrival — ROOT CAUSE FOUND (instrumented runs `logs/selfgate-20260903-053731-haze-candidate`, `…-054153-haze-candidate-2`, chunk-4 control `…/bisect-chunk4/logs/selfgate-20260903-054328-haze-chunk4`): the server keeps the player Hidden until acdream sends LoginComplete at reveal `complete` (retail-correct); the Hidden-state script's emitters spawn in the arrival cell at `materialized`, are view-eligible at `world-visible`, and are never DRAWN (frame `h02-arrive-400ms`: room, no character, no cloud) because the walk draws an owner's emitters only through the owner's registry rows and a hidden owner's shadow is suspended; the deleted chunk-5 fallback used to carry them. Retail gives every emitter its OWN cell membership (`add_particle_shadow_to_cell` 0x00514a70, one shadow in its own cell, no clip planes, drawn at that cell's turn regardless of the parent's hidden state) — the branch AD-117 item 4 had deferred as 'no production path'. Fix = S2 chunk 6 `f6b4584b` (packet §10): `ParticleSystem` per-pass cell→handles index + `DrawForCell`; the walk draws particles BY CELL at the existing turns; every owner-union particle path deleted; the post-replay per-cell pass deleted (it double-submitted the root flood — the implementer flagged it, the lead verified `EmitCellContentsTurn` fires `CellParticles` for root-flood and look-in cells alike); AD-117 item 4 → port note; temporary probes removed. VERIFIED: `logs/selfgate-20260903-062522-haze-chunk6` frame `h02-arrive-400ms` shows the purple cloud at the character in Facility Hub; three-pose self-gate `logs/selfgate-20260903-062615-s2-chunk6` in the accepted band (cathedral 12.7% / Facility 15.1% / house 13.9% px vs baseline, wall-panel mean 79,20,25), zero exceptions. Gates at `f6b4584b`: Core 4,987/4,987; Content 214/214; Runtime 1,884/1,884; App hermetic 6,760/6,760; App InstalledDat 217 / 2 pre-existing #383. Owner re-check of the haze: CONFIRMED FIXED 2026-09-03 ("Ok yeah it is fixed now"). Morning handoff: `docs/research/2026-09-01-overhaul/2026-09-03-g2-morning-handoff.md` | owner double-checks G2 (handoff checklist); then the owner capture session (the S3 packet §7 names the two traces); then S3 |
|
||
| S3 Walk | CHUNK 2 IN PROGRESS 2026-09-03 (contract `s3-walk-ownership-map.md` §8, decomp-verified during the capture session; captures done: cathedral-leak, cathedral-arrival; owed: holtburg-doorway-still, terrace-edge, foundry-deep). Chunk 3 contract written (§9): the ported ring order, closest-cell table and ring-to-LOD mapping reproduce every captured LC/SC sequence at both cathedral poses with zero mismatches (LOD cell ids are `x*8+y+1` in LOD coordinates). Chunk 2 finding: retail gates the landscape flush, stamp advance, Z clear and exit seals on `outside_view.view_count > 0` (`PView::DrawCells` 0x005a4840) and the Z clear additionally on the persistent seal counter `D3DPolyRender::portalsDrawnCount` (fed by exit seals alone in the building path) — acdream's unconditional clear/seals and the `_skyDrawnThisFrame` proxy are the divergence chunk 2 retires | `s3-walk-ownership-map.md` (retail table, current owners, four chunks, review lenses, gate, the three exact captures to ask for) + built-mesh/world contracts | — | — | — | folded into G3 | chunk 2 implementing on the decomp oracle; the remaining three captures land when the owner is at each pose; chunk 1 (transcript emitter/parser) follows the captures |
|
||
| S4 Depth + alpha | PLANNED — the Holtburg terrain-punch finding carried from G2 may close in S3 chunk 3 by draw ORDER alone (retail draws every nearer land cell's terrain AFTER a farther building's far-Z punch; acdream draws all terrain first — `s3-walk-ownership-map.md` §9 R4); S4 re-reads its "exact z-func" question only if the Holtburg self-gate still shows the fragments after chunk 3 | depth/alpha contracts + captures | — | — | — | G3 | retires AP-34 |
|
||
| S5 Consumers + closeout | PLANNED | landscape contract; AP-232 | — | — | — | G4 | retires AP-117/AP-232; deletes probes |
|
||
|
||
### Rollback ledger
|
||
|
||
| Slice | Commits | Last accepted gate | Revert |
|
||
|---|---|---|---|
|
||
| FW closeout | `b8befded`, `4808d4d1`, `4683ac6f`, `e8808602` | FW/Tusker gates | historical anchors only |
|
||
| v1 OH0 | `b3b7d922` | n/a | `git revert b3b7d922` removes the investigation candidates including the Facility stair fix; not a visual claim |
|
||
| S1 | `acf17246`, `b681717c`, `0840d5fb`, `e2543d0e`, `8c6563ca` (+ pin test) | G1 PASS 2026-09-02 | revert newest-first; then restore `acdream.recipe7.pak` over `acdream.pak` in the dev DAT dir (the recipe-8 consumer rejects a recipe-7 pak, and vice versa) |
|
||
| S2 | `059b8883`, `5a2792d6`, `707d2803`, `afbd2410`, `75ea269d`, `c94a1a40`, `f6b4584b` | G2 PASSED 2026-09-03 (owner-confirmed after the chunk-6 haze fix; terrain punch carried to S4) | revert newest-first `c94a1a40` → `059b8883`; the registry's retail product and the walk's borrowed views go together — do not revert a middle chunk alone |
|
||
| S3 | — | G3 | fill |
|
||
| S4 | — | G3 | fill |
|
||
| S5 | — | G4 | fill |
|
||
|
||
---
|
||
|
||
## 14. Risk register (condensed)
|
||
|
||
- **R1 second scene graph.** Graph records own only topology/membership facts;
|
||
mesh/entity state is borrowed. Consumer deletion is inside S2.
|
||
- **R2 over-porting C++ mechanics.** Port observable ordering, ownership,
|
||
stamps, and transitions into retained arrays; equality by transcript.
|
||
- **R3 Vulkan reorders.** Immutable stream; only adjacent compatible runs
|
||
merge; tests place merge-compatible draws around alpha/depth boundaries.
|
||
- **R4 package churn.** S1 owns one recipe bump with strict rejection,
|
||
migration, rollback, corruption tests, launcher coverage.
|
||
- **R5 oracle incompleteness.** The §7 capture is the answer key; a missing
|
||
fact gets one exact additional capture, never an approximation.
|
||
- **R6 scene overfitting.** Production guards reject scene IDs; installed-DAT
|
||
sampling and ordinary-dungeon gates are mandatory.
|
||
- **R7 per-cell command cost.** Correctness-first; the 20% rule triggers an
|
||
explicit optimization slice.
|
||
- **R8 stale docs.** S5 cannot close until architecture text is checked
|
||
against production call sites.
|
||
- **R9 evidence sink (new).** Rule 2 and rule 15. A slice with no production
|
||
change after its first chunk is a red flag, not progress.
|
||
|
||
---
|
||
|
||
## 15. v2 rescope record (2026-09-02)
|
||
|
||
**What happened.** v1's OH1 ("upgrade the oracle first") ran unsupervised for
|
||
eighteen hours and produced ~32K lines of uncommitted canonical-JSONL
|
||
evidence grammar plus 142 tests, three review rounds each finding the grammar
|
||
encoded wrong retail semantics, and zero production change. The grammar
|
||
re-encoded PView inside a validator, making it a second port that needed the
|
||
same retail review; it also validated "strong" evidence that neither the
|
||
retail captures nor the acdream recorder produced. The one unlocking item,
|
||
extending the cdb capture templates, was never started.
|
||
|
||
**What v2 keeps.** All committed research contracts; the FW0 capture corpus
|
||
and its proven line-format + parser + replay pattern (which reached 9/10
|
||
conformant fixtures in FW1); the `b3b7d922` candidates as S1/S2 seeds; the
|
||
retail facts the T3 reviews established (handoff §5.3).
|
||
|
||
**What v2 parks.** The evidence grammar, recorder hooks, importer, manifest
|
||
command, and their docs, verbatim, on
|
||
`quarantine/oh1-evidence-grammar-2026-09-02`.
|
||
|
||
**Stage mapping.** OH2 → S1; OH3a–d → S2; OH4 + OH5 → S3; OH6 + OH7 → S4;
|
||
OH8–OH11 → S5. Owner gates: G1 after S1, G2 after S2, G3 after S4, G4 final.
|
||
|
||
**Process changes.** Rules 2 and 15; the §5 working model; the §7 single
|
||
capture session; evidence products limited to what each slice consumes.
|
||
|
||
**Memory:** `claude-memory/feedback_evidence_infrastructure_sink.md`;
|
||
`claude-memory/project_overhaul_campaign.md` is the START HERE.
|