Two commits, no migration. CI green on 52bf40d (run 3543).
The last step of #278: find_duplicate_records(kind=note|task) with per-kind cures in a suggestion field (notes are never merged — supersede, extract, or leave), members with dates and existing_supersessions on each group, MCP + REST + a KnowledgeView panel that follows the type filter.
After deploy, the "Find duplicates" button appears on the Knowledge view.
Two commits, no migration. CI green on `52bf40d` (run 3543).
The last step of #278: `find_duplicate_records(kind=note|task)` with per-kind cures in a `suggestion` field (notes are **never** merged — supersede, extract, or leave), `members` with dates and `existing_supersessions` on each group, MCP + REST + a KnowledgeView panel that follows the type filter.
After deploy, the "Find duplicates" button appears on the Knowledge view.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs
Step 5 of #278, folding in #2534. The operator's no-gate decision for the web
UI (#2482 — "an llm attached to this surface is the corrections system") has a
precondition nobody had built: the corrector has to be able to SEE what needs
correcting. find_duplicate_snippets had no equivalent for notes or tasks, so a
duplicate note was only ever noticed by accident.
find_duplicate_records(kind="snippet"|"note"|"task") — the same indexed
self-join, parameterised. Tasks are notes with a status, not a note_type, so
the kind split is a status predicate; mixing them would propose folding a
to-do into a write-up. find_duplicate_snippets stays as a wrapper because both
surfaces and SnippetListView consume it by name.
What differs by kind is the CURE, and the report says so in a `suggestion`
field rather than leaving the caller to guess:
snippet merge — lossless, the survivor keeps every call site
note NEVER merge. A correction pair → supersedes on the newer; state
smeared across dated records → extract to the System's reference
note; genuinely parallel → leave alone. Choosing needs the records
READ, which is the agent's job — so non-snippet groups carry
`members` with dates and any `existing_supersessions` already
declared inside the group. A pair someone ruled on is not an open
question.
task usually the same work opened twice — keep the one with the history,
cancel the other with a pointer.
The snippet sibling filter stays snippet-only: it keys on symbol/code_sha,
which other kinds don't carry — and for them a look-alike is a finding.
Surfaces: MCP find_duplicate_records (classified into _READ_ONLY_TOOLS — the
completeness test would have caught the omission), REST /api/notes/duplicates,
and a KnowledgeView panel mirroring SnippetListView's — links only, no merge
button, because for notes the report proposes and the correction is a read-
and-decide act. The panel follows the type filter and clears when it changes,
so a note report can't linger under a task view.
Correcting the task's own premise: it claimed the snippet report had "no view
consuming it" — stale; SnippetListView has consumed it since it shipped. The
UI gap was only ever notes/tasks.
Answers the question carried from #2482: yes, the update routes on BOTH
surfaces can turn a record into a duplicate — the gate is create-time by
design. This report is the mechanism that catches it after the fact, which is
the model the operator chose.
Refs #278, #2547
The step-5 field addition (d7039dc) broke a test pinning the error-path
return literally. The field is deliberate: a failed scan must match a clean
scan in shape, or every consumer grows a second code path for the degraded
case. Assert the parts instead.
Refs #2547
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Two commits, no migration. CI green on
52bf40d(run 3543).The last step of #278:
find_duplicate_records(kind=note|task)with per-kind cures in asuggestionfield (notes are never merged — supersede, extract, or leave),memberswith dates andexisting_supersessionson each group, MCP + REST + a KnowledgeView panel that follows the type filter.After deploy, the "Find duplicates" button appears on the Knowledge view.
🤖 Generated with Claude Code
https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs