bug(799): render breadcrumb lineage below the archive root and unify suggestion-path projection - #802
Merged
Merged
Conversation
…older Records the promoted potential entry and seeds the active bug folder for issue #799 in full-bug work mode. The promoted record carries the eight acceptance criteria AC1-AC8 settled with the maintainer on 2026-09-06 verbatim, and issue.md carries the full-bug work-mode marker. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MS8fb2wX1Sx1bG67LAr41e
Records the verified research artifact covering the seven archive-root stripping sites, the chain-trim seam, the Efc score join, the stale-label log gate, and the leading-underscore question. Authors spec.md with the eight maintainer-settled acceptance criteria verbatim, an explicit statement that this supersedes the issue #439 root-to-leaf lineage rather than fixing a regression, and a Write Set section. Findings of note: the leading-underscore report is a transcription artifact and needs no code change; the ToDoModel sort utility is not a compile item and has no live caller; the recents row-model mirror is a second unprojected site the issue did not report. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MS8fb2wX1Sx1bG67LAr41e
Four phases and 74 tasks covering worktree bootstrap, fail-before regression tests, the implementation, and the final quality-control loop. The plan validator passes; its single warning is a false positive raised by the plan's own delta self-check prose, which names the git diff rule it satisfies while every real invocation is anchored to the recorded base commit. Three planner determinations depart from the spec's literal wording and are recorded with their evidence: the acceptance-criterion 7 row suppression takes the spec's documented escalation to the Efc surface because the QuickFiler row set is composed only inside a file owned by a concurrent sibling item; the acceptance-criterion 6 score projection is additive rather than substitutive so a rooted presented row keeps its percentage; and the two issue 439 router test files need no change because their provider is a strict mock above the trimming seam. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Preflight returned revisions required with twelve blocking findings. The reviewer could not execute any command, because the pre-tool guard refuses pwsh inside an isolated agent worktree, so its runtime claims were adjudicated against the committed evidence of the completed issue 791 run on this same host. Confirmed by that evidence: vstest prints no failed-count line on a fully passing run, so any acceptance condition reading one from console output is unsatisfiable. Refuted by that evidence: the claim that full-framework MSBuild is absent from the path, which a recorded bare invocation contradicts. Narrowed: the execution-environment finding, whose proposed substitute installer was rejected as scope creep. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Applies every accepted finding, applies the two narrowed findings in their narrowed form, and leaves the refuted MSBuild finding unapplied. The most consequential change closes an acceptance-criterion delivery gap: the row-suppression branch for criterion 7 was executed by no test and would have shipped uncovered while being checked off on the strength of provider-level tests that cannot reach it. Two named tests now pin the zero-candidate suppression and the ambiguous-case non-suppression. Three assertions that read a failed-count line from console output are corrected to read the test result file instead, because the runner prints no such line on a fully passing run. Declarations added to a nullable-enabled file now carry the annotations the warnings-as-errors gate requires, and the four consuming tasks gained the guards that follow. The new test file is constrained to the older language version its project compiles at. The plan validator now passes with no warnings. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The confirming round returned revisions required with four blocking findings, all local corrections to acceptance clauses and one task body. All four are accepted; none is rejected or narrowed. Two were verified directly against the tree: a relocation task demanded zero matches for an identifier whose call site sits outside the moved range, and the fifth consumer of a newly nullable return was missed when the previous round narrowed its two siblings. One finding is a defect the orchestrator introduced, by accepting a replacement clause in round one that asserts an observation no scheduled command in that phase produces. It is recorded as such rather than attributed elsewhere. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Closes the four blocking findings from the confirming review. A relocation task no longer demands zero matches for an identifier whose call site sits outside the moved range. The fifth consumer of the newly nullable projection return now carries the same reasoned suppression its siblings received. An assets check now derives its result from an anchored diff with a porcelain companion instead of asserting an absence that was true for every possible execution. A clause asserting an observation no scheduled command produced now reads two diagnostic counts the phase-one build actually emits. The plan file no longer carries any line matching the preflight or convergence signal vocabulary. Clearance is the executor return recorded in the orchestrator checkpoint, not an unmaintained assertion inside the plan. The plan validator passes with no warnings. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e-below-archive-root-799
Executes Phase 0 tasks P0-T1 through P0-T15 of the approved atomic plan. Bootstraps the worktree (repo-local SDK 8.0.205, 172 NuGet packages, CSharpier 1.2.6, dotnet-coverage) and records the base commit, the two MSBuild gate baselines (0 warnings, 0 errors each), the CSharpier check baseline (1593 files, exit 0), the two suite baselines (4786 and 1363 tests, 0 failures), the nine-assembly coverage baseline (7048 tests, 84.55 percent comparability line index), Write Set measurability and line-count baselines, and the pre-change status of the 18 named tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds the issue #799 declaration seams and the test-first regression set that Phase 2 must turn green. No production behaviour changes in this commit: every seam body either throws NotImplementedException or stores a value nothing reads. Seams: - ArchiveStemProjection.ToDisplayStem — lenient display projection (AC4-AC6) - ArchiveChainProjection.TryTrimBelowArchiveRoot — chain trim (AC1, AC2) - OutlookFolderHierarchyProvider: IFolderLabelAbsenceReport, optional lazy archive-root accessor, and an injected diagnostic error sink (AC7) Tests: 4 new UtilitiesCS.Test classes, 1 new QuickFiler.Test class, and 2 retargeted tests whose expectations encoded the empty-root separator strip that AC4 eliminates. Evidence: 33 tests are red at the end of Phase 1 (19 SEAM-BLOCKED, 11 NEW, 3 RETARGETED); both fail-before runs exit 1 as intended. Both Phase 1 builds exit 0 with 0 warnings and 0 errors, and CS8625-COUNT and CS8618-COUNT are both zero. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…jection Phase 2 of the atomic plan: production implementation for issue #799. - ArchiveStemProjection.ToDisplayStem: lenient display projection over ArchiveStemContract, returning the input unchanged for a null/empty/ whitespace root, which removes the empty-root one-separator strip (AC4). - ArchiveChainProjection.TryTrimBelowArchiveRoot: yields the lineage below the archive-root node, false when the chain misses the root or the leaf is the root (AC1, AC2). - OutlookFolderHierarchyProvider: applies the trim inside GetAncestorChainAsync behind a lazy, fault-tolerant root accessor; adds the AC7 once-per-label log gate and the zero-candidate absence classification as two distinct per-instance concurrent sets, with the absence signal cleared on both resolution success routes. - FolderPredictor: ProjectSuggestionPath delegates to the shared projection, both recents surfaces are projected (AC5), and the include-children branch of GetOlSubpath becomes a verified prefix removal. - QfcItemController.ProjectPredeterminedFolder delegates to the same shared projection, so the two members agree by construction (AC4). - BreadcrumbBridgeRouter: adds an archive-relative alias alongside every raw score key so archive-rooted suggestions keep their percentage (AC6), and filters known-absent suggestion rows before row construction so row ids and segment keys stay aligned (AC7, Efc surface only per decision D5). - Relocates EnsureBreadcrumbPipeline into a new QfcItemController partial before adding the root-accessor argument, so ViewerSetup.cs never passes through 501 lines. All 33 tests left deliberately red by Phase 1 now pass, the seven deliberately-green pins remain green, and both suites are fully passing (UtilitiesCS.Test 4816/4816, QuickFiler.Test 1370/1370) with no newly failing test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Close out the atomic plan for issue #799 with the full C# toolchain loop, coverage comparison and acceptance-criteria check-off. Toolchain loop closed clean in one uninterrupted pass, in the mandated order: - CSharpier format: exit 0, "Formatted 1601 files in 8171ms.". Nine files touched, five with a content change, all inside the plan's Write Set, so nothing was reverted and the scope boundary is unchanged. - CSharpier check: exit 0, "Checked 1601 files in 6748ms.", no drift. The count is the 1593-file baseline plus exactly the eight new .cs files. - Analyzer gate (/t:Rebuild, EnableNETAnalyzers, EnforceCodeStyleInBuild): exit 0, 0 Warning(s), 0 Error(s), matching the baseline. - Nullable gate (/t:Rebuild, TreatWarningsAsErrors): exit 0, 0 Warning(s), 0 Error(s), zero CS86 diagnostics, matching the baseline. - Nine-assembly run under dotnet-coverage: exit 0, 7085 tests, 7085 passed, 0 failed, NEWLY-FAILING: NONE against a 7048-test baseline. Coverage, on the pinned comparability index applied identically to both documents with PACKAGES_MATCHED 9 on each side: lines 112855/133485 (84.55 percent) to 113143/133765 (84.58 percent); branches 26642/33624 (79.24 percent) to 26746/33736 (79.28 percent). The denominator grew, so the percentages are the comparison used. Neither decreased. Of 315 changed production lines, 0 have lower post-change hits than their baseline. Both new production types reach 100 percent line and branch coverage. Size budgets after the final format: ViewerSetup 467/500, EfcFormController 1321/1322, FolderPredictor 1002/1003, every other .cs at or below 500. The formatter did not touch the two files carrying one line of headroom. Scope: the changed source set under '*.cs' '*.csproj' is exactly the twenty Write Set paths. All six sibling-owned files and both issue-439 test files were queried individually and carry no hunk. All eight acceptance criteria AC1 through AC8 are checked off in spec.md. spec.md Status is now Implemented and records the four deviations from its own prose, with the AC7 escalation (row suppression on the Efc surface only, logging on both) written before the AC7 box was checked. issue.md records the outcome and states that this is a specification change superseding #439 rather than a regression fix against it, with #439's filing-target and score-key constraint carried forward as AC3. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MS8fb2wX1Sx1bG67LAr41e
Feature review of the breadcrumb archive-root lineage fix returned PASS with zero blocking findings and seven non-blocking observations. All eight acceptance criteria evaluate to PASS and were already checked off in spec.md, so no checkbox changed. The reviewer tested the three documented judgment calls rather than accepting them: the decision D5 AC7 escalation is warranted because the QuickFiler presented row set is composed only inside a sibling-owned file; the decision D7 additive score projection is correct because BuildProbabilityIndex assigns through its indexer, so substitution would have silently broken the rooted-presented case; and the decision D8 no-hunk finding holds because every provider in both issue-439 files is a strict mock, placing the trim below that boundary. The one finding worth scheduling is non-blocking CR-1: AddRecents and AddRecentRows now read ArchiveRootPath unconditionally, and that getter throws InvalidOperationException, so with zero suggestions and non-empty recents they become the first reader on a path that previously never touched it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MS8fb2wX1Sx1bG67LAr41e
The issue #799 code review raised CR-1 as a non-blocking finding: the two recents projections in FolderPredictor read the archive root through a getter that throws InvalidOperationException, so with zero suggestions and a non-empty recents list they become the first reader on a path that previously never touched that property. Recording it only as prose in the feature folder would lose it at merge, so it is promoted through the lifecycle into a tracked bug with the reachability argument, the two sites and the proposed guard preserved. The finding is deliberately not fixed on this branch. It is outside the issue #799 write set, and widening that set here would falsify the scope assertion the plan already verified. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MS8fb2wX1Sx1bG67LAr41e
5 tasks
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.
Summary
Breadcrumb suggestion and search-result rows rendered the ancestor chain from the mailbox root, so a
row for a folder three levels below the archive root showed the store and
Archivesegments before thesegments the user cares about. Separately, four archive-root stripping sites had drifted apart, and one
of them stripped a single leading separator when the archive root was empty.
This change trims the ancestor chain at the archive root inside the hierarchy provider, which is the one
seam both the QuickFiler item view and the Efc view route through, and collapses the drifted stripping
sites onto a single shared projection built on
ArchiveStemContract.TryMakeArchiveRelative.Closes #799.
What changed
ArchiveStemProjectionis the shared display projection;ArchiveChainProjectionis the chain trim. Both are covered at 100 percent line and branch.
OutlookFolderHierarchyProvidergains the trim, an optional root-accessor constructor parameter ofdelegate type, an error log plus single-segment fallback when a chain does not pass through the archive
root, and a per-instance absence gate published through a small new interface.
FolderPredictordelegates the suggestion and recents projections to the shared projection, and theempty-root one-separator strip is eliminated.
BreadcrumbBridgeRouterprojects the Efc score paths so archive-rooted suggestions keep theirpercentage, and suppresses zero-candidate rows on the Efc surface.
QfcItemControllergains a new partial that receives the relocated breadcrumb pipeline helper.The archive-relative stem remains the filing target and the score-lookup key, so the issue 439 constraint
is preserved and all ten of its tests pass unmodified.
Two deviations from the specification's own prose, both pre-authorised and recorded
Row suppression is delivered on the Efc surface only. The QuickFiler presented row set is composed
entirely inside a file owned by a concurrently running sibling item, and at the point the QuickFiler
handler hands its row model to the viewer no provider resolution has been attempted, so the zero-candidate
classification does not exist there yet. Producing it would have required a second synchronous resolution
pass on the UI thread, duplicating the router's work and changing the very ordering the sibling owns. The
specification's decision D-B pre-authorises this escalation; the QuickFiler surface keeps today's fallback
rendering, and the logging half is delivered on both surfaces because it lives in the shared provider.
The projected score is added alongside the raw score rather than substituted for it. The join index
assigns through its indexer, so a substitution would have fixed the stem-presented case and silently broken
the rooted-presented case, whose test does not assert the percentage and would therefore have stayed green
through the regression.
Verification
Full toolchain, one unbroken pass with zero restarts:
dotnet tool run csharpier check ./t:Rebuild/t:RebuildRegression discipline was fail-before then pass-after: Phase 1 left 33 tests deliberately red and Phase 2
turned all 33 green, with full suites moving from 4786 to 4816 and from 1363 to 1370 and
NEWLY-FAILING: NONE.Coverage did not regress. On the pinned first-party comparability index, line moved 84.55 to 84.58 and
branch 79.24 to 79.28, with
PACKAGES_MATCHED=9on both sides. Of 135 executable changed lines, none haslower post-change hits than baseline; the four zero-hit lines were checked against the baseline document
and were already zero before this change.
The change footprint is exactly the 20 paths the plan declared. Six files owned by a concurrent sibling
item, and the two issue 439 router test files, were each queried individually and carry no hunk.
Review outcome
Feature review returned PASS with zero blocking findings and seven non-blocking observations. All eight
acceptance criteria evaluate to PASS.
The one finding worth scheduling is non-blocking and is tracked separately rather than fixed here, because
its two sites are outside this change's declared write set: the recents projections read the archive root
through a getter that throws when the root is unresolvable, so the combination of zero suggestions and a
non-empty recents list is a newly exposed throw path. Follow-up: #801
Notes for the reviewer
The branch merges
origin/mainat2085504e, which brought in a cohort sibling whose declared changesurface overlapped this one. That merge is the base for every anchored diff and coverage comparison in the
evidence, so the figures measure this item's own footprint rather than the sibling's merged work.
Manual validation against a live Outlook profile has not been performed; the specification states explicitly
that it does not gate the automated review.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MS8fb2wX1Sx1bG67LAr41e