-
-
Notifications
You must be signed in to change notification settings - Fork 11
Configuration
CKB configuration is stored in .ckb/config.json in your repository root. This file is created when you run ckb init.
your-repo/
└── .ckb/
├── config.json # Configuration
└── ckb.db # SQLite database
{
"version": 6,
"backends": {
"scip": {
"enabled": true,
"indexPath": "index.scip",
"autoReindex": false
},
"lsp": {
"enabled": true,
"servers": {}
},
"git": {
"enabled": true
}
},
"queryPolicy": {
"backendLadder": ["scip", "lsp", "git"],
"mergeStrategy": "prefer-first"
},
"lspSupervisor": {
"startupTimeoutMs": 30000,
"shutdownTimeoutMs": 5000,
"maxRestarts": 3,
"healthCheckIntervalMs": 60000
},
"modules": {
"detectStrategy": "auto",
"customRoots": [],
"declarationFile": "MODULES.toml"
},
"ownership": {
"enabled": true,
"codeownersPath": ".github/CODEOWNERS",
"gitBlameEnabled": true,
"timeDecayHalfLife": 90,
"excludeBots": true,
"botPatterns": ["\\[bot\\]$", "^dependabot", "^renovate"]
},
"decisions": {
"enabled": true,
"directories": ["docs/decisions", "docs/adr", "adr", "decisions"],
"storePath": "~/.ckb/repos/{repo}/decisions"
},
"staleness": {
"freshDays": 7,
"freshCommits": 50,
"staleDays": 30,
"staleCommits": 200,
"obsoleteDays": 90,
"obsoleteCommits": 500
},
"importScan": {
"enabled": true,
"maxDepth": 10
},
"cache": {
"queryCacheTtlSeconds": 300,
"viewCacheTtlSeconds": 3600,
"negativeCacheTtlSeconds": 60,
"maxCacheEntries": 10000
},
"budget": {
"maxModules": 10,
"maxSymbolsPerModule": 5,
"maxImpactItems": 20,
"maxDrilldowns": 5,
"estimatedMaxTokens": 4000
},
"backendLimits": {
"maxRefsPerQuery": 10000,
"maxSymbolsPerSearch": 1000,
"maxFilesScanned": 5000,
"maxFileSizeBytes": 1048576,
"maxUnionModeTimeMs": 60000,
"maxScipIndexSizeMb": 500
},
"privacy": {
"redactPaths": false,
"excludePatterns": []
},
"logging": {
"level": "info",
"format": "human"
}
}Schema version number. Current version is 6 (v6.0 Architectural Memory).
{
"version": 6
}Configure which backends are enabled and their settings.
SCIP (Source Code Intelligence Protocol) backend.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable SCIP backend |
indexPath |
string | "index.scip" | Path to SCIP index file |
autoReindex |
bool | false | Automatically regenerate stale index |
{
"backends": {
"scip": {
"enabled": true,
"indexPath": "index.scip",
"autoReindex": false
}
}
}Language Server Protocol backend.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable LSP backend |
servers |
object | {} | Language-specific server configs |
{
"backends": {
"lsp": {
"enabled": true,
"servers": {
"go": {
"command": "gopls",
"args": ["serve"]
},
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"]
}
}
}
}
}Git backend for fallback operations.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable Git backend |
Controls how queries are routed and merged.
| Field | Type | Default | Description |
|---|---|---|---|
backendLadder |
string[] | ["scip", "lsp", "git"] | Backend priority order |
mergeStrategy |
string | "prefer-first" | How to merge results |
Merge Strategies:
-
prefer-first: Use first successful backend response -
union: Merge all backend responses, deduplicate
{
"queryPolicy": {
"backendLadder": ["scip", "lsp", "git"],
"mergeStrategy": "prefer-first"
}
}Controls LSP server lifecycle management.
| Field | Type | Default | Description |
|---|---|---|---|
startupTimeoutMs |
int | 30000 | Max time to wait for server start |
shutdownTimeoutMs |
int | 5000 | Max time to wait for graceful shutdown |
maxRestarts |
int | 3 | Max restart attempts before giving up |
healthCheckIntervalMs |
int | 60000 | Health check interval |
Module detection settings.
| Field | Type | Default | Description |
|---|---|---|---|
detectStrategy |
string | "auto" | Detection strategy |
customRoots |
string[] | [] | Additional module roots |
declarationFile |
string | "MODULES.toml" | Path to explicit module declarations (v6.0) |
Detection Strategies:
-
auto: Detect based on language markers (go.mod, package.json, etc.) -
manual: Only use customRoots -
directory: Treat each top-level directory as a module
{
"modules": {
"detectStrategy": "auto",
"customRoots": ["internal/legacy"],
"declarationFile": "MODULES.toml"
}
}Ownership tracking settings.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable ownership tracking |
codeownersPath |
string | ".github/CODEOWNERS" | Path to CODEOWNERS file |
gitBlameEnabled |
bool | true | Compute ownership from git blame |
timeDecayHalfLife |
int | 90 | Days for blame time decay |
excludeBots |
bool | true | Exclude bot commits from blame |
botPatterns |
string[] | [...] | Regex patterns to detect bots |
{
"ownership": {
"enabled": true,
"codeownersPath": ".github/CODEOWNERS",
"gitBlameEnabled": true,
"timeDecayHalfLife": 90,
"excludeBots": true,
"botPatterns": ["\\[bot\\]$", "^dependabot", "^renovate"]
}
}Ownership Thresholds:
| Scope | Threshold |
|---|---|
| maintainer | >= 50% weighted contribution |
| reviewer | >= 20% weighted contribution |
| contributor | >= 5% weighted contribution |
Architectural Decision Record settings.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable ADR tracking |
directories |
string[] | [...] | Paths to scan for ADR files |
storePath |
string | "~/.ckb/repos//decisions" | Where to store new ADRs |
{
"decisions": {
"enabled": true,
"directories": [
"docs/decisions",
"docs/adr",
"adr",
"decisions"
],
"storePath": "~/.ckb/repos/{repo}/decisions"
}
}Staleness detection thresholds.
| Field | Type | Default | Description |
|---|---|---|---|
freshDays |
int | 7 | Max age for "fresh" data |
freshCommits |
int | 50 | Max commits for "fresh" |
staleDays |
int | 30 | Age threshold for "stale" |
staleCommits |
int | 200 | Commit threshold for "stale" |
obsoleteDays |
int | 90 | Age threshold for "obsolete" |
obsoleteCommits |
int | 500 | Commit threshold for "obsolete" |
{
"staleness": {
"freshDays": 7,
"freshCommits": 50,
"staleDays": 30,
"staleCommits": 200,
"obsoleteDays": 90,
"obsoleteCommits": 500
}
}Import/dependency scanning settings.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable import scanning |
maxDepth |
int | 10 | Maximum dependency depth |
Cache tier configuration.
| Field | Type | Default | Description |
|---|---|---|---|
queryCacheTtlSeconds |
int | 300 | Query cache TTL (5 min) |
viewCacheTtlSeconds |
int | 3600 | View cache TTL (1 hour) |
negativeCacheTtlSeconds |
int | 60 | Negative cache TTL |
maxCacheEntries |
int | 10000 | Max entries per cache tier |
{
"cache": {
"queryCacheTtlSeconds": 300,
"viewCacheTtlSeconds": 3600,
"negativeCacheTtlSeconds": 60,
"maxCacheEntries": 10000
}
}Response budget limits for LLM optimization.
| Field | Type | Default | Description |
|---|---|---|---|
maxModules |
int | 10 | Max modules in response |
maxSymbolsPerModule |
int | 5 | Max symbols per module |
maxImpactItems |
int | 20 | Max impact items |
maxDrilldowns |
int | 5 | Max drilldown suggestions |
estimatedMaxTokens |
int | 4000 | Target token budget |
{
"budget": {
"maxModules": 10,
"maxSymbolsPerModule": 5,
"maxImpactItems": 20,
"maxDrilldowns": 5,
"estimatedMaxTokens": 4000
}
}Hard limits to protect against resource exhaustion.
| Field | Type | Default | Description |
|---|---|---|---|
maxRefsPerQuery |
int | 10000 | Max references per query |
maxSymbolsPerSearch |
int | 1000 | Max symbols per search |
maxFilesScanned |
int | 5000 | Max files to scan |
maxFileSizeBytes |
int | 1048576 | Max file size (1 MB) |
maxUnionModeTimeMs |
int | 60000 | Max time for union merge |
maxScipIndexSizeMb |
int | 500 | SCIP index size warning |
Privacy and redaction settings.
| Field | Type | Default | Description |
|---|---|---|---|
redactPaths |
bool | false | Redact file paths in responses |
excludePatterns |
string[] | [] | Glob patterns to exclude |
{
"privacy": {
"redactPaths": false,
"excludePatterns": [
"**/secrets/**",
"**/*.env"
]
}
}Logging configuration.
| Field | Type | Default | Description |
|---|---|---|---|
level |
string | "info" | Log level (debug, info, warn, error) |
format |
string | "human" | Output format (human, json) |
{
"logging": {
"level": "info",
"format": "human"
}
}Configuration can be overridden with environment variables:
| Variable | Description |
|---|---|
CKB_LOG_LEVEL |
Override log level |
CKB_LOG_FORMAT |
Override log format |
CKB_CONFIG_PATH |
Custom config path |
{
"version": 6,
"backends": {
"scip": { "enabled": true },
"lsp": { "enabled": false },
"git": { "enabled": true }
}
}{
"version": 6,
"backends": {
"scip": {
"enabled": true,
"autoReindex": true
},
"lsp": { "enabled": false },
"git": { "enabled": true }
},
"queryPolicy": {
"backendLadder": ["scip", "git"],
"mergeStrategy": "prefer-first"
},
"cache": {
"queryCacheTtlSeconds": 600,
"viewCacheTtlSeconds": 7200,
"maxCacheEntries": 50000
}
}{
"version": 6,
"budget": {
"maxModules": 20,
"maxSymbolsPerModule": 10,
"maxImpactItems": 50,
"estimatedMaxTokens": 8000
},
"backendLimits": {
"maxRefsPerQuery": 50000,
"maxSymbolsPerSearch": 5000,
"maxFilesScanned": 20000
}
}{
"version": 6,
"ownership": {
"enabled": true,
"codeownersPath": ".github/CODEOWNERS",
"gitBlameEnabled": true,
"timeDecayHalfLife": 90
},
"decisions": {
"enabled": true,
"directories": ["docs/decisions", "docs/adr"]
},
"modules": {
"detectStrategy": "auto",
"declarationFile": "MODULES.toml"
}
}The MODULES.toml file allows you to explicitly declare module boundaries and metadata. Place this file in your repository root.
# MODULES.toml - Explicit module declarations for CKB
[modules.internal/api]
responsibility = "HTTP API handlers and middleware"
owner = "@api-team"
tags = ["core", "api"]
public = ["Handler", "Router", "Middleware"]
internal = ["helper*", "private*"]
[modules.internal/storage]
responsibility = "Database operations and persistence"
owner = "@platform-team"
tags = ["core", "database"]
public = ["Repository", "Query", "Transaction"]
[modules.internal/auth]
responsibility = "Authentication and authorization"
owner = "@security-team"
tags = ["security", "core"]
public = ["Authenticator", "Authorizer", "Token*"]| Field | Type | Description |
|---|---|---|
responsibility |
string | One-sentence description of what the module does |
owner |
string | Primary owner (@team or @username) |
tags |
string[] | Classification tags for filtering |
public |
string[] | Glob patterns for public exports |
internal |
string[] | Glob patterns for internal-only symbols |
- Higher confidence - Declared modules have confidence 1.0 vs 0.5-0.7 for inferred
- Preserved on refresh - Declared data is never overwritten by inference
- Better ownership - Explicit owners override git-blame heuristics
- Clearer boundaries - Public/internal patterns define module contracts
CKB uses this priority when determining module information:
- MODULES.toml (confidence: 1.0) - Explicit declarations
- README.md / doc comments (confidence: 0.8-0.9) - Extracted documentation
- Inference (confidence: 0.5-0.7) - Heuristics from code structure
Validate your configuration:
ckb doctorThis checks:
- JSON syntax
- Schema version compatibility
- Required fields
- Value ranges
- Backend availability
- MODULES.toml syntax (v6.0)