Summary
The pump-hosted QfcItemController tests in QuickFiler.Test intermittently fail by expiring at the 60,000 ms PumpTimeoutMs when the machine is under CPU contention. This is the real defect behind #511 and #571, both of which attribute the failure to a missing window handle. That attribution is falsified — see the premise-correction comments on #511 and #571.
Evidence
Measured during the quickfiler-suite-determinism-foundation epic execution run on 2026-08-22. Full artifacts on branch bug/winformspumphost-suite-determinism-511-exec, commit 53a2a08f, under docs/features/active/winformspumphost-suite-determinism-511/evidence/.
- The one genuine pre-fix failure was seven expiries at 60,000 ms, not an exception. A missing handle makes
Control.Invoke throw immediately; it does not hang for sixty seconds.
- Pre-fix run-level failure rate is about 1 in 21 (~4.8%).
- Under induced 17-node MSBuild contention, a supplementary ten-run pass was 8 of 10 green. The failure reproduces under load.
- Both WebView2 children, and therefore the parent
ItemViewer, are already handle-created by InitializeComponent, so handle availability is not the variable.
Hypothesis to test (not a finding)
QuickFiler.Test/Controllers/QfcItemController.InitializationTests.Part2.cs defines a UiThreadDispatcherGate and a SwapUiThreadDispatcher helper that mutate the process-wide static UtilitiesCS.UiThread._dispatcher by reflection in order to serialize the pump tests across two test classes. QfcItemController.SeamFactoryTests and QfcItemController.InitializationTests contend on that gate.
A sixty-second expiry under CPU starvation is consistent with gate contention or a lock-ordering stall between those two classes, rather than with anything about window handles. That should be the first thing instrumented. It is stated here as a lead to test, not as a conclusion.
Also worth measuring: whether the pump thread is simply starved of CPU under contention, and whether any work currently performed on the pump thread can be moved off it.
Why this could not be fixed inside the originating epic
The quickfiler-suite-determinism-foundation epic forbade, by design, every remedy that plausibly addresses a load-induced timeout:
Those constraints were chosen against the misdiagnosed root cause. With the correct root cause, the constraint set leaves no in-scope remedy, which is why the epic child halted instead of shipping a no-op. Whoever picks this up should expect to re-open at least one of those constraints, and should decide deliberately which.
Acceptance Criteria
Summary
The pump-hosted
QfcItemControllertests inQuickFiler.Testintermittently fail by expiring at the 60,000 msPumpTimeoutMswhen the machine is under CPU contention. This is the real defect behind #511 and #571, both of which attribute the failure to a missing window handle. That attribution is falsified — see the premise-correction comments on #511 and #571.Evidence
Measured during the
quickfiler-suite-determinism-foundationepic execution run on 2026-08-22. Full artifacts on branchbug/winformspumphost-suite-determinism-511-exec, commit53a2a08f, underdocs/features/active/winformspumphost-suite-determinism-511/evidence/.Control.Invokethrow immediately; it does not hang for sixty seconds.ItemViewer, are already handle-created byInitializeComponent, so handle availability is not the variable.Hypothesis to test (not a finding)
QuickFiler.Test/Controllers/QfcItemController.InitializationTests.Part2.csdefines aUiThreadDispatcherGateand aSwapUiThreadDispatcherhelper that mutate the process-wide staticUtilitiesCS.UiThread._dispatcherby reflection in order to serialize the pump tests across two test classes.QfcItemController.SeamFactoryTestsandQfcItemController.InitializationTestscontend on that gate.A sixty-second expiry under CPU starvation is consistent with gate contention or a lock-ordering stall between those two classes, rather than with anything about window handles. That should be the first thing instrumented. It is stated here as a lead to test, not as a conclusion.
Also worth measuring: whether the pump thread is simply starved of CPU under contention, and whether any work currently performed on the pump thread can be moved off it.
Why this could not be fixed inside the originating epic
The
quickfiler-suite-determinism-foundationepic forbade, by design, every remedy that plausibly addresses a load-induced timeout:PumpTimeoutMs),Those constraints were chosen against the misdiagnosed root cause. With the correct root cause, the constraint set leaves no in-scope remedy, which is why the epic child halted instead of shipping a no-op. Whoever picks this up should expect to re-open at least one of those constraints, and should decide deliberately which.
Acceptance Criteria
QuickFiler/Controllers/QfcItemController.Initialization.cs,QuickFiler/Controllers/QfcItemController.ViewerSetup.cs) is retained or improved.