diff --git a/docs/reports/2026-07-28-campaign-v-report.md b/docs/reports/2026-07-28-campaign-v-report.md index 51cf6109..b1231be7 100644 --- a/docs/reports/2026-07-28-campaign-v-report.md +++ b/docs/reports/2026-07-28-campaign-v-report.md @@ -238,31 +238,57 @@ that mattered. That's the campaign's per-slice discipline working as intended: ## Current status -- **V8 (performance gate)** is **running**. Its first commit landed the - missing instrument: the Vulkan arm had been silently wired to - `NullRenderFrameGpuMeasurement` and emitted no `[frame-prof]` line at all, so - the campaign's own performance tooling had nothing to point at it. GPU - timestamp measurement now brackets identically on both arms. The acceptance - table (CPU frame p50 ≤ 1.60 ms, GPU p50 ≤ 1.00 ms, working set ≤ 600 MiB, - private set ≤ 860 MiB, 0 B/frame managed allocation, CPU/GPU p99 ≤ GL) is the - next thing this slice measures against the RX 9070 XT. -- **V9 (Linux CI)** is **implemented, first CI run pending**. A `linux-vulkan` - job now runs the probe on lavapipe under Xvfb, asserts a clean accepting - verdict, checks the forced-unsupported exit-4 path, and verifies committed - `.spv` binaries are byte-identical to a fresh compile. lavapipe satisfies - every one of the seventeen gated features, including `samplerAnisotropy`, - which V7 made load-bearing. The physical Linux GPU row and Wayland stay - deferred on the same precedent as Slice L. -- **V10 (cutover)** is **ahead**: Vulkan becomes the default backend, GL stays - reachable by environment variable for one further slice, and **user visual - sign-off** is the gate — the same kind of connected session the user already - ran once mid-campaign (six targeted checks, all passed with merits: the AD-46 - treeline judged invisible in practice, dyed-gear composites, doorway - look-out/threshold crossing, stacked translucency, icon/text crispness, and - motion feel — the one open finding from that session is #253 below). -- **V11 (closeout)** deletes `Gpu/Gl`, `OpenGLGraphicsDevice`, the - `ManagedGL*` stack, the ImGui developer stack, and UI Studio, and re-measures - working set one final time. +> **Updated 2026-07-29.** The campaign is **complete**. V8 through V11 have all +> landed; the tree is statically green and OpenGL is gone. What remains is +> runtime evidence for V11, which is blocked by a **machine fault rather than a +> campaign result** — see below and +> [`2026-07-29-overnight-report.md`](2026-07-29-overnight-report.md) §1.1. + +- **V8 (performance gate)**, **V9 (Linux CI)** and **V10 (cutover)** are + **complete**. V8's first commit landed the missing instrument: the Vulkan arm + had been silently wired to `NullRenderFrameGpuMeasurement` and emitted no + `[frame-prof]` line at all, so the campaign's own performance tooling had + nothing to point at it. V9's `linux-vulkan` job runs the probe on lavapipe + under Xvfb, asserts a clean accepting verdict, checks the forced-unsupported + exit-4 path, and verifies committed `.spv` binaries are byte-identical to a + fresh compile. V10 made Vulkan the default backend behind the user's visual + sign-off; the one open finding from that session is #253 below. The physical + Linux GPU row and Wayland stay deferred on the same precedent as Slice L. +- **V11 (closeout)** is **deleted and statically green; runtime gates + outstanding.** Five commits (`844cf092` → `c265b52d`) removed **27,607 lines + against 1,870 added** across 204 files. `Gpu/Gl`, `OpenGLGraphicsDevice`, the + `ManagedGL*` stack, `GLHelpers`, `GLStateScope`, both render-state caches, + `BindlessSupport`, `GraphicalGlFunctionProbe`, the ImGui project, the Studio + tree, the `ui-studio` verb, `RenderBackendKind` and the + `ACDREAM_RENDER_BACKEND` escape hatch are all gone. `Silk.NET.OpenGL` and + `.Extensions.ARB` are dropped — **final reference count zero**. 9/9 shader + pairs recompile. + +**Three findings from the deletion.** *Chorizite could not be dropped*, and not +for the reason the risk register predicted: `TextureFormat` sits in the +`IWorldTextureArray.CreateClampedArray` signature the **Vulkan** path +implements, and `BoundingBox` is a **serialized type in the pak format**, so +removing it touches the on-disk format and is its own slice. +*`Studio/SampleData.cs` was production code*, not devtools — +`InteractionRetainedUiComposition` uses it as the character sheet's fallback — +so it was moved, not deleted. And *one real bug fell out*: +`WbMeshAdapter.Dispose()` was still pattern-matching the deleted +`GpuFrameFlightController` to decide whether to wait for submitted GPU work. +`VulkanFrameFlightController` replaced that type at V6a and the site was never +updated, so **the wait had been silently dead on every Vulkan run since V6a**. +Deleting the GL type is what turned a no-op into a compile error. + +**Why the runtime gates did not run.** The offline pixel gate died at startup in +`vkGetPhysicalDeviceSurfaceCapabilitiesKHR`. Bisecting put the fault outside the +tree — the client fails identically at a pre-V11 commit whose offline capture had +succeeded three hours earlier — and `vulkaninfo --summary`, a Khronos tool +containing no acdream code, fails at the same call. Win32 surface creation is +broken process-wide on this machine ([#259](../ISSUES.md)); Vulkan itself is +healthy and both adapters report 1.4. Nothing was relaxed to manufacture a pass +and nothing was declared green on a prediction — a gate that could not run is not +a gate that passed. The outstanding commands are listed in the overnight report; +the pre-deletion baseline for the self-differential is already on disk at +`artifacts/v11-pre`. --- @@ -271,7 +297,10 @@ that mattered. That's the campaign's per-slice discipline working as intended: - **[#248](../ISSUES.md)** — `FrustumCuller` extracts its near plane with the GL `[-1,1]`-NDC formula against a `[0,1]`-NDC projection; harmless today (makes culling strictly more permissive near the eye) but wrong hygiene. - OPEN. + **DONE 2026-07-29** — `near = Normalize(col3)`, pinned by a theory asserting + the extracted near distance equals the camera's near value across four + near/far pairs; the old formula fails all four. The gate half of its + acceptance (offline pixel gate + connected route) is outstanding under #259. - **#249** — Released bindless texture slots never call `MakeNonResident` before the texture is deleted, which `GL_ARB_bindless_texture` leaves undefined, and leaks a resident handle for the process lifetime per release. @@ -279,7 +308,14 @@ that mattered. That's the campaign's per-slice discipline working as intended: - **#250** — Four "zero managed allocation" tests fail intermittently, roughly one run in three, from tiered-JIT/GC measurement noise rather than a real regression — but an acceptance-gating test that flakes trains everyone to - re-run until green. OPEN. + re-run until green. **DONE 2026-07-29**, and it was not noise: in all four the + measured window was never the warmed path — two measured a thousand-iteration + loop written inline (which on-stack replacement rewrites mid-flight, on the + measuring thread), and two measured a code path the warmup had never taken. + Fixed with a shared `ZeroAllocationProbe` that measures already-warmed batches + and reports their minimum; **the zero bound is unchanged and the apparatus has + its own tests proving it can still fail.** The family turned out to be ten + tests, not four. 20/20 clean App-suite runs. - **#251** — `glClientWaitSync` returned a fence status of `0` (not a value the API is specified to return) and crashed the render loop once in nine connected runs; possibly the same below-the-API driver family the diff --git a/docs/reports/2026-07-29-overnight-report.md b/docs/reports/2026-07-29-overnight-report.md new file mode 100644 index 00000000..eee8092b --- /dev/null +++ b/docs/reports/2026-07-29-overnight-report.md @@ -0,0 +1,414 @@ +# Overnight consolidation — 2026-07-29 + +**Branch:** `claude/git-sync-status-5fb1d2` +**Started at:** `d312bd2f` (Campaign V slice V11 landed; OpenGL deleted) +**Sessions merged:** the enum verification campaign and the wire-stack audit +**Machine constraint:** [#259](../ISSUES.md) — Win32 Vulkan surface creation is +broken process-wide, so **no client was launched**. Everything below is build, +test and documentation. + +--- + +## 1. What needs you + +Open questions first, because several of them gate work that is otherwise ready +to start. Nothing here is blocked on more analysis — each one needs a decision or +a machine that can make a window. + +### 1.1 Reboot the machine, then run five gates + +`vulkaninfo --summary` — a Khronos tool containing no acdream code — fails at +`vkGetPhysicalDeviceSurfaceCapabilitiesKHR` with `ERROR_UNKNOWN`. Vulkan itself +is healthy (both adapters enumerate and report 1.4); Win32 *surface* creation is +what is broken, and it is broken for every process on the box. It was bisected +to a pre-V11 commit whose offline capture had succeeded three hours earlier, so +it is transient driver/compositor state of the class a reboot clears. + +V11 is committed and statically green. Its runtime evidence is outstanding, and +this is the exact outstanding list from campaign §5.5.24: + +| Gate | Command | +|---|---| +| Offline pixel gate (VK self-differential) | `tools/run-offline-pixel-gate.ps1 -Out artifacts/v11-post -Baseline artifacts/v11-pre -SkipBuild` | +| Repeat connected gate | `tools/run-repeat-connected-gate.ps1 -Runs 3` | +| Connected world-lifecycle route | `tools/run-connected-world-lifecycle-gate.ps1` | +| Validation proven-loaded, zero errors | any connected launch with `ACDREAM_DEVTOOLS=1` | +| Working-set re-measure | the offline scene, once it renders | + +The pre-deletion baseline for the self-differential is **already on disk** at +`artifacts/v11-pre`, captured before the deletion. The left-hand side of the +comparison survived the fault; only the right-hand side is missing. + +**Also now runtime-outstanding:** [#248](../ISSUES.md)'s near-plane fix landed +tonight with a unit test, but its other acceptance criterion — unchanged culling +in the offline pixel gate and the connected route — needs the same window. The +change can only tighten culling toward the true frustum, which the issue had +already established is the safe direction, but it has not been seen running. + +### 1.2 Three decisions the enum campaign could not make + +The campaign explicitly refused to guess on these and recorded them rather than +inventing an answer. All three are yours. + +1. **`WeenieError` — adopt 362 server-side status codes wholesale?** acdream has + 16 members; the catalog's `StatusMessage` has 372, with 10 shared and **zero + conflicts**. Retail's `charError` (26 members) is a *different* enum — + character-creation errors only — so retail cannot arbitrate this one. Register + row AP-15 already tracks that our translation table covers only ~30 common + codes. Ideally paired with retail's `string_table.bin` for the real sentences. +2. **`SoundId` — adopt retail's table, or record the subset as a divergence?** + Ours is a curated 23-member local subset of retail's `SoundType` (206), with + acdream-local names (`FootstepGrass`, `BuffApplied`) that do not correspond + 1:1 to retail members. Either adopt wholesale, or give it a register row. + Neither was done. +3. **Re-clone the reference repos.** Five of six are empty — **and this is true + of the main checkout, not just a worktree.** It has two concrete costs. The + enum campaign left **456 of 864 property members single-sourced** (transcribed + from the catalog, no independent attestation) that ACE and Chorizite would + promote to two-oracle confirmed. And CLAUDE.md's "cross-reference at least two + of them" is currently unexecutable as written, so every session re-solves it + privately — four duplicate ACE copies under `%TEMP%` are the evidence. Working + copies exist at `C:\Users\erikn\source\repos\client\ACE` and + `C:\Users\erikn\source\repos\holtburger`; **Chorizite.ACProtocol was not found + anywhere on disk** and needs a genuine re-clone. + +A fourth, cheaper lead the campaign flagged but could not pursue: the client +DAT's own `EnumMapper` file type is a genuinely *retail* oracle for property +names, and `acclientlib` already has a reader for it. That is the most promising +unexplored route to attesting the single-sourced members without any re-clone. + +### 1.3 One instrumented connected session + +The wire audit's highest-leverage next action, and it needs a connected client: + +``` +ACDREAM_DUMP_OPCODES=1 +``` + +on an otherwise normal Coldeve session. The audit catalogued all 349 opcodes but +could not *rank* the 128 MISSING rows, because nothing tells it which of them the +server actually sends during play. One environment variable converts "128 missing +parsers, unknown priority" into a real work order. This is the cheapest +high-value item on the board. + +### 1.4 Walked-portal follow-up for #256 and #257 + +Both were observed in the same long live Coldeve session with repeated +town-portal-network transits, and both are HIGH: + +- **#256** — server-spawned signs and portals go *visually* missing after + repeated transits while remaining interactive, so the entity is alive in the + object table and only its render projection is gone. +- **#257** — working set balloons to ~1.5 GB against the ~930 MiB neighborhood + the campaign baselines measured, suggesting per-transit accumulation. + +Neither has been reproduced since, and neither can be worked without a client. +Both are marked "backend attribution pending" — whether they are Vulkan-era or +pre-existing is unknown, and a walked portal-network session is the only thing +that settles it. Worth doing in the same sitting as §1.1, since the machine will +already be up. + +### 1.5 Two `MEMORY.md` entries point at documents that do not exist + +Out of my reach to fix — user-level memory lives outside this repo — so flagging +it here instead. + +`claude-memory/MEMORY.md` indexes `research/2026-06-04-property-enum-divergence.md` +(the "929 values across 7 enums" ledger) and +`research/2026-06-04-magic-number-audit.md`. **Neither exists** — not in the +working tree, not under any ref (`git log --all --diff-filter=A` finds no add), +and the memory directory has no `research/` subfolder at all. The same pattern +holds for the 2026-06-04 combat-math and wire-catalog drops. + +This has a real cost, already paid twice tonight. The enum campaign could not +reproduce or audit the 929 figure and regenerated from scratch, arriving at 864 +property members; the wire audit hit the identical wall. A link that silently +resolves to nothing is worse than no link, because a future session plans around +a document that does not exist. Suggest either restoring them or repointing those +index entries at the two documents that landed tonight, which supersede them: + +- `docs/research/2026-07-29-enum-verification-campaign.md` +- `docs/research/2026-07-29-wire-stack-audit.md` + +--- + +## 2. What landed overnight + +Six commits on `claude/git-sync-status-5fb1d2`, `d312bd2f` → `HEAD`. + +### 2.1 The enum verification campaign (merged) + +`github/overnight/enums` (`c19680fd`, 5 commits) merged **with no conflicts**. +It was cut at `b70b9832`, before the deletion, and its subject turned out to be +disjoint from V11's: the campaign lives entirely in `AcDream.Core` and its tests, +while V11 emptied `AcDream.App`. Not one file was touched by both. + +- 17 files, **+3,767 / −27** lines +- **+597 tests**, verified exactly — the `Properties` namespace alone runs 597 +- Names for AC's seven property tables, verified against two oracles +- Corrections to `DamageType`'s rotated bits and `ItemType`'s shifted craft ladder +- The retail members the equipment and physics enums were missing +- Names for `AmmoType`, `CombatUse` and `ItemUseable` + +### 2.2 The wire-stack audit (merged) + +`github/overnight/wire-audit` (`41f74fcd`, 6 commits), same base, **one conflict** +— see §2.3. + +- 14 files, **+2,068 / −38** lines +- **+59 tests**; `AcDream.Core.Net.Tests` went 600 → 659 +- **Three real parser fixes:** ranged speech carries a range float the parser was + eating; a chat type that is never sent was silently dropping every transient + string on it; `xpSpent` is a dword on the wire where we were writing eight bytes +- The transport flag word pinned against ACE across all 23 bits +- Golden fixtures generated from ACE's own writer rather than hand-typed hex +- The audit document, covering all 349 opcodes + +### 2.3 The one merge conflict: #255, reconciled + +Both branches reopened **#255** — the `RetailDatLoader` concurrency tests that +measure the thread pool rather than the loader — on the same day, from different +trees, without knowing about each other. + +Neither is a duplicate. The V11 closeout saw **2 failures in 5** complete-solution +Release runs on the post-deletion tree; the wire-audit session saw **2 in 4** on +the pre-deletion tree; both saw **124/124 in isolation every time**. They +independently reached the same conclusion — `TaskCreationOptions.LongRunning` is +a hint, not a guarantee — and independently proposed the same fix, a rendezvous +inside the read stub. + +Resolved by merging the two notes into one issue with **both evidence sets kept** +as labelled subsections, rather than one overwriting the other. Four failures +across nine runs on two trees is a materially stronger case than either half, and +the agreement between two blind observations is the part worth preserving. No +assertion was weakened; the fix itself remains open. + +My own 20-run baseline tonight independently reproduced it a third time — +**4 failures in 20** complete-solution runs — which is consistent with both. + +### 2.4 #248 — the near plane is `col3`, not `col4 + col3` + +`FrustumPlanes.FromViewProjection` extracted the near plane with the +Gribb-Hartmann form written for OpenGL's `[-1,1]` clip-space z range, against +projections from `Matrix4x4.CreatePerspectiveFieldOfView`, whose range is `[0,1]`. +Under `[-1,1]` the near plane is `clip.z = -clip.w`, which is `col4 + col3`; +under `[0,1]` it is `clip.z = 0`, which is `col3` alone. + +The error put the effective near threshold at `-n·f/(2f-n)` — about 0.5 m where +the retail chase camera asks for 1.0 m — which only ever *kept* geometry the true +frustum would have dropped. Harmless, and still wrong; it is the same mistake +that *was* visible in `PortalProjection`, where it culled the cell behind a +doorway the camera stood close to. + +Pinned by a theory over four near/far pairs asserting the extracted plane is unit +length, faces down -Z, and stands off the eye by exactly the camera's near value. +**The test was run against the old formula before commit and fails all four +cases**, so it measures the fix rather than merely accompanying it. The far plane +is unchanged under both conventions and is pinned alongside so a later edit +cannot drift it. + +Status: DONE for the unit-test half of its acceptance criterion; the gate half is +in §1.1. + +### 2.5 #250 — fixed at the measurement, and the family was larger than four + +**The four named members shared one root: the measured window was never the +warmed path.** This had been dismissed as inherent noise in +`GC.GetAllocatedBytesForCurrentThread` three separate times. It is not noise. + +| Test | Warmup | Measured window | +|---|---|---| +| `UiDatFontTests` | 1 call | a **10,000-iteration loop** written inline | +| `RenderFrameProductTests` | **8** calls | a **1,000-iteration loop** written inline | +| `CurrentRenderSceneOracleTests` | 1 call | a 10,000-iteration loop written inline | +| `ArchRenderSceneTests` | `Apply(registrations)` | `Apply(**updates**)` — a different switch arm | + +Two mechanisms follow. A test method is JIT-compiled at tier 0 like anything +else, and a long-running loop in tier-0 code is replaced mid-flight by **on-stack +replacement**, which compiles on the thread running the loop — so its bookkeeping +is charged to the window being measured. That is the loop-shaped ones. And +`ArchRenderSceneTests` warmed one arm of a switch and measured the other, so the +measured call was the first ever into `ApplyUpdate` and paid that arm's tier-0 +JIT, type loads and static initialisation inside the window; +`RenderFrameProductTests` warmed 8 times, below the tier-0 call-counting +threshold of **30**, so promotion was still pending when measurement began. + +That also explains the signature nobody could account for — clean in isolation, +failing about one run in three. Alone, the process is quiet and the runtime has +finished before the assertion arrives. Alongside eight other test assemblies, +tier-0 compilation never stops, the call-counting delay is re-armed continually, +and the work slides into the window. + +**The fix** is `tests/AcDream.App.Tests/ZeroAllocationProbe.cs`. It invokes the +step many times before measuring anything, then measures windows that run the +same already-warmed loop over the same already-taken path. Each window is a +**batch** of 32 invocations and it reports the **minimum** across 4 of them. Both +halves are load-bearing: the minimum excludes a one-time cost, and the batch is +what keeps the assertion as strong as the loops it replaces — minimising over +*single* invocations would report zero for a path that allocates every tenth +call. I had written it that way first and the apparatus test caught it. + +**The bound is untouched: exactly zero, no tolerance, no retry, no assertion +relaxed.** `ZeroAllocationProbeTests` proves the apparatus can still fail — a +step allocating every call reads above zero and does throw, a first-invocation +cost reads as zero, a cost every tenth call is caught, and the one stated limit +(the batch must cover the period) is pinned as a test rather than left as prose. + +**The family was larger than four.** The first pass converted only the named four. +A 20-run baseline disproved "none of the others has been observed failing" within +minutes — `LiveEntityRuntimeTests` failed in run 2, `StaticRenderProjection` +`JournalTests` in runs 14 and 18, both the same shape, neither previously +recorded. Run 19 was sharper still: the issue named +`SurfaceOverrideFingerprint_DictionaryHotPathAllocatesNothing`, and the first +pass had converted a *different* test in that same file. Matching by file was not +matching by test. + +All ten strict-zero sites are now on the probe. **Two came out stricter rather +than merely steadier:** + +- `StaticRenderProjectionJournalTests` was measuring a synchronise whose journal + **does not coalesce**. Repeating it grew the journal by 1,000 entries per call + — 192,000 by the end of a probe run — so the steady state it claimed to test + did not exist, and the single-call window had been hiding that. Its step is now + the whole frame cycle, synchronise *and* drain, putting `DrainTo` inside the + measured window for the first time. +- `RetailInboundEventDispatcherTests` asserted a hard-coded 1,001 callbacks; it + now counts its own dispatches and pins the callback count against them. + +Four sites asserting a *tolerance* rather than zero were deliberately left alone +(`CellViewDedupTests` ×2, `PortalProjectionTests` ×2) — their ceilings already +absorb this noise and none has flaked. `PortalProjectionTests` is worth +revisiting: its ceiling exists explicitly to tolerate "a tiered-JIT/ArrayPool +bookkeeping transition ... to the first measured batch", which is exactly what +the probe removes, so it could probably be tightened to zero now. + +**Acceptance:** the issue asks for 20 consecutive clean Release runs of the App +suite. See §4 for the count actually achieved and how to read it. + +### 2.6 Worktree sweep + +Removed **9** finished worktrees — the two temp ones +(`%TEMP%\claude\prerevert`, `%TEMP%\claude\v4a-verify-base`) and seven +`agent-a*` paths including the two whose branches were merged tonight. Pruned +afterward. `codex/*`, `.worktrees/*` and the named `claude/*` worktrees were not +touched. + +**Two were deliberately left in place**, because "finished" is load-bearing and +neither is: + +- `agent-a1589ee2f5360c7a2` — has an **unresolved merge conflict** (`UU + src/AcDream.Core/Physics/TransitionTypes.cs`), three other modified physics + files, and an untracked new `EdgeSlideTests.cs`. This is in-progress L.2.3 + step-up/step-down work belonging to some other session, not tonight's. +- `agent-af83539515c87d43e` — has an uncommitted **1,073-line** edit to + `WbDrawDispatcher.cs` (−961/+112), an in-progress GL-removal pass. V11 has + since landed the equivalent, so this is probably superseded scratch — but it is + a thousand lines of uncommitted work and deleting it is not reversible. + +Both are yours to keep or discard. + +--- + +## 3. Campaign V — final state + +**The campaign is complete and the tree is statically green. Its runtime +evidence is outstanding, and that is a machine fault rather than a campaign +result.** + +V11 removed the GL backend across 5 commits (`844cf092` → `c265b52d`): 204 files, +**+1,870 / −27,607** lines. Gone are `Gpu/Gl`, `ManagedGL*`, `GLHelpers`, +`GLStateScope`, both render-state caches, `BindlessSupport`, +`GraphicalGlFunctionProbe`, the ImGui project, the Studio tree, the `ui-studio` +verb, `RenderBackendKind` and the `ACDREAM_RENDER_BACKEND` escape hatch. +`Silk.NET.OpenGL` and `.Extensions.ARB` are dropped — **final reference count +zero**. 9/9 shader pairs recompile. + +Three findings from the deletion are worth keeping: + +- **Chorizite could not be dropped, and not for the reason the risk register + predicted.** It was assumed to survive only via `IUniformBuffer`. In fact + `TextureFormat` sits in the `IWorldTextureArray.CreateClampedArray` signature + that the **Vulkan** path implements, and `BoundingBox` is a **serialized type + in the pak format**. Dropping it touches the on-disk format and is its own + slice. +- **`Studio/SampleData.cs` was production code**, not devtools — + `InteractionRetainedUiComposition` uses it as the character sheet's fallback. + Moved, not deleted. +- **One real bug fell out.** `WbMeshAdapter.Dispose()` was still pattern-matching + the deleted `GpuFrameFlightController` to decide whether to wait for submitted + GPU work. `VulkanFrameFlightController` replaced that type at V6a and the site + was never updated, so **the wait had been silently dead on every Vulkan run + since V6a**. Deleting the GL type is what turned a no-op into a compile error. + +Nothing was relaxed to manufacture a pass and nothing was declared green on a +prediction. A gate that could not run is not a gate that passed — the outstanding +list is §1.1. + +--- + +## 4. Numbers + +### Complete solution suite + +| | Passed | Skipped | Total | +|---|---|---|---| +| V11 baseline (`d312bd2f`) | 8,999 | 5 | 9,004 | +| **Tonight (`HEAD`)** | **9,666** | **5** | **9,671** | + +The **+667** decomposes exactly, with nothing unaccounted for: + +| Source | Tests | +|---|---| +| Enum verification campaign | +597 | +| Wire-stack audit | +59 | +| #248 near-plane theory (4 near/far pairs) + far-plane pin | +5 | +| #250 `ZeroAllocationProbe` apparatus guards | +6 | +| **Total** | **+667** | + +Per project at `HEAD`: App 3,941/3 · Core 3,898/2 · Core.Net 659 · UI.Abstractions +543 · Runtime 415 · Content 124 · Headless 67 · Bake 15 · Cli 4. **Zero failures.** + +Release build: **0 errors.** 21 warnings, all pre-existing — one `xUnit1025` +(duplicate `InlineData` in `MotionInterpreterTests`) and a family of `CS8767` +nullability mismatches in the App test composition fakes. None cites a file +touched tonight; the count is unchanged from the V11 baseline. + +### The #250 acceptance gate + +The issue asks for 20 consecutive clean Release runs of the **App suite**, and +that is the right scope: it isolates #250 from #255, which lives in +`AcDream.Content.Tests` and is still open. + +**Result: 20 / 20 clean, 3,941 passed / 3 skipped every run.** + +For contrast, the pre-fix 20-run **complete-solution** baseline taken earlier the +same night, on the same machine: + +| Failure | Runs | +|---|---| +| #250 family (3 distinct tests) | 2, 14, 18, 19 | +| #255 `RetailDatLoaderTests` | 7, 14, 17, 18 | + +So the #250 family went from 4 failing runs in 20 to 0 in 20, and the three tests +involved were each converted. **#255 is untouched and still flakes** — it is a +different issue with an open fix, and it will keep appearing in +complete-solution runs until the rendezvous lands. + +One caveat, stated plainly: 20 consecutive App-suite runs is what the acceptance +criterion asks for and what was delivered, but the App suite alone applies less +parallel pressure than a complete-solution run. The strongest evidence would be +20 clean complete-solution runs, and that is not currently obtainable while #255 +flakes independently. Re-running this gate after #255 is fixed would close that +gap. + +--- + +## 5. Where to pick up + +1. Reboot, then §1.1's five gates and §1.4's walked portal session — one sitting. +2. Answer §1.2's three enum decisions; they unblock adoption commits that are + otherwise ready. +3. One `ACDREAM_DUMP_OPCODES=1` session (§1.3) turns the wire audit's 128 MISSING + rows into a ranked work order. +4. #255's rendezvous fix — the diagnosis is settled from three independent + observations and the fix direction is agreed; it is only unwritten.