Skip to content

Bug/quickfiler folder selector dropdown 400 - #416

Open
drmoisan wants to merge 23 commits into
mainfrom
bug/quickfiler-folder-selector-dropdown-400
Open

Bug/quickfiler folder selector dropdown 400#416
drmoisan wants to merge 23 commits into
mainfrom
bug/quickfiler-folder-selector-dropdown-400

Conversation

@drmoisan

@drmoisan drmoisan commented Aug 3, 2026

Copy link
Copy Markdown
Owner

No description provided.

drmoisan and others added 23 commits August 2, 2026 22:31
- Add a lazy WebView2 popup with synchronized collapsed and expanded surfaces
- Preserve committed and pending selections through keyboard, activation, and cancellation flows
- Retain stable identities and probabilities across asynchronous hierarchy upgrades

Refs: #400
- Preserve unique row identity, probability display, UI dispatch, and exact collapsed readiness.
- Add regression coverage and orchestration evidence through remediation phase 4.
- Leave lifecycle, subfolder activation, final QA, and review for continuation.

Refs: #400
…lifetime

- Add BreadcrumbPopupBoundaryCoverageTests (18 tests for popup boundary behavior)
- Add BreadcrumbDropDownLifecycleCoverageTests (12 tests for open lifetime management)
- Add BreadcrumbMessengerHubCoverageTests (10 tests for hub attachment and disposal)
- Extract BreadcrumbDropDownOpenCoordinator for testable open-request coordination
- Extract BreadcrumbDropDownOpenLifetime for testable open-task lifetime management
- Extract BreadcrumbPopupUiOperations for testable UI operation orchestration
- Update existing test classes to verify edge cases and state transitions
- Include evidence artifacts from automated remediation run

Refs: #400

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
…ocker finding

- Check off P5-T153 (final scope/file-size/project/exclusion inventory)
- Record evidence proving prior P5 CSharpier gates used non-enforcing
  csharpier pipe-files, which never wrote formatted output to disk
- Document that genuine csharpier format pushes two P5 test files
  (BreadcrumbDropDownOpenCoordinatorTests.cs,
  BreadcrumbPopupBoundaryCoverageTests.cs) over the 500-line limit,
  blocking P5-T154 pending a plan revision

Refs: #400

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
… split

Insert P5-T154-T167 correction batch that splits
BreadcrumbDropDownOpenCoordinatorTests.cs and
BreadcrumbPopupBoundaryCoverageTests.cs into partial-class pairs so
genuine csharpier format keeps every P5 file within the 500-line
limit, and renumber the former P5-T154-T160 gates to P5-T168-T174.
Also corrects the plan to require csharpier format (not the
non-enforcing pipe-files) as the formatting gate throughout P5-P9.

Refs: #400

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
…rpier format

Execute P5-T154 through P5-T171 of the remediation plan:

- Split BreadcrumbDropDownOpenCoordinatorTests.cs into a partial-class
  pair (386 + 144 lines), preserving all 10 cases
- Split BreadcrumbPopupBoundaryCoverageTests.cs into a partial-class
  pair (361 + 220 lines), preserving all 18 cases
- Add one QuickFiler.Test.csproj Compile include per new partial file
- Apply genuine csharpier format (not the non-enforcing pipe-files) to
  the full P5 file set, reformatting BreadcrumbDropDownOpenCoordinator.cs,
  BreadcrumbWebViewSurfaceFactory.cs, and ItemViewer.Breadcrumb.cs
- Analyzer and nullable builds pass; 17-class/160-case VSTest run passes

Coverage gates P5-T172 through P5-T174 remain outstanding.

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
The 17-class filtered coverage run reaches natural completion but
returns 159/160: BreadcrumbUiThreadDispatchTests
.SetSuggestionsAsync_WorkerProviderCompletion_SchedulesPostOnOwningContext
observes PostCount == 0.

Control matrix recorded in the evidence:
- instrumented + full 17-class filter: fails (reproduced twice)
- instrumented + that class in isolation: 9/9 passes (three runs)
- uninstrumented + full 17-class filter: 160/160 passes

Because PostCount increments before FirstPost is signalled, the
observed zero indicates the population task completed without any post
reaching the captured context. Root cause is undetermined pending
analysis; P5-T172 through P5-T174 remain unchecked and the Cobertura
artifact is retained as non-authoritative evidence.

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
…m defect

Insert P5-T172-T184 before the authoritative coverage gates and
renumber the former P5-T172/T173/T174 to P5-T183/T185/T186.

