Skip to content

cairn: add PromotedBeadID writer + promote-mark CLI#50

Merged
quad341 merged 12 commits into
mainfrom
deploy/crn-2m8r-gate
Jul 24, 2026
Merged

cairn: add PromotedBeadID writer + promote-mark CLI#50
quad341 merged 12 commits into
mainfrom
deploy/crn-2m8r-gate

Conversation

@quad341

@quad341 quad341 commented Jul 24, 2026

Copy link
Copy Markdown
Owner

What this changes

Adds a way to record, on a memory entry itself, which bead it was promoted
into — a PromotedBeadID field written back into the entry's TOML
frontmatter — plus a new cairn promote-mark --bead <id> CLI command that
sets it.

promote-mark dispatches on the entry's scope tier: for a private-scope
entry it commits the field directly; for a shared/rig-scope entry it opens
the existing review-request flow instead (same "commit to a review branch,
mail a reviewer" path other write-back operations already use), so a
promotion into shared memory still gets a human/reviewer look before it's
final. Calling it twice with the same bead ID is a no-op success; calling it
again with a different bead ID is a hard error rather than silently
overwriting the original promotion record.

Why built this way

Mirrors the existing RecurrenceCount write-back mechanism's exact shape
(same anchor-based TOML frontmatter patch, same tier-conditional commit vs.
review-request dispatch) rather than introducing a new pattern — keeps this
consistent as cairn accumulates more "record something back onto the entry"
operations.

Review notes

  • New CLI verb: cmd/promote.go
  • Write-back logic: internal/cairn/entry.go (WriteBackPromotedBeadID,
    patchPromotedBeadID)
  • Review-branch commit path: internal/cairn/remember.go
    (CommitPromotionToReviewBranch)
  • Reviewer request/mail: cmd/reviewer.go
    (requestPromotionReview/sendPromotionReviewMail)
  • Incidental rename along the way: EntryForEvictEntryByID — the
    lookup helper is now shared between cull's eviction path and
    promote-mark, so the name was generalized.

Test plan

  • go build ./... / go vet ./... clean
  • go test ./... -race — all packages green
  • Tier-conditional dispatch exercised: private-scope direct commit,
    shared-scope review-request, same-bead-ID idempotency, different-bead-ID
    hard error (cmd/promote_test.go)
  • Release gate: release-gates/promoted-bead-id-writer-promote-mark-gate.md

quad341 added 12 commits July 24, 2026 09:02
Neutral name so cmd/promote.go's upcoming promote-mark command can reuse
the same Find-bypassing lookup instead of adding a near-duplicate.
Add `cairn promote-mark <id> --bead <bead-id>`: tier-conditional dispatch
for PromotedBeadID, mirroring the shape already shipped for
RecurrenceCount and CULL. Private scope commits directly; shared scope
proposes a review branch via the new requestPromotionReview/
sendPromotionReviewMail (cmd/reviewer.go), mailing the reviewer to merge
with `cairn review merge` since a promotion mark is a content change, not
a deletion.

PromotedBeadID doubles as an idempotency guard: repeating the same bead
ID is a no-op success; a different bead ID on an already-promoted entry
is refused rather than silently overwritten.
… crn-ghn8.2)

The step already filed a bead per recurrence-promotion finding via bd
create, but never persisted the promotion back onto the cairn entry, so
promote-candidates kept re-reporting the same findings forever. Call
cairn promote-mark <entry-id> --bead <bead-id> immediately after bd
create returns its ID, mirroring how the capture-time recurrence path
calls WriteBackRecurrenceCount right after incrementing RecurrenceCount.

Applied identically to both mol-cairn-librarian.formula.toml and
mol-cairn-librarian-rig.formula.toml per
TestLibrarianRigFormulaHasSameStepsAsLibrarian.
…fs crn-lox2)

Every call site (2 in cmd/cull_test.go, 5 in cmd/promote_test.go) passed
the literal "old-fact", tripping golangci-lint's unparam check. Hardcode
it inside the helper instead of threading a parameter that never varies.
@quad341
quad341 merged commit 5bf87a6 into main Jul 24, 2026
2 checks passed
quad341 added a commit that referenced this pull request Jul 24, 2026
* test: librarian PROMOTE/CULL step idempotency (crn-28ge.1.11)

promote-candidate-beads and cull-candidate-beads (crn-28ge.1.8, now on
main) must skip already-tracked findings via the same bd-list-before-
bd-create idiom the other three sweep steps use, or a second pass over
an unchanged findings set files duplicate beads.

cull-candidate-beads carries a sharper invariant: cairn cull-evict
itself hard-errors on a repeat call for the same entry (its review
branch name is deterministic), so the EXISTING check must run BEFORE
that call, not just before the eventual bd create. Added an ordering-
specific test for that beyond the shared presence check.

Authored by validator (gc-validator-7306216f5c97 @ aa030f5); builder
independently re-verified against clean origin/main (4858187) in an
isolated worktree: gofmt/vet/build/full-suite -race all green,
targeted TestLibrarian* tests pass individually and via full run.

refs crn-28ge.1.11

* release-gate: librarian PROMOTE/CULL step idempotency test (crn-0sdm)

Gate PASS for edc4937 (formulas/formulas_test.go, +61/-0, test-only).
Bounded self-rebase performed: origin/main advanced to 5bf87a6 (PR #50)
past the reviewed commit's assumed base; reconciled via cherry-pick
(disjoint files, clean merge-tree). New tip 34eb1fa, content-identical
to the reviewed commit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant