Repository navigation
Conversation
read_knowledge_chapter and list_annotations asked the annotation store for two spellings of a chapter path and merged the results by id, because the panels once filed notes under different spellings. Commit 120f2d5 made the store canonicalize every key on read, write and load, so the MCP tools now make one List call with the normalized path and ChapterReading.Spellings is gone. New tests pin that a note filed under another spelling is still found, and what happens to a bare area-relative key (kept as-is; no product build ever wrote one). Refs #574 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 30, 2026
JSdotNet
marked this pull request as ready for review
October 1, 2026 05:53
JSdotNet
deleted the
schedule/issue-sweep/2026-09-30/574-canonical-annotation-paths
branch
October 1, 2026 05:53
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.
Closes #574
What changed
I finished item 4 of issue #574. The MCP tools read_knowledge_chapter (review mode) and list_annotations used to ask the annotation store twice, once under the repository-relative path and once under the area-relative path, and merge the results by id. They now ask once, with the normalized repository-relative path. The store's own DevbookChapterKey.Canonical handles every other spelling of the chapter.
Source changes:
normalizedonly.Tests, written first and seen failing for the right reason (5 failures, each showing Listed with two entries such as [".arc42/adr/0012-mcp.md", "adr/0012-mcp.md"]):
.devbook/arc42/...,docs/arch/...and.arc42/...and asked for under another spelling.adr/x.mdis claimed by no area wherever arc42 is pointed, so it is not migrated. The other loads the real Arc42DevbookReader catalog for the.arc42,.devbook/arc42,docs/archand off-clone layouts, and shows that each document path carries its folder and canonicalizes to.arc42/adr/....Why no stored note is lost: git history shows that the arc42 panel has filed remarks under the catalog's document path since the store was introduced (b1c3eba). The catalog has always spelled that path relative to the repository root, or to the folder's parent (ResolveRoot), so it always includes the folder. The bare
adr/x.mdspelling the issue and the old Spellings comment described was never actually written by the product.Results:
Nothing was committed.
Files:
D:/iswp/574-canonical-annotation-paths/src/Infrastructure/Backlog.Infrastructure.Mcp/ChapterReading.cs,D:/iswp/574-canonical-annotation-paths/src/Infrastructure/Backlog.Infrastructure.Mcp/DevbookTools.cs,D:/iswp/574-canonical-annotation-paths/tests/Backlog.Infrastructure.Mcp.UnitTests/DevbookToolsTests.cs,D:/iswp/574-canonical-annotation-paths/tests/Backlog.Infrastructure.Mcp.UnitTests/FakeDevbook.cs,D:/iswp/574-canonical-annotation-paths/tests/Backlog.Desktop.UI.UnitTests/DevbookChapterKeyTests.cs,D:/iswp/574-canonical-annotation-paths/tests/Backlog.Infrastructure.FileSystem.UnitTests/DevbookAnnotationStoreTests.csAcceptance criteria
Verification
cd "D:/iswp/574-canonical-annotation-paths"; dotnet build Backlog.sln; dotnet test Backlog.sln --no-build; then per project: dotnet build <proj> --no-incremental; dotnet test <proj> --no-build for tests/Backlog.Infrastructure.Mcp.UnitTests, tests/Backlog.Infrastructure.FileSystem.UnitTests, tests/Backlog.Desktop.UI.UnitTestsReview
src/Infrastructure/Backlog.Infrastructure.Mcp/DevbookTools.cs:186: The comment above list_annotations still says "the folder settings are read without resolving anything", but the change removed the only folder read on that path (the ChapterPaths.Split call). The new inline comment at line ~211 now says "no folder is resolved", so the two comments contradict each other.src/Infrastructure/Backlog.Infrastructure.Mcp/DevbookTools.cs:188: The comment above ListAnnotationsOn still says the tool reads the folder settings ("the folder settings are read without resolving anything"). The change removed the only folder read in that method, the ChapterPaths.Split(folders.Folders(scope.Alias), ...) call, and its new inline comment says "no folder is resolved". The two comments now describe the method differently.What could not be proved
adr/0012-....md, no folder segment) still exist in stored annotation JSON from builds before the arc42 reader spelled paths from the repository root? DevbookChapterKey.Canonical returns such a key unchanged, so the on-load migration would not fix it, and today only the MCP dual lookup finds it. Assumption: the implementer first checks git history of Arc42Devbook.cs / Arc42DevbookPanel.razor. If an area-relative spelling ever shipped, a mapping for it goes in DevbookChapterKey.Canonical, only when exactly one area plausibly claims it, keeping it idempotent and adding tests, before the MCP lookup is removed. If it never shipped, the removal goes ahead as-is.; Should the MCP test fake canonicalize like the real store, or should the tests use the real DevbookAnnotationStore? Assumption: the fake calls DevbookChapterKey.Canonical (the MCP test project already references Devbook.Abstractions), which keeps the tests free of file I/O.; The MCP tools echo the chapter path in their payloads as the caller spelled it (normalized), not in the canonical.arc42/...form. Assumption: keep echoing the caller's normalized path, so the tool contract for callers does not change.; I did not invoke delivery:flow-code myself. I took the orchestrating workflow (issue sweep / resolve-issue) to be the flow this stage runs inside, since the task told me to implement test first in the given worktree and to leave git and GitHub to the parent session.; I read the 'unreachable' option of criterion 5 as: no build of the product ever filed a bare area-relative key. Git history supports this. At b1c3eba, where IDevbookAnnotationStore was introduced, Arc42DevbookPanel already filed under document.Path, and Arc42Devbook.ResolveRoot already spelled paths relative to the repository root or the folder's parent. A key written by hand or by a non-product tool could still be bare, and the MCP tools would no longer find it.; Known edge case I left alone: if an area is pointed at a folder whose last segment is 'adr' (for example .tech at .arc42/adr), DevbookChapterKey claims bare 'adr/...' paths for that area. EveryConfiguration in DevbookChapterKeyTests already includes that layout, so the new test lists its own arc42-only layouts.; FakeDevbookAnnotationStore now canonicalizes at comparison time instead of on write. For List results this is equivalent to the real store, which canonicalizes on Put and on load.Assumptions
adr/0012-....md, no folder segment) still exist in stored annotation JSON from builds before the arc42 reader spelled paths from the repository root? DevbookChapterKey.Canonical returns such a key unchanged, so the on-load migration would not fix it, and today only the MCP dual lookup finds it. Assumption: the implementer first checks git history of Arc42Devbook.cs / Arc42DevbookPanel.razor. If an area-relative spelling ever shipped, a mapping for it goes in DevbookChapterKey.Canonical, only when exactly one area plausibly claims it, keeping it idempotent and adding tests, before the MCP lookup is removed. If it never shipped, the removal goes ahead as-is..arc42/...form. Assumption: keep echoing the caller's normalized path, so the tool contract for callers does not change.Opened as a draft by an unattended run of
delivery-schedule:schedule-issue-sweep(delivery-schedule@1.13.0) on 2026-09-30. Validate what could not be proved, then mark it ready.🤖 Generated with Claude Code
Checklist