docs(overhaul): capture retail projection mode and contract replay diagnosis

This commit is contained in:
Erik 2026-09-05 07:00:53 +02:00
parent 7c7ccc6252
commit 3f5ca9ff4f
10 changed files with 5999 additions and 3 deletions

View file

@ -74,6 +74,17 @@ plus `OUTSIDE` contracts the test-only EC multiplicity correction and classifies
e229 under existing AD-118. Do not change production, normalize the fixture,
or add a KnownFailure before this fact is observed. Packet §38 is authoritative.
**2026-09-05 owner capture:** the new same-stairwell frame proves e229 is
resident and rejected in all seven views; its tilt differs from the historical
fixture. A follow-up read proves `newmethod=1`, so retail uses
`PrimD3DRender::ScreenToViewTransform`; the test replay instead uses the legacy
ray formula with a different screen center. The capture blocker is removed.
Status is **IN-PROGRESS** under packet §39's test-only projection diagnostic.
Do not call the old mismatch an accepted x87 boundary until that experiment
is complete. Evidence: `oh-capture/cathedral-stair-arch-e229.combined-r1.log`
and `cathedral-stair-arch-e229.projection-mode.log`.
## #471 — Production walk-ordered building detail was classified but never rendered
**Status:** DONE — fixed by Campaign OVERHAUL v2 S5-c4 at `03a108ffa`

View file

