Repository navigation
fix(core): report case-only Wiki scope collisions instead of failing the run - #1789
Open
phernandez wants to merge 1 commit into
Open
phernandez wants to merge 1 commit into
phernandez wants to merge 1 commit into
Conversation
…the run Two folders that differ only by case or Unicode normalization (for example marketing/Teams and marketing/teams) made plan_wiki_projection raise. The planner covers the whole project, so every later run failed the same way and the project's Wiki stopped updating with no message. Keep the portable-path uniqueness rule, but leave every colliding spelling out of the plan and return it as a typed WikiScopeCollision on WikiProjectionResult.scope_collisions, with its text in warnings (the channel bm wiki and the Cloud run ledger already surface). All other scopes project and the watermark advances. Parent indexes no longer link to a skipped folder. Fixes #1787 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KjsDUcHANBa17M84sKxFG3 Signed-off-by: phernandez <paul@basicmachines.co>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
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.
Fixes #1787
Problem
plan_wiki_projectionraisedValueError: Wiki projected scopes must be unique when compared as portable pathswhen two source folders differed only by letter case or Unicode normalization, for examplemarketing/Teamsandmarketing/teams. The planner is pure and runs over the whole project, so one collision failed the entire run. Every later run hit the same folders and failed the same way. That project's Wiki stopped updating, and nothing told the user why. Production has had 69 failures since 10-11 (cloud Logfire issue #2636). It recurs daily on one workspace and happened earlier on another (customers/CPCagainstcustomers/cpc).The check that raised existed at three sites: the queued scopes, the scopes derived from notes, and the ancestors of retained projector-owned indexes. This change covers all three.
Design
The portable-path uniqueness rule stays. Two spellings of one folder would write their
index.mdandlog.mdto the same file on a case-insensitive sync target. What changes is the outcome when the rule is broken._scope_collisionsgroups every candidate scope by its portable path key. These are note folders, queued or requested scopes, and retained index ancestors. Any key with more than one spelling becomes aWikiScopeCollision.WikiProjectionResult.scope_collisions. Its user-facing text also goes intoresult.warnings. That is the existing per-run diagnostic channel.bm wikiprints warnings for each project, and Cloud already copiesresult.warningsinto the run ledgerdetailsthat the Wiki state API returns. The user sees which folders to rename without any new plumbing.current. A new state would break Cloud's exhaustive status match.partialmeans waiting for materialization and is retried, which would loop on something only a rename can fix.Folder collisions with a source note path (a folder spelled like an existing
.mdnote) still raise, as before. That is a different invariant and out of scope here.I rejected the alternative, projecting each spelling into a scope with a stable suffix. A Wiki
index.mdlives in the folder it indexes. A suffixed scope would either put the index in a folder that doesn't hold the notes, or invent folders the user never created. Then those folders would need their own lifecycle when the user later renames one. Skipping and reporting keeps the output honest and gives the user one clear action.Tests
test_case_only_folder_collision_does_not_fail_the_rebuild. A manual rebuild withmarketing/Teamsandmarketing/teamscompletes. Root,guides,guides/deepandmarketingall project.marketing/index.mdstill lists its own notes and doesn't link to either colliding folder. The collision is onscope_collisionsand inwarnings, the state iscurrent, and the watermark advances.test_case_only_folder_collision_does_not_fail_an_incremental_run. Same shape for an accepted edit inside one of the colliding folders, which is the production path.test_projection_skips_nonportable_duplicate_scopes, coveringFoo/fooand NFC/NFDcafé;..._skips_case_folded_existing_empty_scope,..._skips_existing_scope_colliding_with_unchanged_notes,..._skips_retained_scope_ancestor_collisions).duplicate source note paths, and case-folded and Unicode-normalized duplicate reserved documents);Load-bearing check:
Commands:
just fast-checkpasses, andtests/indexing/test_wiki_projector.pypasses (105).OPENAI_API_KEY= just fast-test(testmon) had 225 passed and 1 failed. The failure istest_benchmark_search_query_latency_by_mode, which fails the same way on unmodified main.Follow-up (Cloud, not in this PR)
Cloud stores
warningstoday, so this is visible through the Wiki state API right away. The web UI could renderscope_collisionsas a "rename one of these folders" prompt.🤖 Generated with Claude Code
https://claude.ai/code/session_01KjsDUcHANBa17M84sKxFG3