diff --git a/tests/AcDream.App.Tests/Rendering/Walk/WalkOracleTrace.cs b/tests/AcDream.App.Tests/Rendering/Walk/WalkOracleTrace.cs
new file mode 100644
index 00000000..d4af658a
--- /dev/null
+++ b/tests/AcDream.App.Tests/Rendering/Walk/WalkOracleTrace.cs
@@ -0,0 +1,150 @@
+using System.Globalization;
+using System.Text.RegularExpressions;
+
+namespace AcDream.App.Tests.Rendering.Walk;
+
+///
+/// Parser for the FW0 retail walk-oracle traces
+/// (docs/research/2026-08-30-fw-walk-oracle/ — captured live from the
+/// PDB-paired 2013 retail client on 2026-08-30; format documented in that
+/// directory's README). These traces are Campaign FW's conformance
+/// fixtures: FW1's RetailFrameWalk must reproduce each frame's event
+/// sequence position-for-position.
+///
+/// The final frame of every capture is dropped: the harness detaches at
+/// the frame MARKER, so the last frame never records its draws and would
+/// read as a false "outdoor, no landscape" frame.
+///
+public static class WalkOracleTrace
+{
+ public static IReadOnlyList Parse(IEnumerable lines)
+ {
+ var frames = new List();
+ List? current = null;
+ int currentNumber = 0;
+
+ foreach (string line in lines)
+ {
+ Match frameMatch = FramePattern.Match(line);
+ if (frameMatch.Success)
+ {
+ if (current is not null)
+ frames.Add(new WalkOracleFrame(currentNumber, current));
+ currentNumber = int.Parse(
+ frameMatch.Groups[1].Value, CultureInfo.InvariantCulture);
+ current = new List();
+ continue;
+ }
+ if (current is null)
+ continue;
+
+ if (line == "LS")
+ {
+ current.Add(WalkOracleEvent.Landscape());
+ continue;
+ }
+ Match buildingMatch = BuildingPattern.Match(line);
+ if (buildingMatch.Success)
+ {
+ current.Add(WalkOracleEvent.Building(ParseId(buildingMatch.Groups[1].Value)));
+ continue;
+ }
+ Match insideMatch = DrawInsidePattern.Match(line);
+ if (insideMatch.Success)
+ {
+ current.Add(WalkOracleEvent.DrawInside(ParseId(insideMatch.Groups[1].Value)));
+ continue;
+ }
+ Match cellsMatch = DrawCellsPattern.Match(line);
+ if (cellsMatch.Success)
+ {
+ uint[] cells = cellsMatch.Groups[3].Value
+ .Split(' ', StringSplitOptions.RemoveEmptyEntries)
+ .Select(ParseId)
+ .ToArray();
+ current.Add(WalkOracleEvent.DrawCells(
+ outsideViewCount: int.Parse(
+ cellsMatch.Groups[1].Value, CultureInfo.InvariantCulture),
+ declaredCount: int.Parse(
+ cellsMatch.Groups[2].Value, CultureInfo.InvariantCulture),
+ cells));
+ }
+ // Anything else is cdb chrome (banner, prompts, symbol notes) — ignored.
+ }
+
+ // The last STARTED frame (still in `current`) is deliberately never
+ // appended — that is the truncated detach frame (see class doc).
+ return frames;
+ }
+
+ public static IReadOnlyList Load(string fixtureName)
+ {
+ string root = FindRepositoryRoot();
+ string path = Path.Combine(
+ root, "docs", "research", "2026-08-30-fw-walk-oracle", fixtureName + ".log");
+ return Parse(File.ReadLines(path));
+ }
+
+ private static string FindRepositoryRoot()
+ {
+ DirectoryInfo? dir = new(AppContext.BaseDirectory);
+ while (dir is not null)
+ {
+ if (File.Exists(Path.Combine(dir.FullName, "AcDream.slnx")))
+ return dir.FullName;
+ dir = dir.Parent;
+ }
+ throw new InvalidOperationException(
+ "AcDream.slnx not found above the test base directory; walk-oracle fixtures unavailable.");
+ }
+
+ private static uint ParseId(string hex)
+ => uint.Parse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+
+ private static readonly Regex FramePattern = new(@"^F (\d+)\s*$", RegexOptions.Compiled);
+ private static readonly Regex BuildingPattern = new(@"^BLD ([0-9a-f]{8})\s*$", RegexOptions.Compiled);
+ private static readonly Regex DrawInsidePattern = new(@"^DI ([0-9a-f]{8})\s*$", RegexOptions.Compiled);
+ private static readonly Regex DrawCellsPattern = new(
+ @"^DC pv=[0-9a-f]{8} ov=(\d+) n=(\d+):((?: [0-9a-f]{8})*)\s*$", RegexOptions.Compiled);
+}
+
+public sealed record WalkOracleFrame(int Number, IReadOnlyList Events)
+{
+ /// The frame's root: the first DrawInside cell, or null when outdoor-rooted.
+ public uint? InteriorRootCell
+ => Events.FirstOrDefault(e => e.Kind == WalkOracleEventKind.DrawInside)?.CellId;
+
+ public bool HasLandscape => Events.Any(e => e.Kind == WalkOracleEventKind.Landscape);
+
+ public IEnumerable Buildings
+ => Events.Where(e => e.Kind == WalkOracleEventKind.Building).Select(e => e.CellId!.Value);
+}
+
+public enum WalkOracleEventKind
+{
+ Landscape,
+ Building,
+ DrawInside,
+ DrawCells,
+}
+
+public sealed record WalkOracleEvent(
+ WalkOracleEventKind Kind,
+ uint? CellId,
+ int OutsideViewCount,
+ int DeclaredCellCount,
+ IReadOnlyList Cells)
+{
+ public static WalkOracleEvent Landscape()
+ => new(WalkOracleEventKind.Landscape, null, 0, 0, Array.Empty());
+
+ public static WalkOracleEvent Building(uint cellId)
+ => new(WalkOracleEventKind.Building, cellId, 0, 0, Array.Empty());
+
+ public static WalkOracleEvent DrawInside(uint cellId)
+ => new(WalkOracleEventKind.DrawInside, cellId, 0, 0, Array.Empty());
+
+ public static WalkOracleEvent DrawCells(
+ int outsideViewCount, int declaredCount, IReadOnlyList cells)
+ => new(WalkOracleEventKind.DrawCells, null, outsideViewCount, declaredCount, cells);
+}
diff --git a/tests/AcDream.App.Tests/Rendering/Walk/WalkOracleTraceTests.cs b/tests/AcDream.App.Tests/Rendering/Walk/WalkOracleTraceTests.cs
new file mode 100644
index 00000000..c066c4a0
--- /dev/null
+++ b/tests/AcDream.App.Tests/Rendering/Walk/WalkOracleTraceTests.cs
@@ -0,0 +1,171 @@
+namespace AcDream.App.Tests.Rendering.Walk;
+
+///
+/// Integrity tests for the FW0 walk-oracle fixtures: every checked-in
+/// trace parses, and the load-bearing shapes recorded in the fixture
+/// README hold. FW1's conformance suite builds on these parsed frames;
+/// if a fixture is edited or recaptured, these goldens catch drift.
+///
+public sealed class WalkOracleTraceTests
+{
+ private const uint FarBuilding = 0xF518002Eu;
+
+ public static readonly TheoryData AllFixtures = new()
+ {
+ "terrace-center",
+ "terrace-edge",
+ "cathedral-arrival",
+ "holtburg-doorway-still",
+ "holtburg-walkout",
+ "holtburg-street-porchcam",
+ "holtburg-street-outdoor",
+ "holtburg-walkabout",
+ "foundry-entry",
+ "foundry-deep",
+ };
+
+ [Theory]
+ [MemberData(nameof(AllFixtures))]
+ public void Fixture_parses_with_complete_frames(string name)
+ {
+ IReadOnlyList frames = WalkOracleTrace.Load(name);
+
+ Assert.NotEmpty(frames);
+ // Frame numbers are contiguous from 1; the truncated final frame is dropped.
+ Assert.Equal(1, frames[0].Number);
+ Assert.Equal(frames.Count, frames[^1].Number);
+ Assert.All(frames, f => Assert.NotEmpty(f.Events));
+ }
+
+ [Fact]
+ public void Terrace_edge_draws_the_far_building_every_outdoor_frame()
+ {
+ // The #456 acceptance oracle: retail HIDES the vista by depth cover,
+ // not by omission — 0xF518002E is submitted every single frame.
+ IReadOnlyList frames = WalkOracleTrace.Load("terrace-edge");
+
+ Assert.All(frames, f =>
+ {
+ Assert.Null(f.InteriorRootCell);
+ Assert.True(f.HasLandscape);
+ Assert.Contains(FarBuilding, f.Buildings);
+ });
+ }
+
+ [Fact]
+ public void Cathedral_arrival_roots_interior_and_culls_the_far_building()
+ {
+ IReadOnlyList frames = WalkOracleTrace.Load("cathedral-arrival");
+
+ Assert.All(frames, f =>
+ {
+ Assert.Equal(0xF4180106u, f.InteriorRootCell);
+ Assert.True(f.HasLandscape); // drawn THROUGH the exit view
+ Assert.DoesNotContain(FarBuilding, f.Buildings);
+ });
+ }
+
+ [Fact]
+ public void Doorway_root_is_stable_across_every_frame()
+ {
+ IReadOnlyList frames = WalkOracleTrace.Load("holtburg-doorway-still");
+
+ Assert.All(frames, f => Assert.Equal(0xA9B4013Fu, f.InteriorRootCell));
+ }
+
+ [Fact]
+ public void Walkout_hands_over_between_interior_cells_in_one_frame()
+ {
+ IReadOnlyList frames = WalkOracleTrace.Load("holtburg-walkout");
+
+ uint?[] roots = frames.Select(f => f.InteriorRootCell).Distinct().ToArray();
+ Assert.Equal(new uint?[] { 0xA9B4013Fu, 0xA9B40150u }, roots);
+ // Exactly one handover: the root sequence is two contiguous runs.
+ int transitions = frames.Zip(frames.Skip(1))
+ .Count(pair => pair.First.InteriorRootCell != pair.Second.InteriorRootCell);
+ Assert.Equal(1, transitions);
+ }
+
+ [Fact]
+ public void Street_porchcam_roots_at_the_camera_cell_not_the_player()
+ {
+ // The player stood in the street; the chase camera sat inside the
+ // cottage porch — and retail rooted the frame at the CAMERA's cell.
+ IReadOnlyList frames = WalkOracleTrace.Load("holtburg-street-porchcam");
+
+ Assert.All(frames, f => Assert.Equal(0xA9B40150u, f.InteriorRootCell));
+ }
+
+ [Fact]
+ public void Street_outdoor_never_enters_an_interior_root()
+ {
+ IReadOnlyList frames = WalkOracleTrace.Load("holtburg-street-outdoor");
+
+ Assert.All(frames, f =>
+ {
+ Assert.Null(f.InteriorRootCell);
+ Assert.True(f.HasLandscape);
+ });
+ }
+
+ [Fact]
+ public void Foundry_entry_flips_outdoor_to_interior_and_drops_the_landscape()
+ {
+ IReadOnlyList frames = WalkOracleTrace.Load("foundry-entry");
+
+ WalkOracleFrame flip = frames.First(f => f.InteriorRootCell is not null);
+ Assert.Equal(0xA9B40178u, flip.InteriorRootCell);
+ // The frame before the flip is fully outdoor; the flip frame itself
+ // draws NO landscape and NO buildings — the pure-interior shape.
+ WalkOracleFrame before = frames[flip.Number - 2];
+ Assert.Null(before.InteriorRootCell);
+ Assert.True(before.HasLandscape);
+ Assert.False(flip.HasLandscape);
+ Assert.Empty(flip.Buildings);
+ }
+
+ [Fact]
+ public void Foundry_deep_draws_the_town_through_the_surviving_chain()
+ {
+ IReadOnlyList frames = WalkOracleTrace.Load("foundry-deep");
+
+ Assert.All(frames, f =>
+ {
+ Assert.Equal(0xA9B40176u, f.InteriorRootCell);
+ Assert.True(f.HasLandscape);
+ Assert.NotEmpty(f.Buildings);
+ });
+ }
+
+ [Fact]
+ public void Stationary_frames_repeat_their_event_sequence_exactly()
+ {
+ // README finding 6: while the camera is still, the whole-frame
+ // sequence repeats bit-for-bit. Assert it on the terrace fixture.
+ IReadOnlyList frames = WalkOracleTrace.Load("terrace-center");
+
+ WalkOracleFrame first = frames[0];
+ Assert.All(frames.Skip(1), f =>
+ {
+ Assert.Equal(first.Events.Count, f.Events.Count);
+ for (int i = 0; i < first.Events.Count; i++)
+ Assert.Equal(first.Events[i], f.Events[i], WalkOracleEventComparer.Instance);
+ });
+ }
+
+ private sealed class WalkOracleEventComparer : IEqualityComparer
+ {
+ public static readonly WalkOracleEventComparer Instance = new();
+
+ public bool Equals(WalkOracleEvent? x, WalkOracleEvent? y)
+ => x is not null && y is not null
+ && x.Kind == y.Kind
+ && x.CellId == y.CellId
+ && x.OutsideViewCount == y.OutsideViewCount
+ && x.DeclaredCellCount == y.DeclaredCellCount
+ && x.Cells.SequenceEqual(y.Cells);
+
+ public int GetHashCode(WalkOracleEvent obj)
+ => HashCode.Combine(obj.Kind, obj.CellId, obj.Cells.Count);
+ }
+}