-
-
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.
Note: The v6.0 Architectural Memory features (ownership, decisions, hotspots) are implemented but currently use sensible defaults. Configurable settings for these features are planned for a future release. See v6.0 Configuration Roadmap below.
your-repo/
└── .ckb/
├── config.json # Configuration
└── ckb.db # SQLite database
CKB also maintains a global repository registry for multi-repo management:
~/.ckb/
├── repos.json # Repository registry
└── repos.lock # Lock file for concurrent access
repos.json format:
{
"version": 1,
"repos": {
"myproject": {
"name": "myproject",
"path": "/path/to/myproject",
"added_at": "2025-12-22T10:30:00Z",
"last_used_at": "2025-12-22T15:00:00Z"
},
"api": {
"name": "api",
"path": "/path/to/api",
"added_at": "2025-12-22T11:00:00Z"
}
},
"default": "myproject"
}Managing repos:
ckb repo add myproject # Add cwd as "myproject"
ckb repo add api /path/to/api # Add specific path
ckb repo list # List all repos
ckb repo default myproject # Set default
ckb repo remove api # Remove{
"version": 5,
"repoRoot": ".",
"backends": {
"scip": {
"enabled": true,
"indexPath": ".scip/index.scip"
},
"lsp": {
"enabled": true,
"workspaceStrategy": "repo-root",
"servers": {}
},
"git": {
"enabled": true
}
},
"queryPolicy": {
"backendPreferenceOrder": ["scip", "glean", "lsp"],
"alwaysUse": ["git"],
"maxInFlightPerBackend": { "scip": 10, "lsp": 3, "git": 5 },
"coalesceWindowMs": 50,
"mergeMode": "prefer-first",
"supplementThreshold": 0.8,
"timeoutMs": { "scip": 5000, "lsp": 15000, "git": 5000 }
},
"lspSupervisor": {
"maxTotalProcesses": 4,
"queueSizePerLanguage": 10,
"maxQueueWaitMs": 200
},
"modules": {
"detection": "auto",
"roots": [],
"ignore": ["node_modules", "build", ".dart_tool", "vendor"]
},
"importScan": {
"enabled": true,
"maxFileSizeBytes": 1000000,
"scanTimeoutMs": 30000,
"skipBinary": true,
"customPatterns": {}
},
"cache": {
"queryTtlSeconds": 300,
"viewTtlSeconds": 3600,
"negativeTtlSeconds": 60
},
"budget": {
"maxModules": 10,
"maxSymbolsPerModule": 5,
"maxImpactItems": 20,
"maxDrilldowns": 5,
"estimatedMaxTokens": 4000
},
"backendLimits": {
"maxRefsPerQuery": 10000,
"maxFilesScanned": 5000,
"maxUnionModeTimeMs": 60000
},
"privacy": {
"mode": "normal"
},
"logging": {
"level": "info",
"format": "human"
}
}Schema version number. Current version is 5.
{
"version": 5
}Root directory for the repository. Usually ".".
{
"repoRoot": "."
}Analysis tier mode. Controls which backends are used for analysis.
| Value | Description |
|---|---|
"auto" |
Auto-detect highest available tier (default) |
"fast" |
Use tree-sitter only, ignore SCIP even if available |
"standard" |
Require SCIP index |
"full" |
Require SCIP + telemetry |
{
"tier": "standard"
}Precedence: CLI --tier flag > CKB_TIER env var > config > auto-detect
Example use cases:
- Set
"tier": "fast"for quick lookups in large repos - Set
"tier": "standard"to ensure SCIP is always used - Use
--tier=fastfor a single command without changing config
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 | ".scip/index.scip" | Path to SCIP index file |
{
"backends": {
"scip": {
"enabled": true,
"indexPath": ".scip/index.scip"
}
}
}Language Server Protocol backend.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable LSP backend |
workspaceStrategy |
string | "repo-root" | How to initialize workspace |
servers |
object | {...} | Language-specific server configs |
Default servers configured:
-
go: gopls -
typescript: typescript-language-server -
dart: dart language-server -
python: pylsp
{
"backends": {
"lsp": {
"enabled": true,
"workspaceStrategy": "repo-root",
"servers": {
"go": {
"command": "gopls",
"args": []
},
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"]
},
"dart": {
"command": "dart",
"args": ["language-server"]
},
"python": {
"command": "pylsp",
"args": []
}
}
}
}
}Git backend for blame, history, and fallback operations.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable Git backend |
Controls how queries are routed to backends and how results are merged.
| Field | Type | Default | Description |
|---|---|---|---|
backendPreferenceOrder |
string[] | ["scip", "glean", "lsp"] | Backend priority order |
alwaysUse |
string[] | ["git"] | Backends to always query |
maxInFlightPerBackend |
object | {...} | Max concurrent queries per backend |
coalesceWindowMs |
int | 50 | Window for coalescing similar queries |
mergeMode |
string | "prefer-first" | How to merge results |
supplementThreshold |
float | 0.8 | When to supplement with additional backends |
timeoutMs |
object | {...} | Timeout per backend in milliseconds |
Merge Modes:
-
prefer-first: Use first successful backend response -
union: Merge all backend responses, deduplicate
{
"queryPolicy": {
"backendPreferenceOrder": ["scip", "lsp"],
"alwaysUse": ["git"],
"maxInFlightPerBackend": {
"scip": 10,
"lsp": 3,
"git": 5
},
"coalesceWindowMs": 50,
"mergeMode": "prefer-first",
"supplementThreshold": 0.8,
"timeoutMs": {
"scip": 5000,
"lsp": 15000,
"git": 5000
}
}
}Controls LSP server lifecycle and resource management.
| Field | Type | Default | Description |
|---|---|---|---|
maxTotalProcesses |
int | 4 | Max LSP processes across all languages |
queueSizePerLanguage |
int | 10 | Max queued requests per language |
maxQueueWaitMs |
int | 200 | Max time to wait in queue |
{
"lspSupervisor": {
"maxTotalProcesses": 4,
"queueSizePerLanguage": 10,
"maxQueueWaitMs": 200
}
}Module detection settings.
| Field | Type | Default | Description |
|---|---|---|---|
detection |
string | "auto" | Detection strategy |
roots |
string[] | [] | Additional module roots to include |
ignore |
string[] | [...] | Directories to ignore |
Detection Strategies:
-
auto: Detect based on language markers (go.mod, package.json, etc.) -
manual: Only use specified roots -
directory: Treat each top-level directory as a module
Default ignore patterns:
node_modulesbuild.dart_toolvendor
{
"modules": {
"detection": "auto",
"roots": ["internal/legacy"],
"ignore": ["node_modules", "build", ".dart_tool", "vendor", "dist"]
}
}Import/dependency scanning settings.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable import scanning |
maxFileSizeBytes |
int | 1000000 | Skip files larger than this (1 MB) |
scanTimeoutMs |
int | 30000 | Timeout for scanning (30s) |
skipBinary |
bool | true | Skip binary files |
customPatterns |
object | {} | Custom import patterns by language |
{
"importScan": {
"enabled": true,
"maxFileSizeBytes": 1000000,
"scanTimeoutMs": 30000,
"skipBinary": true,
"customPatterns": {}
}
}Cache tier configuration.
| Field | Type | Default | Description |
|---|---|---|---|
queryTtlSeconds |
int | 300 | Query cache TTL (5 min) |
viewTtlSeconds |
int | 3600 | View cache TTL (1 hour) |
negativeTtlSeconds |
int | 60 | Negative cache TTL (1 min) |
{
"cache": {
"queryTtlSeconds": 300,
"viewTtlSeconds": 3600,
"negativeTtlSeconds": 60
}
}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 |
maxFilesScanned |
int | 5000 | Max files to scan |
maxUnionModeTimeMs |
int | 60000 | Max time for union merge (60s) |
{
"backendLimits": {
"maxRefsPerQuery": 10000,
"maxFilesScanned": 5000,
"maxUnionModeTimeMs": 60000
}
}Privacy settings.
| Field | Type | Default | Description |
|---|---|---|---|
mode |
string | "normal" | Privacy mode |
Privacy Modes:
-
normal: Full output with paths and symbols -
redacted: Paths and symbol names are hashed
{
"privacy": {
"mode": "normal"
}
}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"
}
}Runtime telemetry integration for observed usage and dead code detection. See Telemetry for full documentation including OTEL Collector setup, coverage levels, and CLI commands.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | false | Enable telemetry features |
serviceMap |
object | {} | Service name → repo ID mapping |
storage |
object | {...} | Retention and aggregation settings |
privacy |
object | {...} | Privacy settings |
Basic enablement:
{
"telemetry": {
"enabled": true,
"serviceMap": {
"api-gateway": "repo-api",
"user-service": "repo-users"
}
}
}Full schema:
{
"telemetry": {
"enabled": true,
"serviceMap": {
"service-name": "repo-id"
},
"storage": {
"retention_days": 365,
"aggregation_interval": "1h"
},
"privacy": {
"hash_service_names": false,
"redact_symbol_names": false
}
}
}Configure documentation indexing for doc-symbol linking. See Doc-Symbol Linking for full documentation.
| Field | Type | Default | Description |
|---|---|---|---|
paths |
[]string | ["docs", "README.md", ...] | Directories and files to scan |
include |
[]string | ["*.md"] | Glob patterns to include |
exclude |
[]string | ["node_modules", ...] | Glob patterns to exclude |
Default paths scanned:
docs/README.mdARCHITECTURE.mdDESIGN.mdCONTRIBUTING.md
Default exclude patterns:
node_modulesvendor.gitdistbuild
{
"docs": {
"paths": ["docs", "README.md", "ARCHITECTURE.md", "DESIGN.md", "CONTRIBUTING.md"],
"include": ["*.md", "*.markdown"],
"exclude": ["node_modules", "vendor", ".git"]
}
}Example: Custom documentation structure
{
"docs": {
"paths": ["documentation", "wiki", "*.md"],
"include": ["*.md"],
"exclude": ["node_modules", "vendor", ".git", "examples"]
}
}Example: Only check specific docs
{
"docs": {
"paths": ["docs/api", "README.md"],
"include": ["*.md"]
}
}The index server is configured via a separate TOML file, not the main config.json. This enables serving symbol indexes over HTTP for remote federation clients. For authentication configuration (scoped tokens, rate limiting), see Authentication.
# Start server with index-serving endpoints
ckb serve --index-server --index-config /path/to/index-server.toml[index_server]
enabled = true
max_page_size = 10000
cursor_secret = "your-secret-key-here"
[[repos]]
id = "company/core-lib"
name = "Core Library"
path = "/repos/core-lib"
description = "Shared utilities and common code"
[[repos]]
id = "company/api"
name = "API Service"
path = "/repos/api"
[repos.privacy]
expose_paths = true
expose_docs = false
expose_signatures = false
path_prefix_strip = "/home/build/"
[default_privacy]
expose_paths = true
expose_docs = true
expose_signatures = true| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | false | Enable index-serving endpoints |
max_page_size |
int | 10000 | Maximum items per page for pagination |
cursor_secret |
string | (auto) | HMAC secret for cursor signing (auto-generated if omitted) |
data_dir |
string | ~/.ckb-server |
Server data directory for uploaded repos (Phase 2) |
max_upload_size |
int | 524288000 | Maximum upload size in bytes (500MB default, Phase 2) |
allow_create_repo |
bool | true | Allow creating repos via upload API (Phase 2) |
enable_compression |
bool | true | Accept gzip/zstd compressed uploads (Phase 3) |
supported_encodings |
array | ["gzip", "zstd"] | Supported Content-Encoding values (Phase 3) |
enable_delta_upload |
bool | true | Enable incremental delta uploads (Phase 3) |
delta_threshold_percent |
int | 50 | Suggest full upload when >N% files changed (Phase 3) |
Each repository to serve is defined as a [[repos]] entry:
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Repository identifier (e.g., "company/core-lib") |
name |
string | No | Human-readable display name |
path |
string | Yes | Absolute path to repository with .ckb/ directory |
description |
string | No | Repository description |
privacy |
object | No | Per-repo privacy settings (overrides default_privacy) |
Privacy settings control what information is exposed in API responses:
| Field | Type | Default | Description |
|---|---|---|---|
expose_paths |
bool | true | Include full file paths in responses |
expose_docs |
bool | true | Include documentation strings |
expose_signatures |
bool | true | Include function signatures |
path_prefix_strip |
string | "" | Strip this prefix from all paths |
Full exposure (default):
[default_privacy]
expose_paths = true
expose_docs = true
expose_signatures = trueMinimal exposure (paths only):
[default_privacy]
expose_paths = true
expose_docs = false
expose_signatures = falseStrip build paths:
[repos.privacy]
expose_paths = true
path_prefix_strip = "/home/build/workspace/"
# "/home/build/workspace/src/main.go" becomes "src/main.go"# index-server.toml
[index_server]
enabled = true
max_page_size = 5000
cursor_secret = "your-hmac-secret-key"
# Core library - fully exposed
[[repos]]
id = "company/core-lib"
name = "Core Library"
path = "/code/core-lib"
description = "Shared utilities and common code"
# API service - hide docs and signatures
[[repos]]
id = "company/api"
name = "API Service"
path = "/code/api-service"
[repos.privacy]
expose_paths = true
expose_docs = false
expose_signatures = false
path_prefix_strip = "/code/"
# Internal service - minimal exposure
[[repos]]
id = "company/internal"
name = "Internal Service"
path = "/code/internal-service"
[repos.privacy]
expose_paths = false
expose_docs = false
expose_signatures = falseFor index server mode that accepts uploads via HTTP API:
# index-server-upload.toml
[index_server]
enabled = true
max_page_size = 10000
data_dir = "~/.ckb-server" # Where uploaded repos are stored
max_upload_size = 524288000 # 500MB max upload
allow_create_repo = true # Auto-create repos on first upload
# Phase 3: Enhanced uploads
enable_compression = true # Accept gzip/zstd compressed uploads
supported_encodings = ["gzip", "zstd"]
enable_delta_upload = true # Enable incremental delta uploads
delta_threshold_percent = 50 # Suggest full upload if >50% files changed
# No [[repos]] section needed - repos are created via API upload
[default_privacy]
expose_paths = true
expose_docs = true
expose_signatures = true-
Cursor Secret: If not provided, a random secret is generated at startup. For multi-instance deployments, set the same
cursor_secreton all instances. -
Read-Only Mode: The index server opens all databases in read-only mode for safety.
-
Network Binding: Use
--hostto control binding:# Local only (default) ckb serve --index-server --host localhost # All interfaces (use with caution) ckb serve --index-server --host 0.0.0.0
-
Authentication: Use
--auth-tokenorCKB_AUTH_TOKENenvironment variable for API authentication. See Authentication for scoped tokens, rate limiting, and TOML-based auth configuration.
See Federation for more details on Remote Index Serving use cases.
Each CLI command has specific flags. Use --help to see all options:
ckb --help # Global help
ckb search --help # Search command help
ckb serve --help # Server command help| Flag | Default | Description |
|---|---|---|
--scope |
"" | Limit to module ID |
--kinds |
"" | Filter by kinds (comma-separated) |
--limit |
20 | Max results |
--format |
"json" | Output format (json, human) |
| Flag | Default | Description |
|---|---|---|
--format |
"json" | Output format |
| Flag | Default | Description |
|---|---|---|
--format |
"json" | Output format |
| Flag | Default | Description |
|---|---|---|
--format |
"json" | Output format |
--depth |
1 | Dependency depth |
| Flag | Default | Description |
|---|---|---|
--port |
8080 | HTTP port |
--host |
"localhost" | Bind address |
--auth-token |
"" | Auth token for mutating requests |
--cors-allow |
"" | Comma-separated allowed CORS origins |
--index-server |
false | Enable index-serving endpoints (v7.3) |
--index-config |
"" | Path to index server config file (TOML) (v7.3) |
Load shedding protects the server under heavy load by queuing and rejecting excess requests. Disabled by default.
Configuration in config.json:
{
"loadShedding": {
"enabled": true,
"maxConcurrentRequests": 100,
"queueSize": 50,
"queueTimeoutMs": 5000,
"priorityEndpoints": ["/health", "/ready", "/metrics", "/symbol/", "/search"],
"retryAfterSeconds": 5
}
}| Setting | Default | Description |
|---|---|---|
enabled |
false | Enable load shedding |
maxConcurrentRequests |
100 | Max concurrent requests before queuing |
queueSize |
50 | Max requests waiting in queue |
queueTimeoutMs |
5000 | How long to wait in queue (ms) |
priorityEndpoints |
[...] | Endpoints that bypass load shedding |
retryAfterSeconds |
5 | Value for Retry-After header |
Behavior:
- Requests beyond
maxConcurrentRequestsenter a queue - If queue is full or timeout expires, returns
503 Service Unavailable - Priority endpoints (
/health,/ready,/metrics) always proceed - Response includes
Retry-Afterheader
Adaptive Mode:
For latency-aware shedding, the adaptive shedder tracks response times and sheds earlier when latency exceeds targets:
{
"loadShedding": {
"enabled": true,
"adaptive": true,
"targetLatencyMs": 100
}
}| Flag | Default | Description |
|---|---|---|
--out |
"" | Output file path |
--anonymize |
false | Anonymize paths and symbols |
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 file path |
CKB_TIER |
Analysis tier mode (fast, standard, full, auto) |
CKB_REPO |
Repository path for Claude Desktop (no project context) |
CKB_NO_UPDATE_CHECK |
Disable npm update notifications (set to any value) |
When installed via npm (npm install -g @tastehub/ckb), CKB automatically checks for updates once per day. The check:
- Runs asynchronously (never blocks command execution)
- Caches results for 24 hours in
~/.ckb/update-check.json - Has a 3-second timeout (fails silently if network is slow/unavailable)
- Skips
mcpandservecommands to avoid breaking protocols
Disable update checks:
export CKB_NO_UPDATE_CHECK=1Example notification:
╭─────────────────────────────────────────────────────╮
│ Update available: 7.3.0 → 7.4.0 │
│ Run: npm update -g @tastehub/ckb │
╰─────────────────────────────────────────────────────╯
{
"version": 5,
"backends": {
"scip": { "enabled": true },
"lsp": { "enabled": false },
"git": { "enabled": true }
}
}{
"version": 5,
"backends": {
"scip": { "enabled": true },
"lsp": { "enabled": false },
"git": { "enabled": true }
},
"queryPolicy": {
"backendPreferenceOrder": ["scip"],
"alwaysUse": ["git"],
"mergeMode": "prefer-first"
}
}{
"version": 5,
"budget": {
"maxModules": 20,
"maxSymbolsPerModule": 10,
"maxImpactItems": 50,
"estimatedMaxTokens": 8000
},
"backendLimits": {
"maxRefsPerQuery": 50000,
"maxFilesScanned": 20000
},
"cache": {
"queryTtlSeconds": 600,
"viewTtlSeconds": 7200
}
}{
"version": 5,
"privacy": {
"mode": "redacted"
},
"logging": {
"level": "warn"
}
}The MODULES.toml file allows you to explicitly declare module boundaries and metadata. Place this file in your repository root.
Note: Module declarations in MODULES.toml take priority over auto-detection and provide higher confidence scores.
# MODULES.toml - Explicit module declarations for CKB
version = 1version = 1
[[module]]
name = "api"
path = "internal/api"
responsibility = "HTTP API handlers and middleware"
owner = "@api-team"
tags = ["core", "api"]
language = "go"
[module.boundaries]
exports = ["Handler", "Middleware", "Router"]
internal = ["internal/api/internal", "internal/api/helpers"]
allowed_dependencies = ["internal/query", "internal/storage"]
[[module]]
name = "query"
path = "internal/query"
responsibility = "Query engine for code intelligence"
owner = "@platform-team"
tags = ["core", "query"]
[[module]]
name = "storage"
path = "internal/storage"
responsibility = "Database operations and persistence"
owner = "@platform-team"
tags = ["core", "database"]
[module.boundaries]
exports = ["Repository", "Query", "Transaction"]
internal = ["internal/storage/schema"]| Field | Type | Required | Description |
|---|---|---|---|
path |
string | Yes | Repo-relative path to the module root |
name |
string | No | Human-readable name (defaults to last path segment) |
id |
string | No | Stable module ID (auto-generated if omitted) |
responsibility |
string | No | One-sentence description of what this module does |
owner |
string | No | Primary owner (@team or user@email.com) |
tags |
string[] | No | Classification tags for filtering |
language |
string | No | Primary language (auto-detected if omitted) |
The optional [module.boundaries] section defines the module's API surface:
| Field | Type | Description |
|---|---|---|
exports |
string[] | Symbol names that form the public API |
internal |
string[] | Paths considered internal/private |
allowed_dependencies |
string[] | Modules this module is allowed to depend on |
For simple cases, you only need the path field:
version = 1
[[module]]
path = "internal/api"
[[module]]
path = "internal/query"
[[module]]
path = "pkg/utils"When id is not specified, CKB generates a stable ID:
ckb:mod:<hash>
The hash is derived from the normalized module path, ensuring the ID remains stable as long as the path doesn't change.
- 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
-
Dependency control -
allowed_dependenciesenables future dependency violation detection
Validate your MODULES.toml:
ckb doctorCKB validates:
- Required
pathfield is present - Paths exist in the repository
- TOML syntax is correct
CKB includes a complete ADR system for documenting architectural decisions. ADRs are stored as markdown files and indexed for search.
An Architectural Decision Record (ADR) documents a significant decision made about the system architecture, including:
- The context and problem being addressed
- The decision made
- The consequences of that decision
- Alternatives that were considered
CKB looks for ADRs in these directories (in priority order):
docs/decisions/docs/adr/adr/decisions/doc/adr/doc/decisions/
When creating new ADRs via the API/MCP, they are stored in:
-
~/.ckb/repos/<repo-hash>/decisions/(v6.0 global persistence)
ADRs are markdown files with a specific structure:
# ADR-001: Use PostgreSQL for primary database
**Status:** accepted
**Date:** 2024-12-18
**Author:** @platform-team
## Context
We need a primary database for the application. The database must support:
- ACID transactions
- Complex queries with JOINs
- JSON column types for flexible data
## Decision
We will use PostgreSQL 15 as our primary database.
## Consequences
- PostgreSQL provides robust ACID compliance
- JSON/JSONB columns allow schema flexibility
- Requires PostgreSQL expertise on the team
- Need to manage database migrations
## Affected Modules
- internal/storage
- internal/api
- cmd/migrate
## Alternatives Considered
- MySQL - Less JSON support, weaker transaction isolation
- MongoDB - No ACID, eventual consistency concerns
- SQLite - Not suitable for production multi-user access| Status | Description |
|---|---|
proposed |
Under discussion, not yet accepted |
accepted |
Approved and implemented |
deprecated |
No longer recommended, being phased out |
superseded |
Replaced by a newer decision |
| Field | Required | Description |
|---|---|---|
| Title | Yes | Short description of the decision (in # ADR-NNN: Title format) |
| Status | Yes | One of: proposed, accepted, deprecated, superseded |
| Date | No | Decision date (defaults to file modification time) |
| Author | No | Who made or proposed the decision |
| Context | Yes | The problem being addressed |
| Decision | Yes | What was decided |
| Consequences | Yes | List of effects (positive and negative) |
| Affected Modules | No | Which modules are impacted |
| Alternatives Considered | No | Other options that were evaluated |
| Superseded by | No | ADR ID that replaces this one (if superseded) |
ADR files should follow this naming pattern:
ADR-001-use-postgresql-for-database.md
adr-002-adopt-hexagonal-architecture.md
003-implement-caching-layer.md
CKB recognizes patterns:
-
ADR-NNN-*.mdoradr-NNN-*.md -
NNN-*.md(3-4 digit number prefix)
# Create a new decision (opens in $EDITOR or creates with title)
ckb decisions new --title "Use Redis for caching"
# List all decisions
ckb decisions
# Filter by status
ckb decisions --status accepted
# Search decisions
ckb decisions --search "caching"{
"name": "recordDecision",
"arguments": {
"title": "Use Redis for session caching",
"context": "User sessions need fast access with automatic expiration...",
"decision": "We will use Redis 7 for session storage...",
"consequences": [
"Sessions stored in-memory for fast access",
"Built-in TTL handles expiration",
"Requires Redis infrastructure"
],
"affectedModules": ["internal/auth", "internal/session"],
"alternatives": [
"Database sessions - too slow for auth checks",
"JWT only - no server-side revocation"
],
"status": "proposed"
}
}Returns:
{
"adrId": "ADR-005",
"filePath": "~/.ckb/repos/abc123/decisions/adr-005-use-redis-for-session-caching.md",
"status": "proposed"
}curl -X POST http://localhost:8080/decisions \
-H "Content-Type: application/json" \
-d '{
"title": "Use Redis for session caching",
"context": "User sessions need fast access...",
"decision": "We will use Redis 7...",
"consequences": ["Fast access", "Built-in TTL"],
"status": "proposed"
}'{
"name": "getDecisions",
"arguments": {
"status": ["accepted", "proposed"],
"search": "database",
"affectedModule": "internal/storage",
"limit": 10
}
}# List all decisions
curl http://localhost:8080/decisions
# Filter by status
curl "http://localhost:8080/decisions?status=accepted"
# Search
curl "http://localhost:8080/decisions?search=caching"
# Filter by affected module
curl "http://localhost:8080/decisions?affectedModule=internal/api"-
Propose: Create ADR with status
proposed - Discuss: Review with team, update context/alternatives
-
Accept: Change status to
accepted - Implement: Build the solution
-
Supersede (if needed): Create new ADR, mark old as
superseded
- One decision per ADR - Keep ADRs focused on a single decision
- Include context - Future readers need to understand why, not just what
- Document alternatives - Show what was considered and why it was rejected
- Link affected modules - Helps with impact analysis
- Update status - Keep ADRs current as decisions evolve
- Don't delete - Supersede instead; history is valuable
ADRs are indexed in federation for cross-repo search:
{
"name": "federationSearchDecisions",
"arguments": {
"federation": "platform",
"query": "authentication",
"status": ["accepted"]
}
}The v6.0 Architectural Memory features are implemented and working, but currently use hardcoded defaults. Future releases will add configurable settings:
{
"ownership": {
"enabled": true,
"codeownersPath": ".github/CODEOWNERS",
"gitBlameEnabled": true,
"timeDecayHalfLife": 90,
"excludeBots": true,
"botPatterns": ["\\[bot\\]$", "^dependabot", "^renovate"]
}
}Current defaults:
- CODEOWNERS:
.github/CODEOWNERSorCODEOWNERS - Git blame: enabled with 90-day half-life
- Bot exclusion: enabled
{
"decisions": {
"enabled": true,
"directories": ["docs/decisions", "docs/adr", "adr", "decisions"],
"storePath": "~/.ckb/repos/{repo}/decisions"
}
}Current defaults:
- Scans common ADR directories
- Stores new ADRs in CKB data directory
{
"staleness": {
"freshDays": 7,
"freshCommits": 50,
"staleDays": 30,
"staleCommits": 200,
"obsoleteDays": 90,
"obsoleteCommits": 500
}
}Current defaults:
- Fresh: <7 days or <50 commits
- Stale: 30-90 days or 200-500 commits
- Obsolete: >90 days or >500 commits
Validate your configuration:
ckb doctorThis checks:
- JSON syntax
- Schema version compatibility
- Required fields
- Value ranges
- Backend availability
- MODULES.toml syntax