acdream/docs/reviews/2026-08-18-r3-test-truth-ledger.md
2026-08-18 13:19:30 +02:00

50 KiB
Raw Blame History

R3 test-truth and cleanup ledger

Status: active

Branch: codex/release-stabilization

Starting commit: 8e884679e0b6ce3dc1c84004ba9c5c8e3ff91d2a

This is the cross-session authority for R3. The historical all-file audit remains in test-quality-audit.md; this ledger reconciles that baseline against current source and records each cleanup decision before code is removed. R3 does not change product behavior.

Current executable baseline

The clean R2 gate at implementation commit c38f6b88 built all 44 maintained projects with zero warnings and ran every default test assembly once:

  • 12 test assemblies;
  • 14,742 passed;
  • 77 reported skipped;
  • 0 failed; and
  • one redundant Core theory row discarded by xUnit discovery before the totals.

The six-case reduction from the earlier 14,748-pass headline is understood: seven launcher editor-focus theory rows were consolidated into one fact that still executes all seven variants in a single Avalonia application session.

Fresh reproducible syntax inventory

tools/audit-test-inventory.ps1 now regenerates the complete attributed-method manifest from tracked C# test sources with Roslyn:

pwsh ./tools/audit-test-inventory.ps1

The generated JSON lives under ignored artifacts/test-audit/; it is not a second 6.8 MB checked-in source of truth. The script and this reviewed ledger are durable, while paths and line numbers regenerate after every batch. The inventory refreshed for Batch L reports:

Syntax signal Current count
Tracked/parsed C# test files 1,256 / 1,256
Attributed test methods (not expanded theory cases) 11,447
Exact duplicate-data rows 0
Reviewed body-equivalent groups / methods 11 / 27
Methods containing at least one empty return; 138
Empty-return sites 143
Direct / same-file-helper prerequisite-return candidates 2 / 1
Mechanical output-only candidates 2
Constant-truth assertion methods / sites 0 / 0
Reviewed syntactic self-comparison methods / sites 4 / 5
Reviewed diagnostic methods 57
Methods directly using Thread.Sleep / Task.Delay 15 / 14
Cancellable-infinite-only / elapsed-time methods 5 / 24
Methods directly reading environment variables 47
Methods directly reading .cs source text 63

The three remaining prerequisite-return candidates are all reviewed branch false positives: the two Windows/Linux factory assertions and the launcher's cross-platform directory-link helper. Every true prerequisite return found by the inventory now fails explicitly inside its selected non-hermetic lane. The remaining 143 empty returns are behavioral control flow, callback exits, or the three platform branches; they are not missing-prerequisite passes.

The output-only classifier follows same-file helper calls, so an assertion used only while constructing a probe can prevent an otherwise diagnostic method from appearing in its two-candidate result. The reviewed Purpose=Diagnostic set is therefore the authority: Batch C's 51 methods plus six artifact/report writers reconciled in Batch L, for 57 methods and 76 discovered cases (28 App, 48 Core). Their investigative output and historical rationale remain executable outside the release total.

The five syntactic self-comparisons are reviewed, not vacuous: two call a hash twice to assert determinism, one reads the singleton twice, and two read the same Runtime owner's properties twice to assert stable identity. The inventory keeps these candidates visible separately from the now-zero constant-truth assertions.

Exact 77-skip reconciliation

The latest clean-gate TRX files account for every reported skip:

Classification Count Current source R3 decision
Installed retail DAT lane 73 InstalledDatFactAttribute across nine files Retain the contracts, replace the campaign-specific shared reason with prerequisite- and suite-specific identity, and report this lane separately. Batch B assigns all nine classes to Lane=InstalledDat.
Manual fixture generation 2 ChatLayoutFixtureGenerator.GenerateChatFixture; RadarLayoutFixtureGenerator.GenerateRadarFixture Delete both redundant generators: the existing comprehensive RetailLayoutFixtureGenerator already owns their chat and radar outputs. Assign that generator to the explicit Manual lane.
Empty future scaffold 1 PvsConformanceTests.Pvs_CottageInterior_MatchesRetailCellDrawList Delete the test. Preserve its retail oracle and capture recipe here and in the existing P0 plan.
Known product failure 1 TowerAscentReplayTests.TowerAscent_StaircaseStaysConeVisible_EveryStep Do not pretend this is unavailable coverage. Keep the oracle and move it to an explicitly reported known-failure/non-blocking lane until #119 is fixed.

Installed-DAT skip distribution:

Test class Count
ChargenPreviewControllerTests 10
CharacterCreationLiveDatTests 42
CharacterManagementLiveDatTests 3
DatStringEscapeSweepTests 1
LayoutImporterMediaBearingChildSweepTests 3
MapHousePanelLiveDatMountTests 1
MapNoteLiveDatTests 3
TooltipLiveDatTests 7
UiButtonCorpusSweepTests 3

The 11 source sites that conditionally threw SkipException.ForSkip were not part of the R2 77 because their prerequisites happened to be available on that machine. Batch G preserves their reasons but replaces the misleading dynamic- skip exception with explicit lane-prerequisite failures. No static skip or SkipException.ForSkip remains in current test source.

The lane vocabulary is deliberately orthogonal:

  • Lane states the execution environment (InstalledDat, PreparedPackage, Live, Manual, Windows, Linux, or SystemFont);
  • Purpose=Diagnostic marks output/investigation apparatus that cannot add to the contract-test pass count; and
  • Status=KnownFailure keeps a named executable oracle visible without making a green release claim.

The default gate excludes all three dimensions. An explicitly selected lane must fail clearly when its prerequisite is missing; it may not pass through an empty return. The 73 custom installed-DAT facts retain discovery-time skips when their opt-in is absent so each unavailable contract and reason remains identifiable in the lane report.

