# Phase A6.P1 — cdb Probe Spike Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Build the `[push-back]` acdream probe + the 7-breakpoint cdb script, then capture paired retail vs acdream traces at 9 indoor scenarios so A6.P2 can quantify the BSP collision response divergence. **Architecture:** Three layers — (1) a new `ProbePushBackEnabled` toggle in `PhysicsDiagnostics` with 3 helper methods + 3 emission sites in `BSPQuery` / `Transition`; (2) a cdb breakpoint script + PowerShell wrapper that attaches to live retail; (3) a per-scenario capture protocol producing `{retail,acdream}.log` pairs. **Tech Stack:** C# / .NET 10, xUnit, `Console.WriteLine` for probe emission (existing pattern), `cdb.exe` (Windows debugger), PowerShell. **Spec:** [`docs/superpowers/specs/2026-05-21-phase-a6-indoor-physics-fidelity-design.md`](../specs/2026-05-21-phase-a6-indoor-physics-fidelity-design.md). --- ## File Structure **Files to create:** - `tools/cdb/a6-probe.cdb` — cdb breakpoint script (~80 lines) - `tools/cdb/a6-probe-runner.ps1` — PowerShell wrapper to attach cdb (~40 lines) - `tools/cdb/README-a6-probe.md` — usage documentation (~60 lines) - `docs/research/2026-05-21-a6-captures/.gitkeep` — directory marker - `docs/research/2026-05-21-a6-captures/scenN-/{retail,acdream}.log` — capture pairs (filed by Task 15) - `docs/research/2026-05-21-a6-cdb-capture-findings.md` — findings doc stub (Task 14) **Files to modify:** - `src/AcDream.Core/Physics/PhysicsDiagnostics.cs` — add `ProbePushBackEnabled` toggle + 3 helpers - `src/AcDream.Core/Physics/BSPQuery.cs` — 2 emission sites (lines 332, 1550) - `src/AcDream.Core/Physics/TransitionTypes.cs` — 1 emission site in `CheckOtherCells` (line ~1472) - `src/AcDream.UI.Abstractions/Panels/Debug/DebugVM.cs` — add `ProbePushBack` mirror - `tests/AcDream.Core.Tests/Physics/PhysicsDiagnosticsTests.cs` — add toggle roundtrip test - `CLAUDE.md` — add `ACDREAM_PROBE_PUSH_BACK=1` to "Diagnostic env vars" section --- ## Phase A — Build the `[push-back]` probe (TDD) ### Task 1: Add `ProbePushBackEnabled` toggle to `PhysicsDiagnostics` **Files:** - Modify: `src/AcDream.Core/Physics/PhysicsDiagnostics.cs` (append after `ProbeWalkMissEnabled` at line ~277) - Test: `tests/AcDream.Core.Tests/Physics/PhysicsDiagnosticsTests.cs` - [ ] **Step 1: Write the failing test** Append to `tests/AcDream.Core.Tests/Physics/PhysicsDiagnosticsTests.cs` (before the final closing `}` of the class): ```csharp // ----------------------------------------------------------------------- // ProbePushBackEnabled — flag gates the [push-back] emission path. // A6.P1 (2026-05-21). // ----------------------------------------------------------------------- [Fact] public void ProbePushBack_StaticApi_Roundtrip() { bool initial = PhysicsDiagnostics.ProbePushBackEnabled; try { PhysicsDiagnostics.ProbePushBackEnabled = true; Assert.True(PhysicsDiagnostics.ProbePushBackEnabled); PhysicsDiagnostics.ProbePushBackEnabled = false; Assert.False(PhysicsDiagnostics.ProbePushBackEnabled); } finally { PhysicsDiagnostics.ProbePushBackEnabled = initial; } } ``` - [ ] **Step 2: Run test to verify it fails** Run: `dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj --filter FullyQualifiedName~ProbePushBack_StaticApi_Roundtrip --no-build` Expected: COMPILE ERROR — `'PhysicsDiagnostics' does not contain a definition for 'ProbePushBackEnabled'`. - [ ] **Step 3: Implement the toggle** Append to `src/AcDream.Core/Physics/PhysicsDiagnostics.cs` immediately before the `LogCpBoolWrite` method (around line 279): ```csharp /// /// Phase A6.P1 cdb probe spike (2026-05-21). When true, every BSP /// collision response site emits a structured [push-back] line: /// input/output sphere center, plane geometry, push-back delta, walk /// interp, and the dispatcher's selected path. Direct comparison to /// retail's cdb breakpoint set documented at /// tools/cdb/a6-probe.cdb. /// /// /// Three emission sites: /// (the suspected over-correction site), /// (the 6-path dispatcher), and /// (multi-cell BSP iteration outcomes). All three are zero-cost when /// off — checked via early-out at each site. /// /// /// /// Initial state from ACDREAM_PROBE_PUSH_BACK=1. /// Runtime-toggleable via DebugVM mirror. /// /// /// /// Spec: docs/superpowers/specs/2026-05-21-phase-a6-indoor-physics-fidelity-design.md. /// /// public static bool ProbePushBackEnabled { get; set; } = Environment.GetEnvironmentVariable("ACDREAM_PROBE_PUSH_BACK") == "1"; ``` - [ ] **Step 4: Run test to verify it passes** Run: `dotnet build src/AcDream.Core/AcDream.Core.csproj -c Debug --nologo && dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj --filter FullyQualifiedName~ProbePushBack_StaticApi_Roundtrip --no-build` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add src/AcDream.Core/Physics/PhysicsDiagnostics.cs tests/AcDream.Core.Tests/Physics/PhysicsDiagnosticsTests.cs git commit -m "$(cat <<'EOF' feat(physics): A6.P1 — add ProbePushBackEnabled toggle New PhysicsDiagnostics flag gates the [push-back] probe shipping in subsequent tasks. Env-var ACDREAM_PROBE_PUSH_BACK=1 + DebugVM mirror, matching the existing probe-toggle pattern. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 2: Add `LogPushBackAdjust` helper method **Files:** - Modify: `src/AcDream.Core/Physics/PhysicsDiagnostics.cs` - [ ] **Step 1: Add the helper method** Append immediately after the `ProbePushBackEnabled` property (just added) in `src/AcDream.Core/Physics/PhysicsDiagnostics.cs`: ```csharp /// /// A6.P1 emission helper for the AdjustSphereToPlane site. /// One line per call: input sphere center, plane geometry, push-back /// delta, walk-interp before/after, and whether the adjust applied. /// Direct paired comparison to retail's cdb breakpoint on /// CPolygon::adjust_sphere_to_plane. /// /// /// Caller MUST guard with if (!ProbePushBackEnabled) return; /// before computing the delta arguments — this method assumes the /// caller paid that price already. /// /// public static void LogPushBackAdjust( Vector3 inputCenter, Vector3 outputCenter, Plane plane, float radius, float walkInterpBefore, float walkInterpAfter, float dpPos, float dpMove, float iDist, bool applied) { var delta = outputCenter - inputCenter; float deltaMag = delta.Length(); Console.WriteLine(System.FormattableString.Invariant( $"[push-back] site=adjust_sphere " + $"in=({inputCenter.X:F4},{inputCenter.Y:F4},{inputCenter.Z:F4}) " + $"out=({outputCenter.X:F4},{outputCenter.Y:F4},{outputCenter.Z:F4}) " + $"delta=({delta.X:F4},{delta.Y:F4},{delta.Z:F4}) deltaMag={deltaMag:F4} " + $"n=({plane.Normal.X:F4},{plane.Normal.Y:F4},{plane.Normal.Z:F4}) d={plane.D:F4} " + $"r={radius:F4} winterp={walkInterpBefore:F4}->{walkInterpAfter:F4} " + $"dpPos={dpPos:F4} dpMove={dpMove:F4} iDist={iDist:F4} applied={applied}")); } // Note: cellId/polyId omitted — ResolvedPolygon has no Id property and // AdjustSphereToPlane is called from inside BSP traversal without cell // attribution. Cross-reference with [push-back-cell] (same trace, time- // adjacent) for cell attribution; polyId pursued only if A6.P2 needs it // (would require plumbing the ushort dict-key through BSP traversal). ``` - [ ] **Step 2: Verify it compiles** Run: `dotnet build src/AcDream.Core/AcDream.Core.csproj -c Debug --nologo` Expected: BUILD SUCCEEDED with 0 errors. - [ ] **Step 3: Commit** ```bash git add src/AcDream.Core/Physics/PhysicsDiagnostics.cs git commit -m "$(cat <<'EOF' feat(physics): A6.P1 — add LogPushBackAdjust helper One-line per-call emission helper for the AdjustSphereToPlane instrumentation site. Direct field-for-field paired comparison to retail's CPolygon::adjust_sphere_to_plane breakpoint. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 3: Wire `LogPushBackAdjust` into `BSPQuery.AdjustSphereToPlane` **Files:** - Modify: `src/AcDream.Core/Physics/BSPQuery.cs:332-362` (the `AdjustSphereToPlane` method body) - [ ] **Step 1: Read the current method body** Read `src/AcDream.Core/Physics/BSPQuery.cs` lines 320-365 to confirm the current shape — `AdjustSphereToPlane` returns bool, modifies `validPos.Center` and `path.WalkInterp` in-place. - [ ] **Step 2: Replace the method body with the instrumented version** Replace the body of `AdjustSphereToPlane` in `src/AcDream.Core/Physics/BSPQuery.cs` (lines 332-362) with: ```csharp private static bool AdjustSphereToPlane( ResolvedPolygon poly, SpherePath path, CollisionSphere validPos, Vector3 movement) { // A6.P1: snapshot inputs for the [push-back] probe (cheap copy of // Vector3 + 2 floats). Only the LogPushBackAdjust call below pays // the Console.WriteLine cost, and only when the probe is on. var inputCenter = validPos.Center; float walkInterpBefore = path.WalkInterp; float dpPos = Vector3.Dot(validPos.Center, poly.Plane.Normal) + poly.Plane.D; float dpMove = Vector3.Dot(movement, poly.Plane.Normal); float dist; if (dpMove <= PhysicsGlobals.EPSILON) { if (dpMove >= -PhysicsGlobals.EPSILON) { if (PhysicsDiagnostics.ProbePushBackEnabled) { PhysicsDiagnostics.LogPushBackAdjust( inputCenter, validPos.Center, poly.Plane, validPos.Radius, walkInterpBefore, path.WalkInterp, dpPos, dpMove, 0f, applied: false); } return false; } dist = dpPos - validPos.Radius; } else { dist = -validPos.Radius - dpPos; } float iDist = dist / dpMove; float interp = (1f - iDist) * path.WalkInterp; if (interp >= path.WalkInterp || interp < -0.5f) { if (PhysicsDiagnostics.ProbePushBackEnabled) { PhysicsDiagnostics.LogPushBackAdjust( inputCenter, validPos.Center, poly.Plane, validPos.Radius, walkInterpBefore, path.WalkInterp, dpPos, dpMove, iDist, applied: false); } return false; } validPos.Center -= movement * iDist; path.WalkInterp = interp; if (PhysicsDiagnostics.ProbePushBackEnabled) { PhysicsDiagnostics.LogPushBackAdjust( inputCenter, validPos.Center, poly.Plane, validPos.Radius, walkInterpBefore, path.WalkInterp, dpPos, dpMove, iDist, applied: true); } return true; } ``` **Note:** Cell + poly attribution intentionally omitted — `ResolvedPolygon` has no `Id` property and `AdjustSphereToPlane` is private inside BSP traversal without cell scope. A6.P2 cross-references with the time-adjacent `[push-back-cell]` line for cell attribution. If `polyId` becomes necessary, A6.P3 plumbs the dictionary key through (mechanical change). - [ ] **Step 3: Verify build is green** Run: `dotnet build src/AcDream.Core/AcDream.Core.csproj -c Debug --nologo` Expected: BUILD SUCCEEDED with 0 errors. The probe is now wired but inactive unless `ACDREAM_PROBE_PUSH_BACK=1`. - [ ] **Step 4: Quick smoke run to confirm the probe emits** Set the env var and run any test that calls AdjustSphereToPlane (existing BSPQuery tests touch this path): ```powershell $env:ACDREAM_PROBE_PUSH_BACK = "1" dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj --filter "FullyQualifiedName~BSPQuery" --no-build --logger "console;verbosity=detailed" 2>&1 | Select-String "\[push-back\]" | Select-Object -First 3 Remove-Item Env:\ACDREAM_PROBE_PUSH_BACK ``` Expected: at least 1 `[push-back] site=adjust_sphere ...` line in the output. If zero lines, the probe didn't fire — investigate. - [ ] **Step 5: Commit** ```bash git add src/AcDream.Core/Physics/BSPQuery.cs git commit -m "$(cat <<'EOF' feat(physics): A6.P1 — instrument AdjustSphereToPlane with [push-back] Wires the LogPushBackAdjust helper into all three return paths of AdjustSphereToPlane (early-return on no-movement, early-return on interp out-of-window, and the applied path). Probe is gated by ProbePushBackEnabled so it's zero-cost when off. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 4: Add `LogPushBackDispatch` helper method **Files:** - Modify: `src/AcDream.Core/Physics/PhysicsDiagnostics.cs` - [ ] **Step 1: Add the helper method** Append immediately after the `LogPushBackAdjust` method (just added) in `src/AcDream.Core/Physics/PhysicsDiagnostics.cs`: ```csharp /// /// A6.P1 emission helper for the FindCollisions dispatcher /// site. One line per call: input sphere center, movement vector, /// path-selection state flags (collide / insertType / objState), /// walk-interp at entry, and the return state. Direct paired /// comparison to retail's cdb breakpoint on /// BSPTREE::find_collisions. /// /// /// Caller MUST guard with if (!ProbePushBackEnabled) return; /// before calling. /// /// public static void LogPushBackDispatch( Vector3 sphereCenter, Vector3 movement, bool collide, int insertType, int objState, float walkInterpEntry, int returnState) { Console.WriteLine(System.FormattableString.Invariant( $"[push-back-disp] site=dispatch " + $"center=({sphereCenter.X:F4},{sphereCenter.Y:F4},{sphereCenter.Z:F4}) " + $"mvmt=({movement.X:F4},{movement.Y:F4},{movement.Z:F4}) " + $"collide={collide} insertType={insertType} objState=0x{objState:X} " + $"winterp={walkInterpEntry:F4} return={returnState}")); } ``` - [ ] **Step 2: Verify it compiles** Run: `dotnet build src/AcDream.Core/AcDream.Core.csproj -c Debug --nologo` Expected: BUILD SUCCEEDED. - [ ] **Step 3: Commit** ```bash git add src/AcDream.Core/Physics/PhysicsDiagnostics.cs git commit -m "$(cat <<'EOF' feat(physics): A6.P1 — add LogPushBackDispatch helper One-line per-call emission helper for the FindCollisions dispatcher instrumentation site. Captures path-selection state (collide flag, insertType, objState) + walk-interp + return state for direct comparison to retail's BSPTREE::find_collisions breakpoint. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 5: Wire `LogPushBackDispatch` into `BSPQuery.FindCollisions` (modern overload only) **Files:** - Modify: `src/AcDream.Core/Physics/BSPQuery.cs:1550-1576` (the modern `FindCollisions` overload entry) **Note:** The legacy overload at `:1895` delegates to the modern overload — instrumenting only the modern one covers all dispatches. - [ ] **Step 1: Locate the dispatcher's entry block** Read `src/AcDream.Core/Physics/BSPQuery.cs` lines 1550-1580 to confirm the entry shape (we want to emit AFTER the path/collisions/obj locals are computed but BEFORE the actual dispatch begins). - [ ] **Step 2: Insert the probe emission after `movement` is computed** After line 1576 (`var movement = sphere0.Center - localCurrCenter;`) and BEFORE the next significant statement in `BSPQuery.cs`'s `FindCollisions`, add: ```csharp // A6.P1: snapshot dispatcher entry for the [push-back-disp] probe. // Emitted before path selection so the captured state reflects // the inputs the dispatcher routes on. Return value is captured // by wrapping the actual dispatch — see end of method. if (PhysicsDiagnostics.ProbePushBackEnabled) { PhysicsDiagnostics.LogPushBackDispatch( sphereCenter: sphere0.Center, movement: movement, collide: path.Collide, insertType: (int)path.InsertType, objState: (int)obj.State, walkInterpEntry: path.WalkInterp, returnState: -1); // Sentinel; full return state captured separately. } ``` **Note:** The `returnState=-1` sentinel marks "entry log" — A6.P2 analysis can pair entry/exit by call order in the trace. If a per-call exit log is needed, A6.P1.5 adds a wrapping try/finally; for now entry-only suffices since the dispatcher's path can be inferred from subsequent `[push-back]` adjust-sphere lines and the eventual return. - [ ] **Step 3: Verify build is green** Run: `dotnet build src/AcDream.Core/AcDream.Core.csproj -c Debug --nologo` Expected: BUILD SUCCEEDED. - [ ] **Step 4: Quick smoke run** ```powershell $env:ACDREAM_PROBE_PUSH_BACK = "1" dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj --filter "FullyQualifiedName~FindCollisions" --no-build --logger "console;verbosity=detailed" 2>&1 | Select-String "\[push-back-disp\]" | Select-Object -First 3 Remove-Item Env:\ACDREAM_PROBE_PUSH_BACK ``` Expected: at least 1 `[push-back-disp] site=dispatch ...` line. - [ ] **Step 5: Commit** ```bash git add src/AcDream.Core/Physics/BSPQuery.cs git commit -m "$(cat <<'EOF' feat(physics): A6.P1 — instrument FindCollisions with [push-back-disp] Wires LogPushBackDispatch into the modern FindCollisions overload at the entry block (after path/collisions/obj locals + movement computed). Legacy overload delegates to modern, so single instrumentation site covers all dispatches. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 6: Add `LogPushBackCellTransit` helper method **Files:** - Modify: `src/AcDream.Core/Physics/PhysicsDiagnostics.cs` - [ ] **Step 1: Add the helper method** Append immediately after `LogPushBackDispatch` in `src/AcDream.Core/Physics/PhysicsDiagnostics.cs`: ```csharp /// /// A6.P1 emission helper for the CheckOtherCells multi-cell /// BSP iteration site. One line per off-cell hit: from-cell, to-cell, /// BSP result (Ok / Adjusted / Slid / Collided), and the iteration /// outcome. Direct paired comparison to retail's /// CTransition::check_other_cells loop at decomp line /// 272717. Augments the existing A4 multi-cell BSP instrumentation /// with explicit per-iteration outcome telemetry. /// /// /// Caller MUST guard with if (!ProbePushBackEnabled) return; /// before calling. /// /// public static void LogPushBackCellTransit( uint primaryCellId, uint otherCellId, int bspResult, bool halted) { Console.WriteLine(System.FormattableString.Invariant( $"[push-back-cell] site=other_cell " + $"primary=0x{primaryCellId:X8} other=0x{otherCellId:X8} " + $"bspResult={bspResult} halted={halted}")); } ``` - [ ] **Step 2: Verify it compiles** Run: `dotnet build src/AcDream.Core/AcDream.Core.csproj -c Debug --nologo` Expected: BUILD SUCCEEDED. - [ ] **Step 3: Commit** ```bash git add src/AcDream.Core/Physics/PhysicsDiagnostics.cs git commit -m "$(cat <<'EOF' feat(physics): A6.P1 — add LogPushBackCellTransit helper One-line per-iteration emission helper for the CheckOtherCells multi-cell BSP loop. Captures primary/other cell ids, BSP result, and halted flag for direct comparison to retail's CTransition::check_other_cells loop. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 7: Wire `LogPushBackCellTransit` into `Transition.CheckOtherCells` **Files:** - Modify: `src/AcDream.Core/Physics/TransitionTypes.cs:1404-1480` (the `CheckOtherCells` loop) - [ ] **Step 1: Locate the insertion point** In `src/AcDream.Core/Physics/TransitionTypes.cs`, find the line block at ~1466-1473: ```csharp if (PhysicsDiagnostics.ProbeIndoorBspEnabled) { Console.WriteLine(System.FormattableString.Invariant( $"[other-cells] primary=0x{sp.CheckCellId:X8} iter=0x{cellId:X8} result={result}")); } if (ApplyOtherCellResult(result, out var halted)) return halted; ``` We add the new `[push-back-cell]` emission AFTER the existing `[other-cells]` block and BEFORE the `ApplyOtherCellResult` call. - [ ] **Step 2: Insert the new emission** In `src/AcDream.Core/Physics/TransitionTypes.cs`, modify the line block at ~1466-1473 by inserting a new `if` block between the existing `[other-cells]` probe and the `ApplyOtherCellResult` call. The locals in scope at this point are `sp.CheckCellId` (the primary), `cellId` (the loop variable for the candidate cell), and `result` (the BSP query return state). After the edit it reads: ```csharp if (PhysicsDiagnostics.ProbeIndoorBspEnabled) { Console.WriteLine(System.FormattableString.Invariant( $"[other-cells] primary=0x{sp.CheckCellId:X8} iter=0x{cellId:X8} result={result}")); } if (PhysicsDiagnostics.ProbePushBackEnabled) { PhysicsDiagnostics.LogPushBackCellTransit( primaryCellId: sp.CheckCellId, otherCellId: cellId, bspResult: (int)result, halted: false); // Sentinel; A6.P2 infers halt by checking if the iter ended here. } if (ApplyOtherCellResult(result, out var halted)) return halted; ``` - [ ] **Step 3: Verify build is green** Run: `dotnet build src/AcDream.Core/AcDream.Core.csproj -c Debug --nologo` Expected: BUILD SUCCEEDED with 0 errors. - [ ] **Step 4: Quick smoke run** ```powershell $env:ACDREAM_PROBE_PUSH_BACK = "1" dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj --filter "FullyQualifiedName~CheckOtherCells" --no-build --logger "console;verbosity=detailed" 2>&1 | Select-String "\[push-back-cell\]" | Select-Object -First 3 Remove-Item Env:\ACDREAM_PROBE_PUSH_BACK ``` Expected: at least 1 `[push-back-cell] site=other_cell ...` line. - [ ] **Step 5: Commit** ```bash git add src/AcDream.Core/Physics/TransitionTypes.cs git commit -m "$(cat <<'EOF' feat(physics): A6.P1 — instrument CheckOtherCells with [push-back-cell] Wires LogPushBackCellTransit into the multi-cell BSP iteration loop just before ApplyOtherCellResult halts. Captures primary/other cell ids + BSP result for direct comparison to retail's CTransition::check_other_cells loop (already ported as A4). Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 8: Add `ProbePushBack` mirror to `DebugVM` **Files:** - Modify: `src/AcDream.UI.Abstractions/Panels/Debug/DebugVM.cs` (append after `ProbeIndoorBsp` at line ~360) - [ ] **Step 1: Add the mirror property** After the `ProbeIndoorBsp` property in `src/AcDream.UI.Abstractions/Panels/Debug/DebugVM.cs` (closing `}` around line 360), insert: ```csharp /// /// Phase A6.P1 cdb probe spike (2026-05-21). Runtime mirror of /// PhysicsDiagnostics.ProbePushBackEnabled (env var /// ACDREAM_PROBE_PUSH_BACK). Toggling here flips the three /// [push-back] emission sites live — no relaunch required. /// public bool ProbePushBack { get => PhysicsDiagnostics.ProbePushBackEnabled; set => PhysicsDiagnostics.ProbePushBackEnabled = value; } ``` - [ ] **Step 2: Verify build is green** Run: `dotnet build src/AcDream.UI.Abstractions/AcDream.UI.Abstractions.csproj -c Debug --nologo` Expected: BUILD SUCCEEDED. - [ ] **Step 3: Commit** ```bash git add src/AcDream.UI.Abstractions/Panels/Debug/DebugVM.cs git commit -m "$(cat <<'EOF' feat(ui): A6.P1 — add ProbePushBack mirror to DebugVM Runtime checkbox mirror for ProbePushBackEnabled. Toggling in DebugPanel (under ACDREAM_DEVTOOLS=1) flips all three [push-back] emission sites live without relaunch. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 9: Update CLAUDE.md "Diagnostic env vars" section **Files:** - Modify: `CLAUDE.md` ("Diagnostic env vars" subsection) - [ ] **Step 1: Locate the section** Run: `grep -n "ACDREAM_PROBE_RESOLVE\|Diagnostic env vars" CLAUDE.md | head -5` Identify the line where the existing `ACDREAM_PROBE_*` env var documentation ends. - [ ] **Step 2: Add the new env var entry** Append the new entry immediately after the existing `ACDREAM_PROBE_WALK_MISS` entry (look for the `[walk-miss]` documentation line). Add: ```markdown - `ACDREAM_PROBE_PUSH_BACK=1` — A6.P1 cdb probe spike (2026-05-21). Emits three line types per physics tick: `[push-back]` (per `BSPQuery.AdjustSphereToPlane` call), `[push-back-disp]` (per `BSPQuery.FindCollisions` dispatch), `[push-back-cell]` (per `Transition.CheckOtherCells` off-cell hit). Heavy under motion (~100–500 lines/sec). Pair with retail's cdb breakpoint set at `tools/cdb/a6-probe.cdb` for the A6.P1 capture protocol. Runtime-toggleable via the DebugPanel "Diagnostics" section. ``` - [ ] **Step 3: Commit** ```bash git add CLAUDE.md git commit -m "$(cat <<'EOF' docs(CLAUDE): A6.P1 — document ACDREAM_PROBE_PUSH_BACK env var Adds the new probe to the Diagnostic env vars list with hit-rate estimate and cross-reference to the cdb probe script. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ## Phase B — Build the cdb script + infrastructure ### Task 10: Write `tools/cdb/a6-probe.cdb` **Files:** - Create: `tools/cdb/a6-probe.cdb` - [ ] **Step 1: Verify the parent directory exists** ```bash ls tools/ 2>&1; mkdir -p tools/cdb ``` - [ ] **Step 2: Write the cdb script** Create `tools/cdb/a6-probe.cdb`: ```text $$ $$ Phase A6.P1 cdb probe spike — 2026-05-21 $$ $$ 7 breakpoints on retail's BSP collision response sites. Each BP fires $$ a non-blocking action (printf + gc), incrementing a per-BP counter. $$ Auto-detaches via 'qd' after 50,000 total hits to avoid retail lag. $$ $$ Symbol lookup convention per CLAUDE.md "Retail debugger toolchain": $$ - snake_case for BSPTREE, CTransition, OBJECTINFO, COLLISIONINFO, SPHEREPATH $$ - PascalCase for CPhysicsObj $$ - Always 'x' first to confirm the actual name $$ .logopen /t a6-probe-${ARG_LOG_TAG}.log .sympath C:\Users\erikn\source\repos\acdream\refs .symopt+ 0x40 .reload /f acclient.exe $$ Counters: $t0 = total hits, $t1..$t7 = per-BP hits r $t0 = 0 r $t1 = 0 r $t2 = 0 r $t3 = 0 r $t4 = 0 r $t5 = 0 r $t6 = 0 r $t7 = 0 $$ BP1: CTransition::transitional_insert bp acclient!CTransition::transitional_insert "r $t1 = @$t1 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP1] transitional_insert hit#%d eax_2=%d insertType=%d\\n\", @$t1, poi(@ecx+0x18), poi(@ecx+0x1c); .if (@$t0 >= 50000) { qd } .else { gc }" $$ BP2: CTransition::step_up bp acclient!CTransition::step_up "r $t2 = @$t2 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP2] step_up hit#%d walkable_allowance=%f\\n\", @$t2, poi(@ecx+0x60); .if (@$t0 >= 50000) { qd } .else { gc }" $$ BP3: SPHEREPATH::set_collide bp acclient!SPHEREPATH::set_collide "r $t3 = @$t3 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP3] set_collide hit#%d normalZ=%f\\n\", @$t3, dwo(@edx+0x8); .if (@$t0 >= 50000) { qd } .else { gc }" $$ BP4: BSPTREE::find_collisions bp acclient!BSPTREE::find_collisions "r $t4 = @$t4 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP4] find_collisions hit#%d collide=%d insertType=%d\\n\", @$t4, poi(@ecx+0x40), poi(@ecx+0x1c); .if (@$t0 >= 50000) { qd } .else { gc }" $$ BP5: CPolygon::adjust_sphere_to_plane (the over-correction suspect) bp acclient!CPolygon::adjust_sphere_to_plane "r $t5 = @$t5 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP5] adjust_sphere hit#%d Nx=%f Ny=%f Nz=%f d=%f cx=%f cy=%f cz=%f r=%f winterp=%f\\n\", @$t5, dwo(@ecx+0x0), dwo(@ecx+0x4), dwo(@ecx+0x8), dwo(@ecx+0xc), dwo(@edx+0x0), dwo(@edx+0x4), dwo(@edx+0x8), dwo(@edx+0xc), dwo(@edi+0x40); .if (@$t0 >= 50000) { qd } .else { gc }" $$ BP6: CTransition::validate_walkable bp acclient!CTransition::validate_walkable "r $t6 = @$t6 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP6] validate_walkable hit#%d arg2=%f\\n\", @$t6, dwo(@esp+0x4); .if (@$t0 >= 50000) { qd } .else { gc }" $$ BP7: COLLISIONINFO::set_contact_plane bp acclient!COLLISIONINFO::set_contact_plane "r $t7 = @$t7 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP7] set_contact_plane hit#%d isWater=%d\\n\", @$t7, dwo(@esp+0x8); .if (@$t0 >= 50000) { qd } .else { gc }" .printf \"a6-probe armed: BPs 1-7 set, threshold=50000 total hits, qd on threshold\\n\" $$ Continue execution g ``` **Note:** The `${ARG_LOG_TAG}` placeholder is substituted by the PowerShell runner (Task 11) per scenario. The field offsets (`+0x18`, `+0x1c`, etc.) are based on the named-retail struct layouts in `docs/research/named-retail/acclient.h`; if a BP fires with garbage values, verify the offset against the struct definition. - [ ] **Step 3: Commit** ```bash git add tools/cdb/a6-probe.cdb git commit -m "$(cat <<'EOF' feat(cdb): A6.P1 — 7-BP probe script for retail BSP collision response Sets non-blocking breakpoints on transitional_insert, step_up, set_collide, find_collisions, adjust_sphere_to_plane, validate_walkable, set_contact_plane. Each BP increments a counter and emits a single printf line. Auto-detach via qd at 50K total hits to avoid retail lag (CLAUDE.md gotcha — high BP rates trigger ACE timeout). Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 11: Write `tools/cdb/a6-probe-runner.ps1` **Files:** - Create: `tools/cdb/a6-probe-runner.ps1` - [ ] **Step 1: Write the wrapper** Create `tools/cdb/a6-probe-runner.ps1`: ```powershell # Phase A6.P1 cdb probe runner — 2026-05-21 # # Attaches cdb to a live retail acclient.exe with the a6-probe.cdb script. # Per-scenario usage: # .\tools\cdb\a6-probe-runner.ps1 -ScenarioTag "scen1_inn_doorway" # # Prerequisites (verify before invoking): # 1. Retail acclient.exe v11.4186 running and in-world (matches refs/acclient.pdb). # Verify with: py tools\pdb-extract\check_exe_pdb.py "C:\Turbine\Asheron's Call\acclient.exe" # 2. ACE running locally on 127.0.0.1:9000. # 3. Retail character at the scenario start position. # # Output: # docs\research\2026-05-21-a6-captures\\retail.log param( [Parameter(Mandatory=$true)] [string]$ScenarioTag ) $cdbExe = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe" if (-not (Test-Path $cdbExe)) { Write-Error "cdb.exe not found at $cdbExe. Install Microsoft Store WinDbg (~50 MB)." exit 1 } $scriptPath = Join-Path $PSScriptRoot "a6-probe.cdb" if (-not (Test-Path $scriptPath)) { Write-Error "a6-probe.cdb not found at $scriptPath." exit 1 } $captureDir = Join-Path $PSScriptRoot "..\..\docs\research\2026-05-21-a6-captures\$ScenarioTag" if (-not (Test-Path $captureDir)) { New-Item -ItemType Directory -Path $captureDir | Out-Null } $logPath = Join-Path $captureDir "retail.log" # Patch the .cdb script with the scenario-tagged log path (in-place substitution). $scriptContent = Get-Content $scriptPath -Raw $patchedScript = $scriptContent -replace '\$\{ARG_LOG_TAG\}', $ScenarioTag $tempScript = Join-Path $env:TEMP "a6-probe-$ScenarioTag.cdb" Set-Content -Path $tempScript -Value $patchedScript -Encoding ASCII Write-Host "Attaching cdb to acclient.exe with scenario tag '$ScenarioTag'..." Write-Host "Log: $logPath" Write-Host "(cdb auto-detaches at 50K total hits; or press Ctrl-Break to interrupt.)" & $cdbExe -pn acclient.exe -cf $tempScript 2>&1 | Tee-Object -FilePath $logPath Remove-Item $tempScript -ErrorAction SilentlyContinue Write-Host "" Write-Host "Capture complete. Log saved to $logPath" ``` - [ ] **Step 2: Commit** ```bash git add tools/cdb/a6-probe-runner.ps1 git commit -m "$(cat <<'EOF' feat(cdb): A6.P1 — PowerShell runner for a6-probe.cdb Wrapper that attaches cdb to a live retail acclient.exe with a scenario-tagged log path. Per-scenario invocation: .\tools\cdb\a6-probe-runner.ps1 -ScenarioTag "scen1_inn_doorway" Output: docs\research\2026-05-21-a6-captures\\retail.log Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 12: Write `tools/cdb/README-a6-probe.md` **Files:** - Create: `tools/cdb/README-a6-probe.md` - [ ] **Step 1: Write the README** Create `tools/cdb/README-a6-probe.md`: ```markdown # A6.P1 cdb probe — usage Phase A6.P1 cdb probe spike (2026-05-21). Captures retail's per-tick BSP collision response state for paired comparison against acdream. ## Files - `a6-probe.cdb` — the 7-breakpoint cdb script (see comments inside). - `a6-probe-runner.ps1` — PowerShell wrapper that attaches cdb to live retail. ## Prerequisites 1. **Retail binary matches our PDB.** Verify with: ```powershell py tools\pdb-extract\check_exe_pdb.py "C:\Turbine\Asheron's Call\acclient.exe" ``` Expected: `=== MATCH: this exe pairs with our acclient.pdb ===` 2. **cdb installed.** Microsoft Store WinDbg installs cdb at `C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe`. 32-bit required for acclient.exe. 3. **Retail running and in-world.** Launch retail, log into your character, navigate to the scenario start point. 4. **ACE running locally on 127.0.0.1:9000.** ## Usage For each of the 9 A6.P1 scenarios: ```powershell # 1. Position retail character at scenario start (e.g., outside Holtburg inn). # 2. Launch the probe with a scenario tag: .\tools\cdb\a6-probe-runner.ps1 -ScenarioTag "scen1_inn_doorway" # 3. cdb attaches; "a6-probe armed: BPs 1-7 set" appears in console. # 4. In the retail client window, perform the scripted walk for this scenario. # 5. cdb auto-detaches at 50K total hits (cleanly via qd; retail keeps running). # 6. Log filed at docs\research\2026-05-21-a6-captures\scen1_inn_doorway\retail.log ``` ## The 9 scenarios Per the A6 design spec, in capture order: | # | Tag | Walk script | |---|---|---| | 1 | `scen1_inn_doorway` | Walk forward through door, stop just inside | | 2 | `scen2_inn_stairs` | Walk up 4 steps, stop on landing | | 3 | `scen3_inn_2nd_floor` | Walk forward 3 m, sidestep 1 m, walk back | | 4 | `scen4_cottage_cellar` | Walk to cellar opening, descend 2 steps | | 5 | `scen5_sewer_entry` | Walk into portal, then walk 2 m forward inside | | 6 | `scen6_sewer_first_stair` | Walk down full stair flight | | 7 | `scen7_sewer_inter_room` | Walk through portal, stop 1 m past | | 8 | `scen8_sewer_chamber` | Walk in, traverse center, walk out other side | | 9 | `scen9_sewer_corridor` | Walk full length end-to-end | ## Pairing with acdream For each scenario, run acdream IN PARALLEL with the same scripted walk: ```powershell $env:ACDREAM_DAT_DIR = "$env:USERPROFILE\Documents\Asheron's Call" $env:ACDREAM_LIVE = "1" $env:ACDREAM_TEST_HOST = "127.0.0.1" $env:ACDREAM_TEST_PORT = "9000" $env:ACDREAM_TEST_USER = "testaccount" $env:ACDREAM_TEST_PASS = "testpassword" $env:ACDREAM_DEVTOOLS = "1" $env:ACDREAM_PROBE_PUSH_BACK = "1" $env:ACDREAM_PROBE_INDOOR_BSP = "1" $env:ACDREAM_PROBE_CELL = "1" $env:ACDREAM_PROBE_CELL_CACHE = "1" $env:ACDREAM_PROBE_CONTACT_PLANE = "1" dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Debug 2>&1 | Tee-Object -FilePath "docs\research\2026-05-21-a6-captures\scen1_inn_doorway\acdream.log" ``` The `[push-back]`, `[push-back-disp]`, `[push-back-cell]` lines in `acdream.log` pair with the `[BP1]..[BP7]` lines in `retail.log` via scenario tag. ## Known watchouts Per [`CLAUDE.md`](../../CLAUDE.md#known-watchouts): - **High BP hit rates cause retail lag.** 50K threshold is the calibrated ceiling that keeps retail responsive without triggering ACE timeout. - **`qd` (quit detached) is forbidden in BP actions** per CLAUDE.md cdb watchout. The a6-probe.cdb script puts `qd` ONLY in the threshold branch, NOT directly in a BP action's primary command list. Verify this is preserved if editing. - **Killing cdb kills retail.** `qd` detaches cleanly; `Stop-Process` does not. If you must interrupt mid-capture, press Ctrl-Break in the cdb console. - **acclient.exe is 32-bit + uses thiscall.** `this` is in `ecx`. Struct field offsets in the script come from `docs/research/named-retail/acclient.h`. ``` - [ ] **Step 2: Commit** ```bash git add tools/cdb/README-a6-probe.md git commit -m "$(cat <<'EOF' docs(cdb): A6.P1 — README for the cdb probe + runner Documents prerequisites (PDB match, cdb install, retail+ACE running), per-scenario invocation, the 9-scenario tag table, and the parallel acdream capture command. Includes the CLAUDE.md cdb watchouts inline so probe operators don't have to chase them. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ## Phase C — Execute 9 captures + file findings stub ### Task 13: Verify retail binary matches PDB **Files:** None modified — verification step. - [ ] **Step 1: Run the PDB matcher** ```powershell py tools\pdb-extract\check_exe_pdb.py "C:\Turbine\Asheron's Call\acclient.exe" ``` Expected: `=== MATCH: this exe pairs with our acclient.pdb ===` If MISMATCH: stop. Investigate which retail build is installed; either re-install the matching build or update `refs/acclient.pdb` to match. Don't proceed with captures using a mismatched PDB — symbol resolution will fail and all BP actions will dump garbage. - [ ] **Step 2: Document the result in the capture directory** After confirming MATCH, capture the verification output to file. This is the audit trail for the capture session: ```powershell mkdir -p docs\research\2026-05-21-a6-captures py tools\pdb-extract\check_exe_pdb.py "C:\Turbine\Asheron's Call\acclient.exe" > docs\research\2026-05-21-a6-captures\pdb-match-verification.txt 2>&1 ``` - [ ] **Step 3: Commit the verification artifact** ```bash git add docs/research/2026-05-21-a6-captures/pdb-match-verification.txt git commit -m "$(cat <<'EOF' docs(research): A6.P1 — record retail-PDB match verification Audit trail for the A6.P1 capture session: confirms the live retail acclient.exe matches refs/acclient.pdb before any BP-driven captures fire. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 14: Create capture directory structure + findings doc stub **Files:** - Create: `docs/research/2026-05-21-a6-captures/scen{1..9}_/.gitkeep` (9 stub dirs) - Create: `docs/research/2026-05-21-a6-cdb-capture-findings.md` (findings doc stub) - [ ] **Step 1: Create the per-scenario directory stubs** ```powershell $scenarios = @( "scen1_inn_doorway", "scen2_inn_stairs", "scen3_inn_2nd_floor", "scen4_cottage_cellar", "scen5_sewer_entry", "scen6_sewer_first_stair", "scen7_sewer_inter_room", "scen8_sewer_chamber", "scen9_sewer_corridor" ) foreach ($s in $scenarios) { $dir = "docs\research\2026-05-21-a6-captures\$s" if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir | Out-Null } New-Item -ItemType File -Path "$dir\.gitkeep" -Force | Out-Null } ``` - [ ] **Step 2: Create the findings doc stub** Create `docs/research/2026-05-21-a6-cdb-capture-findings.md`: ```markdown # A6.P1 cdb capture findings — 2026-05-21 **Status:** STUB — captures in progress. Tables filled by A6.P2 analysis. **Spec:** [`docs/superpowers/specs/2026-05-21-phase-a6-indoor-physics-fidelity-design.md`](../superpowers/specs/2026-05-21-phase-a6-indoor-physics-fidelity-design.md). **PDB match verification:** [`pdb-match-verification.txt`](2026-05-21-a6-captures/pdb-match-verification.txt). ## Capture inventory | Scenario | Tag | Retail log | acdream log | Status | |---|---|---|---|---| | 1 | scen1_inn_doorway | [retail.log](2026-05-21-a6-captures/scen1_inn_doorway/retail.log) | [acdream.log](2026-05-21-a6-captures/scen1_inn_doorway/acdream.log) | pending | | 2 | scen2_inn_stairs | [retail.log](2026-05-21-a6-captures/scen2_inn_stairs/retail.log) | [acdream.log](2026-05-21-a6-captures/scen2_inn_stairs/acdream.log) | pending | | 3 | scen3_inn_2nd_floor | [retail.log](2026-05-21-a6-captures/scen3_inn_2nd_floor/retail.log) | [acdream.log](2026-05-21-a6-captures/scen3_inn_2nd_floor/acdream.log) | pending | | 4 | scen4_cottage_cellar | [retail.log](2026-05-21-a6-captures/scen4_cottage_cellar/retail.log) | [acdream.log](2026-05-21-a6-captures/scen4_cottage_cellar/acdream.log) | pending | | 5 | scen5_sewer_entry | [retail.log](2026-05-21-a6-captures/scen5_sewer_entry/retail.log) | [acdream.log](2026-05-21-a6-captures/scen5_sewer_entry/acdream.log) | pending | | 6 | scen6_sewer_first_stair | [retail.log](2026-05-21-a6-captures/scen6_sewer_first_stair/retail.log) | [acdream.log](2026-05-21-a6-captures/scen6_sewer_first_stair/acdream.log) | pending | | 7 | scen7_sewer_inter_room | [retail.log](2026-05-21-a6-captures/scen7_sewer_inter_room/retail.log) | [acdream.log](2026-05-21-a6-captures/scen7_sewer_inter_room/acdream.log) | pending | | 8 | scen8_sewer_chamber | [retail.log](2026-05-21-a6-captures/scen8_sewer_chamber/retail.log) | [acdream.log](2026-05-21-a6-captures/scen8_sewer_chamber/acdream.log) | pending | | 9 | scen9_sewer_corridor | [retail.log](2026-05-21-a6-captures/scen9_sewer_corridor/retail.log) | [acdream.log](2026-05-21-a6-captures/scen9_sewer_corridor/acdream.log) | pending | ## Analysis tables (filled by A6.P2) ### Table 1 — Per-site push-back delta *Placeholder — filled by A6.P2 analysis. Rows = (site × scenario) cross-product. Delta computed as `‖output_center − input_center‖` per call. Bug candidate threshold: ratio > 3× retail.* | Site | Scenario | Retail mean delta (mm) | Retail p99 (mm) | acdream mean (mm) | acdream p99 (mm) | Ratio | |---|---|---|---|---|---|---| ### Table 2 — Path-frequency diff *Placeholder — filled by A6.P2 analysis. Paths labeled 1-7 per the find_collisions dispatcher.* | Scenario | Path | Retail count | acdream count | Diff % | |---|---|---|---|---| ### Table 3 — ContactPlane lifecycle diff *Placeholder — filled by A6.P2 analysis.* | Scenario | Retail CP writes/sec | acdream CP writes/sec | Retail CP-restore-from-LKCP/sec | acdream CP-restore/sec | |---|---|---|---|---| ### Table 4 — Sub-step state mutations *Placeholder — filled by A6.P2 analysis. Fields: cell_array_valid, hits_interior_cell, walk_interp, walkable, collide.* | Scenario | Field | Retail mutations/sec | acdream mutations/sec | |---|---|---|---| ## Per-scenario narrative (filled by A6.P2) ### Scenario 1 — Inn doorway entry *Placeholder.* ### Scenario 2 — Inn stairs ascent *Placeholder.* *(etc. — 3 through 9)* ## Findings (filled by A6.P2) *Numbered bug candidates. Each entry contains: title, retail decomp anchor (line in acclient_2013_pseudo_c.txt), our suspect code site (file + line), divergence quantified, proposed fix sketch, scenarios affected.* ``` - [ ] **Step 3: Commit the stub structure** ```bash git add docs/research/2026-05-21-a6-captures/ docs/research/2026-05-21-a6-cdb-capture-findings.md git commit -m "$(cat <<'EOF' docs(research): A6.P1 — capture directory structure + findings stub Creates the 9 per-scenario capture directories (gitkeep stubs) and the findings doc stub at docs/research/2026-05-21-a6-cdb-capture-findings.md. A6.P1 fills the capture log slots; A6.P2 fills the analysis tables and findings section. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` --- ### Task 15: Execute the 9 capture scenarios (USER-DRIVEN) **Files:** - Modify (filled by capture runs): `docs/research/2026-05-21-a6-captures/scen{1..9}_/{retail,acdream}.log` - Modify: `docs/research/2026-05-21-a6-cdb-capture-findings.md` (update "Status" column from `pending` → `captured`) **Operator role:** This task is USER-DRIVEN — the user runs retail + acdream clients, executes the scripted walks, and confirms each scenario's capture pair is filed. Each scenario is ~5 min of user time at the keyboard. Captures can be split across days; each scenario's pair is self-contained. For EACH of the 9 scenarios: - [ ] **Step 1: Position retail at scenario start** Open retail client, navigate to the scenario start position. For scenario 1: outside the Holtburg inn front door, facing the doorway. Stop. (Don't move while the cdb attaches.) - [ ] **Step 2: Attach cdb with the scenario tag** ```powershell .\tools\cdb\a6-probe-runner.ps1 -ScenarioTag "" ``` Wait for `a6-probe armed: BPs 1-7 set, threshold=50000 total hits, qd on threshold` in the cdb console. - [ ] **Step 3: Launch acdream with all probes enabled** In a SEPARATE PowerShell window: ```powershell $env:ACDREAM_DAT_DIR = "$env:USERPROFILE\Documents\Asheron's Call" $env:ACDREAM_LIVE = "1" $env:ACDREAM_TEST_HOST = "127.0.0.1" $env:ACDREAM_TEST_PORT = "9000" $env:ACDREAM_TEST_USER = "testaccount" $env:ACDREAM_TEST_PASS = "testpassword" $env:ACDREAM_DEVTOOLS = "1" $env:ACDREAM_PROBE_PUSH_BACK = "1" $env:ACDREAM_PROBE_INDOOR_BSP = "1" $env:ACDREAM_PROBE_CELL = "1" $env:ACDREAM_PROBE_CELL_CACHE = "1" $env:ACDREAM_PROBE_CONTACT_PLANE = "1" dotnet build -c Debug dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Debug 2>&1 | Tee-Object -FilePath "docs\research\2026-05-21-a6-captures\\acdream.log" ``` Navigate `+Acdream` to the same scenario start position. Stop. - [ ] **Step 4: Perform the scripted walk in BOTH clients** Per the README table: | Scenario | Walk script | |---|---| | 1 inn doorway | Walk forward through door, stop just inside | | 2 inn stairs | Walk up 4 steps, stop on landing | | 3 inn 2nd floor | Walk forward 3 m, sidestep 1 m, walk back | | 4 cottage cellar | Walk to cellar opening, descend 2 steps | | 5 sewer entry | Walk into portal, then walk 2 m forward inside | | 6 sewer first stair | Walk down full stair flight | | 7 sewer inter-room | Walk through portal, stop 1 m past | | 8 sewer chamber | Walk in, traverse center, walk out other side | | 9 sewer corridor | Walk full length end-to-end | Perform the SAME walk in retail and in acdream. cdb fires BPs; acdream emits `[push-back]` lines. - [ ] **Step 5: Teardown** cdb auto-detaches at 50K hits. If it doesn't fire within ~30 sec of the walk completing, press Ctrl-Break in the cdb console. Close acdream by gracefully closing the window (NOT Stop-Process, per CLAUDE.md logout-before-reconnect rules). - [ ] **Step 6: Verify capture files are non-empty** ```powershell $dir = "docs\research\2026-05-21-a6-captures\" Get-Item "$dir\retail.log", "$dir\acdream.log" | Format-Table Name, Length ``` Expected: both files > 1 KB. If retail.log is < 1 KB, BPs didn't fire — investigate (probably PDB load failed or retail wasn't in-world). If acdream.log doesn't contain `[push-back]` lines, the env var didn't take effect — re-launch. - [ ] **Step 7: Mark scenario captured + commit** Update `docs/research/2026-05-21-a6-cdb-capture-findings.md`: change the scenario's row "Status" from `pending` to `captured`. ```bash git add docs/research/2026-05-21-a6-captures// docs/research/2026-05-21-a6-cdb-capture-findings.md git commit -m "$(cat <<'EOF' capture(research): A6.P1 — scenario Paired retail + acdream traces filed at docs/research/2026-05-21-a6-captures//. Co-Authored-By: Claude Opus 4.7 (1M context) EOF )" ``` **Repeat steps 1–7 for all 9 scenarios.** Total user time: ~45 min (5 min per scenario) + ~30 min capture-setup overhead = ~75 min single session. Splittable across days; each scenario's commit is self-contained. --- ## A6.P1 acceptance Phase A6.P1 is complete when: 1. All 9 scenarios have `{retail,acdream}.log` pairs filed under `docs/research/2026-05-21-a6-captures/scenN_/`. 2. Each log pair is non-empty (retail > 1 KB, acdream > 1 KB). 3. Each scenario's row in `docs/research/2026-05-21-a6-cdb-capture-findings.md` shows Status = `captured`. 4. `pdb-match-verification.txt` is filed as audit trail. 5. The `[push-back]`, `[push-back-disp]`, `[push-back-cell]` probes ship on main (Tasks 1–9 committed). 6. `dotnet build` green, `dotnet test` baseline unchanged (no test regressions from the probe instrumentation — probe is zero-cost when off). A6.P2 takes the captures + findings doc stub and produces the quantitative analysis tables + bug candidates list.