Skip to content

fix(quickfiler): advisory High Confidence deadline and ordered, logged Cancel teardown (#791) - #795

Merged
drmoisan merged 14 commits into
mainfrom
bug/quickfiler-high-confidence-cancel-teardown-and-deadline-defects-791
Sep 6, 2026
Merged

fix(quickfiler): advisory High Confidence deadline and ordered, logged Cancel teardown (#791)#795
drmoisan merged 14 commits into
mainfrom
bug/quickfiler-high-confidence-cancel-teardown-and-deadline-defects-791

Conversation

@drmoisan

@drmoisan drmoisan commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Suggested title

fix(quickfiler): make the High Confidence deadline advisory and the Cancel teardown ordered, logged, and exception-safe (#791)

Summary

  • The High Confidence first-batch deadline no longer returns an empty batch when nothing has cleared the cutoff; it becomes a logged checkpoint and the scan continues until the first acceptance, genuine source exhaustion, or a hard bound (250 scanned candidates without acceptance, or a 120 second ceiling). A new stop reason QfcDequeueStop.ScanCapReached reports the bounded exit; the queue stays open.
  • The cutoff, batch size, checkpoint interval, and both bounds are logged at launch; each checkpoint and bound decision is logged with the scanned and accepted counts.
  • The Cancel teardown runs in a fixed order through a per-stage logging helper: signal cancellation, marshal to the UI context, reset the keyboard-active flag, park WebView2 focus and cancel open breadcrumb selectors, unregister navigation and form handlers before rows are removed, hide, await the background loader to quiesce, clean up groups, then clean up under finally so the ribbon release callback always runs.
  • The background loader is now awaitable (IQfcDatamodel.QuiesceLoaderAsync), the remaining-queue admission is guarded against nulled fields, QfcDatamodel.Cleanup() is null-safe and idempotent, and ButtonCancel_Click no longer rethrows from an async void handler.
  • Twenty-five new or retargeted MSTest tests (four new test files) cover the checkpoint continuation, both bounds, source exhaustion, logging, the teardown order, exception safety, the loader quiesce, and the exact null 'this' crash reproduced from the production log.
  • Seven test cases that pinned the superseded empty-batch behavior from Bug: quickfiler-high-confidence-queue-init-stall #424 and Bug: quickfiler-high-confidence-partial-screen-backfill #608 are retargeted rather than deleted; Bug: iteratequeueasync-deadline-closes-queue-early #446 AC-6 (queue closes only on source exhaustion) is preserved and pinned by a new test.

Why

On 2026-09-06 three High Confidence launches logged First-batch deadline expired ... Accepted=0 Scanned=38|44|42 Deadline=00:00:12 and opened empty dialogs even though later items in the same view scored above the cutoff; scan order follows the Explorer view, so the same view reproduced the empty result on every rerun. In the same session a Cancel after an undo burst left the Outlook keyboard unusable with no log output for 37 minutes, and a later Cancel left the background loader running until it crashed with Delegate to an instance method cannot have null 'this' at the admission construction in QfcDatamodel, four seconds after the next launch. Root causes are recorded in the feature folder's issue.md and research artifact: the gate checked the deadline only while accepted.Count == 0 and returned; Worker_DoWork was async void with no retained task, and Cleanup() nulled the fields the loader still dereferenced; the Cancel path never reset keyboard state or parked focus and had no try/finally.

What Changed

Core feature (QuickFiler):

  • QuickFiler/Controllers/QfcStreamingDequeueConfidenceGate.cs: checkpoint instead of return; maxScanWithoutAcceptance and zeroAcceptanceCeiling bounds with internal defaults and an optional constructor seam; launch, checkpoint, and bound log lines.
  • QuickFiler/Interfaces/IQfcDatamodel.cs: QfcDequeueStop.ScanCapReached; DeadlineExpired retained and documented as advisory; QuiesceLoaderAsync(TimeSpan) declared.
  • QuickFiler/Controllers/QfcDatamodel.QueueProcessing.cs and QfcDatamodel.cs: loader task captured; QuiesceLoaderAsync; guarded synchronous TryCreateRemainingQueueAdmission; null-safe Cleanup(); internal QuiesceDebugLog test seam.
  • QuickFiler/Controllers/QfcFormController.EventHandlers.cs and QfcFormController.Deactivate.cs: ordered ActionCancelAsync with RunTeardownStage logging; ParkFocusAndCancelSelectors() extracted from the Deactivate handler and shared with the Cancel path; no rethrow from ButtonCancel_Click.
  • QuickFiler/Controllers/QfcHomeController.cs: Cleanup() guarded in two blocks, disposes the token source, detaches the worker-completed handler, and invokes the release callback under finally.

Tests (QuickFiler.Test):

  • New: QfcStreamingDequeueConfidenceGateTests.Part4.cs, QfcFormControllerCancelTeardownTests.cs, QfcHomeControllerCleanupTests.cs, QfcDatamodelTeardownTests.cs.
  • Retargeted: QfcStreamingDequeueConfidenceGateTests.cs, .Part2.cs, .Part3.cs, QfcQueuePurePathsTests.cs, QfcHomeControllerIterationTests.cs; QuickFiler.Test.csproj gains four Compile entries.

Docs and evidence:

Architecture / How It Fits Together

RibbonController launches QfcHomeController, which builds a QfcDatamodel whose BackgroundWorker runs LoadRemainingEmailsToQueueAsync to fill the master queue while QfcStreamingDequeueConfidenceGate.DequeueAsync scores candidates from that queue. RunAsync loads the accepted batch into QfcFormController. On Cancel, QfcFormController.ActionCancelAsync now drives the teardown in order, awaits IQfcDatamodel.QuiesceLoaderAsync through IQfcHomeController.DataModel before any datamodel field is nulled, and reaches QfcHomeController.Cleanup(), which invokes the ribbon release callback under finally. No settings surface changes; both bounds are gate-internal constants with a constructor seam, following the #424 precedent.

Verification

Completed (from the feature folder evidence, final pass in one uninterrupted loop):

  • dotnet tool run csharpier format . then dotnet tool run csharpier check .: exit 0, 1587 files.
  • msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true: exit 0, 0 warnings, 0 errors.
  • msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true: exit 0, 0 warnings, 0 errors.
  • vstest over nine assemblies under dotnet-coverage collect --output-format cobertura (/InIsolation, LiveOutlook filter): 7023 passed, 0 failed; QuickFiler.Test 1362 passed.
  • Coverage: first-party line 84.50% to 84.51%, branch 79.14% to 79.19%; changed executable lines 131 with 12 uncovered (90.8%), 0 regressions. Fail-before evidence recorded for all four regression groups (25 red tests), pass-after recorded for all 25.
  • Feature review: PASS, 0 blocking findings, 6 of 6 acceptance criteria; all three review artifacts pass the MCP artifact validator.

Recommended:

  • CI PR pipeline (format, analyzers, nullable, MSTest coverage) against the PR head.
  • Manual live-Outlook confirmation per runbooks/live-outlook-cancel-teardown-verification.runbook.md (human-interaction exception HI-1): Cancel after an undo burst, keyboard usable, new teardown log lines present, no null 'this' loader error.

Backward Compatibility / Migration Notes

  • IQfcDatamodel gains QuiesceLoaderAsync(TimeSpan); QfcDatamodel is the only implementer in the solution.
  • QfcDequeueStop gains ScanCapReached; DeadlineExpired remains a valid member so existing switch statements and mocks compile.
  • QfcStreamingDequeueConfidenceGate gains two optional constructor parameters; existing call sites are unchanged.
  • Behavior change: a High Confidence run that previously showed an empty first screen after 12 seconds now scans for up to 250 candidates or 120 seconds before showing an empty screen. The Bug: quickfiler-high-confidence-queue-init-stall #424 and Bug: quickfiler-high-confidence-partial-screen-backfill #608 acceptance criteria that ratified the old behavior are recorded as superseded in spec.md.
  • Behavior change: ButtonCancel_Click logs instead of rethrowing.

Risks and Mitigations

  • The bound defaults (250 candidates, 120 seconds) are engineering estimates from the observed 2 to 3 items per second scoring rate, not measured in a live session. Mitigation: both are constants with a constructor seam, the bound decision is logged, and the live-Outlook runbook records the observed wait.
  • Two QfcDatamodel partials carry a type-level [ExcludeFromCodeCoverage] (pre-existing), so 115 new lines there are covered by named tests but not by the coverage metric.
  • Review residuals filed rather than fixed here: Bug: quickfiler-teardown-disposed-tokensource-and-unprotected-release-link #793 (disposed but shared token source; unprotected release link in SetupDisposal.cs, which was out of scope) and Bug: gate-scan-bound-log-line-content-unasserted #794 (scan-bound log line content not asserted). Rollback is a revert of the single implementation commit plus the test csproj entries.

Review Guide

  1. QfcStreamingDequeueConfidenceGate.cs (checkpoint loop and bounds), then QfcStreamingDequeueConfidenceGateTests.Part4.cs.
  2. QfcFormController.EventHandlers.cs (ActionCancelAsync order and RunTeardownStage), QfcFormController.Deactivate.cs, then QfcFormControllerCancelTeardownTests.cs.
  3. QfcDatamodel.QueueProcessing.cs and QfcDatamodel.cs (quiesce and guarded admission), then QfcDatamodelTeardownTests.cs.
  4. QfcHomeController.cs Cleanup(), then QfcHomeControllerCleanupTests.cs.
  5. Retargeted tests in .Part2.cs, .Part3.cs, QfcQueuePurePathsTests.cs, QfcHomeControllerIterationTests.cs.
  6. Feature folder docs and evidence (large, mechanical; the three review artifacts summarize them). The PR-context collector reports "Core logic changes: 0 files" because it classifies C# under docs; the appendix lists the 17 code and project files.

Follow-ups

GitHub Auto-close

The PR-context collector ran without GitHub CLI access, so its author-asserted list is unverified and includes non-issue tokens; the single closing reference above is the canonical issue created for this branch and was verified directly with gh in the authoring session.

🤖 Generated with Claude Code

https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP

drmoisan and others added 14 commits September 6, 2026 13:00
…dline defects

Add the promoted potential entries for issues #791 (QuickFiler High
Confidence cancel teardown and first-batch deadline defects) and #792
(breadcrumb WebView2 initialization failure 0x8007139F, filed as a
sibling defect out of scope for #791), and seed the active full-bug
feature folder for #791 with issue.md, the spec template, and the plan
template.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
Record the human-exception runbook for the manual live-Outlook
verification step that AC2 of issue #791 requires, and carry the
runbook agent's memory re-verification date bump.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
Record the task-researcher design for the advisory first-batch
checkpoint with hard scan bounds (AC1) and the ordered, logged,
exception-safe Cancel teardown (AC2). Refine AC1 to permit an empty
dialog only on exhaustion or at the bound, and move the live-Outlook
confirmation in AC2 to a runbook-backed human follow-up.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
…dline fix

Fill spec.md from the design research (advisory checkpoint with hard
scan bounds, ordered logged Cancel teardown, superseded #424/#608
criteria, test strategy, logging plan) and add the operator user story.
Carry the prd-feature agent memory updates.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
Four-phase plan: policy reads and C# baseline capture, fail-first
regression tests with retargeting of the seven superseded gate tests,
per-file implementation of the advisory checkpoint and ordered Cancel
teardown, and the final QA loop with coverage delta and AC check-off.
Plan validator passed. Carry the atomic-planner agent memory notes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
Scope the 500-line ceiling to .cs files, add the R10 shell-variable
re-binding rule, retarget the datamodel stop-reason test to the time
ceiling, make the NuGet restore a confirmation step, fix the
NotImplementedException and pass-count gates, and record the coverage
collector substitution. Carry the atomic-planner memory notes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
… task

Admit a non-executable marker for changed lines that carry no Cobertura
line element and scope the zero-hits count to executable lines.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
- QfcStreamingDequeueConfidenceGate: first-batch deadline is now a
  zero-acceptance checkpoint that resets and logs rather than
  returning an empty batch; the scan is instead bounded by hard
  candidate-scan and duration caps, reported via the new
  QfcDequeueStop.ScanCapReached member, with a launch line logging
  the checkpoint interval and both caps.
- QfcFormController.EventHandlers/Deactivate: ActionCancelAsync now
  runs its stages in order through a shared helper that logs each
  stage and its failures, awaits QuiesceLoaderAsync to drain the
  background loader before groups cleanup, and invokes the ribbon
  release callback under finally so a throwing stage still releases
  it; ButtonCancel_Click no longer lets an exception escape the
  async void handler.
- QfcHomeController/QfcDatamodel: cleanup guards its two stages
  independently, nulls datamodel fields only after the loader has
  quiesced, and runs ParentCleanup under finally.
- Retargeted five confidence-gate and controller test files from the
  deadline-expiry contract to the checkpoint/scan-cap contract, and
  added four new test files covering datamodel teardown ordering,
  form-controller cancel teardown, home-controller cleanup, and the
  scan-cap iteration path.
- Added the plan, spec, issue record, and evidence artifacts under
  docs/features/active/2026-09-06-quickfiler-high-confidence-cancel-
  teardown-and-deadline-defects-791/.

Refs: #791

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
… path

Promote the two non-blocking feature-review findings into tracked
issues (#793 disposed-but-shared token source and unprotected release
link; #794 unasserted scan-bound log line) and replace the absolute
account-bearing manifest path in the live-Outlook runbook with a
registry-derived placeholder.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
Record the policy audit, code review, and feature audit for the
cancel-teardown and deadline fix. All three pass the MCP artifact
validator after two structural repairs to the policy audit (checklist
bullets and the positional coverage metrics table). Carry the
feature-review agent memory notes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
Capture the follow-up idea surfaced by the #791 research: expose the
High Confidence scan cap and zero-acceptance ceiling as user settings
once live measurement has confirmed the defaults.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Hugw6Vwd7q8bopFt4g9KP
@drmoisan
drmoisan merged commit f059219 into main Sep 6, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: quickfiler-high-confidence-cancel-teardown-and-deadline-defects

1 participant