Finding disposition

Finding Current disposition Evidence / next action
T-001 launcher lock inversion resolved in R1 Deterministic captured-callback regression and bounded full gate.
T-002 physics tautology high-confidence cleanup batch A Compare old-model and new-model reflection decisions, as the surrounding contract states.
T-003 duplicate theory row high-confidence cleanup batch A Remove literal 0x41000012, which is identical to MotionCommand.Crouch; remove the temporary analyzer suppression.
T-004 warning mismatches resolved in R2 Clean rebuild is zero-warning with repository-wide warnings-as-errors.
T-005 dormant panel stack production reachability and architecture intent reconciled in batch P; user taxonomy decision remains No shipping code implements IPanelRenderer/IPanelHost or constructs ChatPanel, DebugPanel, or VitalsPanel, but the architecture explicitly preserves this first-party developer-panel contract for issue #258. Do not call its behavioral tests useless or delete the contract as dead code. Decide separately whether 26 fake-renderer self-tests belong in the release count.
T-006 misleading installed-DAT reason resolved in batch B Shared opt-in is now ACDREAM_RUN_INSTALLED_DAT_TESTS=1 (legacy switch retained), the reason names the lane, and all nine owners carry Lane=InstalledDat.
T-007 271 silent passing gates resolved in batch G All 280 directly found gates plus three later-reconciled sites now fail explicitly when their selected lane lacks its prerequisite. The only three syntax candidates left are reviewed cross-platform branch false positives.
T-008 incapable-of-failing diagnostics resolved in batches A, C, and L The literal wiring smoke test was deleted, the GPU contract tautology was repaired, and the six remaining constant-truth diagnostic assertions were removed after their output was preserved under Purpose=Diagnostic.
T-009 wall-clock double-click tests resolved in batch E Four sleeps were replaced by a deterministic test clock behind an internal factory overload. The production factory still reads Environment.TickCount64 exactly as before.
T-010 two useless cases high-confidence cleanup batch A Delete SmokeTest.TestProject_IsWired and ChaseCameraTests.ImplementsICamera; compilation already proves both claims.
T-011 output-only methods classified in batches C and L The reviewed current set is 57 methods / 76 cases. All carry Purpose=Diagnostic, preserving the apparatus while removing it from release pass totals. Contract-shaped names remain explicitly flagged until a stable oracle exists.
T-012 source-text freezes replacement map complete in batch I; 46 implementation-shape facts remain staged Twelve whole-tree architecture rules and five cross-artifact contracts stay. The other 46 are campaign-era literal implementation freezes; retire each only beside its semantic/behavioral replacement, with user approval for owner/lifecycle assertions that have no equivalent yet.
T-013 controller self-comparison high-confidence cleanup batch A Capture the first controller next to the first body and compare every retry with that reference.
T-014 seven load-sensitive tests six mechanisms repaired in batch F; one product defect classified Virtual/wall-clock mixing, tiered-JIT allocation noise, a live controller clock, and a ThreadPool-start timing oracle were removed without weakening behavioral contracts. DatSoundCache #321 is a real in-flight-entry race and now runs as Status=KnownFailure pending a product fix.
T-015 four non-prerequisite skips resolved in batches A/B PVS scaffold deleted with rationale preserved; redundant chat/radar generators deleted in favor of the comprehensive Manual lane; tower oracle is Status=KnownFailure.
T-016 historical test taxonomy first descriptive-identity batch active in batch J Remove opaque AP/R/J/K/Slice codes from current test/type names while preserving provenance in comments and ledgers. The 47 Issue### files remain an explicit user-decision set because their IDs still connect tests to retail evidence.
T-017 Avalonia ownership reopened and closed in batch D The full gate exposed the same compositor ownership class between six newer MainWindowViewTests facts. Their six named assertion phases now run in one owned Avalonia application session; 25 fresh-process stress iterations and the complete gate pass.
T-018 stderr observer race resolved in R2 Live reader shares writes/deletes; 25 focused repetitions plus the complete gate.
T-019 remaining explicit waits resolved in batches MO All nine fixed-delay negative oracles now use observed monitor/thread/lease/process state. The remaining 24 elapsed-time methods are the reviewed cancellation, real-time protocol, cooperative-yield, bounded-polling, and positive-timeout categories from Batch H.
T-020 exact duplicate bodies/data resolved in batch K Four redundant executions were removed. The remaining 11 body-equivalent groups are intentionally split theories with disjoint, meaningfully named datasets; the inventory enforces zero repeated rows within a theory or across body-equivalent theories.
T-021 suspicious assertion shapes resolved in batch L The inventory enforces zero Assert.True(true) / Assert.False(false) sites and reports syntactic self-comparisons for review. All five current self-comparisons assert meaningful determinism or stable identity.

Preserved rationale for removals in batch A

PVS scaffold

The empty PVS fact has no executable oracle and must not remain a permanent skip. Its useful note is preserved here: retail PView::ConstructView(CEnvCell*) at 0x005a57b0 produces the ordered cell_draw_list for a (viewer_cell, eye) input. A future conformance test requires a retail trace captured around PView::DrawCells/cell_draw_list. The intended invariants were: the PVS root equals physics CurrCell.Id; a cell seen through two portals appears once per slice; and dungeon outside_view == 0. The complete original scaffold and capture plan remain in docs/superpowers/plans/2026-06-03-p0-conformance-apparatus.md.

Compile-only smoke cases

SmokeTest.TestProject_IsWired contains only Assert.True(true). ChaseCameraTests.ImplementsICamera assigns ChaseCamera to ICamera and calls ToString() without an oracle. Removing them discards no runtime contract: the test project build and the remaining camera behavior tests are strictly stronger evidence.