The new sequence requires a read-only root-cause diagnosis to decide
whether the instrumented-only failure is a test-harness race (branch A)
or a production dispatch defect (branch B) before authorizing any edit.
Branch B scope covers BreadcrumbUiDispatcher.cs as well as the
coordinator, because Dispatch executes inline and returns
Task.CompletedTask without posting whenever IsCurrentBoundary() sees a
matching managed thread id.

Adds an anti-masking rule to the fixed execution rules: no weakened or
deleted assertions, no sleeps/retries/timing thresholds, no
DoNotParallelize/Ignore as a fix, no filter narrowing or new exclusions,
per .claude/rules/csharp.md and .claude/rules/general-unit-test.md.

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
…oundary

BreadcrumbUiDispatcher.IsCurrentBoundary accepted bare owner-thread
identity as proof the caller was on the UI boundary. After a
ConfigureAwait(false) await, a continuation can be scheduled onto a
recycled thread-pool thread whose managed thread id equals the captured
owner thread id. Dispatch then ran the action inline and returned
Task.CompletedTask without any post crossing the captured context, so
SetSuggestionsAsync could complete with zero posts observed.

When a context was captured it is now the authoritative boundary and
only an ambient reference match to that exact context proves inline
access. Thread identity remains a boundary proof only for the
context-less CreateForCurrentThreadTests dispatcher, which has no
context to compare against.

This matches the reasoning already documented on DispatchValue, which
refuses the same inference because ambient context and thread identity
do not survive awaits, and satisfies the plan rule prohibiting the
inference that an operation remains UI-bound merely because it began on
the owner thread.

Diagnosed as production defect (determination B) under P5-T172; the
17-class instrumented coverage gate now passes 160/160 with exit 0.

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
… units

Insert P5-T185-T202 before the authoritative gates and renumber the
former P5-T185/T186 to P5-T203/T204.

Two zero-production batches add five deterministic cases each against
the nine below-threshold host-neutral units, targeting the two .Part2.cs
partials that have headroom. Every uncovered line is a reachable
failure, cancellation, rollback, retention, or late-callback branch of
already-correct production code, so no production edit is authorized and
a proposed production edit stops for replanning. Coverage-only tests
that merely execute a line are rejected; each case must assert real
behavior at the branch.

Class inventory stays at 17; case total goes 160 to 170.

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
- Add released-guard, rollback-secondary, and counting-probe tests for BreadcrumbDropDownOpenCoordinator
- Add popup lifetime, cleanup-failure, and late-native-close boundary tests for BreadcrumbDropDownHost
- Record P5 branch-coverage QA gate, target inventory, batch allocation, and anti-masking ledger evidence
- Check off completed P5 remediation-plan tasks

Refs: #400
…-T201)

Add five deterministic cases to each of the two .Part2.cs partials
covering coordinator guard/reset/rollback branches and lifetime
surface-retention/ensure/complete and host close-callback branches.
The instrumented 17-class gate now passes 170/170 with exit 0.

Eight units reach >=90% (seven at 100%). The ninth,
BreadcrumbDropDownOpenLifetime.<CompleteOpenAsync>d__16 lines 153-156,
holds at 85.71%: that inner catch is unreachable because its only
trigger (HandleOpenFailureAsync throwing) requires
BreadcrumbUiDispatcher.Report to throw, which it never does for a
non-null argument. Recorded as a blocking finding for plan revision;
no production edit and no coverage exclusion were made.

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
… final unit

Insert P5-T202-T209 (one-production-file batch) and renumber the former
P5-T202/T203/T204 to P5-T210/T211/T212.

The batch authorizes removing only the provably-unreachable inner catch
at BreadcrumbDropDownOpenLifetime.CompleteOpenAsync lines 153-156, so
HandleOpenFailureAsync is awaited directly in the existing outer catch.
HandleOpenFailureAsync cannot throw (its own catch routes to Report,
which swallows all non-null exceptions), so the removal is
behavior-preserving on the reachable path and takes the d__16 state
machine to 24/24 = 100% by shrinking the denominator.

Coverage exclusion, a 24/28 acceptance carve-out, and forced rethrow are
all explicitly rejected per .claude/rules/general-unit-test.md. The
anti-masking rule is extended with a one-line justification that
dead-code removal under the unreachability proof is not a masking action.

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
Remove the provably-unreachable inner try/catch at
BreadcrumbDropDownOpenLifetime.CompleteOpenAsync lines 153-156 so
HandleOpenFailureAsync is awaited directly in the outer catch.
HandleOpenFailureAsync cannot throw (its own catch routes to Report,
which swallows all non-null exceptions), so the removal is
behavior-preserving on the reachable path and takes the <CompleteOpenAsync>d__16
state machine from 85.71% to 100% by shrinking the denominator.

