cairn: reviewer-patch kind/auto-actionable flags, dedup conflict primitive, recall stamping + reporting#46
Merged
Merged
Conversation
…eviewer-patch flags (refs crn-28ge.1.2)
… reviewer-patch flags (refs crn-28ge.1.2)
…le/conflicts via cairn get (refs crn-28ge.1.3) internal/cairn/dedup_test.go: coverage for a not-yet-existing exported Conflicts(candidate, others) []DedupFinding — topic_key match, content match, shadow-exemption on both signals, incomparable-scope-still-flagged, both-signals-fire-for-one-pair (documents Conflicts is deliberately not tier-scoped, unlike topicKeyCollisions), no-signal, self-skip, sort order. cmd/commands_test.go: execRoot-based coverage of `cairn get`'s new kind/auto_actionable/conflicts output lines. internal/cairn fails to compile (undefined: Conflicts); cmd's new get tests fail on missing output — expected red.
…able/conflicts via cairn get (refs crn-28ge.1.3) internal/cairn/dedup.go: extract pairSignals (topic_key equality + Title/Summary Jaccard similarity, shadow-exemption-aware) as the single shared primitive; contentSimilarityPairs (Dedup's whole-store scan) now calls it per-candidate instead of duplicating the comparison, and the new exported Conflicts(candidate, others) reuses it for single-candidate callers. Per NFR-05 this is one shared implementation, not a second independently-drifting one. Conflicts is deliberately tier-agnostic (match OR similarity, no tier restriction) for the recall-time conflict-check use case; topicKeyCollisions' same-tier-only behavior for Dedup's own bead-filing path is intentionally left unrefactored. cmd/commands.go: getCmd now prints kind (defaulting to "note") and auto_actionable, and computes conflicts against other visible entries sharing the candidate's topic. Sources "others" data from IterEntries (filtered to the ID set from Visible) rather than Visible's output directly, since Visible never populates Title/Summary — passing it straight to Conflicts would make the content-similarity signal always silently miss. Existing cairn dedup output/tests are unaffected (all 12 pre-existing dedup/similarity tests pass unmodified); all 8 new Conflicts tests and 5 new getCmd tests pass. gofmt/vet/build/golangci-lint/test all clean; internal/cairn race-enabled tests pass.
… (refs crn-28ge.1.5) TestFindStampsLastRecalledAt fails: Find never sets Entry.LastRecalledAt today, though the field/column have existed since crn-28ge.1.1. Also locks in the same never-touched-by-Visible/Status scoping hit_count already has.
…nt (refs crn-28ge.1.5) Extends Find's UPDATE ... SET hit_count = hit_count + 1 ... RETURNING transaction to also set last_recalled_at = ? (RFC3339) and RETURN it into Entry.LastRecalledAt, in the same statement. Scoping is identical to hit_count by construction: getCmd/freshnessCmd/verifyCmd all route through Find and pick this up automatically; mapCmd/primeCmd go through Visible/Prime and never touch it (crn-6az.6.1.3's dependency, previously believed unmerged per this bead's own note, is confirmed landed on origin/main via superseding PR #42, commit ac691c3).
…n-28ge.1.6) RecallStats and PromoteCandidates don't exist yet: compile-error RED against internal/cairn.RecallStats/PromoteCandidates and their finding types.
…crn-28ge.1.6) internal/cairn/recall.go: RecallStats and PromoteCandidates, both built on a shared loadEntryRecallRows index read (NFR-05) rather than each hand-rolling its own SELECT. RecallStats reports every entry's HitCount/LastRecalledAt (FR-08) -- report-everything, not a filter. PromoteCandidates filters entries where RecurrenceCount >= threshold AND PromotedBeadID == "" (FR-07, NFR-02 idempotency), always including Anchor.Repo so a downstream consumer files the resulting bead in the entry's own repo/tracker (crn-28ge.1.8) rather than defaulting to wherever the librarian runs. Both are strictly read-only: no store mutation, no bd create -- that happens downstream in the librarian formula step.
…mmands (refs crn-28ge.1.6) Thin cobra wrappers mirroring cmd/dedup.go's shape: identity-guard, call into internal/cairn, nil-guard the findings slice, JSON-encode. promote-candidates gets a --threshold int flag (default 3, NFR-06); recall-stats takes none. Neither filters by identity -- both cover every entry, same as dedup/stale-branches.
… to include crn-28ge.1.6)
quad341
force-pushed
the
deploy/crn-c13d-gate
branch
from
July 24, 2026 01:43
3b7eea5 to
4c5dbc7
Compare
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.
Adds four related capabilities to cairn's entry lifecycle tooling:
See the release gate writeup for full test/verification evidence:
`release-gates/cairn-kind-dedup-conflict-recall-gate.md`.