Batch protocol

Each cleanup batch must:

  1. update this ledger before or with the change;
  2. preserve useful historical rationale in a plan, issue, or this ledger;
  3. run the directly affected test projects without retries;
  4. run a clean warning-as-error build when analyzer/discovery shape changes;
  5. commit one coherent classification/fix group; and
  6. run the complete local Release gate before R3 closeout.

Ambiguous cases stay open in this ledger and are presented to the user rather than being deleted by inference.

Batch A verification

The first high-confidence batch was verified before commit:

  • complete non-incremental Release rebuild: 44 projects, 0 warnings, 0 errors;
  • Core: 4,795 passed / 0 skipped / 0 failed;
  • App: 5,511 passed / 76 skipped / 0 failed; and
  • Runtime: 1,756 passed / 0 skipped / 0 failed.

The count delta is intentional and classified: Core removed the two useless compile-only cases and the skipped PVS scaffold; App gained one case by splitting the old mixed/tautological depth-stencil test into two independently named contracts. Core emitted no duplicate-case discovery warning.

Preserved rationale for removals in batch B

The chat- and radar-only fixture generators were not the sole way to recreate their committed JSON. RetailLayoutFixtureGenerator already includes retail layout IDs 0x2100006F and 0x21000074 and writes the same chat_2100006f.json and radar_21000074.json destinations as part of its complete 20-layout run. Deleting the two permanently skipped duplicates removes two false test entries without losing the regeneration recipe or retail notes; the comprehensive generator and docs/release-gate.md now own that workflow.

The tower staircase oracle is not unavailable or useless. Its former static skip documents issue #119 and the exact failing steps. Batch B keeps the executable assertion under Status=KnownFailure, separates two output-only methods with Purpose=Diagnostic, and makes missing installed DATs a clear lane prerequisite failure instead of a passing early return.

Batch B verification

The lane-classification batch was verified without changing product code:

  • App Release build: 0 warnings, 0 errors;
  • hermetic App lane, isolated: 5,505 passed / 0 skipped / 0 failed;
  • Installed-DAT contract lane without opt-in: 3 passed / 73 individually named skips / 0 failed (the local tower DAT prerequisite was available);
  • known-failure discovery: exactly one tower staircase oracle; and
  • Manual discovery: exactly one comprehensive fixture generator.

One concurrent three-host verification attempt reproduced T-014 rather than being hidden: the hermetic host failed the portal-clipping zero-allocation test at 6,904 bytes while the Installed-DAT and discovery hosts ran beside it. The same unmodified hermetic command then passed 5,505/5,505 in isolation. This is evidence for removing cross-host allocation sensitivity; it is not grounds to weaken the assertion or claim a clean concurrent result.

Batch C diagnostic classification

Batch C assigns the reviewed 51-method diagnostic set to Purpose=Diagnostic. No body, output, historical comment, or fixture is removed. This resolves the misleading release accounting without pretending that every investigation has a stable regression oracle.

The 15 contract-shaped methods called out by T-011 now have a Diagnostic_ prefix: four facility-hub scenarios, six stair/camera sweeps, two ambient-slot inventories, production-emission replication, and two drawn-polygon reports. Their current output and historical method references are preserved, while the new names no longer imply an asserted oracle. Promoting them back into the hermetic lane requires an asserted expected result; R3 will not invent those values.

Batch C verification:

  • App Release build: 0 warnings, 0 errors;
  • Core Release build, serialized after App: 0 warnings, 0 errors;
  • hermetic App: 5,479 passed / 0 skipped / 0 failed;
  • hermetic Core: 4,753 passed / 0 skipped / 0 failed; and
  • diagnostic discovery: 28 App + 42 Core = 70 cases from 51 methods.

An attempted parallel App/Core build collided on the shared AcDream.Plugin.Abstractions intermediate DLL. The repository gate serializes projects, so the authoritative verification is the two isolated clean builds above; no code or assertion was changed in response to that tooling collision.

Batch D prerequisite lanes and Avalonia ownership

The reviewed prerequisite map classifies every true candidate without deleting its existing guard:

Lane Attributed methods Prerequisite
InstalledDat 336 Installed retail DAT directory; includes the 73 custom installed-DAT facts and whole DAT-backed investigation classes.
PreparedPackage 2 Installed DATs plus validated acdream.pak.
Live 3 Explicit live handshake opt-in and reachable service.
Manual 1 Explicit fixture-regeneration opt-in.
Windows 7 Windows-only filesystem/process/timer behavior.
Linux 10 Linux permission/signal/monotonic-clock behavior.
SystemFont 2 A host system TTF available to the BitmapFont path.

Class-level traits legitimately cover some additional methods that share the same fixture owner, so the 336 installed-DAT method count is larger than the 280 syntax candidates. The only candidate methods without a lane are GraphicalHostPlatformServicesTests.CurrentPlatformOwnsPathsPacingAndNativeClosure and LinuxMonotonicFramePacingWaiterTests.PlatformFactorySelectsCurrentOperatingSystem. Both are hermetic cross-platform branch tests: on Windows or Linux they assert the matching branch and return only after the assertion. They are not silent prerequisite passes.

The 11 conditional SkipException.ForSkip source sites are also reconciled. They serve 12 test methods: installed-DAT asset contracts, one prepared-package contract, and two system-font contracts. xUnit v2 reports that exception shape as a failure rather than a dynamic skip, but the owning lanes now keep them out of the hermetic total. A later body-cleanup batch will replace the misleading skip wording/exception with explicit prerequisite failure or discovery-time lane behavior.

