Skip to content

feat(watch): periodic reindex backstop + status freshness signal (#44)#47

Merged
scbrown merged 1 commit into
mainfrom
feat/bo-44-reindex-backstop
Jul 14, 2026
Merged

feat(watch): periodic reindex backstop + status freshness signal (#44)#47
scbrown merged 1 commit into
mainfrom
feat/bo-44-reindex-backstop

Conversation

@scbrown

@scbrown scbrown commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes #44. Index freshness previously hinged entirely on the file watcher. If a watcher missed or dropped events — a process restart, a high-churn burst, a source indexed without an active watcher — the affected content went silently stale, with nothing to detect or correct it until a manual reindex.

Backstop (freshness no longer hinges solely on watchers)

bobbin watch now runs a periodic full-tree reconciliation, on by default, every 15 min (--reindex-interval-secs, 0 disables). Each sweep:

  • reuses the same file collector bobbin index uses,
  • re-embeds any file whose content hash drifted from the stored one,
  • prunes index rows for files that have disappeared from disk (catching missed Remove events).

Sweeps are incremental — unchanged files are hash-skipped — so a sweep where the watcher kept up does almost no work.

Staleness signal (drift is now observable)

bobbin status gains a Freshness line (and a JSON freshness field) that flags the index stale when the current git HEAD commit time is newer than the last index run. Using commit time rather than wall-clock means a quiet repo with no new commits is never a false positive.

Tests

  • Freshness::compute — head-newer / head-older / equal / never-indexed.
  • format_duration unit formatting.
  • Full suite: 899 passed.

Follow-up (not in scope)

A richer per-repo "no active watcher" flag needs a watcher registry that doesn't exist yet; the HEAD-vs-index signal covers the drift case today. Happy to file that separately if wanted.

🤖 Generated with Claude Code

Index freshness previously hinged entirely on the file watcher. A process
restart, a high-churn burst, or a dropped inotify event could leave content
silently stale until a manual reindex, with nothing to detect or correct it.

Backstop: `bobbin watch` now runs a periodic full-tree reconciliation (on by
default, every 15 min; `--reindex-interval-secs`, 0 disables). Each sweep reuses
the same collector `bobbin index` uses, re-embeds files whose content hash
drifted, and prunes rows for files that vanished from disk. Sweeps are
incremental — unchanged files are hash-skipped — so a sweep where the watcher
kept up does almost no work.

Signal: `bobbin status` gains a Freshness line (and JSON field) that flags the
index stale when the current git HEAD is newer than the last index run. Uses
commit time, not wall-clock, so a quiet repo with no new commits is never a
false positive.

Fixes #44

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VsuPDxSUjMYqHvQyPvSAPW
@scbrown
scbrown merged commit 51c071f into main Jul 14, 2026
5 checks passed
@scbrown
scbrown deleted the feat/bo-44-reindex-backstop branch July 14, 2026 02:24
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.

Index freshness relies solely on file watchers — add a periodic reindex backstop + staleness signal

1 participant