Repository navigation
Fix stale title/summary after file-only writeback (crn-bmy54) - #131
Merged
Merged
Conversation
added 4 commits
August 20, 2026 07:14
…ry (needs live repro first) (refs crn-rott9.3) TestStatusServesStaleTitleSummaryAfterFileOnlyWriteback reproduces the asymmetry live: WriteBackBackfill (writeBackPatched) is pure filesystem I/O with no git operation, so it never advances the store's HEAD. ensureFresh's staleness check compares only the index watermark against HEAD, so it never notices the edit -- Status (prime/list) keeps serving the pre-edit title/summary from stale SQL columns, while Find (recall/get) already re-reads the body fresh off disk and is unaffected.
…needs live repro first) (refs crn-rott9.3) WriteBackRetrievalMetadata and WriteBackBackfill now sync the index's title/summary/title_source/summary_source columns directly via SQL right after a successful file patch, mirroring Find's existing hit_count/ last_recalled_at direct-write pattern. Find now stamps the resolved Entry with the store root it came from so this sync has a target; an Entry built via a bare ParseEntry (no store) is a no-op and falls back to today's behavior (correct again after the next reindex). This closes the gap ensureFresh's HEAD-watermark staleness check can't see: WriteBackBackfill/WriteBackRetrievalMetadata are pure filesystem I/O with no git operation, so patching title/summary through them never advances HEAD, and indexStale never fires. Status (prime/list) now reflects the edit immediately instead of waiting for an unrelated reindex to happen to run. Scoped to title/summary only, per this bead's exit contract -- type and the other writeBackPatched-based fields (anchor, recurrence_count, promoted_bead_id, review_status) are untouched.
…(refs crn-rott9.3) golangci-lint's contextcheck flagged cmd/backfill.go:335 after the GREEN commit: WriteBackBackfill now reaches syncIndexRetrievalMetadata, which called context.Background() internally even though applyBackfillRecord already had a ctx in scope. Thread ctx through both public methods instead of manufacturing a fresh background context inside the writeback path; call sites (the one production caller plus both tests) now pass their own in-scope context. No behavior change -- same index sync, just wired to the real context.
…ex-freshness fix)
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.
Summary
WriteBackBackfillandWriteBackRetrievalMetadatapatch an entry'sfrontmatter file directly (
writeBackPatched— pureos.ReadFile/os.WriteFile, zero git ops), without ever advancing the store's checked-outHEAD. Because
ensureFresh's staleness check is HEAD-watermark-based, itnever noticed the file-only edit, so
Status(cairn prime/list) keptserving stale title/summary indefinitely until an unrelated
Reindexhappened to run.
Adds an
Entry.storefield (set byFind) and asyncIndexRetrievalMetadatamethod that directly
UPDATEs the entries table'stitle/summarycolumnsafter a successful file patch, called from both
WriteBackRetrievalMetadata(always) and
WriteBackBackfill(whenupdateRetrievalMetadata=true).Find/recall/getwere never affected — they always re-read the body filefresh — this bug was specific to the cached index columns
Statusreadsfrom. Scoped to title/summary only, per the build bead's exit contract.
Gate result
PASS (7/7) — see
release-gates/crn-bmy54-gate.mdfor full per-criterion evidence.
Independently re-verified on the deployer side, twice: once against the
exact reviewed commit, and again against this branch's actual tip after a
bounded self-rebase onto
main(criterion 6 —mainhad moved on since thereview; the rebase applied clean, zero conflicts, tree-hash-confirmed
identical to the precomputed merge). Both passes:
go build ./...,go vet ./...,golangci-lint run ./...(isolated cache),golangci-lint fmt -d ./...all clean;go test ./... -race -count=1— all 7 packagesPASS, 0 FAIL, including direct re-runs of the two diff-owned tests
(
TestStatusServesStaleTitleSummaryAfterFileOnlyWriteback,TestWriteBackRetrievalMetadataPreservesBody).Diff scope independently confirmed single-themed: 4 files
(
cmd/backfill.go,cmd/backfill_test.go,internal/cairn/entry.go,internal/cairn/index_test.go), +118/-8, 2 source + 2 test.assert_deploy_ancestry_scopeagainstcrn-rott9.3— clean, no foreigncommits, no out-of-scope paths. Exactly 1 open finding on the review side
(
low, non-blocking); no HIGH/blocking findings anywhere in the chain.Merge authority
quad341/cairn — standing self-merge authorization applies (mayor ruling
gm-wisp-2yhv7u, 2026-08-19). This bead's own description carries only thegeneric recycled "route to mayor" boilerplate already covered by that
ruling, nothing bead-specific. Deployer will merge directly
(
gh pr merge --squash, plain, no--auto) once CI is green, thenindependently verify the merge landed.
Test plan
go build ./...go vet ./...golangci-lint run ./...(isolated cache)golangci-lint fmt -d ./...(no diff)go test ./... -race -count=1(all 7 packages) — re-run at both thereviewed SHA and the post-rebase deploy SHA
build-test,lint) — to be confirmed green post-open🤖 Opened by cairn/deployer on a green release gate.