The first complete Batch D gate correctly failed in Launcher cleanup after 14,396 passes: the six MainWindowViewTests Avalonia facts could start and destroy isolated thread-affine compositors on different xUnit workers. The assertion bodies were preserved as six named private phases under one CompiledMarkupAndEveryModalFocusPathRunInOneOwnedAvaloniaSession fact. The focused two-case class then passed in 25 consecutive fresh processes (50/50 results), and the same full-gate context passed.

Batch D verification:

  • complete 44-project Release build: 0 warnings, 0 errors;
  • final syntax manifest: 11,450 attributed methods, 51 diagnostics, one known failure, 282 prerequisite-return candidates, and only the two reviewed cross-platform false positives unlaned;
  • complete hermetic Release gate: 14,392 passed / 0 skipped / 0 failed across all 12 test assemblies in 131.518 seconds; and
  • Launcher view stress: 25 fresh processes, 2/2 cases per process, no cleanup or ownership failures.

The 350-pass reduction from the clean R2 headline is exactly explained: batch A netted minus one case; batch B removed six non-hermetic passes; batch C removed 68 newly classified diagnostic cases; batch D removed 270 prerequisite-lane passes; and consolidating the six Avalonia sessions into one removed five case IDs without removing any assertion phase. All 77 former default skips are also accounted for by the PVS deletion and batch-B lane/deletion decisions.

Batch E indirect gates and deterministic input time

The inventory now follows same-file helper calls when looking for prerequisite returns. It found one additional path: LauncherSelfUpdateProcessTests.BackupJunctionOrSymlinkAfterCanonicalCrashCannotMutateOutsideOrLaunch calls CreateDirectoryLink, whose non-Windows branch creates the symbolic link and then returns before the Windows mklink /J implementation. This is a reviewed cross-platform control-flow branch, not a prerequisite gate or silent pass. The combined direct/indirect candidate count is therefore 283: 280 true lane-owned gates and three reviewed branch false positives.

The four InputDispatcherDoubleClickTests no longer sleep for 10 or 600 real milliseconds. InputDispatcher has an internal, test-assembly-only factory overload accepting the same millisecond tick delegate used by double-click recognition. The public production factory remains wired directly to Environment.TickCount64; only the tests use a manually advanced counter. The focused class passes 4/4 in 17 ms with exact 10 ms and 600 ms virtual intervals. The complete Release build then passed with 0 warnings/errors, and the no-retry hermetic gate passed 14,392/14,392 with zero skips or failures.

Batch F load-sensitive contracts

The seven cases in T-014 have now been separated into six unreliable test mechanisms and one real product defect:

  • #308 NakEmissionTests.LossSoak... no longer mixes its virtual transport clock with a 60-second DateTime.UtcNow cutoff and fixed sleeps. Its two convergence phases each permit exactly 120 half-second virtual steps and yield to the background receiver. The full 10,000-message oracle is intact; 25 fresh-process repetitions pass.
  • #302 and #346, the two PortalProjectionTests allocation contracts, now cross tiered-JIT/PGO thresholds before measuring and take the minimum of five warmed 1,000-operation batches. A linear result-array regression would allocate in every batch and still fail far above the existing ceilings.
  • #336 RuntimeCollisionReportingStateTests.WarmedSteadyContactRefreshDoesNotAllocate now earns the word "warmed": it performs one complete 10,000-refresh warmup and requires at least one of five subsequent 10,000-refresh batches to allocate exactly zero bytes. It passes in 25 fresh processes.
  • #340 StreamingWorkBudgetTests.DestinationAndEmptyUnloadPriorityNeverBypassPublicationBudget now supplies a frozen meter clock through an internal test-only constructor. The public production constructor still supplies Stopwatch.GetTimestamp and Stopwatch.Frequency exactly as before.
  • #402 LandblockBuildFactoryTests.Build_UsesTheSuppliedSharedReaderGate now starts a dedicated thread and observes it in WaitSleepJoin on the held monitor before checking that no DAT read occurred. It no longer treats a ThreadPool start within two seconds or an arbitrary 100 ms wait as evidence.
  • #321 DatSoundCacheTests.GetWave_ConcurrentSameId_PublishesOneCanonicalWaveAndDecodesOnce exposes a real race. A caller can pass the resident-cache check, pause, and reach _inflight after the winning caller has admitted the wave and removed its Lazy, producing a second decode. The assertion and rationale are preserved under Status=KnownFailure; R3 makes no cache behavior change.

The four changed App cases pass 100/100 across 25 fresh processes. The Runtime allocation case passes 25/25, and the Core.Net loss soak passes 25/25. Complete batch verification then passed: the 44-project Release build reports zero warnings/errors, the refreshed inventory reports two explicit known-failure methods and 15 remaining direct Thread.Sleep methods, and the no-retry hermetic gate passed 14,391/14,391 with zero skips or failures. The one-pass reduction is exactly #321 leaving the release lane.

Batch G honest prerequisite lanes

Batch G removes every true silent prerequisite pass found by the direct and same-file-helper inventory. Across 101 test files, 283 lane-owned return; sites now report a prerequisite failure when that lane was explicitly selected: 261 installed-DAT, ten Linux, seven Windows, three Live, and two prepared-package methods. Seventeen platform guards throw PlatformNotSupportedException; the remaining gates use lane-specific assertion failures. Production behavior and every contract assertion after the guard are unchanged.

The eleven conditional SkipException.ForSkip sites now use explicit prerequisite failures as well. Their asset, package, or font reason is retained, but a selected lane can no longer look green by dynamically skipping the contract. The refreshed syntax inventory finds zero true silent-prerequisite candidates. Its three remaining candidates are the reviewed Windows/Linux branch returns recorded in Batch E.