Phase 5 now complete (P5-T202 through P5-T212 checked):
- instrumented 17-class gate 170/170, natural exit 0
- all nine formerly-sub-90% units now >=90% (eight at 100%)
- seven previously-passing units unchanged (Dispatcher 144/144, etc.)
- ItemViewer coordinator-omission CLEARED (coordinator members 100%)

AC-3 and AC-18 remain unchecked pending the P9 full-repository pass.

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7eiiWENDuhcZo6P3KLFeB
…outing and lifecycle management

- Introduce BreadcrumbCoordinatorUpgradeLifetime class to manage pending population work and cancellation
- Implement IDisposable on BreadcrumbBridgeCoordinator with proper handler unsubscription and resource cleanup
- Replace index-based subfolder selection with stable identity-based activation for accessible expanded selection
- Publish selectedSubfolderIndex and selectedFolder state to UI for durable highlighting and collapsed-path display
- Add comprehensive test coverage for lifecycle edge cases: pending work cancellation, disposal races, reset scenarios
- Enhance FolderBreadcrumb.html with accessible subfolder activation using role/aria attributes and keyboard handling
- Correct stale test expectations for host ownership, close reasons, and surface disposal tracking

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ion closure

- Formatted breadcrumb test scope to CSharpier compliance per plan (4 test files)
- Added Phase 9 QA gate evidence artifacts for analyzer, nullable, and formatter
- Updated remediation plan with Phase 9 scope verification and closure results

Refs: #400

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ge.config

- Add ConvertTo-DerivedCoverageSettingsXml, Get-DerivedCoverageSettingsPath,
  and Invoke-DotnetCoverageCollection so the wrapper writes one output-adjacent
  effective settings file, retains every canonical module exclusion, adds the
  test-assembly exclusion exactly once, and removes only the verified derived
  path in a finally block
- Guard the derived path against collision with the canonical settings and
  against placement outside the requested Cobertura output directory
- Move the -NoExecute return ahead of collection and route the exit-code check
  through the new collection function
- Cover the derived-settings lifecycle with four Pester cases asserting
  exclusion retention, argument ordering across the vstest boundary, all eight
  forwarded test assemblies, and cleanup on both success and failure
- Convert the breadcrumb popup dispatch tests to a synchronous fixture that
  records operations by managed thread id, removing async wait dependence
- Record baseline, QA-gate, and regression evidence for the coverage wrapper
  and surface-factory owner-thread work; update the remediation plan for the
  PowerShell batch route and the new HEAD

Refs: #400
- Preserve the failed consumer-workspace PoshQC run and the successful corrected rerun evidence
- Record formatter, analyzer, Pester, and coverage-wrapper scope verification
- Mark P8-T39 through P8-T42 complete while leaving independent review pending

Refs: #400
- Move ItemViewer breadcrumb state and event wiring into a new
  BreadcrumbItemViewerLifecycleCoordinator so the lifecycle is testable
  without a WinForms host, and remove the coverage exclusions it replaced
- Split BreadcrumbPopupUiOperations into delegate-driven seams and
  production-only WebView2 bindings, reusing shared navigation and
  disposal helpers
- Return the configured JunkCertain folder directly in SpamBayes suggested
  destination logic, falling back to the parent folder only when unset
- Add MSTest coverage for the lifecycle coordinator, popup direct adapter,
  coordinator upgrade lifetime, and the SpamBayes destination regression
- Record AC18 reconciliation, remediation-delta, and QA-gate evidence for
  the non-numeric adapter coverage remediation

Refs: #400
- Add lifecycle and popup navigation tests with an injectable binder seam that preserves production binding
- Record 19/19 focused and 6,075/6,075 full-suite passes with 100% coverage for five targeted members
- Advance issue #400 remediation through P9-T59 with accounting and diff-integrity gates pending

Refs: #400
- Record independent P9-T60 adapter accounting and P9-T61 source, configuration, and final-diff integrity checks
- Reverify all 19 acceptance criteria, restore supported spec checkboxes, and validate canonical completed artifacts
- Normalize whitespace-only lines in raw test evidence and refresh adjacent SHA-256 references without semantic changes

Refs: #400
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.

1 participant