Fix QuickFiler navigation key collisions during collection rebuild - #112
Merged
drmoisan merged 4 commits intoMar 28, 2026
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix QuickFiler navigation key collisions during collection rebuild
Summary
KbdActionscould throwSystem.ArgumentExceptionduring collection navigation rebuild because stored keys were treated as duplicates by substring matching instead of exact stored-key identity.KaStringAsync.KeyEquals.QuickFiler.Test/Controllers/KbdActionsTests.cs.QuickFiler.Test/QuickFiler.Test.csprojto include the new regression test file in the test assembly.docs/features/active/2026-03-27-quickfiler-navigation-key-collision-111/.docs/features/potential/promoted/.gitkeepto preserve the promoted-folder path expected by tooling.Why
QuickFilercould fail while rebuilding keyboard navigation after collection items were removed or re-registered. The issue document records thatKbdActionsreusedKaStringAsync.KeyEqualssubstring matching for stored-key identity, which caused distinct literal keys such as1,01, and10for the sameSourceIdto collide during storage operations.The approved plan constrained the fix to a minimal change: storage operations in
KbdActionsmust distinguish exact stored keys, but runtime keyboard-input matching must remain available for filtering and lookup behavior. The acceptance criteria required four outcomes:ArgumentException;What Changed
Core behavior / architecture
QuickFiler/Controllers/KbdActions.csso storage operations use exact stored-key identity instead of substring-based matching for duplicate detection and removal.KeyEquals.QuickFiler/Controllers/QfcCollectionController.cs.Tests
QuickFiler.Test/Controllers/KbdActionsTests.cswith focused regressions covering:10and1coexisting forSourceId = "Collection";ArgumentException;QuickFiler.Test/QuickFiler.Test.csprojso the new test file is included in the test project.Docs / audit / evidence
#111, includingissue.md,plan.2026-03-27T12-45.md, regression evidence, QA-gate evidence, and audit artifacts.docs/features/potential/promoted/.gitkeepto keep the promoted-folder path present for tooling.Architecture / How It Fits Together
The production flow described in the issue remains the same:
QfcCollectionController.RegisterNavigationAsyncAction,RegisterNavigation, andRemovedItemMonitorrebuild collection navigation entries.QuickFiler.Controllers.KbdActions.Add.KbdActionsuses exact stored-key identity for storage-oriented operations such as duplicate detection and removal.KaStringAsync.KeyEqualsfor methods called out in the feature audit, includingContainsKey,FilterKeys,Find, andFindIndex.This preserves the existing keyboard-input matching contract while preventing storage-time collisions between distinct literal keys.
Verification
Completed
docs/features/active/2026-03-27-quickfiler-navigation-key-collision-111/evidence/regression-testing/p1-t2-kbdactions-distinct-keys.2026-03-27T13-01.md:pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/vscode/Invoke-MSTest.ps1 -SearchRoot QuickFiler.Test -Configuration DebugEXIT_CODE: 1QuickFiler.Controllers.Tests.KbdActionsTests.Add_WhenSourceAndStoredKeysAreDistinct_DoesNotTreatSubstringAsDuplicateSystem.ArgumentException: Cannot add key because it already exists. Key 1 SourceId Collectiondotnet tool run csharpier format .EXIT_CODE: 0pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/vscode/Invoke-VSBuild.ps1 -SolutionPath TaskMaster.sln -Configuration Debug -Platform 'Any CPU' -EnableNETAnalyzers -EnforceCodeStyleInBuildEXIT_CODE: 0pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/vscode/Invoke-VSBuild.ps1 -SolutionPath TaskMaster.sln -Configuration Debug -Platform 'Any CPU' -EnableNullable -TreatWarningsAsErrorsEXIT_CODE: 0pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/vscode/Invoke-MSTestWithCoverage.ps1 -SearchRoot . -Configuration DebugEXIT_CODE: 02877total tests,2875passed,2skipped,0failed61.61%22.50%Recommended
dotnet tool run csharpier format .pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/vscode/Invoke-VSBuild.ps1 -SolutionPath TaskMaster.sln -Configuration Debug -Platform 'Any CPU' -EnableNETAnalyzers -EnforceCodeStyleInBuildpwsh -NoProfile -ExecutionPolicy Bypass -File scripts/vscode/Invoke-VSBuild.ps1 -SolutionPath TaskMaster.sln -Configuration Debug -Platform 'Any CPU' -EnableNullable -TreatWarningsAsErrorspwsh -NoProfile -ExecutionPolicy Bypass -File scripts/vscode/Invoke-MSTestWithCoverage.ps1 -SearchRoot . -Configuration DebugBackward Compatibility / Migration Notes
QfcCollectionControllerbehavior remains compatible without source changes.KbdActions: distinct stored keys are no longer treated as duplicates solely because one literal key contains another.Risks and Mitigations
Mitigation: The new tests explicitly cover both exact stored-key identity and preserved runtime matching behavior.
10and1, while the issue also mentions01.Mitigation: The feature audit notes that exact string equality generalizes to the
01case, and a future hardening pass can add a direct literal regression if desired.Mitigation: Review the production and test deltas first, then inspect evidence and audit files as supporting material.
Review Guide
docs/features/active/2026-03-27-quickfiler-navigation-key-collision-111/issue.mdfor the bug statement, reproduction path, and acceptance criteria.QuickFiler/Controllers/KbdActions.csfor the storage-identity change.QuickFiler.Test/Controllers/KbdActionsTests.csfor the new regression, duplicate-guard, and compatibility scenarios.QuickFiler.Test/QuickFiler.Test.csprojfor the test-project inclusion update.docs/features/active/2026-03-27-quickfiler-navigation-key-collision-111/evidence/regression-testing/p1-t2-kbdactions-distinct-keys.2026-03-27T13-01.mdfor the recorded pre-fix failure.docs/features/active/2026-03-27-quickfiler-navigation-key-collision-111/evidence/qa-gates/for the clean-pass formatter, analyzer, nullable, and coverage-enabled test loop.Follow-ups
artifacts/pr_context.summary.txtandartifacts/pr_context.appendix.txtagain before merge if the PR-context collector is rerun for the final branch state."01"literal regression in a future hardening pass.Remove()regression in a future hardening pass.GitHub Auto-close
Related issues / PRs