The focused installed-DAT run also exposed a taxonomy error rather than a product failure: 19 interactive layout methods need a retail DAT directory but are operator-driven probes, not automated DAT contracts. They now live under Lane=Manual, divided into ManualTask=LiveMountProbe (13) and ManualTask=PowerbarProbe (6). The comprehensive existing generator is separately named ManualTask=FixtureGeneration, so selecting a probe cannot rewrite committed fixtures. Current attributed-method lane ownership is:

Lane Methods
InstalledDat 317
PreparedPackage 2
Live 3
Manual 20
Windows 7
Linux 10
SystemFont 2

Focused verification before the complete gate:

  • Release build of all 44 maintained projects: 0 warnings, 0 errors;
  • installed-DAT contracts: 311/311 passed (App 150, Bake 3, Content 28, Core 130);
  • prepared-package contracts: 2/2 passed against the validated local package;
  • Windows contracts: 7/7 passed; system-font contracts: 2/2 passed;
  • manual live-mount probes: 13/13 passed; manual powerbar probes: 6/6 passed;
  • a Linux contract selected on Windows failed with the explicit wrong-host reason; and
  • a Live contract selected without opt-in failed with the explicit ACDREAM_LIVE=1/reachable-server prerequisite reason.

The fixture-generation task was intentionally not executed: its documented purpose is to rewrite fixture files, while this R3 batch is review/test-only. The no-retry complete hermetic Release gate passed 14,391/14,391 with zero skips or failures across all 12 test assemblies.

Batch H explicit-wait classification

The syntax inventory now records every direct Thread.Sleep and Task.Delay invocation instead of treating both method-level booleans as equivalent. The 38 attributed methods divide into six materially different groups:

Wait purpose Methods R3 disposition
Cancellable infinite suspension in a fake 5 Keep. Task.Delay(Timeout.InfiniteTimeSpan, token) advances only through the cancellation being tested and consumes no elapsed-time oracle.
Intentional real-time protocol/timeout contract 4 Keep with explicit bounds: two Live handshake race delays, the one-second net-probe cadence, and continuous unrelated shutdown drain.
Cooperative yield while virtual-clock/background transport work drains 8 Retain for now; prefer an observable receiver/worker signal when that seam exists. The virtual behavioral oracle does not derive from the sleep duration.
Bounded completion/readiness polling 11 Retain as integration polling with a terminal assertion and deadline; improve opportunistically with events, not by busy-spinning.
Fixed delay used to prove another operation is still blocked 9 originally; 0 remain Batches MO replace all nine with observed monitor/thread/lease/process state.
Positive completion timeout guard 1 Keep. The two-second WhenAny in RuntimeCharacterStateTests fails only if the operation does not complete; it does not delay a passing run.

The original nine fixed-delay negative oracles are:

  1. LiveSessionCommandRouterTests.ConcurrentDispose_WaitsForInFlightTransportThenMakesRouterInert;
  2. HostQuiescenceGateTests.ExternalStopWaitsForAdmittedCallbackToReturn;
  3. both SilkWindowCallbackBindingTests.ConcurrentDispose... contracts;
  4. LandblockStreamerPoolTests.Dispose_JoinsEveryWorkerInThePool;
  5. LandblockStreamerTests.DisposeAndConcurrentDisposeWaitForInFlightLoad;
  6. HeadlessPluginSessionTests.LateSubscriberReplayQueuesConcurrentRegistrationExactlyOnceInOrder;
  7. LauncherInstallerTests.IndependentInstallersSerializeAndWaitingCancellationTouchesNothing; and
  8. LauncherInstallerTests.OrphanBakeCanNeverPublishAfterRestartRecovery.

This classification is review evidence, not a claim that the remaining waits are flaky. The inventory run at 6faeb4a1 parsed all 1,256 tracked C# test files and reproduced 15 sleep methods, 23 delay methods, five cancellation- only methods, and 33 methods with some elapsed-time wait.

Batch I source-text replacement map

The refreshed inventory finds 63 attributed methods that directly read .cs source text. Reconciliation with historical T-012 assigns every method to one of three dispositions:

Disposition Methods Owning test files
Campaign-era implementation-shape freeze; replace in stages 46 ContentEffectsAudioCompositionTests, FrameRootCompositionTests, HostInputCameraCompositionTests, InteractionRetainedUiCompositionTests, LivePresentationCompositionTests, SessionPlayerCompositionTests, WorldRenderCompositionTests, GameWindowLiveSessionOwnershipTests, GameWindowRenderLeafCompositionTests, GameWindowHostBoundaryTests, ResourceCleanupGroupTests, RetailPViewPassExecutorTests, WorldRenderFrameBuilderTests, WorldSceneRendererTests, LandblockBuildOriginTests, LandblockPhysicsPublisherTests, LandblockRenderPublisherTests, GameWindowLiveEntityCompositionTests, UpdateFrameOrchestratorTests
Whole-tree architecture policy; retain, then make syntax/metadata-aware 12 LinuxPlatformBoundaryTests, RenderSceneArchitectureTests, RuntimePhysicsOwnershipTests, RuntimeEntityOwnershipTests
Source/project/artifact text is the actual cross-artifact contract; retain 5 ParticleBindlessInstanceTests, PerformanceToolsTests, LauncherProjectBoundaryTests

The 46 implementation-shape facts were useful during mechanical ownership cutovers, but are not durable behavioral evidence. They pin constructor spellings, local names, exact call fragments, or statement order; comments can satisfy many of their Contains checks, while a harmless equivalent refactor can fail them. Their intent is often valuable—single ownership, ordering, handoff, teardown, or absence of a parallel path—so wholesale deletion would discard real notes and weaken some boundaries.

