docs(overhaul): hand-off rewritten clean at S4-c2 fix round 1 (review verdicts, #464 fixed, #468 filed, landing procedure, fixer-state check)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-04 06:39:23 +02:00
parent 2001103ca6
commit 2a35f0a4c3

View file

@ -1,38 +1,40 @@
# Campaign OVERHAUL v2 — hand-off at S4 chunk 2 (2026-09-04 morning)
# Campaign OVERHAUL v2 — hand-off at S4 chunk 2, fix round 1 (2026-09-04 ~11:00 local)
Written by the lead session that took over after the 2026-09-03 session ran
out of account credits. Everything below is on disk under the Windows user
`erikn`; a fresh Claude account on this machine can read all of it.
Clean state for a fresh session. Everything referenced is on disk under the
Windows user `erikn`; a different Claude account on this machine reads it all.
The one thing that does NOT survive a session switch is a running subagent —
see §3 for how to find out what the chunk-2 fixer left behind.
## 0. Read order for the new lead
## 0. Read order
1. `CLAUDE.md` in the worktree (project rules; the grep-named-decomp-first
workflow; no workarounds; every new pin needs a mutation check).
2. `docs/plans/2026-09-01-campaign-overhaul-world-solidity.md` — the plan.
§5 working model, §9 slices, §10 scene matrix, **§13 ledger = live state**
(the S3 and S4 rows are long; read their tails).
3. `claude-memory/project_overhaul_campaign.md` (junction of
1. `CLAUDE.md` in the worktree — project rules (grep the named decomp first;
no workarounds; every new pin needs a mutation check; register rows in the
same commit as the deviation).
2. This file, then `docs/plans/2026-09-01-campaign-overhaul-world-solidity.md`
§5 (working model), §9 (slices), §10 (scene matrix), **§13 ledger tail (the
S3 and S4 rows are long; the S4 row is the live state)**.
3. `claude-memory/project_overhaul_campaign.md` (the junction of
`C:\Users\erikn\.claude\projects\C--Users-erikn-source-repos-acdream\memory\`)
— the campaign digest, "Current" heading; then `MEMORY.md` for the
feedback memories it links (`feedback_quote_decomp_predicates`,
— the campaign digest, "Current" heading; then the feedback memories it
links (`feedback_quote_decomp_predicates`,
`feedback_every_new_pin_must_be_shown_to_fail`,
`feedback_skip_ab_before_theorizing`, `feedback_agent_worktree_base`,
`feedback_soak_numbers_need_same_session_type`).
4. `docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md` — S4's
packet: §1§4 what remains of S4, **§8 = the S4-c2 contract**, §6/§7/§9 =
chunk 1's contract and its two fix rounds.
5. `docs/ISSUES.md`#464 (long; the whole investigation), #460#463,
`feedback_skip_ab_before_theorizing`, `feedback_verify_subagent_claims_against_source`,
`feedback_agent_worktree_base`, `feedback_soak_numbers_need_same_session_type`).
4. `docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md`**§8 = the
S4-c2 contract; §11 + §11.1 = the fix round 1 contract (M1M8, A1A8)**;
§10 (the implementer's landing note) lives only in the chunk commit in
worktree `s4-c2-impl` until the cherry-pick; §1§4 what remains of S4.
5. `docs/ISSUES.md`#464 (FIXED, history kept), #468 (new), #460#463,
#465#467.
6. `docs/research/2026-09-01-overhaul/s3-walk-ownership-map.md` — S3's
packet (chunk contracts, review rounds; §6b = the retail capture record).
7. `docs/research/2026-09-01-overhaul/oh-capture/README.md` — the six retail
capture poses and their logs (walk / parts / alphadepth / pmverts /
blockcheck).
8. The previous sessions' transcripts, if you need the reasoning behind a
decision (grep, never read whole):
6. `docs/research/2026-09-01-overhaul/oh1-alpha-list-contract.md` §2§7 — the
retail alpha-list spec S4-c2 ports.
7. `docs/research/2026-09-01-overhaul/s3-walk-ownership-map.md` (S3's packet;
§6b = the retail capture record) and `oh-capture/README.md` (the six
capture poses and their logs) — only when a question reaches them.
8. Transcripts, grep never read whole:
`C:\Users\erikn\.claude\projects\C--Users-erikn-source-repos-acdream--claude-worktrees-peaceful-blackburn-5333f0\f3ae8d4c-4f29-4329-8629-7252bd2bf4c2.jsonl`
(2026-09-02 15:20 → 2026-09-04 04:29, the S1S4-c1 session) and this
session's under
(2026-09-02 → 2026-09-04 04:29, S1 through S4-c1) and the 2026-09-04
session under
`C:\Users\erikn\.claude\projects\C--Users-erikn-source-repos-acdream--claude-worktrees-eloquent-hugle-42119e\`.
## 1. Where the work lives
@ -40,342 +42,235 @@ out of account credits. Everything below is on disk under the Windows user
| Item | Value |
|---|---|
| Worktree | `C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-blackburn-5333f0` |
| Branch | `claude/campaign-w-retail-frame-walk`, tip `4c6fb8fa6` (docs) on `766f9e749` (code), clean |
| Base | `origin/main` `e102fb36` (2026-08-29); the branch carries all of Campaign FW + OVERHAUL, ~270 commits; **nothing merges to main before G4** |
| Dev pak | `%USERPROFILE%\Documents\Asheron's Call\acdream.pak`, bake recipe 8 (`acdream.recipe7.pak` kept beside it) |
| Branch | `claude/campaign-w-retail-frame-walk`; docs tip `2001103ca`, **latest renderer code `766f9e749`** (S4 chunk 1); clean |
| Base | `origin/main` `e102fb36` (2026-08-29); ~275 commits ahead; **nothing merges to main before G4** |
| Dev pak | `%USERPROFILE%\Documents\Asheron's Call\acdream.pak`, bake recipe 8 |
| Release binary | `src\AcDream.App\bin\Release\net10.0\AcDream.App.exe` built at `766f9e749` |
| ACE | `127.0.0.1:9000`, `testaccount` / `testpassword`, character `+Acdream`. **Was NOT running at hand-over** (no UDP 9000 listener). Only the owner starts it. |
| Retail client for captures | `C:\Users\erikn\Downloads\acclient.exe` (2013 v11.4186, pairs with `refs/acclient.pdb`); the Turbine folder's exe is the 2015 build and does NOT pair |
| ACE | `127.0.0.1:9000`, `testaccount` / `testpassword`, character `+Acdream`; was UP from ~08:00 on 2026-09-04 (the owner started it). Check `netstat -an -p UDP \| grep 9000` before assuming. Only the owner starts it. |
| Retail client for captures | `C:\Users\erikn\Downloads\acclient.exe` (2013 v11.4186, pairs with `refs/acclient.pdb`); the Turbine folder's exe (2015) does NOT pair |
Scratch worktrees (all detached; keep or remove as you like):
Scratch worktrees (detached):
| Worktree | At | Purpose |
|---|---|---|
| `s4-c2-impl` | `766f9e749` | S4 chunk 2 implementer's worktree (see §3) |
| `s4-c1-impl` | `9ba8f013e` | chunk 1's rounds (landed; removable) |
| `s3-review-fix` | `6575cfcee` | pre-S4 A/B control build (route-g3b.txt copied in, dirty) |
| `s2-final-ab` | `78068b2c` | S2-final binary for same-session perf A/B soaks (keep) |
| `464-ab` | `0b9e9b64a` | env-gated draw-skip A/B build used to localize #464 |
| `mouselook-verb` | `c43fb4ace` | the `mouselook` automation verb (cherry-picked to the branch; removable) |
| `s4-c2-impl` | `048d5b12f` on `766f9e749` (+ the fixer's round-1 commit when it lands) | **S4 chunk 2 — the chunk commit and its fix round live HERE, not on the branch yet** |
| `s4-c1-impl` | `9ba8f013e` | S4-c1 baseline BINARY, built (Release App + Cli) for the landing soak A/B; keep until S4-c2 lands |
| `s2-final-ab` | `78068b2c` | S2-final binary for same-session perf A/B (keep) |
| `s3-review-fix` | `6575cfcee` | pre-S4 control build; stalls at the foundry login (#462) — not usable as a control |
| `464-ab`, `mouselook-verb` | — | done with; removable |
Binding rules the owner set (do not relax): never `git reset --hard`,
`git checkout --`, `git clean`, bare `git stash`; never kill a client the
owner started; never launch a client while one is running; never more than
five agents per step; a chunk needing a THIRD fix round stops and is written
up in the ledger; self-passed gates stay provisional until the owner looks;
Binding rules the owner set: never `git reset --hard`, `git checkout --`,
`git clean`, bare `git stash`; never kill a client the owner started; never
launch a client while one is running (`tasklist \| grep AcDream.App` first);
never more than five agents per step; a chunk needing a THIRD fix round stops
and is written up; self-passed gates stay provisional until the owner looks;
every deviation gets a register row in the same commit.
## 2. What has landed (with the proof)
## 2. What is done (proof in the §13 ledger)
- **S1 Geometry — CLOSED, G1 owner-passed 2026-09-02.** Exact CellStruct side
and subset construction (`D3DPolyRender::ConstructMesh` @0x0059DFA0),
recipe 8, AP-234 retired.
- **S2 World graph — CLOSED, G2 owner-passed 2026-09-03.**
`ShadowObjectRegistry` is the ONLY render-membership owner (one flood per
registration feeds collision rows AND the retail render product); render-only
statics register from both publishers; particle emitters draw by their own
cell (`add_particle_shadow_to_cell` @0x00514a70) — that fixed the missing
portal-arrival haze.
- **S3 Walk — CLOSED 2026-09-03 (`ea76a3803`).** Chunk 2: the interior turn's
landscape flush / stamp advance / gated Z clear / exit seals run only under
`outside_view.view_count > 0`, the clear gated by retail's persistent
`portalsDrawnCount`. Chunk 3: terrain drawn per land cell in retail's
DrawBlock interleave (this removed the Holtburg house-through-hill
fragments by ORDER alone). Chunk 1: the print-only walk transcript
(`ACDREAM_DUMP_WALK_TRANSCRIPT=1`) + the offline eight-kind conformance gate
over the captures. Chunk 4 + hygiene chunk H: every acdream-only clip rule,
the per-view sky/weather loops, the scissor and terrain-clip stacks and the
six cathedral probes deleted. Slice review fix round: punch fans clipped by
their OWN view (slice/view alignment bug), the seal pin through the real
producer, dead per-cell clip machinery deleted. Owner's S3 double-check:
every pose PASS except the cathedral stairwell zoomed out (→ #464).
- **S4 chunk 1 — LANDED 2026-09-03 23:40** as `d1e3e64f6` + `5de42a12f` +
`323f5a334` (rounds 02 cherry-picked) + `766f9e749` (four comment
sentences corrected by the lead, code unchanged — the plan bars a third
implementer round; **the owner has not reviewed that correction yet**).
Content: retail's far-punch depth bits `0x3F7FFFEF` in `portal_depth.vert`
(ours was `0x3F7FFFFE`, 15 ULPs off); the ±12 local-input portal-polygon
reject with retail's REAL quantifier (reject only when EVERY vertex lies on
ONE plane among x=±12 / y=±12; bytes 0x59BCD60x59BD66; the lead's first
paraphrase inverted it — see `feedback_quote_decomp_predicates`); the seal
count-after-guard order; the AD-119 register row (ColorWrite off vs retail's
zero-alpha blend); and the automated **PM/PC depth-event transcript gate**
(`tests/AcDream.App.Tests/Rendering/Walk/WalkTraceConformanceTests.AlphaDepthTranscript.cs`
+ `WalkAlphaDepthTrace.cs`) replaying all SIX retail `*.alphadepth.log`
captures with `portalsDrawnCount` seeded from each fixture's first counter
(seeds 0/0/1/2/2/8) — 6/6 PASS. Round-2 lenses: retail PASS (byte evidence:
one increment site 0x59BD74, one reset site 0x5A489E, `forceClear` has no
writer), production PASS, gate-honesty FAIL on comment truth only. Landing
gates: Release 0 warnings; hermetic App lane 6,833/6,833; InstalledDat lane
249 pass / 4 known (#383 ×2, TowerAscent, #458) / 1 skip.
- **S1 Geometry, S2 World graph, S3 Walk — CLOSED**, G1/G2 owner-passed, the
S3 owner double-check passed every pose except the cathedral zoom (→ #464,
now fixed). Details: ledger rows; S2 truth and S3 chunk facts in the digest.
- **S4 chunk 1 — LANDED at `766f9e749`** (`d1e3e64f6`+`5de42a12f`+`323f5a334`
cherry-picks + the lead's four comment corrections, code unchanged; the
owner has not reviewed that correction). Retail's far-punch depth bits, the
±12 portal-polygon reject with retail's SAME-plane quantifier, the seal
count order, the seeded PM/PC depth-event transcript gate over six retail
captures (6/6). Landing gates: hermetic 6,833/6,833; InstalledDat 249 pass /
4 known (#383 ×2, TowerAscent, #458) / 1 skip.
- **#464 (hall drawn above the stairwell arch) — FIXED by S4-c1**, owner
reported it and the lead confirmed with the scripted route at the identical
eye (`logs/selfgate-20260904-061530-464-tilt3-s4c1`, frame `01-neg160`,
eye (39.50,17.23,182.61)); the ±12 reject drops the twelve hall-doorway
punches retail also rejects. RenderDoc is no longer needed. Matrix row
"Cathedral stairwell, camera zoomed out" = PASS, provisional.
- **The Holtburg doorway "fog frame" — RESOLVED, not render: #468.** At
route-g3b's old pose 15 the placement resolve seats the player in the
house-interior cell at a floorless point and it falls through the world
(probe run `logs/selfgate-20260904-063313-hd-probe`: z 96 → 20 m); the
frame is the terrain from below. Placement/collision, tactical, outside the
campaign. route-g3b pose 15 now teleports to the outdoor standing point
`A9B40029 133.603592 17.391838 96.330009`.
- Retail axioms (never "fix"): the exterior slab through the cathedral stair
chamber; the zoomed-out FRONT view from the stairwell (hall arches + sky);
#458's far-block admission (AD-118, 0.5 % edge-plane precision).
Retail axioms (owner-confirmed, never "fix"): the exterior slab through the
cathedral stair chamber (2013 + EoR clients show it); the zoomed-out FRONT
view from the stairwell showing the hall arches and sky; #458's doorway
far-block admission is a 0.5 % edge-plane precision boundary (AD-118).
## 3. In flight: S4 chunk 2 — fix round 1
## 3. In flight: S4 chunk 2 (the alpha lists)
**What landed in the worktree:** `048d5b12f` in `s4-c2-impl` (Sonnet, 2026-09-04
09:35): `RetailAlphaQueue` = retail's two FIFO lists (CLIP/ALPHA, 3000 each,
capacity drop), `RetailAlphaMeshRouter` (DrawMesh rows 15 + ConstructMesh
mask), the new `SortCellExit` walk event for DrawBlock's 0.75 valve, the four
flush sites, `FlushFartherThan`/every viewer distance deleted. Hermetic
6,855/6,855; shaders 32/32.
**Contract:** packet §8, verbatim. One production behavior change: replace
the single distance-sorted `RetailAlphaQueue` with retail's two append-order
lists (CLIP and ALPHA, 3000 each; `D3DPolyRender::AddMeshToAlphaList`
@0x0059C230), route every delayed subset through ONE pure router implementing
the OH1 alpha spec's `DrawMesh` branch table (spec §4 rows 15; delay mask
`0x0E` @0x00820D88, `MultiPassAlpha` false @0x0081EF96, constructed subset
mask spec §2), flush at retail's four sites (`DrawBuilding` 0f = the existing
`AlphaBarrier`; `DrawBlock` 0.75 = a NEW leaf event at the sort-cell EXIT;
`PView::DrawCells` 0f = `LandscapeFlush`; `RenderNormalMode` 0f = pass end)
under `FlushAlphaList` @0x0059D2E0's threshold rule (quote the comparison
from the bytes), delete `FlushFartherThan` / `RetailAlphaOrdering.ComputeViewerDistance`
/ every viewer distance on the submit path, retire register row AP-34 in the
same commit, capacity overflow DROPS the subset. Proof = extend the transcript
gate from PM/PC to AM/FL over all six captures (per flush: site, threshold,
drained count PER LIST).
**Review round 1 (both lenses FAIL; lead verified every finding at the source;
the core port is exact at the bytes):**
- BLOCKING: the particle site asserts DrawMesh rows 1/2/4/5 "unreachable" and
THROWS; `ParticleRenderer.TryAppendMeshDraws` appends Opaque-classified mesh
batches → mask 0x00 → row 5 → exception in the render loop.
- MAJOR: the CLIP list is structurally EMPTY for ordinary content (ClipMap
kinds are `WbDrawDispatcher.IsOpaque` → alpha-to-coverage, never routed;
4,183 of 10,556 captured AM entries are CLIP) — no register row;
contract C3's detail input hardcoded false while building shells reach the
alpha path and the DRAIN applies the detail pass retail's replay never has
(`DrawBuilding` @0x0059f2a0 installs `building_detail_surface` @0x0059f2eb
before its flush → row 1 immediate); C4 (EnvCell detail-off append) skipped
though `EnvCellRenderer.RenderTransparentOrdered` makes it bounded;
`IsFirstForList` = first-since-drain where retail's `new` is per-DrawMesh
invocation (`0059d4cc/0059d4d0`); the AM/FL gate is all-KnownFailure and the
counts are unmatchable by construction; a THIRD `FlushLandscapeAlpha` caller
(`RetailPViewRenderer.cs:485`, the #132 outdoor-root drain) is mislabelled as
retail's DrawCells flush, which never runs on an outdoor root; AP-236 REUSES
an id filed and retired on main by #132.
- MINOR: AP-237's cloud example is disproven (Type 0x10114 has alpha-family
bits → mask 0x02 both sides); `DrawBlock` cited at its loop head
0x005a18d0 (function is 0x005a17c0); "return site" = the call address;
scratch-retention argument; stale comments; §10 transcription off by one.
- Everything is itemized as **packet §11 (M1M8) + §11.1 (A1A8)** on the
campaign branch (`3813f0bbf`, `3e76f71d5`).
**Dispatch state:** this session dispatched one Sonnet implementer (plain
Agent tool, not the Workflow tool) at ~08:35 local on 2026-09-04 into
`s4-c2-impl` (detached at `766f9e749`). It commits ONCE on top of that HEAD
when done. **To find its state:**
**Dispatched:** one Sonnet implementer (plain Agent tool) at ~10:55 local into
`s4-c2-impl`, told to commit ONCE on top of `048d5b12f` with every mutation
check's actual failing assertion and every gate's real output line in the
commit body. **It runs inside the 2026-09-04 lead session; a session switch
kills it.** Find its state:
```bash
git -C C:/Users/erikn/source/repos/acdream/.claude/worktrees/s4-c2-impl log --oneline -3
git -C C:/Users/erikn/source/repos/acdream/.claude/worktrees/s4-c2-impl status --short
```
- A commit above `766f9e749` → the implementer finished. Its report is lost
with the session; reconstruct it from the commit body (it was told to paste
every mutation-check failing assertion and every gate's real output line
there). Proceed to the review round below.
- No commit, dirty tree → it was cut off mid-way. Read the diff; either
finish it yourself against §8 or discard the worktree's changes (it is a
disposable detached worktree; `git worktree remove --force` + re-add) and
re-dispatch from §8. Do not stash.
- No commit, clean tree → it never started editing; re-dispatch.
- A commit above `048d5b12f` → round 1 finished; its report is the commit
body. Run the two review lenses (below), verify their findings yourself.
- No commit, dirty tree → cut off mid-round. Read the diff against §11/§11.1;
finish it yourself or discard the worktree's changes (it is disposable:
`git worktree remove --force` + re-add detached at `048d5b12f`) and
re-dispatch §11 + §11.1 from scratch. Never stash.
- No commit, clean tree → never started; re-dispatch.
The previous session's Workflow script for this chunk (prompt text identical
to §8, one implementer + three sequential lenses) is at
`C:\Users\erikn\.claude\projects\C--Users-erikn-source-repos-acdream--claude-worktrees-peaceful-blackburn-5333f0\f3ae8d4c-4f29-4329-8629-7252bd2bf4c2\workflows\scripts\s4-c2.js`
— reusable via `Workflow({scriptPath})` only if the owner has opted into
workflows in your session; otherwise use the Agent tool.
**Round-1 review:** two lenses (Opus or the session model; the Opus tier was
529-overloaded for ~90 min on 2026-09-03): retail-faithful, narrowed to the
decomp claims of M1/M3/M6 and the router inputs; production/gate-honesty (the
six live `AlphaFlushSites_*` Facts, the new valve pin, the immediate-draw
paths' allocation, the register). Lead verifies every finding against the
source (`feedback_verify_subagent_claims_against_source`). PASS → land. FAIL →
fix round 2 (the LAST) → PASS → land; a third round STOPS the chunk and is
written up in the ledger.
**Review round (the §5 model):** two lenses (retail-faithful: every
predicate quoted against `docs/research/named-retail/acclient_2013_pseudo_c.txt`
and the paired binary at raw = VA 0x400000; production/gate-honesty: no
distance left on the alpha path, AP-34 retired, no per-frame allocation, every
claimed gate reproduced read-only, at least three mutation checks re-performed,
no KnownFailure without a written divergence in packet §9). The LEAD verifies
every finding against the source before acting (`feedback_verify_subagent_claims_against_source`).
Lenses on `model:'opus'` were 529-overloaded for ~90 min on 2026-09-03; the
session model worked as a lens. Max two fix rounds, then the ledger.
**Landing:** cherry-pick the chunk commit(s) onto the campaign branch; Release
build; the six transcript Facts; hermetic lane
(`--filter "Lane!=InstalledDat&Lane!=PreparedPackage&Lane!=Live&Lane!=Manual&Lane!=Timing&Lane!=Windows&Lane!=Linux&Lane!=SystemFont&Purpose!=Diagnostic&Status!=KnownFailure"`);
**Landing procedure:** cherry-pick `048d5b12f` and the round-1 commit onto the
campaign branch (the packet will conflict on §10 vs §11 — both are appends;
keep both, §10 before §11); Release build 0 warnings; hermetic lane
(`dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj -c Release --no-build --filter "Lane!=InstalledDat&Lane!=PreparedPackage&Lane!=Live&Lane!=Manual&Lane!=Timing&Lane!=Windows&Lane!=Linux&Lane!=SystemFont&Purpose!=Diagnostic&Status!=KnownFailure"`);
InstalledDat lane (`ACDREAM_RUN_INSTALLED_DAT_TESTS=1`,
`ACDREAM_DAT_DIR="C:/Users/erikn/Documents/Asheron's Call"`,
`--filter "Lane=InstalledDat"`, expect exactly the four known failures);
shader classes; the validation-on self-gate at the S3-closed poses diffed
against the S3-closed run; a stationary-phase soak A/B against the S4-c1
binary (removing the sort must not regress; judge `stationary` only — #463).
Then the §13 S4 row and the memory digest.
`--filter "Lane=InstalledDat"`; expect exactly the four known failures plus
the six `AlphaFlushCounts_*` KnownFailure Facts); shader classes; the
validation-on self-gate (`route.txt` four poses + `route-g3b.txt`) diffed
against the S3-closed run `logs/selfgate-20260903-16*` /
`…-234934-s4c1-landed-route2` with `py scratchpad/selfgate-diff4.py <run> <baseline>`
(PIL; the script lives in the OLD session's scratchpad — re-create it if
missing: per-frame mean-abs-diff sheet); a STATIONARY-phase soak A/B against
the S4-c1 binary in `s4-c1-impl`
(`tools/run-connected-r6-soak.ps1 -SkipBuild -PreparedAssetPath "$env:USERPROFILE\Documents\Asheron's Call\acdream.pak"`,
then `-Repository <s4-c1-impl> -SkipBuild`; same Windows session type; judge
`stationary` only — #463). Then the §13 S4 row, the register, and the digest.
**After chunk 2:** S4-c3 = deletions (packet §4); then G3 (S4's owner gate:
the §10 scene matrix + the capture poses; the lead's G3 pre-run of 2026-09-03
is the baseline, 20/20 provisional, owner passed all but the cathedral); then
S5 (consumers, material/degrade exact ports, delete every inventoried
fallback/probe, closeout); then G4 and the merge to main.
## 4. After chunk 2
## 4. Open investigation: #464 (the cathedral stairwell arch)
1. **S4 chunk 3 — deletions** (packet §4): whatever of the old queue/sort/
distance residue survives, the `AlphaFlushCounts_*` Facts if a real
content-bearing gate replaces them, the two `EnvCell`/CLIP residual rows'
re-check. Write the contract from the LANDED code, not from §4's 2026-09-03
guess.
2. **G3 — S4's owner gate:** the lead runs `route-g3.txt` (13 matrix shots),
`route-g3b.txt` (the capture poses; pose 15 now outdoors), `route-g3c.txt`
(Nanto ×3, 300 s waits) with `pwsh -File tools/overhaul-selfgate/run-selfgate.ps1 -Label <l> -Route <file>`
— ONE run per background command (three chained runs exceed the tool's
10-minute limit and get hard-killed mid-run; that happened once today);
records PASS/FAIL + PNG paths in the ledger; the owner double-checks. Rows
only the owner can do: the cathedral wall actor (two clients), the exterior
ramp (no coordinates), Tusker, two ordinary dungeons.
3. **S5** (consumers, material/degrade exact ports, delete every inventoried
fallback/probe, closeout), then **G4** and the merge to main.
4. Before G4, outside the slices: #460 (windowless shutdown hang after an
aborted script), #461 (crash on a late motion update after logout), #462
(interior login reveal stall — recurred twice today on `6575cfcee`), #463
(soak turn-sample artifact), #468 (the doorway fall). Tactical, not S4:
#466 (Ravenous Eater textures, owner says ours), #467 (running in place at
the corridor mouth), #465 (panel fill — POST-campaign only).
Read `docs/ISSUES.md` #464 in full first. Compressed state:
## 5. Owner-owed
- **Pinned pose (owner, 2026-09-03 22:04):**
`/teleloc F4180113 39.502899 19.832422 180.976700 1 0 0 0`, default camera
distance, tilted slightly UP. Scripted reproduction:
`tools/overhaul-selfgate/route-464-tilt3.txt`, frame `01-neg160`
(eye z 182.61, pitch 4°) = ARTIFACT; frame `02-neg240` (eye z 182.32) =
clean. Run: `logs/selfgate-20260903-225434-464-tilt3`. Owner's acdream
screenshot and retail screenshot are in the issue's history; the retail
capture at this pose is `oh-capture/cathedral-stair-arch.{walk,alphadepth,pmverts}.log`
(retail shows a SOLID far face above the arch).
- **Symptom:** above and around the bottom arch the hall's interior (cut-off
columns, vault, an unsealed pink quad) draws where retail shows solid wall.
- **Proven EQUAL to retail at this pose:** camera cell and eye (four probe
rounds, `ACDREAM_PROBE_FLAP=1` + `ACDREAM_PROBE_FACILITY_STAIRS=1`: root
0x114, eye inside, sweep uncontacted); the read-only decomp investigation
(`464-camera-investigation.md`: eleven sweep/root differences, each
unreachable here); the admission set (retail's walk log = our cells/groups/
order exactly); the punch/seal EVENT stream (16 `PM mode=1` punches, 8
seals, counter 8 — the PM/PC gate PASSES at this pose); the punch VERTICES
(retail `pmverts` capture vs our dump: 16 attempts, vertex-identical; retail
rejects 12/16 by its ±12 rule, so do we); clip-plane overflow (none, 35
edges per view); the delayed-alpha draws (skipping ALL of them = identical
frame; the piers are opaque); the interior Z clear (skipping it = identical
frame); the degrade level (`GfxObjDegradeInfo::get_degrade` @0x0051e4b0
gives level 0 in both clients at 20 m).
- **Source localized 2026-09-03 23:19 by env-gated draw skips (worktree
`464-ab`, `AB_SKIP_BLDS=F418000A`):** skipping the HALL BUILDING'S SHELL
(model `0x01001FB3`, building `F418000A`) removes the hanging pieces and the
frame matches retail. Skipping cell f3180105, the far-block shells
f3170034/f317003d, cell f4180104, the tower shell 0x01001FB7, corridor cell
0x109, or ALL hall cells does NOT (with 0x109 or the hall skipped the pieces
persist over SKY). So the pieces are the hall shell's own geometry above/
beside the corridor that cell 0x109's vault (emitPos=True, z 187.2190.7)
should hide, and 0x109 contributes nothing to those pixels in our frame.
- **The remaining question, three candidates:** (1) 0x109's vault polygons
are never drawn at those pixels (the walk or the exit-view clip drops them
where retail keeps them); (2) they are drawn but the shell is nearer in
depth than believed; (3) the bound depth state at the shell draw is not the
declared Test/Write/Less (`EnvCellRenderer.Rhi.cs:113` vs
`WbDrawDispatcher.Rhi.cs:343`). Also unproven: that retail hides the pieces
at the SAME eye (the capture eye is 182.79 level; the artifact band is
~182.6 at 4° and gone 0.29 m lower).
- **Next step, the lead's own job, no owner needed once ACE is up: a
RenderDoc pixel history on the scripted artifact frame.** RenderDoc is NOT
installed (`renderdoccmd` absent). Plan: install RenderDoc (Vulkan capture
is supported); launch the client under `renderdoccmd capture` with the same
arguments the self-gate runner uses (`--session-config
tools/overhaul-selfgate/session.json`, `ACDREAM_SELFGATE_PASS=testpassword`,
`ACDREAM_UI_PROBE_SCRIPT=<route-464-tilt3.txt>`, artifact dir env); when the
route reaches frame `01-neg160` trigger a capture through RenderDoc's
target-control API (python `renderdoc` module: `CreateTargetControl`
`TriggerCapture(1)`; the route's `sleep` before the screenshot gives the
window) — or add a `sleep` and trigger by wall clock; then open the `.rdc`
with the python module (`OpenCaptureFile``OpenCapture`
`ReplayController.PixelHistory(texture, x, y, ...)`) at a pixel above the
arch (in the 1760×990 frame the pieces sit in the upper-middle band; pick
from `464-tilt3-01-neg160.png`). The history lists every draw touching the
pixel with its depth value and pass/fail. Candidate (1) shows as no draw
from 0x109 at all; (2) as a 0x109 draw that failed the depth test against
the shell's value; (3) as a shell draw with a depth state other than Less
or with writes off. Map draw IDs back to cells via the walk transcript
(`ACDREAM_DUMP_WALK_TRANSCRIPT=1`) or RenderDoc's debug markers if present.
Fallback without RenderDoc: a per-frame probe printing which of 0x109's
polygons `0x0`/`0x1` survive admission/clip and the depth the shell writes
(about a day). Owner alternative: a retail tilt sweep through the band at
the pinned pose.
- **Fix rule:** whatever the cause, the fix must follow a quoted retail rule
from the decomp, not a patch at the symptom; if anything deviates it gets a
register row. #464 blocks G3 (zoom is a named criterion of the cathedral
matrix row). It is scheduled AHEAD of S4-c2's landing gate but does not
block S4-c2's implementation. When fixed, promote the two #464 replays
(sweep stops on the pier; walk from root 0x114 floods 114/113/112) into
InstalledDat pins.
- **Related, not #464:** #467 (character runs in place at the corridor mouth;
movement/collision; outside the campaign); the "running down the stairs"
artifact is a transient of #464 (`logs/selfgate-20260903-211930-464-run`
frame 22).
- **Post-campaign:** #465 panel fill (paint unreachable interior portal
polygons opaque to beat retail's seam leak) — deferred until G4, retail
mode off, registered, A/B sweep acceptance. Never start it mid-campaign.
1. Review the four comment corrections in `766f9e749`.
2. Double-check the provisional verdicts: #464 fixed (their own report + the
lead's route), the S3-closed self-gate, and G3 when the lead has run it.
3. The G3 rows only they can run (§4.2).
## 5. Open question: the Holtburg doorway frame (before trusting any self-gate there)
## 6. Tooling and gotchas (all paid for)
> **RESOLVED 2026-09-04 08:40 — not a render question.** The probe run `logs/selfgate-20260904-063313-hd-probe` shows the player seated in the interior cell at a floorless point and FALLING (z 96 → 20 m); the frame is the terrain seen from below. Filed as #468 (placement, tactical). route-g3b pose 15 now teleports to the good run's outdoor standing point. The text below is the pre-resolution record.
`tools/overhaul-selfgate/route-g3b.txt` frame 15 (`holtburg-doorway`,
`/teleloc A9B4013F 133.603592 13.391837 96.330009 …`): the landed build's runs
`logs/selfgate-20260903-234030-s4c1-landed-g3b` and `…-235044-s4c1-landed-g3b2`
both show an empty plane under fog instead of the village; the S3-state run
`logs/selfgate-20260903-165634-g3b` shows the village. Log read: the server
snaps y 13.39→17.39 in every run; the CLIENT then seated the player in the
house-interior cell `0xA9B4013F` at (134.07, 17.36) in the new runs versus the
outdoor cell `0xA9B40029` at (133.60, 17.39) in the old one (0.46 m apart on
the threshold) → the frame roots indoors with the eye outside. Read as a
placement boundary at the doorway, not a draw change (chunk 1 touched no
placement code). The pre-S4 control (`s3-review-fix/logs/selfgate-20260904-042324-pre-s4-g3b`,
build at `6575cfcee`) produced 0 frames: the login reveal at 0xA9B40176 never
went visible (#462 class) and the process exited 0xE0434352 after the graceful
logout (#461 class). **Owed:** with ACE up, run route-g3b on the landed tip
twice and on the pre-S4 build once
(`pwsh -File tools/overhaul-selfgate/run-selfgate.ps1 -Label <l> -Route ./tools/overhaul-selfgate/route-g3b.txt`
from the respective worktree; it refuses to start beside any AcDream.App;
runs are logged under `logs/selfgate-<stamp>-<label>/`, screenshots under
`artifacts/screenshots/`, and `client.log` carries the `live: teleport
materialized - snapped to <…> cell=…` line). If the cell flips between runs
at the same requested pose, file it as a placement issue (not the campaign's)
and change the route's pose 0.5 m outward so the gate frame is deterministic.
## 6. Owner-owed items (ask, do not wait silently)
1. Start ACE (nothing connected runs without it).
2. Review the four comment corrections in `766f9e749` (the lead's own edit
after the barred third round).
3. #464: either let the lead run RenderDoc (preferred) or do the retail tilt
sweep at the pinned pose.
4. Double-check the provisional G3 pre-run rows and the S3-closed self-gate
(all PNGs under `logs/selfgate-20260903-16*`, `…-234934-s4c1-landed-route2`,
`…-235044-s4c1-landed-g3b2`).
5. Matrix rows only the owner can run: the cathedral wall actor (two clients),
the exterior ramp (no coordinates recorded), Tusker, two ordinary dungeons.
6. Before G4: fixes for #460 (windowless shutdown hang after an aborted
script), #461 (crash on a late motion update after logout), #462
(intermittent interior login reveal stall), #463 (soak turn-sample
artifact). #466 (Ravenous Eater textures, `/create 35121`, owner says it is
ours) and #467 are tactical, outside the campaign.
## 7. Tooling and gotchas the previous sessions paid for
- **Self-gate kit** `tools/overhaul-selfgate/`: `run-selfgate.ps1` (pwsh 7
only), `session.json` (direct login, no select screen; `plugins: []`),
routes `route.txt` (4 poses incl. `04-holtburg-terrain-leak`),
`route-g3.txt` (13 matrix shots), `route-g3b.txt` (4 capture poses),
`route-g3c.txt` (Nanto ×3, 300 s wait), `route-464-*.txt`. Verbs: `command`,
`wait world-visible <ms>`, `sleep`, `screenshot <name> <ms>`, `input
press|down|up <InputAction>`, `mouselook <dx> <dy>` (negative dy = look up),
`close-client`. A probe `wait` that times out ABORTS the script so
`close-client` never runs (#460): give cold regions 300 s. Pixel diff:
`py scratchpad/selfgate-diff4.py <run> [<baseline>]` (PIL) — the sheet
approach; Facility left-wall mean RGB ≈ (79,20,25) = panels present.
- **Interactive owner launch:**
`$env:ACDREAM_SELFGATE_PASS="testpassword"; & ./src/AcDream.App/bin/Release/net10.0/AcDream.App.exe --session-config tools/overhaul-selfgate/session.json`
(add `ACDREAM_PROBE_FLAP=1` / `ACDREAM_PROBE_FACILITY_STAIRS=1` /
`ACDREAM_DUMP_WALK_TRANSCRIPT=1` as needed; the transcript log grows to
millions of lines in minutes).
- **Vulkan validation:** the client never enables layers; force
`VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation`,
`VK_LOADER_LAYERS_ENABLE=*validation*`,
`VK_LAYER_DEBUG_ACTION=VK_DBG_LAYER_ACTION_LOG_MSG`,
`VK_LAYER_REPORT_FLAGS=error,warn,perf`, `VK_LAYER_LOG_FILENAME=<file>`.
Zero errors at the S3 tip after #459; ten pre-existing
`WARNING-Shader-OutputNotConsumed` perf warnings remain.
- **Soak:** `tools/run-connected-r6-soak.ps1 -SkipBuild -PreparedAssetPath
"$env:USERPROFILE\Documents\Asheron's Call\acdream.pak"` (needs
`src/AcDream.Cli` built; refuses if the binary stamp ≠ checked-out commit —
do not commit between build and soak; `-Repository <worktree>` for A/B).
An RDP session flattens every destination to ~31 ms; compare only within
one session type (check `VideoControllers` in the report) and judge the
`stationary` phase only.
- **Retail capture kit** `tools/walk-oracle/oh/` (recon first; walk / parts /
alpha-depth / pmverts / blockcheck / blockset templates; `oh-run-capture.ps1
-Script <template> -Log <abs path> -Frames N`; pass `-Log` as
`"${L}${log}"`, a bash `\$log` collapses). cdb: `qd` only top-level after
fall-through; `poi()` inside `.if` is sign-extended → use `dwo()`; attach is
exclusive; the 5th `F` marker is the detach frame.
- **Agents:** provision worktrees yourself (`git worktree add --detach <path>
<sha>`); `isolation:'worktree'` has started from the WRONG base. Workflow
scripts must be LF-only with no unescaped backticks. Every new pin needs a
mutation check pasted into the commit body; IL-offset "order" pins are not
pins. A contract must QUOTE decomp predicates, never paraphrase (the ±12
inversion). Grep-verify every sentence of a contract before dispatch: three
of yesterday's review findings were the lead's own prescribed comments.
- **Bash on this box:** `py` not `python`; heredocs collapse `\\`; the
harness appends `&& pwd -P` to the last line (never end on a heredoc
terminator); `grep -c` with zero matches exits 1 and kills `&&` chains;
cp1252 console → `PYTHONIOENCODING=utf-8`.
- **Self-gate kit** `tools/overhaul-selfgate/`: `run-selfgate.ps1` (pwsh 7;
refuses to start beside any `AcDream.App`; records HEAD and dirty state;
`-TimeoutSeconds N`), `session.json` (direct login; `plugins: []`), routes
`route.txt` (4 poses incl. the Holtburg hill), `route-g3.txt`, `route-g3b.txt`,
`route-g3c.txt`, `route-464-tilt3.txt` (the #464 scripted tilt),
`route-holtburg-doorway-probe.txt`. Verbs: `command`, `wait world-visible <ms>`,
`sleep`, `screenshot <name> <ms>`, `input press|down|up <InputAction>`,
`mouselook <dx> <dy>` (negative dy = look up), `close-client`. A `wait` that
times out ABORTS the script so `close-client` never runs (#460): cold regions
get 300 s. Runs land in `logs/selfgate-<stamp>-<label>/` with
`artifacts/screenshots/*.png` and `client.log` (`live: teleport materialized -
snapped to <…> cell=…` is the placement line). Read PNGs with the Read tool.
- **Probes:** `ACDREAM_PROBE_FLAP=1` (`[flap-cam]` root/viewerCell/playerCell/
eye per frame; `[flap-sweep]`), `ACDREAM_PROBE_FACILITY_STAIRS=1`,
`ACDREAM_PROBE_TELEPORT=1` (`[tp-probe]`), `ACDREAM_PROBE_PLACEMENT_FAIL=1`,
`ACDREAM_DUMP_WALK_TRANSCRIPT=1` (millions of lines in minutes — short runs
only). Every flag: `docs/launch-options.md`.
- **Interactive owner launch:** `$env:ACDREAM_SELFGATE_PASS="testpassword"; & ./src/AcDream.App/bin/Release/net10.0/AcDream.App.exe --session-config tools/overhaul-selfgate/session.json`.
- **Vulkan validation:** force `VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation`,
`VK_LOADER_LAYERS_ENABLE=*validation*`, `VK_LAYER_DEBUG_ACTION=VK_DBG_LAYER_ACTION_LOG_MSG`,
`VK_LAYER_REPORT_FLAGS=error,warn,perf`, `VK_LAYER_LOG_FILENAME=<file>`; zero
errors at the S3 tip; ten pre-existing `OutputNotConsumed` perf warnings.
- **ACE session:** a hard-killed client leaves the session logged in ~3 min
(relaunch fails with exit 29); graceful close clears in seconds.
- **Two App tests fail only in Debug** (#457, IL-offset pins); gates run
Release.
(relaunch fails with exit 29); graceful close clears in seconds. A crashed
control run (`0xE0434352`) counts as hard-killed.
- **Retail capture kit** `tools/walk-oracle/oh/` (recon first; walk / parts /
alpha-depth / pmverts / blockcheck templates; only the 2013 exe pairs; cdb
`.if` sign-extends `poi()` → use `dwo()`; `qd` only top-level).
- **Agents:** provision worktrees yourself (`git worktree add --detach`);
`isolation:'worktree'` has started from the wrong base. Every pin needs a
mutation check pasted in the commit body. Contracts QUOTE decomp predicates
(the ±12 inversion was a paraphrase). Grep-verify every sentence of a
contract before dispatch. The Workflow tool needs the owner's opt-in; the
plain Agent tool works without it.
- **Bash on this box:** `py` not `python`; a multi-line python heredoc with
many quotes broke bash's parser today — write the script to the scratchpad
with the Write tool and run `py <file>`; heredocs collapse `\\`; never end
a command on a heredoc terminator; `grep -c` with zero matches exits 1 and
kills `&&` chains; cp1252 console → `PYTHONIOENCODING=utf-8`; the Bash tool
timeout maxes at 10 min → one self-gate run per background command.
- **Two App tests fail only in Debug** (#457); gates run Release.
## 8. Paste-prompt for the new agent
## 7. Paste-prompt for the new agent
```
Work in the worktree C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-blackburn-5333f0
(branch claude/campaign-w-retail-frame-walk). You are taking over Campaign OVERHAUL v2 mid-slice.
Read, in this order, and then tell me the summary you formed before acting:
1. docs/research/2026-09-01-overhaul/2026-09-04-s4-handoff.md (this hand-off; its §0 lists the rest of the read order).
2. CLAUDE.md, then docs/plans/2026-09-01-campaign-overhaul-world-solidity.md §13 (the S3 and S4 row tails).
1. docs/research/2026-09-01-overhaul/2026-09-04-s4-handoff.md (the hand-off; its §0 lists the rest).
2. CLAUDE.md, then docs/plans/2026-09-01-campaign-overhaul-world-solidity.md §13 (the S4 row tail).
3. claude-memory/project_overhaul_campaign.md "Current".
Then check the state of the S4 chunk 2 implementer per the hand-off's §3, report what landed / what is in flight / what you propose next, and continue under the campaign goal: drive the plan until the renderer is solid and G4 passes; never merge to main before G4; the §5 working model (you write each bounded chunk contract, Sonnet implements, you verify every claim against the named retail decomp and the paired binary, review lenses per round, you commit, ledger current; a chunk needing a third fix round stops and is written up); self-gate with the graphical client (Release, build green first, never beside a running client, close your own gracefully) and record PASS/FAIL with PNG paths — provisional until I look; stop only for a third fix round, a retail fact that cannot be recovered statically, or anything destructive or outside the plan; never reset/checkout--/clean/stash; never more than five agents in one step. ACE may be down — tell me if it is.
4. docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md §8, §11, §11.1.
Then check the S4 chunk 2 fixer's state per the hand-off's §3 and report: what landed, what is
in flight, what you propose next. Continue under the campaign goal: drive the plan until the
renderer is solid and G4 passes; never merge to main before G4; the §5 model (you write each
bounded chunk contract, Sonnet implements, you verify every claim against the named retail decomp
and the paired binary, review lenses per round, you commit, ledger current; a chunk needing a
third fix round stops and is written up; every deviation gets a register row in the same commit);
self-gate with the graphical client (Release, build green first, never beside a running client,
one run per background command, close your own gracefully) and record PASS/FAIL with PNG paths —
provisional until I look; stop only for a third fix round, a retail fact that cannot be recovered
statically, or anything destructive or outside the plan; never reset/checkout--/clean/stash;
never more than five agents in one step. Check whether ACE is up (UDP 9000) and whether a client
is running before launching anything, and tell me.
```