@ -216,7 +216,7 @@ readiness/requeue adaptation. See
| AD-102 | **Filed 2026-08-15 at Campaign CC slice CC4 (the Heritage page's Viamontian button and the Town page's Sanamar button).** Retail gates BOTH controls behind `CPlayerSystem::AccountHasThroneOfDestiny`: `gmCGHeritagePage::ListenToElementMessage @ 0x00483860` shows `MakeToDWarningDialog` instead of selecting Viamontian (element `0x100003c3`) for a non-ToD account, and `gmCGTownPage::ListenToElementMessage @ 0x0047c480` does the same for Sanamar (element `0x1000040b`, `startArea` index 3 — also the reason `CharGenState::RandomizeStartArea`'s ToD-aware `RandInt(3 or 4)` bound exists). acdream's `ChargenOptions` (CC1) carries no account/DLC-ownership signal anywhere in the model, so both controls ship WITHOUT the gate — every installed heritage/town in `Options.HeritagesById`/`Options.StarterAreas` is always selectable, matching what a ToD-owning account would see. | `src/AcDream.App/UI/Layout/CharacterCreationHeritagePage.cs` (`HeritageByButtonId[0x100003C3u]`); `src/AcDream.App/UI/Layout/CharacterCreationTownPage.cs` (`StartAreaByButtonId[0x1000040Bu]`, `Randomize`) | ACE's server-side `CharacterCreate` handler never checks ToD ownership either (the field is purely a retail-client UI gate), so accepting the selection unconditionally never produces a request the emulator would reject; adding an account-ownership model to CC1's DAT-only `ChargenOptions` is out of this slice's scope and would need its own design (where does the "ToD owned" bit come from — account service, launcher config, a new env flag?). | None observable against ACE. A future retail-parity gate that specifically checks "does a non-ToD account get warned off Viamontian/Sanamar" will fail until an account-ownership signal exists to gate on. | `gmCGHeritagePage::ListenToElementMessage @ 0x00483860`; `gmCGTownPage::ListenToElementMessage @ 0x0047c480`; `gmCGTownPage::SetTown @ 0x0047c360`; `CharGenState::RandomizeStartArea` (DoRandom case 4, `RandInt(hasToD ? 4 : 3)`) |
| AD-99 | **Filed 2026-08-15 at Campaign LA gate round 2 finding 1 (character-select Exit button).** On a confirmed Exit, acdream closes the client through the existing graceful window-close path (`d.Window.Close`, the same seam `GameplayInputCommandController`'s in-world Escape fallback already uses) instead of retail's real post-confirm behavior: `RecvNotice_CloseDialog`'s case-1 arm queues UI mode `0x10000009`, which `gmEpilogueUI::Register` claims — a brief epilogue/farewell screen — before the process actually terminates. The confirmation dialog itself (`MakeConfirmExitDialog`, its exact `ID_CharacterManagement_ConfirmExit` text, and the `m_confirmExitDialogContext != 0` re-entry guard) IS ported faithfully; only the post-confirm destination differs, the same shape as AD-74's Options-panel exit. | `src/AcDream.App/UI/Layout/CharacterManagementUiController.cs` (`RequestExit`); `src/AcDream.App/UI/RetailUiRuntime.cs` (`CharacterSelectionRuntimeBindings.RequestExit`); `src/AcDream.App/Composition/InteractionRetainedUiComposition.cs` (`d.Window.Close` binding) | acdream has no `gmEpilogueUI` port (out of scope this round); reusing the ONE existing graceful-shutdown seam keeps `disconnected`/`exited` status events firing through `GameWindow.OnClosing``CompleteShutdown` rather than inventing a second shutdown path, per explicit direction for this finding. | A user confirming Exit sees the window close immediately instead of retail's brief epilogue screen; a future feature wanting to reproduce that screen (or an intermediate "logged off, returned to character select" state) has no seam yet — same gap class as AD-44. | `gmCharacterManagementUI::MakeConfirmExitDialog @0x004ed250`; `RecvNotice_CloseDialog @0x004ed760` case 1; `gmEpilogueUI::Register(0x10000009)` @0x0047a680; `gmCharacterManagementUI::OnAction @0x004ed410` (Escape key, unported — button-only this round) |
| AD-113 | **Filed 2026-08-25 at Campaign CT slice CT-GF1 (client-wide retained-UI ancestor clip).** Porting retail's `UIRegion::DrawHere @0x0069FA30` ancestor-clip intersection (an element's screen rect is intersected against the FULL inherited clip-rect chain and the subtree is skipped when the intersection is empty — the `var_24` gate @0x0069FB8E) as `UiElement.ClipsChildren`'s new client-wide default (true, threaded through the pre-existing `UiRenderContext.PushClip`/`PopClip`) needed one deliberate opt-out: retail spawns a menu's dropdown popup as a SEPARATE top-level region (`UIElement_Menu::MakePopup`), clipped only by the screen, while acdream's `UiMenu` draws its popup INLINE from the owning button in a second traversal (`OnDrawOverlay`, pre-existing, "regardless of this element's position in the tree" by its own doc comment). Without an escape, the new ancestor clip would wrongly cut off a popup that legitimately extends outside its own (possibly short) owning window — e.g. a channel dropdown opened upward past a short chat window's top edge. `UiElement.ExpandsClipForPopup` (default false) resets the accumulated clip to the full CANVAS rect (0,0,ScreenSize) — SCREEN-clipped, not truly unbounded, matching retail's own popup region (`UIElement_Menu::MakePopup` spawns a top-level region bounded by the screen) — for exactly the `OnDrawOverlay` call of an opted-in element (`UiRenderContext.PushClipUnbounded`, sharing the existing clip stack; corrected from an earlier `null`/unbounded clip at the CT-GF1 fix round); `UiMenu` overrides it true, paired with `ClipsChildren => false` so its own out-of-bounds `OnHitTest` union (the popup occupies `ly < 0` or `ly >= Height` depending on open direction) stays reachable through the same early-bounds gate that now defaults on for every other element. | `src/AcDream.App/UI/UiElement.cs` (`ClipsChildren`, `ExpandsClipForPopup`, `DrawOverlays`); `src/AcDream.App/UI/UiRenderContext.cs` (`PushClipUnbounded`); `src/AcDream.App/UI/UiMenu.cs` (the two overrides) | The popup is the ONLY overlay-drawing widget in the tree today (grep-confirmed: exactly one `OnDrawOverlay` override client-wide), and it already renders on top of the whole UI by construction (the overlay pass beats even rect backgrounds), so exempting it from the ancestor clip matches its existing "regardless of tree position" contract rather than introducing new behavior. | A future `OnDrawOverlay` override that is NOT a screen-anchored popup (e.g. an in-place highlight meant to stay window-clipped) would silently escape every ancestor's clip if it left `ExpandsClipForPopup` at its default; the opt-in default direction makes that the exception rather than the rule, but a widget that WANTS window-clipped overlay content has no dedicated seam beyond simply not overriding the escape. | `UIRegion::DrawHere @0x0069FA30`; `UIElement_Menu::MakePopup`; the register's own AP-201 retirement note (the FIRST `ClipsChildren`/`PushClip` port, for `UiScrollablePanel`'s viewport) |
| AD-118 | **Filed 2026-09-03 at Campaign OVERHAUL v2 S3 (docs/ISSUES.md #458, resolved).** The walk's portal-view EDGE PLANES are built from acdream's own float projection (`WalkCopyView` on `IWalkRayCaster`'s unprojected rays; the replay context's `Matrix4x4` view-proj), while retail builds them in `Render::copy_view @0x0054dfc0` from D3D-transformed screen points under x87 arithmetic. The planes agree to about 0.5 % (measured live at the Holtburg doorway: the fourth door-edge plane's clip height at the ring-21 block `a9c9` is 300.4/310.2 m in retail vs 298.8/308.5 m here — a slope ratio of 0.05104 vs 0.05042, roughly 0.35 px of projected door-vertex position at 720p), which is invisible everywhere except at a block/cell corner that sits within that margin of a plane: there `Render::block_check`'s four-corner unanimity test can flip PartiallyInside↔Outside for a far LOD block (one corner inside for us, outside for retail), admitting or skipping a whole distant land block retail decides the other way. | `src/AcDream.App/Rendering/Walk/WalkCopyView.cs` (per-edge plane build); `src/AcDream.App/Rendering/Walk/WalkVisibilityMath.cs` (`FillClipHeights`, `CornerPlaneCheck`, `BlockCheck`); `tests/AcDream.App.Tests/Rendering/Walk/WalkTraceReplay.cs` (the replay's projection) | Bit-exact agreement would require reproducing D3D's x87 vertex transform and `copy_view`'s exact rounding order; the algorithm, sentinels, loop shape, z slab padding and verdict logic are all ported verbatim and reproduce three of four capture poses exactly at the eight-kind transcript level. | A land block at ≥ 20 rings whose corner lies within ~0.5 % of a doorway edge plane may be drawn where retail skips it (or vice versa) — one far, low-LOD block, no known visible artifact; the `WalkTraceConformanceTests.Oh_doorway_still_first_frame_diff` row stays `KnownFailure` as the standing example. | `Render::copy_view @0x0054dfc0`; `Render::get_clip_height @0x0054cff0`; `Render::block_check @0x0054dc50`; `LScape::draw_check_blocks @0x00505f80` (the `if (esi_3 != 0)` residency gate and the per-view `block_check` call @0x005061df); captures `docs/research/2026-09-01-overhaul/oh-capture/holtburg-doorway-still.blockcheck.log` / `.blockset.log` |
| AD-118 | **ATTRIBUTION REOPENED 2026-09-05 (#472, S5 packet §39): live `newmethod=1` selects matrix-based rays while the replay implements the legacy branch. The earlier x87-only explanation below is not established until the mixed-projection harness defect is isolated; no production change or new accepted failure is implied.** **Filed 2026-09-03 at Campaign OVERHAUL v2 S3 (docs/ISSUES.md #458, resolved).** The walk's portal-view EDGE PLANES are built from acdream's own float projection (`WalkCopyView` on `IWalkRayCaster`'s unprojected rays; the replay context's `Matrix4x4` view-proj), while retail builds them in `Render::copy_view @0x0054dfc0` from D3D-transformed screen points under x87 arithmetic. The planes agree to about 0.5 % (measured live at the Holtburg doorway: the fourth door-edge plane's clip height at the ring-21 block `a9c9` is 300.4/310.2 m in retail vs 298.8/308.5 m here — a slope ratio of 0.05104 vs 0.05042, roughly 0.35 px of projected door-vertex position at 720p), which is invisible everywhere except at a block/cell corner that sits within that margin of a plane: there `Render::block_check`'s four-corner unanimity test can flip PartiallyInside↔Outside for a far LOD block (one corner inside for us, outside for retail), admitting or skipping a whole distant land block retail decides the other way. | `src/AcDream.App/Rendering/Walk/WalkCopyView.cs` (per-edge plane build); `src/AcDream.App/Rendering/Walk/WalkVisibilityMath.cs` (`FillClipHeights`, `CornerPlaneCheck`, `BlockCheck`); `tests/AcDream.App.Tests/Rendering/Walk/WalkTraceReplay.cs` (the replay's projection) | Bit-exact agreement would require reproducing D3D's x87 vertex transform and `copy_view`'s exact rounding order; the algorithm, sentinels, loop shape, z slab padding and verdict logic are all ported verbatim and reproduce three of four capture poses exactly at the eight-kind transcript level. | A land block at ≥ 20 rings whose corner lies within ~0.5 % of a doorway edge plane may be drawn where retail skips it (or vice versa) — one far, low-LOD block, no known visible artifact; the `WalkTraceConformanceTests.Oh_doorway_still_first_frame_diff` row stays `KnownFailure` as the standing example. | `Render::copy_view @0x0054dfc0`; `Render::get_clip_height @0x0054cff0`; `Render::block_check @0x0054dc50`; `LScape::draw_check_blocks @0x00505f80` (the `if (esi_3 != 0)` residency gate and the per-view `block_check` call @0x005061df); captures `docs/research/2026-09-01-overhaul/oh-capture/holtburg-doorway-still.blockcheck.log` / `.blockset.log` |
---

View file

@ -696,7 +696,7 @@ Update immediately when a slice changes state. Chat is not the ledger.
| S5-#470 | **LANDED + REVIEW-CLOSED 2026-09-05; LEAD GRAPHICAL A/B PROVISIONAL PASS.** Campaign implementation stack `15a796c3a` -> `7506e5f14` -> `b333edb4f`; route `19b44e5e3`; reviewed scratch `51f974da4` -> `2cad9c84` -> `98c004aa7`; packet §§2730. | G4 UNPASSED | Retail/behavior pass 2/10 and production pass 4/10 closed the two evidence-only findings. Fresh campaign Release 0W/0E and focused 48/48; exact scratch hermetic 16,976/16,976 and canonical InstalledDat 386/10/1, manifests 30/30. Pinned gate `logs/selfgate-20260905-032132-s5-470-pinned-shadow-ab-r1`: retail/off -> High -> retail/off, 3/3 PNGs, exit 0, graceful, no client; visual PASS provisional. The stale recipe-8 pre-route launch is excluded and recorded in §30. |
| S5-#469 | **LANDED + REVIEW-CLOSED 2026-09-05; LEAD GRAPHICAL TRANSITION PROVISIONAL PASS.** Contract `809887524`; reviewed scratch `c09b6cf0f`; campaign implementation `94ddde69a`; route `62efc72cb`; packet §§3132. | G4 UNPASSED | Retail/deviation pass 1/10 and production pass 2/10 both PASS with no finding. The two atmospheric vertex receivers keep retail's authored unnormalized `uLights` direction across every shadow gate; celestial direction remains for opt-in shadow/volumetric projection; IA-24 corrected in the same commit. Exact scratch: Release 0W/0E, focused 126/126, Vulkan 2/2, hermetic 16,983/16,983, InstalledDat 386/10/1. Fresh campaign Release 0W/0E, focused 82/82, Vulkan 2/2. Gate `logs/selfgate-20260905-040449-s5-469-lighting-transition-r1`: five PNGs, active 2,500-caster/four-cascade High rows, no near-black relight, exit 0/graceful, no client; visual PASS provisional. |
| S5-c5 | **CLOSED + LANDED 2026-09-05; LEAD GRAPHICAL SMOKE PROVISIONAL PASS.** Contract `b77989c32`; campaign `bf53e2ad6` -> `e625dc4e6` -> `1b7ee4e58`; reviewed scratch tip `158656f0d`; packet §§3335. | G4 UNPASSED | Retail/deletion pass 1/10 PASS. Production pass 2/10 found one static-field hole in the owner guard; fix round 1 reproduced both static-owner mutations, and production pass 3/10 PASS. Exact scratch hermetic 16,921/16,921, canonical InstalledDat 368/9/1, manifests 30/30. Fresh campaign Release 0W/0E, App 146/146, Core 8/8. A stale recipe-8 preflight is excluded; a non-destructive recipe-10 bake produced 2,237,865 keys with zero failures. Corrected gate `logs/selfgate-20260905-052130-s5-c5-landed-v10`: five PNGs, exit 0/graceful, no fatal/deleted-prefix match, no client left; geometry matches S5-c4, visual PASS provisional. |
| S5 | **STOPPED at C1a on #472's retail-live fact** — c1c5 plus #470/#469 landed, review-closed, and provisionally self-gated; closeout C1 evidence complete; C1a exact transcript attempt stopped clean; connected/performance C2 and G4 remain | G4 | Packet §§7 and 1238 are binding. C1 passed the literal offline matrix. C1a proved the stair transcript's two missing `EC:f4180106` tokens are a test-recorder multiplicity defect while the extra `LC/SC:e2290001` cannot be classified statically: retail may have had no resident e229 slot, or a resident slot may have failed `block_check`. Scratch returned clean with no commit/gate/client. One targeted retail blockset/blockcheck capture at the exact fixture pose unblocks the bounded test-only correction and geometry/membership witness. Never merge main before G4. |
| S5 | **IN FLIGHT: owner capture completed; C1b projection diagnostic contracted.** c1c5 plus #470/#469 landed, review-closed, and provisionally self-gated; C1 offline evidence complete; C1a remains stopped pending diagnostic result. | G4 | Packet §§7 and 1239 bind. New capture proves e229 resident+rejected at the current stairwell pose; follow-up `newmethod=1` exposes test replay's wrong legacy ray branch. C1b compares coherent captured-matrix projection/rays with baseline and all OH transcripts, without production or default-test changes. Then close C1a's recorder/geometry-hash witnesses, C2 and G4. Never merge main before G4. |
---

View file

@ -0,0 +1,41 @@
.logopen C:\Users\erikn\.codex\worktrees\742f\acdream\artifacts\overhaul-472-owner-capture\cathedral-stair-arch-e229.combined-r1.log
.sympath C:\Users\erikn\source\repos\acdream\refs
.reload /f acclient.exe
.time
x acclient!Render::portal_npnts
x acclient!Render::portal_vertex
dt acclient!DrawParms
x /t acclient!Render::bw
x /t acclient!Render::bh
x /t acclient!Render::xinvscale
x /t acclient!Render::yinvscale
x /t acclient!Render::tx
x /t acclient!Render::ty
x /t acclient!Render::vdst
dq acclient!Render::bw L1
dq acclient!Render::bh L1
dq acclient!Render::xinvscale L1
dq acclient!Render::yinvscale L1
dq acclient!Render::tx L1
dq acclient!Render::ty L1
dd acclient!Render::vdst L1
dd acclient!Render::znear L1
r $t0 = 0
r $t8 = 0
bp 00453aa0 "r $t0 = @$t0 + 1; .printf \"F %d\\n\", @$t0; .printf \"P %08x %08x %08x %08x %08x %08x %08x %08x\\n\", dwo(0081ef00+4), dwo(0081ef00+0x3c), dwo(0081ef00+0x40), dwo(0081ef00+0x44), dwo(0081ef00+8), dwo(0081ef00+0xc), dwo(0081ef00+0x10), dwo(0081ef00+0x14); .if (@$t0 < 2) { gc }"
bp 00505f80 ".if (@$t0 == 1) { .printf \"LSTATE width=%d xoff=%d yoff=%d loaded=%08x viewer=%08x\\n\", dwo(@ecx+4), dwo(@ecx+0x18), dwo(@ecx+0x1c), dwo(@ecx+0x10), dwo(@ecx+0x14); r $t1 = dwo(@ecx+4)*dwo(@ecx+4); r $t2 = poi(@ecx+8); r $t3 = 0; .while (@$t3 < @$t1) { r $t4 = poi(@$t2+@$t3*4); .if (@$t4 == 0) { .printf \"SLOT %d NULL\\n\", @$t3 } .else { .printf \"SLOT %d did=%08x side=%d\\n\", @$t3, dwo(@$t4+0x28), dwo(@$t4+0x48) }; r $t3 = @$t3+1 } }; gc"
bp 0054dc50 ".if ((@$t0 == 1) & (poi(@esp) == 0x005061e4)) { .if (dwo(@esi+0x28) == 0xe229ffff) { r $t8 = 1; .printf \"BC did=%08x gx=%d gy=%d view=%d np=%d max=%08x min=%08x\\n\", dwo(@esi+0x28), @ebx, @ebp, dwo(acclient!Render::portal_view_num), dwo(acclient!Render::portal_npnts), dwo(@esp+0x14), dwo(@esp+0x18); .echo W0; dd poi(@esp+4) L20; .echo W1; dd poi(@esp+8) L20; .echo E0; dd poi(@esp+0xc) L20; .echo E1; dd poi(@esp+0x10) L20; .echo VIEWER; dd acclient!Render::viewer_world_space L10; r $t5 = 0; r $t6 = poi(acclient!Render::portal_vertex); .while (@$t5 < dwo(acclient!Render::portal_npnts)) { .printf \"EDGE %d %08x %08x %08x %08x %08x %08x\\n\", @$t5, dwo(@$t6), dwo(@$t6+4), dwo(@$t6+8), dwo(@$t6+0xc), dwo(@$t6+0x10), dwo(@$t6+0x14); r $t5 = @$t5+1; r $t6 = @$t6+0x18 } } }; gc"
bp 005061e4 ".if (@$t8 == 1) { .printf \"BR ret=%d\\n\", @eax; r $t8 = 0 }; gc"
bp 005a4840 ".if (@$t0 == 1) { r $t10 = dwo(@ecx+0x60); .printf \"DC pv=%08x ov=%d n=%d:\", @ecx, dwo(@ecx+0x38), @$t10; r $t11 = poi(@ecx+0x50); r $t12 = 0; .while (@$t12 < @$t10) { .printf \" %08x\", dwo(poi(@$t11+@$t12*4)+0x28); r $t12 = @$t12+1 }; .printf \"\\n\" }; gc"
bp 005a5860 ".if (@$t0 == 1) { .printf \"DI %08x\\n\", dwo(poi(@esp+4)+0x28) }; gc"
bp 00506330 ".if (@$t0 == 1) { .echo LS }; gc"
bp 0059f2a0 ".if (@$t0 == 1) { .printf \"BLD %08x\\n\", dwo(poi(@esp+4)+0x4c) }; gc"
bp 0059f170 ".if (@$t0 == 1) { .printf \"EC %08x\\n\", dwo(poi(@esp+4)+0x28) }; gc"
bp 005a0760 ".if (@$t0 == 1) { .printf \"OC %08x\\n\", dwo(poi(@esp+4)+0x28) }; gc"
bp 0059f120 ".if (@$t0 == 1) { .printf \"LC %08x\\n\", dwo(poi(@esp+4)+0x28) }; gc"
bp 0059f140 ".if (@$t0 == 1) { .printf \"SC %08x\\n\", dwo(poi(@esp+4)+0x28) }; gc"
g
bc *
.echo ===DETACHING===
.logclose
qd

View file

@ -0,0 +1,16 @@
.logopen C:\Users\erikn\.codex\worktrees\742f\acdream\artifacts\overhaul-472-owner-capture\projection-mode.log
.sympath C:\Users\erikn\source\repos\acdream\refs
.reload /f acclient.exe
.time
dt acclient!RenderDevice
dt acclient!RenderDevice::GraphicsStatesType
u 0054e4d8 0054e525
r $t0 = 0
bp 00453aa0 "r $t0 = @$t0 + 1; .printf \"F %d\\n\", @$t0; .if (@$t0 < 2) { gc }"
bp 00505f80 ".if (@$t0 == 1) { .printf \"P %08x %08x %08x %08x %08x %08x %08x %08x\\n\", dwo(0081ef00+4), dwo(0081ef00+0x3c), dwo(0081ef00+0x40), dwo(0081ef00+0x44), dwo(0081ef00+8), dwo(0081ef00+0xc), dwo(0081ef00+0x10), dwo(0081ef00+0x14); .echo NEWMETHOD; dd 0081efe8 L1; .echo VIEWPORT; dd poi(0086f330)+0x8c L8; .echo WORLD_TO_VIEW; dd poi(0086f330)+0x108 L10; .echo VIEW_TO_CLIP; dd poi(0086f330)+0x148 L10; .echo FOV_NEAR_FAR; dd acclient!Render::fov L1; dd acclient!Render::znear L1; dd acclient!Render::zfar L1 }; gc"
g
bc *
.echo ===DETACHING===
.logclose
qd

View file

@ -0,0 +1,129 @@
Opened log file 'C:\Users\erikn\.codex\worktrees\742f\acdream\artifacts\overhaul-472-owner-capture\projection-mode.log'
0:018> .sympath C:\Users\erikn\source\repos\acdream\refs
Symbol search path is: C:\Users\erikn\source\repos\acdream\refs
Expanded Symbol search path is: c:\users\erikn\source\repos\acdream\refs
************* Path validation summary **************
Response Time (ms) Location
OK C:\Users\erikn\source\repos\acdream\refs
0:018> .reload /f acclient.exe
0:018> .time
Debug session time: Sat Sep 5 06:58:16.219 2026 (UTC + 2:00)
System Uptime: 1 days 2:14:49.020
Process Uptime: 0 days 0:09:37.156
Kernel time: 0 days 0:00:16.468
User time: 0 days 0:01:57.062
0:018> dt acclient!RenderDevice
+0x000 __VFN_table : Ptr32
=0086f330 render_device : (null)
+0x004 m_presentation : RenderDevicePresentation
+0x020 m_config : RenderDeviceConfig
+0x028 m_caps : RenderDeviceCaps
+0x058 m_displayInfo : RenderDeviceDisplayInfo
+0x08c m_viewportX : Uint4B
+0x090 m_viewportY : Uint4B
+0x094 m_viewportWidth : Uint4B
+0x098 m_viewportHeight : Uint4B
+0x09c m_RenderTargetWidth : Uint4B
+0x0a0 m_RenderTargetHeight : Uint4B
+0x0a4 m_DisplayAspectRatio : Float
+0x0a8 m_ViewportAspectRatio : Float
+0x0ac m_bOpenScene : Bool
+0x0ad m_bDeviceLost : Bool
+0x0b0 m_nFrameStamp : Uint4B
+0x0b4 m_pFrameBufferSurface : Ptr32 RenderSurface
+0x0b8 m_pDepthStencilSurface : Ptr32 RenderSurface
+0x0bc m_pRenderTarget : Ptr32 RenderSurface
+0x0c0 m_pDepthStencilTarget : Ptr32 RenderSurface
+0x0c4 m_WireframeMode : Bool
+0x0c5 m_ReverseCulling : Bool
+0x0c8 m_GState : RenderDevice::GraphicsStatesType
+0x2f8 m_pDebugFont : Ptr32 TextureBasedFont
+0x2fc m_DebugFontWidth : Uint4B
+0x300 m_DebugFontHeight : Uint4B
0:018> dt acclient!RenderDevice::GraphicsStatesType
+0x000 ModelToWorldMatrix : Matrix4
+0x040 WorldToViewMatrix : Matrix4
+0x080 ViewToClipMatrix : Matrix4
+0x0c0 AmbientLight : RGBAColor
+0x0d0 DistanceFogColor : RGBAColor
+0x0e0 DistanceFogNear : Float
+0x0e4 DistanceFogFar : Float
+0x0e8 DistantSpriteOpacityNear : Float
+0x0ec DistantSpriteOpacityRange : Float
+0x0f0 OpacityFogNearDistance : Float
+0x0f4 OpacityFogRange : Float
+0x0f8 pMPLightSource : Ptr32 RenderLight
+0x0fc pMPLightProjectorTexture : Ptr32 RenderTexture
+0x100 FFLightSources : SmartArray<RenderLight,1>
+0x10c ChangedFFLightSources : Bool
+0x110 FrameBufferBloomRGBAmount : RGBAColor
+0x120 PixelFilterTexCoords : [15] Vector4
+0x210 BSVLightOriginAndExtrusionOffset : Vector4
+0x220 FrameBufferViewportOffsetX : Float
+0x224 FrameBufferViewportOffsetY : Float
+0x228 FrameBufferViewportScaleX : Float
+0x22c FrameBufferViewportScaleY : Float
0:018> u 0054e4d8 0054e525
acclient!Render::copy_view+0x518:
0054e4d8 d95c0814 fstp dword ptr [eax+ecx+14h]
0054e4dc a1e8ef8100 mov eax,dword ptr [acclient!newmethod (0081efe8)]
0054e4e1 4f dec edi
0054e4e2 83f801 cmp eax,1
0054e4e5 7546 jne acclient!Render::copy_view+0x56d (0054e52d)
0054e4e7 85ff test edi,edi
0054e4e9 0f8c48010000 jl acclient!Render::copy_view+0x677 (0054e637)
0054e4ef 8d1c7f lea ebx,[edi+edi*2]
0054e4f2 8d0c7f lea ecx,[edi+edi*2]
0054e4f5 8d5701 lea edx,[edi+1]
0054e4f8 8d9c9cac000000 lea ebx,[esp+ebx*4+0ACh]
0054e4ff 8d2cce lea ebp,[esi+ecx*8]
0054e502 89542434 mov dword ptr [esp+34h],edx
0054e506 8b4504 mov eax,dword ptr [ebp+4]
0054e509 8b4d00 mov ecx,dword ptr [ebp]
0054e50c 50 push eax
0054e50d 51 push ecx
0054e50e 53 push ebx
0054e50f e82cc50400 call acclient!PrimD3DRender::ScreenToViewTransform (0059aa40)
0054e514 8b442440 mov eax,dword ptr [esp+40h]
0054e518 83c40c add esp,0Ch
0054e51b 83ed18 sub ebp,18h
0054e51e 83eb0c sub ebx,0Ch
0054e521 48 dec eax
0054e522 89442434 mov dword ptr [esp+34h],eax
0:018> r $t0 = 0
0:018> bp 00453aa0 "r $t0 = @$t0 + 1; .printf \"F %d\\n\", @$t0; .if (@$t0 < 2) { gc }"
0:018> bp 00505f80 ".if (@$t0 == 1) { .printf \"P %08x %08x %08x %08x %08x %08x %08x %08x\\n\", dwo(0081ef00+4), dwo(0081ef00+0x3c), dwo(0081ef00+0x40), dwo(0081ef00+0x44), dwo(0081ef00+8), dwo(0081ef00+0xc), dwo(0081ef00+0x10), dwo(0081ef00+0x14); .echo NEWMETHOD; dd 0081efe8 L1; .echo VIEWPORT; dd poi(0086f330)+0x8c L8; .echo WORLD_TO_VIEW; dd poi(0086f330)+0x108 L10; .echo VIEW_TO_CLIP; dd poi(0086f330)+0x148 L10; .echo FOV_NEAR_FAR; dd acclient!Render::fov L1; dd acclient!Render::znear L1; dd acclient!Render::zfar L1 }; gc"
0:018> g
F 1
P f4180114 421e02f8 4188a9d3 4337407e 3f7d4959 be14b29f 00000000 00000000
NEWMETHOD
0081efe8 00000001
VIEWPORT
00a64cd4 00000000 00000000 00000400 000002d0
00a64ce4 00000400 00000300 3faaaaab 3fb60b61
WORLD_TO_VIEW
00a64d50 3f800000 00000000 80000000 00000000
00a64d60 80000000 3f75341f be931f22 00000000
00a64d70 00000000 3e931f22 3f75341f 00000000
00a64d80 c21e02f8 c3346eaa 42112d76 3f800000
VIEW_TO_CLIP
00a64d90 3f854304 00000000 00000000 00000000
00a64da0 00000000 3fbd8723 00000000 00000000
00a64db0 00000000 00000000 3f8000d2 3f800000
00a64dc0 00000000 00000000 bdccce1d 00000000
FOV_NEAR_FAR
0081ec78 3f98104b
0081ec84 3dcccccd
0081ec88 457a0000
F 2
eax=17f2ed10 ebx=00000009 ecx=00a56488 edx=3e931f22 esi=00a56488 edi=009a09b0
eip=00453aa0 esp=001afe84 ebp=001aff74 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200202
acclient!SmartBox::RenderNormalMode:
00453aa0 a130f38600 mov eax,dword ptr [acclient!RenderDevice::render_device (0086f330)] ds:002b:0086f330=00a64c48
0:000> bc *
0:000> .echo ===DETACHING===
===DETACHING===
0:000> .logclose
Closing open log file C:\Users\erikn\.codex\worktrees\742f\acdream\artifacts\overhaul-472-owner-capture\projection-mode.log

View file

@ -0,0 +1,22 @@
.logopen C:\Users\erikn\.codex\worktrees\742f\acdream\artifacts\overhaul-472-owner-capture\recon-pose.log
.sympath C:\Users\erikn\source\repos\acdream\refs
.reload /f acclient.exe
.time
lmvm acclient
dt acclient!LScape
dt acclient!CLandBlock
dt acclient!DBObj
dt acclient!portal_view_type
dt acclient!view_type
x acclient!Render::*view*
x acclient!Render::*CY*
u 00506170 00506208
u 005a4a8d 005a4ad0
r $t0 = 0
bp 00453aa0 "r $t0 = @$t0 + 1; .printf \"F %d\\n\", @$t0; .printf \"P %08x %08x %08x %08x %08x %08x %08x %08x\\n\", dwo(0081ef00+4), dwo(0081ef00+0x3c), dwo(0081ef00+0x40), dwo(0081ef00+0x44), dwo(0081ef00+8), dwo(0081ef00+0xc), dwo(0081ef00+0x10), dwo(0081ef00+0x14); .if (@$t0 < 2) { gc }"
bp 005a4840 ".printf \"DC ov=%d n=%d\\n\", dwo(@ecx+0x38), dwo(@ecx+0x60); gc"
g
bc *
.echo ===DETACHING===
.logclose
qd

View file

@ -0,0 +1,287 @@
Opened log file 'C:\Users\erikn\.codex\worktrees\742f\acdream\artifacts\overhaul-472-owner-capture\recon-pose.log'
0:020> .sympath C:\Users\erikn\source\repos\acdream\refs
Symbol search path is: C:\Users\erikn\source\repos\acdream\refs
Expanded Symbol search path is: c:\users\erikn\source\repos\acdream\refs
************* Path validation summary **************
Response Time (ms) Location
OK C:\Users\erikn\source\repos\acdream\refs
0:020> .reload /f acclient.exe
0:020> .time
Debug session time: Sat Sep 5 06:52:12.954 2026 (UTC + 2:00)
System Uptime: 1 days 2:08:45.755
Process Uptime: 0 days 0:03:33.892
Kernel time: 0 days 0:00:11.765
User time: 0 days 0:01:30.468
0:020> lmvm acclient
start end module name
00400000 0096c000 acclient (private pdb symbols) c:\users\erikn\source\repos\acdream\refs\acclient.pdb
Loaded symbol image file: C:\Turbine\Asheron's Call\acclient.exe
Image path: C:\Turbine\Asheron's Call\acclient.exe
Image name: acclient.exe
Timestamp: Fri Sep 6 02:17:56 2013 (52291F34)
CheckSum: 0049D162
ImageSize: 0056C000
File version: 0.0.11.4186
Product version: 0.0.0.0
File flags: 2 (Mask 3F) Pre-release
File OS: 4 Unknown Win32
File type: 1.0 App
File date: 00000000.00000000
Translations: 0409.04b0
Information from resource tables:
CompanyName: Turbine, Inc.
ProductName: acclient
InternalName: acclient
OriginalFilename: acclient.exe
ProductVersion: 00.00.11.4186
FileVersion: 00.00.11.4186
FileDescription: acclient
LegalCopyright: Copyright © Turbine, Inc.
Comments: compiled Thu Sep 5 20:17:33 2013 : RETAIL
0:020> dt acclient!LScape
+0x000 mid_radius : Int4B
+0x004 mid_width : Int4B
+0x008 land_blocks : Ptr32 Ptr32 CLandBlock
+0x00c block_draw_list : Ptr32 Ptr32 CLandBlock
+0x010 loaded_cell_id : Uint4B
+0x014 viewer_cell_id : Uint4B
+0x018 viewer_b_xoff : Int4B
+0x01c viewer_b_yoff : Int4B
=0084194c min_ambient : Float
=00841770 ambient_level : Float
=0084176c ambient_color : RGBAUnion
=00841940 sunlight : AC1Legacy::Vector3
=00841768 sunlight_color : RGBAUnion
+0x020 sky : Ptr32 GameSky
=00841788 next_tick : Float
=00841790 next_light_tick : Float
=0081cbe9 weather_enabled : Bool
=0081cbe8 m_fFogEnabled : Bool
=00841798 m_fAlwaysDaylight : Bool
=00841799 m_override_enabled : Bool
=0084179c m_override_ambient_level : Float
=008417a0 m_override_fog_min : Float
=008417a4 m_override_fog_max : Float
=00841778 m_override_ambient_color : RGBAUnion
=00841774 m_override_fog_color : RGBAUnion
=008417a8 m_override_transition : Float
+0x024 landscape_detail_surface : Ptr32 CSurface
+0x028 environment_detail_surface : Ptr32 CSurface
+0x02c building_detail_surface : Ptr32 CSurface
+0x030 object_detail_surface : Ptr32 CSurface
0:020> dt acclient!CLandBlock
+0x000 __VFN_table : Ptr32
+0x004 m_dataCategory : Uint4B
+0x008 m_bLoaded : Bool
+0x010 m_timeStamp : Float
+0x018 m_pNext : Ptr32 DBObj
+0x01c m_pLast : Ptr32 DBObj
+0x020 m_pMaintainer : Ptr32 DBOCache
+0x024 m_numLinks : Int4B
+0x028 m_DID : IDClass<_tagDataID,32,0>
+0x02c m_AllowedInFreeList : Bool
+0x030 __VFN_table : Ptr32
+0x038 vertex_lighting : Ptr32 RGBColor
=00844ca8 land_uvs : [4] CVec2Duv
+0x03c trans_dir : LandDefs::Direction
+0x040 side_vertex_count : Int4B
+0x044 side_polygon_count : Int4B
+0x048 side_cell_count : Int4B
+0x04c water_type : LandDefs::WaterType
+0x050 height : Ptr32 UChar
+0x054 terrain : Ptr32 Uint2B
+0x058 vertex_array : CVertexArray
+0x080 polygons : Ptr32 CPolygon
+0x084 num_surface_strips : Uint4B
+0x088 surface_strips : Ptr32 CSurfaceTriStrips
+0x08c block_surface_index : Uint4B
+0x090 lcell : Ptr32 CLandCell
+0x094 SWtoNEcut : Ptr32 Int4B
+0x098 block_coord : SqCoord
+0x0a0 block_frame : Frame
+0x0e0 max_zval : Float
+0x0e4 min_zval : Float
+0x0e8 dyn_objs_init_done : Int4B
+0x0ec lbi_exists : Int4B
+0x0f0 dir : LandDefs::Direction
+0x0f4 closest : SqCoord
+0x0fc in_view : BoundingType
=00844acc use_encounter_info : Int4B
+0x100 lbi : Ptr32 CLandBlockInfo
+0x104 num_static_objects : Uint4B
+0x108 static_objects : DArray<CPhysicsObj *>
+0x118 num_buildings : Uint4B
+0x11c buildings : Ptr32 Ptr32 CBuildingObj
+0x120 stab_num : Uint4B
+0x124 stablist : Ptr32 Uint4B
+0x128 draw_array : Ptr32 Ptr32 CLandCell
+0x12c draw_array_size : Uint4B
0:020> dt acclient!DBObj
+0x000 __VFN_table : Ptr32
+0x004 m_dataCategory : Uint4B
+0x008 m_bLoaded : Bool
+0x010 m_timeStamp : Float
+0x018 m_pNext : Ptr32 DBObj
+0x01c m_pLast : Ptr32 DBObj
+0x020 m_pMaintainer : Ptr32 DBOCache
+0x024 m_numLinks : Int4B
+0x028 m_DID : IDClass<_tagDataID,32,0>
+0x02c m_AllowedInFreeList : Bool
0:020> dt acclient!portal_view_type
+0x000 portal : DArray<portal_info>
+0x010 view : view_type
+0x034 max_indist : Float
+0x038 view_count : Uint4B
+0x03c cell_view_done : Int4B
+0x040 view_timestamp : Int4B
+0x044 update_count : Int4B
0:020> dt acclient!view_type
+0x000 vertex_count_total : Uint4B
+0x004 poly : DArray<view_poly>
+0x014 vertex : DArray<view_vertex>
0:020> x acclient!Render::*view*
00846044 acclient!Render::portal_view = 0x009d4a90
008662dc acclient!Render::portal_view_num = 0n3
0081ef00 acclient!Render::viewer_pos = class Position
0086640c acclient!Render::viewer_world_space = struct DrawParms
0086b228 acclient!Render::viewer_lights = struct LightParms
0054b220 acclient!Render::Set3DView (int, int, int, int)
0054c250 acclient!Render::viewconeCheck (class CSphere *)
0054b400 acclient!Render::GetViewerBBox (class CSphere *, class AC1Legacy::Vector3 *, class AC1Legacy::Vector3 *)
0054dfc0 acclient!Render::copy_view (struct portal_view_type *, struct Vec2Dscreen **, unsigned int)
0054d0e0 acclient!Render::set_view (struct view_type *, int)
00694750 acclient!Render::SetupViewportInternal (void)
0054ef50 acclient!Render::set_default_view (void)
0054b9b0 acclient!Render::obj_view_set (void)
0054dc20 acclient!Render::update_viewpoint (class Frame *)
0054cdd0 acclient!Render::update_viewpoint (class Position *)
0054f070 acclient!Render::Set3DViewInternal (int, int, int, int)
0:020> x acclient!Render::*CY*
0:020> u 00506170 00506208
acclient!LScape::draw_check_blocks+0x1f0:
00506170 8e900000008b mov ss,word ptr [eax-75000000h]
00506176 57 push edi
00506177 088bc80fafcb or byte ptr [ebx-3450F038h],cl
0050617d 03cd add ecx,ebp
0050617f 8b348a mov esi,dword ptr [edx+ecx*4]
00506182 85f6 test esi,esi
00506184 7473 je acclient!LScape::draw_check_blocks+0x279 (005061f9)
00506186 8b8ee4000000 mov ecx,dword ptr [esi+0E4h]
0050618c 8b96e0000000 mov edx,dword ptr [esi+0E0h]
00506192 894c2420 mov dword ptr [esp+20h],ecx
00506196 40 inc eax
00506197 8d4bff lea ecx,[ebx-1]
0050619a 83e101 and ecx,1
0050619d 0fafc8 imul ecx,eax
005061a0 89542424 mov dword ptr [esp+24h],edx
005061a4 8b1580178400 mov edx,dword ptr [acclient!block_interval (00841780)]
005061aa 03cd add ecx,ebp
005061ac c1e107 shl ecx,7
005061af 03ca add ecx,edx
005061b1 8bd3 mov edx,ebx
005061b3 83e201 and edx,1
005061b6 0fafd0 imul edx,eax
005061b9 a180178400 mov eax,dword ptr [acclient!block_interval (00841780)]
005061be 03d5 add edx,ebp
005061c0 c1e207 shl edx,7
005061c3 03c2 add eax,edx
005061c5 8b542420 mov edx,dword ptr [esp+20h]
005061c9 52 push edx
005061ca 8b542428 mov edx,dword ptr [esp+28h]
005061ce 52 push edx
005061cf 8d9180000000 lea edx,[ecx+80h]
005061d5 52 push edx
005061d6 51 push ecx
005061d7 8d8880000000 lea ecx,[eax+80h]
005061dd 51 push ecx
005061de 50 push eax
005061df e86c7a0400 call acclient!Render::block_check (0054dc50)
005061e4 83c418 add esp,18h
005061e7 85c0 test eax,eax
005061e9 740e je acclient!LScape::draw_check_blocks+0x279 (005061f9)
005061eb 56 push esi
005061ec 8bcf mov ecx,edi
005061ee 8986fc000000 mov dword ptr [esi+0FCh],eax
005061f4 e8a7eeffff call acclient!LScape::landcell_check (005050a0)
005061f9 8b4704 mov eax,dword ptr [edi+4]
005061fc 45 inc ebp
005061fd 3be8 cmp ebp,eax
005061ff 0f8c70ffffff jl acclient!LScape::draw_check_blocks+0x1f5 (00506175)
00506205 8b4704 mov eax,dword ptr [edi+4]
00506208 43 inc ebx
0:020> u 005a4a8d 005a4ad0
acclient!PView::DrawCells+0x24d:
005a4a8d 8b8634010000 mov eax,dword ptr [esi+134h]
005a4a93 83c40c add esp,0Ch
005a4a96 85c0 test eax,eax
005a4a98 7505 jne acclient!PView::DrawCells+0x25f (005a4a9f)
005a4a9a 83c8ff or eax,0FFFFFFFFh
005a4a9d eb12 jmp acclient!PView::DrawCells+0x271 (005a4ab1)
005a4a9f 8b9638010000 mov edx,dword ptr [esi+138h]
005a4aa5 8b4482fc mov eax,dword ptr [edx+eax*4-4]
005a4aa9 8b4038 mov eax,dword ptr [eax+38h]
005a4aac 6685c0 test ax,ax
005a4aaf 7621 jbe acclient!PView::DrawCells+0x292 (005a4ad2)
005a4ab1 33ff xor edi,edi
005a4ab3 0fb7d8 movzx ebx,ax
005a4ab6 57 push edi
005a4ab7 8bce mov ecx,esi
005a4ab9 e87279f8ff call acclient!CEnvCell::setup_view (0052c430)
005a4abe 8b0d30f38600 mov ecx,dword ptr [acclient!RenderDevice::render_device (0086f330)]
005a4ac4 8b11 mov edx,dword ptr [ecx]
005a4ac6 56 push esi
005a4ac7 ff525c call dword ptr [edx+5Ch]
005a4aca 47 inc edi
005a4acb 4b dec ebx
005a4acc 75e8 jne acclient!PView::DrawCells+0x276 (005a4ab6)
005a4ace 8b7c2418 mov edi,dword ptr [esp+18h]
0:020> r $t0 = 0
0:020> bp 00453aa0 "r $t0 = @$t0 + 1; .printf \"F %d\\n\", @$t0; .printf \"P %08x %08x %08x %08x %08x %08x %08x %08x\\n\", dwo(0081ef00+4), dwo(0081ef00+0x3c), dwo(0081ef00+0x40), dwo(0081ef00+0x44), dwo(0081ef00+8), dwo(0081ef00+0xc), dwo(0081ef00+0x10), dwo(0081ef00+0x14); .if (@$t0 < 2) { gc }"
0:020> bp 005a4840 ".printf \"DC ov=%d n=%d\\n\", dwo(@ecx+0x38), dwo(@ecx+0x60); gc"
0:020> g
DC ov=0 n=1
DC ov=0 n=2
DC ov=0 n=2
DC ov=0 n=1
DC ov=0 n=2
DC ov=0 n=1
DC ov=0 n=1
DC ov=0 n=1
DC ov=0 n=1
DC ov=0 n=5
DC ov=0 n=1
DC ov=0 n=2
DC ov=0 n=5
DC ov=0 n=1
DC ov=0 n=6
F 1
P f4180114 421e02f8 4188ad51 4337405d 3f7d4962 be14b1ba 00000000 00000000
DC ov=7 n=3
DC ov=0 n=1
DC ov=0 n=2
DC ov=0 n=2
DC ov=0 n=1
DC ov=0 n=2
DC ov=0 n=1
DC ov=0 n=1
DC ov=0 n=1
DC ov=0 n=1
DC ov=0 n=5
DC ov=0 n=1
DC ov=0 n=2
DC ov=0 n=5
DC ov=0 n=1
DC ov=0 n=6
F 2
P f4180114 421e02f8 4188a8ce 43374089 3f7d4959 be14b29f 00000000 00000000
eax=17f2ed10 ebx=00000009 ecx=00a56488 edx=3e931f22 esi=00a56488 edi=009a09b0
eip=00453aa0 esp=001afe84 ebp=001aff74 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200202
acclient!SmartBox::RenderNormalMode:
00453aa0 a130f38600 mov eax,dword ptr [acclient!RenderDevice::render_device (0086f330)] ds:002b:0086f330=00a64c48
0:000> bc *
0:000> .echo ===DETACHING===
===DETACHING===
0:000> .logclose
Closing open log file C:\Users\erikn\.codex\worktrees\742f\acdream\artifacts\overhaul-472-owner-capture\recon-pose.log

View file

@ -2,7 +2,8 @@
**Status:** S5-c1 through S5-c5 plus #470/#469 LANDED + REVIEW-CLOSED with lead
graphical gates PROVISIONAL PASS; closeout C1 passed; C1a is STOPPED on the
retail-live fact in #472; connected/performance C2 and G4 remain.
retail-live fact in #472 now captured; C1b projection diagnostic is contracted;
connected/performance C2 and G4 remain.
**Branch:** `claude/campaign-w-retail-frame-walk`.
**Gate:** G4 remains unpassed. Nothing merges to `main` before G4.
@ -3589,3 +3590,116 @@ new bounded contract from the observed facts.
This is the campaign's explicit “retail fact cannot be recovered statically”
stop condition. C1a, connected/performance C2, and G4 do not proceed until the
capture exists. Nothing has merged to `main`.
## 39. Owner capture and C1b projection diagnostic contract — 2026-09-05
### 39.1 New evidence removes the capture blocker, but does not yet close #472
The owner returned to the requested stairwell and authorized capture. Preflight:
ACE UDP 9000/PID 13340, paired retail PID 29732, no AcDream.App or existing cdb.
The live executable SHA and CodeView GUID/age match §38.3. The lead captured
one complete frame with full 2,601-slot residency, all seven e229 block-check
input/return sets, active screen vertices and edge planes, CY, projection
globals, and the full eight-kind walk transcript. Capture:
`oh-capture/cathedral-stair-arch-e229.combined-r1.log`, SHA-256
`9E493F8ACE8CA2E939333BB8B755C218F8115658EE423F5439FCA45C3FBBA9CB`.
The matching .cdb script is preserved beside it. The initial combined attempt
used incorrect newline escaping and is retained in the working artifact
directory, excluded from conformance evidence. Every attach exited 0 through
`bc *`, log close, and `qd`; no debugger remained, and the owner's retail
client was left running.
The valid frame starts at:
`P f4180114 421e02f8 4188aa39 4337407b 3f7d4959 be14b29f 00000000 00000000`.
It is the same stairwell with seven exit views, but is NOT the historical
fixture's exact pose. Retail slot 399 contains `e229ffff`, side 1, z slab
bits `bf800000..43890000` (-1..274). All seven block checks return OUTSIDE;
no e229 LC or SC occurs. This proves residency plus rejection for this captured
pose, not the cause of the old fixture's disagreement.
Marker timing matters: RenderNormalMode's entry breakpoint prints the prior
Render::viewer_pos, before update_viewpoint installs this frame's viewer. All
seven r1 block checks carry y bits 4188aa3a, matching the terminating F2 P
rather than F1's 4188aa39. Pair F1 events with F2 pose for the actual capture
comparison. The older stair fixture must also be checked with events(N) and
pose(N+1); the final marker pose remains present in the raw log even though
the ordinary parser discards the unfinished final frame. Section 38.4's use
of F1 P as the exact original event pose was therefore too strong. Do not
alter the original fixture to hide this association.
A further one-frame `oh-capture/cathedral-stair-arch-e229.projection-mode.log`
reveals the important missing fact: `newmethod @0081efe8 == 1`.
Named `Render::copy_view @0054dfc0` branches at 0054e4e5 and calls
`PrimD3DRender::ScreenToViewTransform @0059aa40` at 0054e50f in that mode.
This reads actual viewport dimensions, ViewToClipMatrix, and inverse
WorldToViewMatrix. The existing test `WalkTraceReplayContext.RetailRayCaster`
instead implements the other, legacy branch. Its forward projection puts
the center at (512,360), while its rays put it at (511.5,359.5). Its claim
that the branches are equal is false. Production already uses matrix-based
rays; no production behavior change is authorized.
Captured viewport is 1024x720, aspect bits 3fb60b61, FOV bits 3f98104b,
near/far bits 3dcccccd/457a0000. Row-major LH ViewToClipMatrix words:
```text
3f854304 00000000 00000000 00000000
00000000 3fbd8723 00000000 00000000
00000000 00000000 3f8000d2 3f800000
00000000 00000000 bdccce1d 00000000
```
The six legacy projection globals are doubles; r1 captures all 64 bits and
confirms the previous nominal values. Treat neither those constants nor
AD-118's old x87 explanation as proof of the active path. AD-118 and #458's
attribution need re-evaluation after the experiment below.
### 39.2 C1b — bounded diagnostic implementation
One OpenAI implementer works in `s5-closeout-harness`, fast-forwarded to this
contract commit. Allowed test edits: `WalkTraceReplay.cs` and at most one
new `WalkProjectionDiagnosticTests.cs`. No production, existing fixture,
existing conformance expectation, KnownFailure, or default constructor
behavior changes. No graphical launch, package bake, broad gate, or commit
by the implementer.
Add an explicit opt-in test-context construction path using the captured
D3D projection and named ScreenToViewTransform rule. Derive a coherent LH
world-to-view matrix from each supplied pose (right, up, forward rows/columns
as confirmed against the captured matrix); invert it for rays as retail does.
Use the same projection for forward screen mapping. Do not subtract a
half-pixel from production TransformToScreen or tune an epsilon. The baseline
constructor remains byte-for-byte behaviorally unchanged for comparison.
Required diagnostics (tag InstalledDat/Purpose=Diagnostic and retain output):
1. At center, corners, and interior points, screen -> ray -> screen must
return the original coordinate within a justified float-rounding bound.
Restoring the legacy ray formula must fail at center by about half a pixel.
2. Drive real RetailFrameWalk and the existing DAT builder for the new capture
and all four complete historical stair-arch frames under both baseline and
matrix-corrected test contexts. Use the actual captured projection and
label its application to older frames as a same-configuration hypothesis.
Compare the prior same-frame pose association and the retail-correct
next-marker association separately; include the final marker's raw pose
without manufacturing a fifth complete event frame.
3. At OnLandscapeViews, read actual live root views and print screen points,
raw edge planes, CY, e229 slot/slab, four corner intervals and per-view
BlockCheck results. Compare that diagnostic admission with real
WalkLandscape.InView, CellInView, LC and SC after the frame.
4. For the experimental transcript observer only, read TopView.ViewCount while
callbacks own the live flood; emit EC per view and OC once per cell in the
normal reverse-cell order. Preserve the current shared Recorder unchanged.
Compare complete Signature8 sequences and report full aligned mismatches,
never equal counts as a substitute.
5. Repeat the exact transcript comparison for existing OH fixtures, especially
Holtburg doorway (#458), to distinguish a real correction from trading one
boundary discrepancy for another. This is diagnostic evidence, not an
automatic change to accepted failure identities.
Build only the affected Release test project and run these focused diagnostics.
Record commands, exact input/output and limitations in the artifact directory.
A result that does not resolve the old fixture must be reported honestly; do
not widen into renderer math or silently accept a new failure. The lead writes
the subsequent correction contract from the measured result; then the normal
sequential retail and production reviews apply. C1a's product hash and test
closure, C2, and G4 remain; no merge to main.