R3 therefore uses this replacement rule for those 46 facts:

  1. preserve the ownership/order rationale in the architecture document or this ledger;
  2. identify an existing behavioral, lifetime-ledger, project-reference, or reflection/Roslyn guard that proves the same claim;
  3. add the semantic replacement first when none exists; and
  4. remove the literal source freeze in the same small batch.

The 12 whole-tree rules remain valuable even before conversion: they ban platform calls outside owners, enforce assembly/namespace containment, and prevent duplicate Runtime entity/physics authorities. The five cross-artifact tests compare two independently consumed artifacts (for example CPU/shader constants, launcher project/workflow/markup, and CLI route tooling); reading text is appropriate there.

No source-freeze fact is removed in this classification batch. The 46 staged facts are an ambiguous architecture decision and will be presented for user approval in behavior-owner groups rather than deleted from a numeric heuristic.

Source-freeze approval groups

The 46 campaign-era facts are not equivalent. Their current semantic coverage and safest replacement path divide into six owner groups:

Owner group Facts What the literal checks still prove R3 recommendation
Composition-root wiring 13 GameWindow calls the intended phase objects and no longer contains the extracted construction bodies. Phase-local tests cover ordering and rollback inside each phase, but not every root-to-phase link. Keep until one symbol-aware composition-graph guard proves the root links. Then remove the literal constructor/local-name checks.
Runtime root, host, and lifetime 12 One canonical Runtime root/command surface, typed owner handoffs, acquisition order, and native-window-last shutdown. Existing Runtime/lifecycle tests prove much of the behavior, but several sole-owner and transfer claims remain unique. Replace with direct ownership receipts, terminal-ledger assertions, and metadata dependency guards before removing any source freeze.
Render delegation and cleanup 4 Rendering is delegated and GameWindow does not regain leaf draw branches or resource ownership. The owning render suites already exercise the executor, frame builder, renderer, and resource disposal behavior. Best first conversion: add one symbol-aware boundary guard for the absence/delegation claim, then remove the four literal checks.
Streaming publication 4 The window does not own render/physics publication bodies, captured build origins flow through the extracted owners, and streamer teardown follows session reset. Publisher/build/origin suites already provide broad behavioral coverage. Best second conversion: consolidate the absence claims into a whole-tree architecture guard and retain the behavioral origin/teardown contracts.
Live-entity composition 2 Typed sources replace window closures and reset closes every streaming/readiness owner. Lifecycle tests cover convergence, but the exact constructor-shape claim is still literal. Replace with constructor/field metadata inspection plus the existing teardown ledger; do not delete alone.
Frame orchestration 11 Exact-once publication, frame-stage order, adapter ownership, and a deliberately thin OnUpdate. These are high-value order rules, but exact statement fragments are the most brittle implementation specification in the set. Replace order assertions with an observable fake event trace and use a symbol-aware dependency guard for the thin-root rule. This is the largest conversion and should be last.

Approval should authorize this replacement sequence, not wholesale deletion: render delegation, streaming, live entities, composition roots, Runtime/host lifetime, then frame orchestration. If the semantic replacement exposes a claim that exists only as historical campaign wording, preserve the rationale and bring that individual deletion back for review.

Batch P dormant panel reachability reconciliation

T-005's production-reachability half is now proved: repository-wide C# usage contains no production IPanelRenderer or IPanelHost implementation and no shipping construction of ChatPanel, DebugPanel, or VitalsPanel. The old ImGui backend is gone; retained UiHost/UiRoot controllers are the sole shipping presentation stack, and plugin UI uses IUiRegistry.AddMarkupPanel rather than IPanel.

That does not make the complete abstraction useless. The architecture document explicitly says AcDream.UI.Abstractions and the IPanel/IPanelRenderer developer-panel contract survive intact for a future host tracked by issue #258. ChatVM and VitalsVM are also live shared models consumed by retained UI, so their model/parser/command tests are production coverage and are outside T-005.

The dormant presentation-only subset currently contains 51 attributed methods (57 expanded cases):

Subset Methods Disposition
IPanelRendererWidgetTests and IPanelRendererMainMenuBarTests 26 They exercise only FakePanelRenderer, not a production backend. Treat as test-harness/contract self-tests; user decision whether to retain outside the release total, consolidate, or remove.
PanelContextTests 2 Small public-contract value, but only compiler-generated record round-trip/equality. Same taxonomy decision as the renderer self-tests.
ChatPanel layout, input, focus, and colored-render behavior 23 Meaningful executable behavior for the explicitly preserved future developer-panel contract. Retain unless that architecture promise is intentionally retired.

The earlier audit's recommendation to remove the whole stack was therefore too broad. The maintainability problem is narrower: 28 harness/trivial contract methods inflate release totals despite having no production renderer, while 23 panel behavior methods protect a deliberately dormant API. The UI framework plan also has stale present-tense statements that ImGui remains permanent, whereas the architecture authority correctly records its deletion; that is a documentation-reconciliation item, not evidence that the old backend still exists.

Batch J descriptive test identities

The first T-016 naming batch changes no oracle or production behavior. It renames eight opaque type/file identities and fifteen test methods whose AP, R, J, K, C3c, or Slice labels described the implementation campaign rather than the contract a maintainer needs to find:

Former identity family Durable identity
GameWindowSlice8BoundaryTests GameWindowHostBoundaryTests
Ap10WaterSemanticsTests, Ap71EntryRestrictionGateTests, Ap155StaticSpherePopulationMeasurementTests, Ap157SortingSphereFloodMeasurementTests WaterSemanticsTests, EntryRestrictionGateTests, StaticSpherePopulationMeasurementTests, SortingSphereFloodMeasurementTests
ConnectedR6SoakContractTests ConnectedWorldSoakRouteContractTests
C3cR1F3DriftModelSourcePinTests CreateAuthorityDriftModelSourcePinTests
R5Host / R5ManagerHarness.cs PhysicsObjHostStub / PhysicsManagerHarness.cs
J4/J5 Runtime methods gameplay-view, gameplay-command, checkpoint, simulation, and ownership-ledger names
K4/Slice-L/K1c/J9 methods multi-session profile, unsupported-platform explanation, legacy keymap difference, and stop-speed behavior names
AP-135/AP-195 method names placement-bookkeeping and authored-LED-sprite names

