docs/design/kv-store.md
Design document for
bd kvcommands Status: Draft - pending Dolt team review Date: 2026-01-21
Add a simple key-value store to beads for persisting lightweight metadata that doesn't fit the issue model. This enables storing things like:
bd kv set debug_mode true)bd kv set entry_point src/main.ts)bd kv set current_sprint 42)bd kv set <key> <value> # Set a key-value pair
bd kv get <key> # Get a value (exit 1 if not found)
bd kv delete <key> # Delete a key
bd kv list [prefix] # List all pairs (optionally filtered by prefix)
All commands support --json for machine-readable output.
# Store project metadata
bd kv set primary_language go
bd kv set entry_point cmd/bd/main.go
# Retrieve values
bd kv get primary_language
# Output: go
# List all pairs
bd kv list
# Output:
# primary_language = go
# entry_point = cmd/bd/main.go
# List with prefix filter
bd kv list entry
# Output:
# entry_point = cmd/bd/main.go
# JSON output
bd kv list --json
# Output: [{"key":"primary_language","value":"go","set_at":"2026-01-21T10:30:00Z","set_by":"beads/crew/collins"},...]
# Delete a key
bd kv delete primary_language
kvCREATE TABLE kv (
`key` VARCHAR(255) PRIMARY KEY,
value TEXT NOT NULL,
set_at DATETIME NOT NULL,
set_by VARCHAR(255) NOT NULL
);
| Column | Type | Description |
|---|---|---|
key | VARCHAR(255) | Primary key, the lookup key |
value | TEXT | The stored value (always string) |
set_at | DATETIME | When the value was set (UTC) |
set_by | VARCHAR(255) | Actor who set it (e.g., "beads/crew/collins", "human") |
Why not use the config table?
Why not make KV pairs into issues/beads?
bd list with non-work entriesWhy track set_at and set_by?
KV data syncs via the standard beads-sync mechanism:
.beads/kv.jsonl.beads/kv.jsonl imports back to KV tableset_at timestamp.beads/kv.jsonl - one JSON object per line:
{"key":"primary_language","value":"go","set_at":"2026-01-21T10:30:00Z","set_by":"beads/crew/collins"}
{"key":"entry_point","value":"cmd/bd/main.go","set_at":"2026-01-21T10:31:00Z","set_by":"human"}
This format is:
issues.jsonl patternFor server mode, add these operations to the RPC protocol:
| Operation | Args | Response |
|---|---|---|
kv_set | {key, value} | {success: bool} |
kv_get | {key} | {value: string, found: bool} |
kv_delete | {key} | {success: bool} |
kv_list | {prefix?: string} | {items: [{key, value, set_at, set_by}]} |
These are NOT in scope for v1, but the design accommodates them:
_local. prefix for keys that don't syncexpires_at column laternamespace column for scoping--type=json flag laterThis feature is inspired by PR #1164 from Piyush Jha (@Hackinet). The original PR proposed bd set/get/clear as top-level commands; this design groups them under bd kv for cleaner namespacing.