DETECTION
chokidar watches vault_path (respects deny_dirs / allow_dirs)
Debounces: 2s after last change event
→ Avoids triggering sync for every keystroke in an editor
BATCHING
Collector window: 5s (configurable)
Groups add/update/delete events into a changeset
→ Single sync call for 10 files changed at once
SYNC TRIGGER
After debounce + collect: spawn indexer with obsidian-rag sync
Indexer processes only modified files (uses mtime comparison)
On completion: indexer writes status JSON to ~/.obsidian-rag/sync-result.json
SYNC RESULT
Plugin reads sync-result.json on next tool call
Updates health state: HEALTHY if indexed > 0 docs, UNAVAILABLE if 0
Stale flag: if last sync > 1h ago and vault changed, next search returns status: "degraded"