Provenance is not discarded. AP-157 remains the row key in the retail divergence register, the connected route keeps its established artifact name, and historical audit/plan documents retain the old identifiers. Current cross-references and test comments point to the new descriptive names. The source-freeze class summary now states its R3 replacement status instead of claiming to be a temporary Slice 8 checkpoint.

This batch intentionally does not rename the 47 Issue### files. Their descriptive suffixes are often useful, and the issue number can be the shortest path to a retail trace or reproduction. Re-homing those contracts by component while retaining Issue provenance is an architecture/taxonomy choice for user approval, not a mechanical cleanup.

Verification before the complete gate:

  • all 44 maintained projects build in Release with 0 warnings and 0 errors;
  • 102 focused App cases, 203 Core cases, 17 Runtime cases, 5 Headless cases, 1 Launcher.Core case, and 10 UI.Abstractions cases pass; and
  • the renamed installed-DAT population measurement passes 1/1 against the local retail DAT.

The no-retry complete hermetic Release gate passed 14,391/14,391 with zero skips or failures across all 12 test assemblies.

Batch K duplicate-body and theory-row truth

The inventory now fingerprints every attributed method body and compares InlineData case-sensitively both within a theory and across theories with an identical body. Case sensitivity prevents legitimate inputs such as iris / IRIS, Sunny / SUNNY, and 0x / 0X from being mislabeled as duplicates.

The initial 14 body-equivalent groups contained four redundant executions:

  • VulkanCapabilityReportContractTests.TheReportFileNameIsTheOneTheWorkflowPathNames duplicated the report-name assertion in VulkanCapabilityGateTests and did not inspect the workflow it named. The retained fact is now TheReportFileNameRemainsStableForDiagnosticsAutomation.
  • MotionInterpreterDoMotionFamilyTests.StopCompletely_NullPhysicsObj_Returns8 was byte-equivalent to the more descriptive MotionInterpreterTests.StopCompletely_NullPhysicsObj_ReturnsNoPhysicsObject.
  • CastSpellTests.ParseMagicUpdateSpell_RoundTrip duplicated the same parser contract under GameEventDispatcherTests, the parser's durable owner.
  • retail motion row (0x0150, 0x10000150u) appeared in both the recall-command theory and the generic anchor theory. It remains in the specifically named recall contract.

The other 11 groups are not useless duplicates. They deliberately reuse a small assertion body while separating disjoint datasets by meaning: command resolution, command argument shapes, valid chat tags, retail string escapes, weenie error-message evidence, help text, invalid chargen ranges, ACE/retail motion tables, character-option oracle sources, and environment-sound gaps. Combining those rows would erase useful failure names without reducing the assertion mechanism.

After cleanup the inventory reports 11,447 attributed methods, zero duplicate rows, and 11 reviewed body-equivalent groups containing 27 methods. Verification for the changed owners passes 46 App, 154 Core, and 32 Core.Net cases. The complete 44-project Release build reports zero warnings and zero errors. The no-retry complete hermetic Release gate passed 14,387/14,387 with zero skips or failures across all 12 test assemblies. The four-case reduction is exactly the three duplicate facts and one duplicate theory row removed above.

Batch L vacuous diagnostic assertions

Six investigation methods still ended in an unconditional green assertion:

  • three cellar-lip trajectory/replay artifact writers in CellarLipWedgeTests;
  • two cellar-ascent trajectory reports in CellarUpTrajectoryReplayTests; and
  • the installed-DAT front-approach probe in DoorCollisionApparatusTests.

These were useful tools but not regression tests. Batch L adds Purpose=Diagnostic, removes the six Assert.True(true, ...) calls, preserves the two reports that previously existed only as assertion messages by writing them to captured console output, and leaves the existing %TEMP% artifacts and probe logs intact. No historical investigation notes, fixtures, or probe logic were deleted.

The durable inventory now recognizes File.WriteAll* / File.AppendAll* as diagnostic-output signals and reports high-confidence constant-truth assertions separately from syntactic self-comparisons. It reports zero constant-truth sites. The five self-comparison sites were individually reviewed and retained:

  • Hash32Tests.Calculate_IsDeterministic and PacketHeaderTests.CalculateHeaderHash32_DeterministicForSameInput execute the calculation twice and compare the results;
  • NullCommandBusTests.Instance_IsSingleton reads the singleton twice; and
  • RuntimeEntityObjectLifetimeTests.Owner_ConstructsOneExactDirectoryAndObjectTablePerInstance verifies repeated access to both owned objects returns the same instances.

Batch L verification:

  • all six affected diagnostic methods pass, including the installed-DAT door probe;
  • the refreshed inventory reports 11,447 attributed methods, 57 diagnostic methods, zero constant-truth assertions, and five reviewed self-comparison sites across four methods;
  • the complete 44-project Release build reports zero warnings and zero errors; and
  • the no-retry complete hermetic Release gate passed 14,382/14,382 with zero skips or failures across all 12 test assemblies.

The five-case reduction from Batch K is exact: five formerly hermetic diagnostic facts are now excluded by Purpose=Diagnostic; the sixth was already outside the portable lane because its class requires installed DATs.

Batch M observable monitor-wait contracts

