Index Management
CKB automatically keeps your SCIP index up-to-date using several mechanisms. This page explains how index refresh works and how to monitor it.
How Index Refresh Works
CKB offers multiple ways to keep your index fresh:
| Method | Latency | Best For |
|---|---|---|
Manual (ckb index) |
Immediate | On-demand updates |
| Daemon file watcher | ~7s | Always-on development |
| MCP watch mode | ~10s | IDE sessions |
| Webhooks | Immediate | CI/CD integration |
Branch Switching
The daemon handles branch switches automatically. No git hooks needed.
When using the daemon, branch switches are detected within seconds:
- You run
git checkout feature-branch - Git updates
.git/HEAD - Daemon detects the change (polling
.git/HEADevery 2s) - After 5s debounce, reindex triggers automatically
- Total latency: ~7 seconds worst case
For MCP-only users (no daemon), watch mode provides similar functionality:
# Default 10s polling interval
ckb mcp --watch
# Faster polling (5s minimum)
ckb mcp --watch --watch-interval 5s
Refresh Triggers
CKB tracks what triggered each index refresh. You can see this in the getStatus MCP response:
{
"lastRefresh": {
"at": "2024-12-25T10:00:00Z",
"trigger": "head-changed",
"triggerInfo": "branch or commit changed",
"durationMs": 1200
}
}
Trigger Types
| Trigger | Description | Source |
|---|---|---|
head-changed |
Branch switch or new commit | Daemon/MCP watching .git/HEAD |
index-changed |
Staged files modified | Daemon watching .git/index |
manual |
CLI ckb index command |
User action |
scheduled |
Daemon scheduler | Cron-like schedule |
webhook |
External webhook trigger | CI/CD or external system |
stale |
Generic staleness detection | Polling detected changes |
Daemon Mode
The daemon provides the most responsive index refresh:
# Start daemon
ckb daemon start
# Check what it's watching
ckb daemon status
What the Daemon Watches
The daemon uses polling (not fsnotify) for simplicity and cross-platform compatibility:
.git/HEAD- Detects branch switches and new commits (content comparison).git/index- Detects staged file changes (modification time)
Polling intervals:
- File check: every 2 seconds
- Debounce: 5 seconds (batches rapid changes)
Configuration
{
"daemon": {
"watch": {
"enabled": true,
"debounceMs": 5000,
"ignorePatterns": ["*.log", "node_modules/**", ".git/objects/**"]
}
}
}
See Daemon-Mode for complete daemon configuration.
MCP Watch Mode
For users running CKB via MCP without the daemon:
# Enable watch mode with default 10s interval
ckb mcp --watch
# Custom interval (5s to 5m)
ckb mcp --watch --watch-interval 15s
MCP watch mode uses polling only (no file watchers). It periodically checks CheckFreshness() which compares:
- Current HEAD commit vs indexed commit
- Current repo state ID vs indexed state ID
- Uncommitted changes
When staleness is detected, it triggers a reindex automatically.
Checking Index Freshness
Via CLI
ckb status
Shows:
- Current index state
- Commits behind HEAD
- Index age
- Last refresh info (if available)
Via MCP
The getStatus tool returns comprehensive freshness info:
{
"repoState": {
"commit": "abc123",
"branch": "feature/auth",
"dirty": false
},
"lastRefresh": {
"at": "2024-12-25T10:00:00Z",
"trigger": "head-changed",
"triggerInfo": "branch or commit changed",
"durationMs": 1200
}
}
Programmatically
meta, _ := index.LoadMeta(ckbDir)
freshness := meta.CheckFreshness(repoRoot)
if !freshness.Fresh {
fmt.Printf("Stale: %s (%d commits behind)\n",
freshness.Reason, freshness.CommitsBehind)
}
Manual Refresh
Force an immediate reindex:
# Standard reindex
ckb index
# Force full reindex (ignores incremental)
ckb index --force
CI/CD Integration
For CI/CD pipelines, use webhooks to trigger refresh:
# Trigger refresh via daemon API
curl -X POST http://localhost:9120/api/v1/refresh
# Full reindex
curl -X POST http://localhost:9120/api/v1/refresh -d '{"full":true}'
See CI-CD-Integration for complete CI/CD setup.
Troubleshooting
Index seems stale after branch switch
- Check if daemon is running:
ckb daemon status - Check last refresh: Use
getStatusMCP tool - Force refresh:
ckb index
Daemon not detecting changes
- Verify daemon is watching the repo:
ckb daemon status - Check logs:
~/.ckb/daemon.log - Ensure
.git/HEADexists and is readable
MCP watch mode not refreshing
- Check watch is enabled: should see "Watch mode enabled" in stderr
- Reduce interval:
--watch-interval 5s - Check for lock contention: another process may be indexing
Implementation Notes
Why polling instead of fsnotify?
CKB uses polling for file watching because:
- Cross-platform consistency (fsnotify has platform-specific edge cases)
- Simpler implementation and debugging
- 2s poll interval is imperceptible for most workflows
- Avoids inotify watcher limits on Linux
The 7s worst-case latency (2s poll + 5s debounce) is acceptable for the "instant reindex on branch switch" use case.
Related
- Daemon-Mode - Complete daemon configuration
- Incremental-Indexing - How incremental updates work
- CI-CD-Integration - CI/CD webhook setup
- Configuration - All configuration options