22 KiB
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 at commit 8f490240 reports:
| Syntax signal | Current count |
|---|---|
| Tracked/parsed C# test files | 1,256 / 1,256 |
| Attributed test methods (not expanded theory cases) | 11,455 |
Methods containing at least one empty return; |
399 |
| Empty-return sites | 426 |
| Prerequisite-return candidates | 282 |
| Mechanical output-only candidates | 47 |
Methods directly using Thread.Sleep / Task.Delay |
20 / 23 |
| Methods directly reading environment variables | 47 |
Methods directly reading .cs source text |
63 |
The 282 prerequisite-return count is intentionally a review candidate set, not
a claim that all 399 methods are broken. It comprises 109 App, 125 Core, 29
Content, 12 Launcher.Core, three Core.Net, three Bake, and one Headless method.
The classifier includes external-asset, opt-in, and platform gates; behavioral
early exits inside callback tests remain outside that candidate set. Every
candidate still requires source inspection because Directory.Exists, for
example, can also be the behavior under test.
The output-only classifier follows same-file helper calls, but it cannot decide
whether an assertion merely establishes probe setup. The reviewed diagnostic
set is therefore 51 methods: the 47 mechanical candidates plus
OptionsPanelLiveMountProbeTests.ProbeLiveMountShapes,
DoorSetupGfxObjInspectionTests.HoltburgCottage_CellPortals_DatInspection, and
the two already classified tower diagnostics. Relative to T-011's historical
51-method table, delete the removed PVS scaffold and add
TowerAscentReplayTests.Diagnostic_TowerAscent_PerStepTable; all other entries
remain. Those 51 methods expand to 70 discovered cases (28 App, 42 Core).
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 |
There are also 11 source sites that throw SkipException.ForSkip conditionally.
They are not part of the current 77 because their prerequisites happened to be
available on the R2 gate machine. R3 must retain their per-test reason and
assign them to the installed-DAT, prepared-package, system-font, or other
explicit prerequisite lane; a future machine may report them as additional
skips.
The lane vocabulary is deliberately orthogonal:
Lanestates the execution environment (InstalledDat,PreparedPackage,Live, orManual);Purpose=Diagnosticmarks output/investigation apparatus that cannot add to the contract-test pass count; andStatus=KnownFailurekeeps 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 unreachable panel stack | requires production reachability proof | Do not delete 52 meaningful tests until the dead presentation surface and any supported plugin compatibility promise are verified together. |
| 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 | lane classification complete in batch D; body cleanup active | Of 282 current candidates, 280 are true prerequisite gates and now have an explicit lane. The two unlaned methods are reviewed false positives that assert the current Windows/Linux branch before returning. Empty-return removal remains, lane by lane. |
| T-008 incapable-of-failing diagnostics | batch A plus diagnostic lane work | Delete the literal wiring smoke test; repair the GPU contract tautology; later re-home output-only apparatus. |
| 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 51 output-only methods | classified in batch C | The reviewed current set is 51 methods / 70 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 | requires semantic replacement map | Retain whole-tree dependency rules; remove exact-text freezes only when an equivalent semantic/behavioral guard is identified. |
| 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 | open | Rename/re-home only after each test's durable owner and oracle are established. |
| 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. |
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:
- update this ledger before or with the change;
- preserve useful historical rationale in a plan, issue, or this ledger;
- run the directly affected test projects without retries;
- run a clean warning-as-error build when analyzer/discovery shape changes;
- commit one coherent classification/fix group; and
- 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-secondDateTime.UtcNowcutoff 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
PortalProjectionTestsallocation 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.WarmedSteadyContactRefreshDoesNotAllocatenow 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.DestinationAndEmptyUnloadPriorityNeverBypassPublicationBudgetnow supplies a frozen meter clock through an internal test-only constructor. The public production constructor still suppliesStopwatch.GetTimestampandStopwatch.Frequencyexactly as before. - #402
LandblockBuildFactoryTests.Build_UsesTheSuppliedSharedReaderGatenow starts a dedicated thread and observes it inWaitSleepJoinon 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_PublishesOneCanonicalWaveAndDecodesOnceexposes a real race. A caller can pass the resident-cache check, pause, and reach_inflightafter the winning caller has admitted the wave and removed itsLazy, producing a second decode. The assertion and rationale are preserved underStatus=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.