Four concurrency tests used a 50100 ms delay and then asserted that disposal had not completed. That was only indirect evidence: a delayed or saturated ThreadPool could satisfy the assertion before the disposal path had attempted to enter its production monitor.

Batch M runs each competing disposal/stop operation on a named dedicated thread, waits with a bounded SpinWait until the runtime reports ThreadState.WaitSleepJoin, and then verifies the thread joins after the controlled callback, transport send, or physical detach is released. This changes no production code and preserves every existing completion, inertness, and propagated-failure assertion. The converted contracts are:

  • HostQuiescenceGateTests.ExternalStopWaitsForAdmittedCallbackToReturn;
  • LiveSessionCommandRouterTests.ConcurrentDispose_WaitsForInFlightTransportThenMakesRouterInert;
  • SilkWindowCallbackBindingTests.ConcurrentDisposeWaitsForPhysicalDetachToComplete; and
  • SilkWindowCallbackBindingTests.ConcurrentDisposeCannotHidePhysicalDetachFailure.

Batch M verification:

  • the four focused contracts pass;
  • 25 fresh-process focused iterations pass, for 100/100 observed-wait cases;
  • the refreshed inventory reduces direct Task.Delay methods from 23 to 19 and elapsed-time methods from 33 to 29;
  • the complete 44-project Release build reports zero warnings and zero errors; and
  • the no-retry complete hermetic Release gate remains 14,382/14,382 with zero skips or failures across all 12 test assemblies.

Five fixed-delay negative oracles remain: the landblock streamer and pool disposal contracts, headless concurrent late-subscriber replay, and the two launcher installer/recovery contracts.

Batch N observable landblock-worker joins

The two landblock disposal contracts used 50100 ms delays to infer that LandblockStreamer.Dispose was waiting for its dedicated worker threads. Batch N replaces those delays with direct observation of the disposer threads:

  • LandblockStreamerTests.DisposeAndConcurrentDisposeWaitForInFlightLoad observes the primary disposer blocked in a worker Join, then observes the concurrent disposer blocked behind the disposal monitor; and
  • LandblockStreamerPoolTests.Dispose_JoinsEveryWorkerInThePool observes the disposer blocked while all three controlled worker lanes remain in their loader callbacks.

Both tests then release the loaders, require every disposal thread to join within the existing bound, and retain their exception and post-disposal inertness checks. Production code is unchanged.

Batch N verification:

  • both focused contracts pass;
  • 25 fresh-process iterations of each pass, for 50/50 observed-wait cases;
  • the refreshed inventory reduces direct Task.Delay methods from 19 to 17 and elapsed-time methods from 29 to 27;
  • the complete 44-project Release build reports zero warnings and zero errors; and
  • the no-retry complete hermetic Release gate remains 14,382/14,382 with zero skips or failures across all 12 test assemblies.

Three fixed-delay negative oracles remain: headless concurrent late-subscriber replay and the two launcher installer/recovery contracts.

Batch O final fixed-delay negative oracles

Batch O removes the last three timing-based absence-of-completion tests:

  • HeadlessPluginSessionTests.LateSubscriberReplayQueuesConcurrentRegistrationExactlyOnceInOrder now runs registration on a dedicated thread and observes it enter WaitSleepJoin while Runtime's exact replay read lease is held;
  • LauncherInstallerTests.IndependentInstallersSerializeAndWaitingCancellationTouchesNothing now waits until the second installer has actually encountered the held transaction lease before cancelling it; and
  • both rows of LauncherInstallerTests.OrphanBakeCanNeverPublishAfterRestartRecovery now observe publication-lock contention where applicable and wait for the exact orphan child process to exit before checking that it cannot publish later.

The launcher observation points are internal callbacks on the existing transaction/publication lease retry paths. They are unset in production, add no new public API, and do not change lock, retry, cancellation, or publication behavior. The former 150/200 ms delays and post-exit settle delay are gone.

Batch O verification:

  • the one focused Headless fact and three focused Launcher cases pass;
  • 25 fresh-process Headless iterations and 25 fresh-process Launcher iterations pass, totaling 100/100 exercised cases;
  • the refreshed inventory reduces direct Task.Delay methods from 17 to 14 and elapsed-time methods from 27 to 24;
  • none of Batch H's nine fixed-delay negative-oracle methods contains a direct sleep or delay;
  • the complete 44-project Release build reports zero warnings and zero errors; and
  • the no-retry complete hermetic Release gate remains 14,382/14,382 with zero skips or failures across all 12 test assemblies.

The 24 remaining elapsed-time methods retain their reviewed Batch H classification: cancellation fakes, intentional real-time protocol behavior, cooperative yields, bounded integration polling, or a positive timeout guard.

Batch Q issue-number taxonomy review

The 47 Issue### files contain 155 attributed methods. They are not a hidden duplicate or source-freeze family: none reads production source text and none contains a direct timing wait. Twenty-nine methods are explicitly classified Purpose=Diagnostic; the other 126 are executable regression contracts. Ninety-four methods belong to the installed-DAT lane, overlapping both groups where retail assets are the evidence prerequisite.

The issue prefix still has concrete navigation value. Every number maps to a named section in docs/ISSUES.md, and the descriptive suffix already exposes the owning behavior—for example Issue334BspBoxCellMembershipTests and Issue345SteepSlopeGlideTests. A 47-file mass rename would discard that direct evidence key, create large history churn, and would not make the individual contracts materially easier to understand.

R3's recommendation is therefore to retain the current Issue### class/file prefixes. Continue correcting individual method names whose oracle overclaims, and keep diagnostic methods outside the release count, but do not re-home 126 useful regressions merely to erase their provenance. If the issue archive is later split into component-owned records, a class-level Issue trait can preserve filtering before any component-based file rename. This recommendation remains a user approval item because it closes T-016 without code churn.