docs(render): rescope Campaign OVERHAUL to five production slices
v2 replaces the twelve-stage plan. OH1's evidence-grammar stage is parked on quarantine/oh1-evidence-grammar-2026-09-02; the committed research contracts stay binding. Stage mapping: OH2 -> S1, OH3 -> S2, OH4+OH5 -> S3, OH6+OH7 -> S4, OH8-OH11 -> S5. Adds the working model (lead in the loop, bounded chunks, time-box), the single retail capture session before S3, and per-slice minimal evidence products. Carries the InitCell inflag prose correction in the flood appendix and marks the T3 handoff superseded. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
5d907ae9ad
commit
13fc7d8349
3 changed files with 1077 additions and 1444 deletions
|
|
@ -6,7 +6,18 @@ Second read round: the interior-flood and view-support functions. Same method as
|
|||
|
||||
### PView::InitCell @0x005a4b70
|
||||
|
||||
**Summary:** Initializes the cell's TOP portal_view slot (portal_view.data[num_view-1]) for the flood: stamps view_timestamp = master_timestamp, clears cell_view_done, grows the per-portal portal_info array to num_portals, classifies every portal as in-view (inflag) or rejected via a cell-local viewpoint-vs-portal-plane side test, computes max_indist = max SQUARED viewpoint distance to any in-view portal vertex, and marks every rejected portal seen=1 so the flood never traverses it. The entry portal (real index; 0xffff sentinel never matches) is forced inflag=1 + seen=1 instead of side-tested.
|
||||
**Corrected summary (2026-09-02, x87 branch re-arbitrated):** Initializes the
|
||||
cell's TOP portal_view slot (`portal_view.data[num_view-1]`) for the flood:
|
||||
stamps `view_timestamp = master_timestamp`, clears `cell_view_done`, grows the
|
||||
per-portal `portal_info` array to `num_portals`, and classifies every portal by
|
||||
the cell-local viewpoint/plane side test. The names are deceptive:
|
||||
`ClipPortals` considers exactly `seen != 0 && inflag != 1`, so `inflag == 0`
|
||||
is the traversable candidate state and `inflag == 1` is excluded. The entered-
|
||||
through portal is forced to `inflag=1, seen=1` and is therefore excluded as the
|
||||
backlink. `max_indist` is the maximum SQUARED viewpoint distance over the
|
||||
`inflag == 1` portal vertices—the excluded/incoming/back-facing set—not the
|
||||
traversable set. The earlier prose labels in this report inverted this meaning;
|
||||
the assignments themselves were correct.
|
||||
|
||||
```c
|
||||
int PView::InitCell(CEnvCell* cell, uint16 entry_portal_idx) // Ghidra: returns int; BN said void
|
||||
|
|
@ -21,12 +32,12 @@ int PView::InitCell(CEnvCell* cell, uint16 entry_portal_idx) // Ghidra: returns
|
|||
DArray<portal_info>::grow(&slot->portal, cell->num_portals); // exact-size; NEW entries UNINITIALIZED
|
||||
|
||||
float max_d2 = 0.0f;
|
||||
int any_rejected = /*UNINITIALIZED stack dword — see gotchas*/;
|
||||
int any_candidate = /*UNINITIALIZED stack dword — see gotchas*/;
|
||||
|
||||
for (i = 0; i < cell->num_portals; i++) { // CCellPortal stride 0x18
|
||||
CPolygon* poly = cell->portals[i].portal;
|
||||
if (i == entry_portal_idx && slot->portal.data[i].inflag == 0) {
|
||||
// entered-through portal: forced visible + consumed (0xffff seed sentinel never hits this)
|
||||
// entered-through backlink: forced excluded + consumed (0xffff seed sentinel never hits this)
|
||||
slot->portal.data[i].inflag = 1;
|
||||
slot->portal.data[i].seen = 1;
|
||||
} else {
|
||||
|
|
@ -36,10 +47,10 @@ int PView::InitCell(CEnvCell* cell, uint16 entry_portal_idx) // Ghidra: returns
|
|||
int side; // 0=POSITIVE, 1=NEGATIVE
|
||||
if (d > F_EPSILON) side = 0; // F_EPSILON = 0.000199999995f
|
||||
else if (d < -F_EPSILON) side = 1;
|
||||
else { slot->portal.data[i].inflag = 0; any_rejected = 1; goto vertex_scan; } // IN_PLANE: always reject
|
||||
else { slot->portal.data[i].inflag = 0; any_candidate = 1; goto vertex_scan; } // IN_PLANE: traversable candidate
|
||||
if (side != cell->portals[i].portal_side)
|
||||
slot->portal.data[i].inflag = 1; // viewer on the see-through side
|
||||
else { slot->portal.data[i].inflag = 0; any_rejected = 1; } // viewer on the portal's own side
|
||||
slot->portal.data[i].inflag = 1; // excluded by ClipPortals
|
||||
else { slot->portal.data[i].inflag = 0; any_candidate = 1; } // traversable candidate
|
||||
}
|
||||
vertex_scan:
|
||||
if (slot->portal.data[i].inflag == 1 && poly->num_pts > 0) // num_pts = byte @ +0xe
|
||||
|
|
@ -48,14 +59,14 @@ vertex_scan:
|
|||
if (max_d2 < d2) max_d2 = d2;
|
||||
}
|
||||
}
|
||||
slot->max_indist = max_d2; // max squared distance to any in-view portal vertex
|
||||
slot->max_indist = max_d2; // max squared distance over inflag==1 (excluded) portal vertices
|
||||
|
||||
if (any_rejected != 0 && slot->view_count > 0)
|
||||
if (any_candidate != 0 && slot->view_count > 0)
|
||||
for (v = 0; v < slot->view_count; v++) {
|
||||
Render::set_view(&slot->view, v); // installs global active view; the check below does NOT read it
|
||||
for (j = 0; j < cell->num_portals; j++)
|
||||
if (portal[j].inflag == 0 && portal[j].seen == 0)
|
||||
portal[j].seen = 1; // rejected portals become 'consumed': flood never walks them
|
||||
portal[j].seen = 1; // makes inflag==0 portals eligible for ClipPortals
|
||||
}
|
||||
|
||||
slot->update_count = slot->view_count;
|
||||
|
|
@ -64,7 +75,29 @@ vertex_scan:
|
|||
}
|
||||
```
|
||||
|
||||
**Gotchas:** BN body @0x005a4b70 is UNUSABLE: it scrambled the x87 side-test control flow AND elided the squared-distance math (showed only the z subtraction). This model is Ghidra-verified (127.0.0.1:8081). Confirmed semantics: side==portal_side rejects, IN_PLANE (|d|<=0.000199999995f) always rejects — matches the FW doc's sidedness table. Real retail quirks: (1) any_rejected (local_4) is NEVER initialized — if no portal is rejected it reads stack garbage; the effect is benign (the fixup inner body no-ops when nothing was rejected; only side effect is redundant set_view churn), so a port should init it to 0 with identical observable behavior. (2) The entry-portal branch is guarded by the STALE inflag (inflag==0) — on a freshly grown portal array inflag is heap garbage (DArray::grow does NOT zero new entries); the caller (AddViewToPortals) presumably establishes it — verify that contract when porting FW3. (3) set_view inside the fixup loop installs each view globally but nothing in the loop consults it, and the LAST view stays installed on exit — both decompilers agree; purpose unclear (possibly vestigial). (4) positionPush(3, cell->pos) means the plane test and max_indist run in CELL-LOCAL coordinates. (5) 0xffff sentinel: ushort zero-extended vs uint loop index — never matches, so the seed cell side-tests every portal. (6) max_indist is a SQUARED distance — todo-list keys fed from it are squared; comparisons stay consistent. Ghidra return type is int (0 = early-out on view_count==0, 1 = did work); BN said void __stdcall.
|
||||
**Gotchas:** BN body @0x005a4b70 is UNUSABLE: it scrambled the x87
|
||||
side-test control flow AND elided the squared-distance math (showed only the z
|
||||
subtraction). The x87 branch was re-arbitrated against retail bytes
|
||||
`005A4C48..005A4C9D` on 2026-09-02. Confirmed semantics:
|
||||
`side==portal_side` and IN_PLANE (`|d|<=0.000199999995f`) produce
|
||||
`inflag=0`, which is the traversable candidate state because `ClipPortals`
|
||||
later requires `seen!=0 && inflag!=1`; side mismatch produces the excluded
|
||||
`inflag=1` state. Real retail quirks: (1) `any_candidate` (`local_4`) is NEVER
|
||||
initialized—if no candidate exists it reads stack garbage; the effect is
|
||||
benign because the fixup inner body no-ops, leaving only redundant `set_view`
|
||||
churn, so a port may initialize it to zero with identical observable behavior.
|
||||
(2) The entry-portal branch is guarded by stale `inflag`; it forces the
|
||||
entered-through backlink to the excluded/seen state. On a freshly grown portal
|
||||
array `inflag` is heap garbage (`DArray::grow` does not zero new entries), so
|
||||
the caller contract remains significant. (3) `set_view` inside the fixup loop
|
||||
installs each view globally but nothing in the loop consults it, and the LAST
|
||||
view stays installed on exit. (4) `positionPush(3, cell->pos)` means the plane
|
||||
test and `max_indist` run in CELL-LOCAL coordinates. (5) The `0xffff` seed
|
||||
sentinel never matches, so the seed cell side-tests every portal. (6)
|
||||
`max_indist` is a SQUARED distance over `inflag==1` portal vertices; todo-list
|
||||
comparisons stay internally consistent even though that set is excluded from
|
||||
traversal. Ghidra return type is int (0 = early-out on `view_count==0`, 1 =
|
||||
did work); BN said void `__stdcall`.
|
||||
|
||||
### PView::InsCellTodoList @0x005a4f50
|
||||
|
||||
|
|
@ -147,7 +180,25 @@ void CEnvCell::curr_view_push()
|
|||
|
||||
**Gotchas:** VERIFIES the earlier read: num_view++ with 0x48-byte lazy slot alloc + counter resets — with precision: exactly view_count/update_count/view_timestamp are reset on EVERY push (fresh or recycled); cell_view_done and max_indist are NOT reset here and stay stale (heap garbage on a brand-new slot) until PView::InitCell writes them — InitCell always runs before they are consumed, but a port must preserve that ordering or zero them harmlessly. The single-slot null after grow is sound only because this DArray grow(n) sets sizeOf to EXACTLY n (verified @0x005a45d0: copies old, sizeOf=arg; blocksize unused by grow; grow with arg<=sizeOf delegates to shrink) — no hidden capacity slack, so no garbage slots. portal_view_type layout confirmed in acclient.h: {DArray<portal_info> portal @0; view_type view @0x10 (vertex_count_total, poly@0x14, vertex@0x24); max_indist @0x34; view_count @0x38; cell_view_done @0x3c; view_timestamp @0x40; update_count @0x44}; DArray = {data, blocksize, next_available, sizeOf}.
|
||||
|
||||
**Report notes:** All four bodies cross-checked against live Ghidra MCP (http://127.0.0.1:8081, patchmem.gpr) — mandatory here, because BN got two of them materially wrong: (1) InsCellTodoList's insertion comparison was polarity-INVERTED in BN (would have modeled a farthest-first pop); Ghidra's strict `dist < prev->dist` break gives a descending-from-index-0 list whose END-pop is NEAREST-first, which is what makes the draw list come out near->far and DrawCells' end-first walk far-to-near — consistent with FW doc section 5. (2) InitCell's BN body scrambled the plane-side branches and elided the dx^2+dy^2+dz^2 accumulation entirely (showed a bare z subtraction). Ghidra-confirmed model: side 0/1 vs portal_side rejects on equality, IN_PLANE always rejects (matches the doc's section 7 sidedness table), max_indist = max SQUARED cell-local distance to in-view portal vertices, and rejected portals get seen=1 in a fixup pass whose per-view set_view calls are side-effect-only. Two genuine retail quirks worth register-awareness if ported observably: InitCell's any_rejected flag is an uninitialized stack read (benign in effect), and the entry-portal force-visible branch keys off STALE inflag whose state is a caller contract (read PView::AddViewToPortals before relying on it in FW3). Struct authorities verified in acclient.h: portal_info {seen, inflag}; portal_view_type (0x48 bytes, field offsets in the curr_view_push gotchas); PView {outside_view, draw_landscape, outdoor_portal_list, cell_draw_list, cell_draw_num, cell_todo_list, cell_todo_num, lscape}; CellListType nodes are 8-byte {CEnvCell* cell, float dist}; CPolygon {vertices@0, num_pts byte@0xe, plane@0x20}. Sources: docs/research/named-retail/acclient_2013_pseudo_c.txt lines 311378-311393, 432896-433045, 433183-433243, 433279-433320; DArray grow/shrink @0x005a45d0 region; struct defs in docs/research/named-retail/acclient.h (portal_info @32458, portal_view_type @32346, view_type @32338, PView @45934, CPolygon @31855).
|
||||
**Report notes (corrected 2026-09-02):** All four bodies were
|
||||
cross-checked against the live Ghidra project; the load-bearing branches were
|
||||
then re-arbitrated against the retail bytes because the earlier prose assigned
|
||||
the intuitive but wrong meaning to `inflag`. (1) `InsCellTodoList` uses strict
|
||||
`dist < prev->dist` as its break, giving a list descending from index zero and
|
||||
nearest-first END pops, with FIFO ties. (2) `InitCell` writes `inflag=0` for
|
||||
`side==portal_side` and IN_PLANE, then its fixup writes `seen=1`; those rows
|
||||
are precisely the candidates later admitted by `ClipPortals`'s
|
||||
`seen!=0 && inflag!=1` gate. Side mismatch and the entered-through backlink
|
||||
use `inflag=1` and are excluded. `max_indist` is the maximum squared
|
||||
cell-local distance over the `inflag==1` portal vertices, not over the
|
||||
traversable candidates. Two genuine retail quirks remain relevant:
|
||||
`local_4` is an uninitialized stack read, and the entry-portal branch keys off
|
||||
stale `inflag` state established by the caller/allocation history. Struct
|
||||
authorities remain `portal_info {seen,inflag}`, `portal_view_type` (0x48
|
||||
bytes), `PView`, `CellListType {cell,float dist}`, and `CPolygon`. Sources:
|
||||
named-retail lines 311378-311393, 432896-433045, 433183-433243, and
|
||||
433279-433320; retail bytes `005A4C48..005A4C9D`; DArray grow/shrink near
|
||||
`0x005A45D0`; and the named retail header definitions.
|
||||
|
||||
## Report 2 - Flood propagation (ClipPortals / AddViewToPortals)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,464 @@
|
|||
> **SUPERSEDED 2026-09-02 (same day) by the v2 rescope.** This handoff describes the v1 OH1/T3 freeze. Its section 8 dirty-tree map is WRONG: the dirty App rendering files were T2 recorder hooks, not pre-overhaul behavior candidates (those were already committed in `b3b7d922`). The T3 grammar it describes is parked on `quarantine/oh1-evidence-grammar-2026-09-02`. Section 5.3 (retail truths bound by T3) remains a binding input to S3/S4. Current plan: `docs/plans/2026-09-01-campaign-overhaul-world-solidity.md` §15.
|
||||
|
||||
# Campaign OVERHAUL handoff — OH1/T3 freeze
|
||||
|
||||
**Frozen:** 2026-09-02 (Europe/Stockholm)
|
||||
|
||||
**Campaign state:** active; not complete
|
||||
|
||||
**Current slice:** OH1, transcript task T3
|
||||
|
||||
**T3 state:** third implementation/fix round is locally green, but independent
|
||||
closure review is still required
|
||||
|
||||
**Production rendering claim:** none. OH1 is evidence/contract work and must not
|
||||
change draw decisions.
|
||||
|
||||
This is the durable handoff for a new model. It records the exact checkout,
|
||||
history, dirty-state constraints, campaign ledger, current automated evidence,
|
||||
review findings, and the next safe actions. Do not reconstruct state from chat
|
||||
summaries when this file and the campaign ledger disagree with them.
|
||||
|
||||
## 1. Exact checkout and recovery boundary
|
||||
|
||||
Work only in this existing worktree:
|
||||
|
||||
```text
|
||||
C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-blackburn-5333f0
|
||||
```
|
||||
|
||||
Repository state at the freeze:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Branch | `claude/campaign-w-retail-frame-walk` |
|
||||
| HEAD | `5d907ae9ad9462347eb697c39ae3ffac136a40bc` |
|
||||
| Upstream | `origin/claude/campaign-w-retail-frame-walk` |
|
||||
| Upstream relation | ahead 32, behind 0 at the freeze |
|
||||
| Staged paths | 0 |
|
||||
| Latest commit | `5d907ae9 docs(render): define OH1 retail world contract` |
|
||||
| Recovery checkpoint | `b3b7d922 checkpoint(render): preserve pre-overhaul investigation state` |
|
||||
|
||||
Recent history:
|
||||
|
||||
```text
|
||||
5d907ae9 docs(render): define OH1 retail world contract
|
||||
5cd4fd2c docs(render): define OH2 CellStruct contract
|
||||
eaea8776 docs(render): clean OH0 baseline formatting
|
||||
fba07e77 docs(render): establish Campaign OVERHAUL baseline
|
||||
b3b7d922 checkpoint(render): preserve pre-overhaul investigation state
|
||||
e8808602 fix(render): restore landscape objects and walk alpha order
|
||||
4683ac6f docs(render): record Campaign FW closeout gates
|
||||
4808d4d1 refactor(render): remove Campaign FW probes
|
||||
```
|
||||
|
||||
The current T3 work is deliberately **uncommitted**. Do not reset, clean,
|
||||
checkout, or wholesale copy another tree over this checkout. The dirty tree
|
||||
contains both intentionally preserved pre-overhaul investigation candidates and
|
||||
new OH1 evidence tooling. Follow the recovery procedure in `oh0-baseline.md`.
|
||||
In particular:
|
||||
|
||||
1. Never use `git reset --hard`, `git checkout --`, or `git clean` here.
|
||||
2. Do not treat every dirty App rendering file as OH1 work.
|
||||
3. To inspect an older state, use a separate detached/read-only worktree.
|
||||
4. To recover through history, revert OH commits in reverse order and stop at
|
||||
`b3b7d922`; do not rewrite history.
|
||||
5. Before staging, inspect each path and exclude line-ending/blank-line noise.
|
||||
|
||||
## 2. Goal and campaign scope
|
||||
|
||||
The active goal is:
|
||||
|
||||
> Complete Campaign OVERHAUL — retail world construction and render solidity —
|
||||
> in this worktree by executing every Plan → Implement → Review slice, using
|
||||
> deterministic retail evidence, independent review, automated gates, and only
|
||||
> the necessary owner visual gates, until the campaign is user-accepted and
|
||||
> closed.
|
||||
|
||||
The campaign exists because locally plausible fixes repeatedly traded one world
|
||||
artifact for another. The accumulated owner-observed symptom family includes:
|
||||
|
||||
- Cathedral opaque walls or wall-textured triangles covering floating stairs;
|
||||
- floating stair slabs appearing/disappearing with camera angle or cell seam;
|
||||
- the cathedral exterior ramp being entirely absent despite supporting the
|
||||
player physically;
|
||||
- wall, terrain, or building textures bleeding through other opaque surfaces;
|
||||
- the local character being chopped at cathedral and Facility Hub cell seams,
|
||||
including a missing head/body sections and equipment drawing through it;
|
||||
- remote players/NPCs and particle systems appearing through opaque walls;
|
||||
- waterfalls disappearing by camera angle, or shining through buildings;
|
||||
- outdoor terrain/scenery/object groups disappearing after small camera turns;
|
||||
- landscape draw range regressions; and
|
||||
- spell effect world objects lingering after their authored lifetime.
|
||||
|
||||
Some preserved dirty-tree candidates improved individual symptoms, but they are
|
||||
explicitly **unaccepted** and are not a retail-parity baseline. The overhaul is
|
||||
meant to replace approximation-by-symptom with one executable retail contract
|
||||
covering authored geometry, cell membership, PView traversal, leaf admission,
|
||||
draw order, depth, alpha, and downstream consumers.
|
||||
|
||||
## 3. Mandatory read order and active ledgers
|
||||
|
||||
Read these before editing:
|
||||
|
||||
1. `AGENTS.md` in the repository root.
|
||||
2. `docs/architecture/acdream-architecture.md` — architecture authority.
|
||||
3. `docs/architecture/worldbuilder-inventory.md` — mandatory before any
|
||||
rendering or DAT algorithm is reimplemented.
|
||||
4. `docs/plans/2026-09-01-campaign-overhaul-world-solidity.md` — the campaign
|
||||
plan and primary execution ledger.
|
||||
5. `docs/research/2026-09-01-overhaul/oh0-baseline.md` — exact dirty-state
|
||||
classification, hashes, baseline gates, and recovery procedure.
|
||||
6. `docs/research/2026-09-01-overhaul/oh1-retail-world-contract.md`.
|
||||
7. The four supporting OH1 evidence packets:
|
||||
- `oh1-construction-landscape-contract.md`
|
||||
- `oh1-built-mesh-view-contract.md`
|
||||
- `oh1-alpha-list-contract.md`
|
||||
- `oh1-depth-lifecycle.md`
|
||||
8. `docs/research/2026-09-01-overhaul/oh1-world-evidence-tooling.md` — the
|
||||
active OH1 tooling/status ledger.
|
||||
9. `docs/research/2026-09-01-overhaul/oh2-cellstruct-surface-contract.md` —
|
||||
completed OH2 design, not authorization to skip unfinished OH1 work.
|
||||
10. `docs/research/2026-08-30-fw-flood-pseudocode-appendix.md` — corrected
|
||||
PView/flood pseudocode and signedness/branch details.
|
||||
|
||||
Historical cathedral context remains useful after the overhaul plan and OH0
|
||||
classification have been read:
|
||||
|
||||
- `docs/research/2026-08-30-cathedral-handover.md`
|
||||
- `docs/research/2026-08-30-cathedral-synthesis.md`
|
||||
- `docs/research/2026-08-30-fw-walk-oracle/posed/`
|
||||
|
||||
Retail source authority:
|
||||
|
||||
- `docs/research/named-retail/acclient_2013_pseudo_c.txt`
|
||||
- `docs/research/named-retail/acclient.h`
|
||||
- `docs/research/decompiled/` only as the older address-range fallback.
|
||||
|
||||
Grep the named retail decomp by `class::method` before decompiling anything
|
||||
fresh. When Binary Ninja or recovered pseudo-C leaves a branch sense ambiguous,
|
||||
use the existing Ghidra arbitration workflow; do not choose the branch that
|
||||
merely makes current tests green. Content identity must be traced to the DAT,
|
||||
not inferred from aggregate owner IDs.
|
||||
|
||||
The campaign plan contains three important ledgers:
|
||||
|
||||
- stage/owner-gate table around lines 434–445;
|
||||
- checkpoint ledger around lines 1461–1473; and
|
||||
- execution ledger around lines 1561–1575.
|
||||
|
||||
The execution ledger is authoritative over the plan header's older
|
||||
`READY TO EXECUTE` wording.
|
||||
|
||||
## 4. Campaign progress at the freeze
|
||||
|
||||
| Scope | State | Durable result | What remains |
|
||||
|---|---|---|---|
|
||||
| OH0 | **CLOSED** | Dirty tree classified; recovery checkpoint `b3b7d922`; baseline and source/package hashes recorded | Nothing unless the checkout must be recovered |
|
||||
| OH1 research contract | **CLOSED/COMMITTED** | Main and four supporting retail contracts at `5d907ae9` | Keep synchronized with executable evidence |
|
||||
| OH1 T0–T2 | **CLOSED** | Canonical schema/codec/hash/coverage foundations, strong frame/call grammar, narrow FW0 importer, and output-only App recorder foundations | Preserve their strict capability boundary |
|
||||
| OH1 T3 | **IMPLEMENTED, GREEN, REVIEW OPEN** | Source-closed PView, installed-view, DrawCells, shell/object-leaf, and persistent-stamp grammar; third fix round frozen uncommitted | Finish the missing adversarial surface and independent retail/architecture closure review |
|
||||
| OH1 T4–T8 | **PENDING** | No closure claim | Complete landscape/building order, alpha/material, depth lifecycle, recorder/fixture integration, aggregate gates, and OH1 closeout as defined by the plan |
|
||||
| OH2 design | **CLOSED/COMMITTED** | Exact CellStruct surface/subset contract at `5cd4fd2c` | Production implementation, package migration, deterministic installed-DAT manifest, review, and G1 are not started |
|
||||
| OH2 implementation | **PLANNED/BLOCKED ON OH1** | None | Start only after OH1's executable contract is review-closed |
|
||||
| OH3 | **PLANNED** | Canonical cell graph/exact part-shadow membership | Entire slice |
|
||||
| OH4 | **PLANNED** | Exact PView views and leaf admission/clipping | Entire slice |
|
||||
| OH5 | **PLANNED** | Exact landscape/building/cell/object interleave | Entire slice |
|
||||
| OH6 | **PLANNED** | Exact depth epoch, clear latch, punches, seals, stamps | Entire slice plus owner gate G2 |
|
||||
| OH7 | **PLANNED** | Exact alpha ownership/order/flushes | Entire slice |
|
||||
| OH8 | **PLANNED** | Exact landscape `in_view` and particle/light/shadow consumers | Entire slice |
|
||||
| OH9 | **PLANNED** | Building/material/degrade leaf fidelity | Entire slice |
|
||||
| OH10 | **PLANNED** | Delete duplicate owners/fallbacks/experiments/stale claims | Entire slice |
|
||||
| OH11 | **PLANNED** | Full regression, performance, connected routes, docs, final acceptance | Entire slice plus final owner gate G4 |
|
||||
|
||||
OH2 did not disappear: its **design** was produced in parallel and committed.
|
||||
Its implementation is intentionally waiting because implementing geometry before
|
||||
the complete OH1 oracle is review-closed would repeat the campaign's central
|
||||
failure mode: a green test encoding the wrong retail behavior.
|
||||
|
||||
## 5. Current T3 implementation
|
||||
|
||||
### 5.1 Purpose and boundary
|
||||
|
||||
T3 does not render anything. It defines a strict, canonical JSONL evidence
|
||||
language in `AcDream.Core.Diagnostics.WorldEvidence` and validators that reject
|
||||
semantic traces that cannot be a retail PView/DrawCells execution. The schema is
|
||||
currently unshipped version 4. Do not add a compatibility path for an older
|
||||
in-progress v4 shape; finish this version atomically unless persisted external
|
||||
artifacts are discovered.
|
||||
|
||||
The third fix round changed only:
|
||||
|
||||
- `src/AcDream.Core/Diagnostics/WorldEvidence/WorldEvidenceModels.cs`
|
||||
- `src/AcDream.Core/Diagnostics/WorldEvidence/WorldEvidenceJsonl.Vocabulary.cs`
|
||||
- `src/AcDream.Core/Diagnostics/WorldEvidence/WorldEvidenceJsonl.TranscriptShapes.cs`
|
||||
- `src/AcDream.Core/Diagnostics/WorldEvidence/WorldEvidenceJsonl.cs`
|
||||
- `src/AcDream.Core/Diagnostics/WorldEvidence/WorldEvidenceJsonl.PViewGrammar.cs`
|
||||
- `tests/AcDream.Core.Tests/Diagnostics/WorldEvidence/WorldEvidenceJsonlTests.cs`
|
||||
- `tests/AcDream.Core.Tests/Diagnostics/WorldEvidence/WorldEvidenceT3Tests.cs`
|
||||
|
||||
The wider uncommitted OH1 evidence scope also includes:
|
||||
|
||||
- `src/AcDream.Core/Diagnostics/WorldEvidence/`
|
||||
- `src/AcDream.App/Rendering/Walk/Diagnostics/`
|
||||
- `tests/AcDream.Core.Tests/Diagnostics/WorldEvidence/`
|
||||
- `tests/AcDream.App.Tests/Rendering/Walk/LegacyWalkOracleImporter.cs`
|
||||
- `tests/AcDream.App.Tests/Rendering/Walk/LegacyWalkOracleImporterTests.cs`
|
||||
- `tests/AcDream.App.Tests/Rendering/Walk/WorldFrameTranscriptRecorderTests.cs`
|
||||
- `tools/A8CellAudit/GeometryManifestCommand.cs`
|
||||
- `docs/research/2026-09-01-overhaul/oh1-world-evidence-tooling.md`
|
||||
|
||||
### 5.2 What round three closed
|
||||
|
||||
The third round closed these previously falsifiable gaps:
|
||||
|
||||
- route-stage truthfulness;
|
||||
- distinct source/destination/outside/temporary ViewSet ownership;
|
||||
- exact previous/current installed-view identity;
|
||||
- caller-owned restore after `OtherPortalClip`;
|
||||
- `CellView`/`AddView` state replay and exact append/count ledgers;
|
||||
- `SetOtherSeen` ordering after branch, recursion, and watermark;
|
||||
- stronger exact call-body, direct-parent, and grouping validation;
|
||||
- actual failed-tail-pop evidence for `NullTail`;
|
||||
- persistent global device, cell-shell, and typed-part stamp ledgers;
|
||||
- reject-then-accept and all-reject stamp cases;
|
||||
- global `Render::PortalList` bindings for `ClipPortals` and object-cell turns;
|
||||
- exact `Render::copy_view(newmethod=1)` algorithm replay rather than checking
|
||||
only caller-supplied output bytes; and
|
||||
- deletion of stale `PortalVisit`/legacy `PartAdmit` vocabulary.
|
||||
|
||||
This round exists because earlier green versions were independently shown to
|
||||
be false oracles. Review caught inverted portal-flag and sidedness meanings,
|
||||
conflated `do_clip`/side state, restore ownership assigned to the wrong
|
||||
function, conflated view containers, incomplete call/cardinality ledgers,
|
||||
self-fulfilling `copy_view` tests, and wrong draw-call ownership. Do not close
|
||||
T3 merely because 153 tests pass.
|
||||
|
||||
### 5.3 Retail truths already bound by T3
|
||||
|
||||
These are not optional interpretations:
|
||||
|
||||
- `portal_info` has raw signed `seen` and `inflag`; a clip candidate is
|
||||
`seen != 0 && inflag != 1`.
|
||||
- Retail sidedness is `POSITIVE = 0`, `NEGATIVE = 1`.
|
||||
- `InitCell` treats `inflag = 0` as a candidate and `inflag = 1` as excluded/
|
||||
backlink; `max_indist` is computed from final `inflag == 1` vertices.
|
||||
- Todo storage is farthest at the front and nearest at the tail; tail pop is
|
||||
nearest-first; equal keys preserve FIFO order.
|
||||
- `ClipPortals` is two-pass: pass one resolves/liveness globally. If any portal
|
||||
is live, pass two evaluates every source view against every flag candidate,
|
||||
including unresolved candidates.
|
||||
- `OtherPortalClip` resets one function-static temporary view set each epoch.
|
||||
Its first copy may reject. Its far clip always uses `do_clip = 1`; the far
|
||||
side is derived separately as
|
||||
`far.portal_side == POSITIVE ? NEGATIVE : POSITIVE`.
|
||||
- `ClipPortals`, not `OtherPortalClip`, restores the source view after the
|
||||
helper returns, including rejection and far-zero paths.
|
||||
- Source CellView, destination CellView, PView outside view, and the one static
|
||||
reciprocal temporary view are separate containers.
|
||||
- `AddToCell` installs every newly appended view unconditionally.
|
||||
- `SetOtherSeen` occurs only after the completed branch/recursion/watermark.
|
||||
- `FixCellList` always calls `AdjustCellPlace` and then `AdjustCellView`; the
|
||||
list move itself remains conditional.
|
||||
- `DrawCells` draws shells first and objects second, in reverse cell order;
|
||||
views are ascending. A null `drawing_bsp` skips only that cell's shell.
|
||||
- The object chain is
|
||||
`DrawObjCellForDummies → insertion_sort → DrawObjCell → DrawPartCell →`
|
||||
`CShadowPart::Draw → CPhysicsPart::Draw → DrawMesh`.
|
||||
- Built EnvCell shells and built parts submit whole after Boolean admission;
|
||||
portal polygons, not arbitrary built meshes, are polygon-clipped.
|
||||
- Device, cell-shell, and part stamps persist. The first ordinary accepted
|
||||
view stamps/draws and later views suppress; force/local-player paths bypass
|
||||
the ordinary inner stamp behavior.
|
||||
|
||||
## 6. Automated state at handoff
|
||||
|
||||
All results below are from the frozen uncommitted tree.
|
||||
|
||||
| Gate | Result | Provenance |
|
||||
|---|---|---|
|
||||
| T3 focused cases | **54/54 passed** | Final third-round agent run |
|
||||
| Core WorldEvidence aggregate | **153/153 passed** | Final third-round agent run |
|
||||
| Core Release build | **PASS, 0 warnings / 0 errors** | Final third-round agent run |
|
||||
| App legacy importer + recorder compatibility | **46/46 passed** | Handoff verification run after the Core freeze |
|
||||
| Complete solution Release build | **PASS, 0 warnings / 0 errors** | Handoff verification run after the Core freeze |
|
||||
| Trailing whitespace | **clean** | Final third-round agent run |
|
||||
| Dead T3 vocabulary grep | **clean** | Only the intentional test asserting `PartAdmit` is absent remains |
|
||||
|
||||
The complete solution **test suite was not rerun** after the third T3 round.
|
||||
No tests are known red. The older OH0 baseline (319 focused passes / 1 skip)
|
||||
and the tooling note's pre-T2 counts are historical provenance, not current OH1
|
||||
closure evidence.
|
||||
|
||||
Reproduction commands from the worktree root:
|
||||
|
||||
```powershell
|
||||
dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj -c Release --no-restore --filter "FullyQualifiedName~Diagnostics.WorldEvidence.WorldEvidenceJsonlTests"
|
||||
|
||||
dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj -c Release --no-restore --filter "FullyQualifiedName~WorldFrameTranscriptRecorderTests|FullyQualifiedName~LegacyWalkOracleImporterTests"
|
||||
|
||||
dotnet build AcDream.slnx -c Release --no-restore --nologo
|
||||
|
||||
git diff --check
|
||||
```
|
||||
|
||||
## 7. Known open T3 review surface
|
||||
|
||||
T3 is not review-closed until these are either implemented and tested or
|
||||
explicitly disproved as required by the retail sources:
|
||||
|
||||
1. Add a dedicated same-typed-part-across-two-cells persistent-stamp fixture.
|
||||
2. Add an outside-`DrawCells` `PortalListBind` positive/completeness fixture.
|
||||
3. Add explicit `copy_view` adversarials for every numerical boundary:
|
||||
- exactly one pixel and just over one pixel;
|
||||
- every wrap-prune branch;
|
||||
- the 32-plane cap;
|
||||
- negative zero;
|
||||
- second append/pool reset; and
|
||||
- normalization epsilon.
|
||||
4. Decide under retail and architecture review whether call boundaries require
|
||||
a typed `PViewCallContext`. Exact identities currently come from owned
|
||||
semantic rows. Do not add the type merely for aesthetics, and do not reject
|
||||
it merely to avoid a schema edit.
|
||||
5. Decide whether `NullTail`'s current
|
||||
`TailPopAttempted = true` + `TailPointerPresent = false` is sufficiently
|
||||
exact, or whether retail evidence requires a standalone nullable-pop event.
|
||||
6. Run a fresh independent retail-faithfulness review and a separate
|
||||
architecture/false-oracle review. The reviewer must try coordinated
|
||||
omissions/relabels, not only single-field mutations.
|
||||
|
||||
No owner/client gate is needed for T3 unless static retail sources genuinely
|
||||
lack one fact. If an owner capture becomes necessary, request one exact pose,
|
||||
action, duration, and expected trace. Do not ask the owner to explore visually.
|
||||
|
||||
## 8. Dirty-tree map
|
||||
|
||||
At the freeze, `git status --short` reports no staged files. The principal
|
||||
groups are:
|
||||
|
||||
### Preserved pre-overhaul behavior candidates — do not attribute to T3
|
||||
|
||||
- App composition/rendering changes in `FrameRootComposition`,
|
||||
`ParticleRenderer`, `RetailAlphaQueue`, `RetailPViewPassExecutor*`,
|
||||
`RetailPViewRenderer`, `OrderedDrawStream`, `WalkFrameDriver`,
|
||||
`WalkStaticStreamPopulator`, `WbDrawDispatcher*`, and
|
||||
`WorldSceneRenderer`;
|
||||
- associated App walk/alpha/PView/runtime-option tests;
|
||||
- `docs/launch-options.md`; and
|
||||
- A8 audit project/lock-file changes.
|
||||
|
||||
Their detailed semantic classification and risk level are in
|
||||
`oh0-baseline.md`. They include geometry recipe, lighting, depth-state,
|
||||
exit-seal, membership, built-mesh, part-stamp, shell-stamp, and diagnostic
|
||||
candidates. None is accepted simply because it remains in the tree.
|
||||
|
||||
### OH1 evidence work
|
||||
|
||||
- Core `Diagnostics/WorldEvidence` models, codec, grammar, and tests;
|
||||
- App transcript recorder and narrow legacy oracle importer/tests;
|
||||
- the synthetic A8 geometry-manifest command boundary;
|
||||
- launch-option documentation for output-only evidence; and
|
||||
- the active tooling note and corrected flood appendix.
|
||||
|
||||
### Known non-semantic noise to exclude from narrow commits
|
||||
|
||||
The following were classified as CRLF-only in OH0:
|
||||
|
||||
- `src/AcDream.App/Rendering/Scene/RenderProjectionRecordFactory.cs`
|
||||
- `src/AcDream.App/Rendering/Scene/RenderSceneContracts.cs`
|
||||
- `src/AcDream.Core/Physics/ShadowPartBox.cs`
|
||||
- `src/AcDream.Core/World/MeshRef.cs`
|
||||
- `src/AcDream.Core/World/WorldEntity.cs`
|
||||
|
||||
`src/AcDream.App/Streaming/LandblockBuildFactory.cs` was blank-line-only.
|
||||
Recheck with `git diff --ignore-space-at-eol -- <path>` before assuming any of
|
||||
these has gained semantic content.
|
||||
|
||||
## 9. Next safe execution sequence
|
||||
|
||||
1. Confirm `HEAD`, branch, and `git status --short`; do not clean the tree.
|
||||
2. Read the documents in section 3, especially OH0 and the active tooling note.
|
||||
3. Review the seven round-three T3 files as one closed grammar change.
|
||||
4. Implement the bounded adversarial fixtures in section 7 without changing
|
||||
production rendering or loosening the canonical schema.
|
||||
5. Run the 153-test WorldEvidence aggregate, the 46-test App compatibility
|
||||
gate, `git diff --check`, and the complete Release solution build.
|
||||
6. Obtain independent retail-faithfulness and architecture/false-oracle
|
||||
reviews. Fix findings and rerun the same gates.
|
||||
7. Update `oh1-world-evidence-tooling.md` and the campaign execution ledger.
|
||||
8. Stage only the reviewed T3/OH1 paths. Preserve the OH0-classified App
|
||||
behavior candidates and line-ending noise. Commit T3 only after review
|
||||
closure; record the commit in the checkpoint ledger.
|
||||
9. Complete OH1 T4–T8 from the plan: landscape/building interleave,
|
||||
alpha/material evidence, depth lifecycle, recorder/fixture integration,
|
||||
and final no-production-change gates/reviews.
|
||||
10. Mark OH1 closed only when all planned evidence families are executable and
|
||||
the narrow FW0 importer is still truthfully narrow.
|
||||
11. Then begin OH2 implementation from the already committed CellStruct
|
||||
contract. OH2 owns the production descriptor, package version/migration,
|
||||
installed-DAT manifest generation, two-run determinism gate, review, and G1.
|
||||
|
||||
Do not jump directly to cathedral symptom fixes. The first production behavior
|
||||
change belongs to OH2 after OH1 closes. Preserve the campaign's Plan →
|
||||
Implement → Review rhythm and combine owner gates according to the stage table;
|
||||
do not launch a client after every code edit.
|
||||
|
||||
## 10. Copy-paste prompt for the next model
|
||||
|
||||
```text
|
||||
Take over Campaign OVERHAUL in the EXISTING worktree:
|
||||
C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-blackburn-5333f0
|
||||
|
||||
Branch: claude/campaign-w-retail-frame-walk
|
||||
Frozen HEAD: 5d907ae9ad9462347eb697c39ae3ffac136a40bc
|
||||
|
||||
Do not use the main checkout. Do not create or copy another worktree over this
|
||||
one. The tree is intentionally dirty and has no staged files. Never run reset
|
||||
--hard, checkout --, or clean. The recovery anchor is b3b7d922.
|
||||
|
||||
First read, in order:
|
||||
1. AGENTS.md
|
||||
2. docs/architecture/acdream-architecture.md
|
||||
3. docs/architecture/worldbuilder-inventory.md
|
||||
4. docs/research/2026-09-01-overhaul/2026-09-02-campaign-overhaul-handoff.md
|
||||
5. docs/plans/2026-09-01-campaign-overhaul-world-solidity.md
|
||||
6. docs/research/2026-09-01-overhaul/oh0-baseline.md
|
||||
7. docs/research/2026-09-01-overhaul/oh1-retail-world-contract.md
|
||||
8. all four supporting OH1 contract packets
|
||||
9. docs/research/2026-09-01-overhaul/oh1-world-evidence-tooling.md
|
||||
10. docs/research/2026-09-01-overhaul/oh2-cellstruct-surface-contract.md
|
||||
11. docs/research/2026-08-30-fw-flood-pseudocode-appendix.md
|
||||
|
||||
Current truth: OH0 is closed. OH1 research and T0-T2 are closed. OH1/T3's third
|
||||
implementation round is uncommitted and locally green (54/54 T3, 153/153 Core
|
||||
WorldEvidence, 46/46 App importer/recorder, complete Release build 0 warnings/
|
||||
errors), but T3 is NOT independently review-closed. OH1/T4-T8 and every
|
||||
production slice OH2-OH11 remain pending. OH2 design exists at 5cd4fd2c, but
|
||||
OH2 implementation must not start until OH1 closes.
|
||||
|
||||
Your first work is to inspect—not rewrite—the frozen T3 grammar and close the
|
||||
explicit review gaps listed in handoff section 7: same-part-across-two-cells
|
||||
stamps, outside-DrawCells PortalListBind, all copy_view numerical adversarials,
|
||||
and evidence-based decisions on PViewCallContext and NullTail representation.
|
||||
Then run independent retail-faithfulness and architecture/false-oracle reviews,
|
||||
fix findings, rerun the recorded gates, update both ledgers, and commit only the
|
||||
narrow reviewed T3 scope.
|
||||
|
||||
The named retail pseudo-C and retail headers are the behavior oracle. Grep by
|
||||
class::method first. Use Ghidra to arbitrate ambiguous branch sense. Do not
|
||||
invent an approximation and do not make production draw decisions in OH1.
|
||||
Do not infer render content from aggregate owner IDs; trace identities to DAT.
|
||||
|
||||
No owner/client gate is currently needed. If a static fact genuinely cannot be
|
||||
recovered, ask for one precise capture with an exact pose/action/duration and
|
||||
expected trace. The user normally closes a running client; never kill it unless
|
||||
the user explicitly authorizes control.
|
||||
```
|
||||
|
||||
## 11. Handoff stop condition
|
||||
|
||||
At this freeze all previous subagents are complete and no agent should be
|
||||
assumed to be editing the tree. The next model owns the next mutation. Before
|
||||
changing anything, compare live `git status` and `git diff` with this document;
|
||||
newer filesystem state always needs explicit classification rather than being
|
||||
silently folded into T3.
|
||||
Loading…
Add table
Add a link
Reference in a new issue