Reference: manifest & configuration¶
mokata's configuration is a committed, reviewable artifact under .mokata/. The manifest
is validated by a built-in structural validator; when jsonschema is installed it adds a
richer pass, and its absence is degraded over (never fatal).
.mokata/ layout¶
Everything mokata creates as its own data lives under .mokata/, with a clear
committed vs. transient split inside it:
| Path | What | Tracked? |
|---|---|---|
manifest.json |
the stack manifest (below) | committed |
constitution.md |
governing articles, read before non-trivial work | committed |
.gitignore |
ignores temp_local/ (shipped by mokata init) |
committed |
mokata-stack.json |
a stack you chose to export here (optional) | committed |
temp_local/ |
all transient/runtime data (below) | gitignored |
temp_local/ (transient, regenerated as you work — safe to delete) holds:
| Path | What |
|---|---|
temp_local/state/ |
pipeline state (JSON) — see below |
temp_local/audit/ledger.jsonl |
the append-only audit ledger |
temp_local/memory/memory.db |
SQLite memory backend (and memory/vault/ for Obsidian) |
State files include approved_approach.json (brainstorm handoff), emitted_spec.json,
memory_stats.json, knowledge_index.json, story_analysis__<id>.json, undo_log.json,
and pipeline_run__<id>.json (resume checkpoints). They're runtime artifacts, not config —
hence temp_local/. (A user-set tools.<id>.config.path/config.vault can point a backend
elsewhere; that's the user's explicit choice, overriding the default location.)
Harness wiring is not mokata data.
mokata setup claudewrites.claude/commands/,.mcp.json, and.claude/settings.json— these are Claude Code's config and must live at those exact paths, so they stay there by necessity (not a violation of the.mokata/invariant)..mokata/holds mokata's own data; the harness owns its wiring.
Manifest schema¶
{
"manifest_version": 1,
"mokata": { "version": "0.0.4" },
"profile": "full",
"layers": {
"engine": { "enabled": true },
"knowledge": { "enabled": true },
"memory": { "enabled": true },
"governance": { "enabled": true }
},
"capabilities": {
"code_graph": {
"description": "…",
"layer": "knowledge",
"fallback": ["code-review-graph", "serena", "ripgrep", "grep"]
},
"memory_store": {
"description": "…",
"layer": "memory",
"fallback": ["native-memory", "obsidian", "sqlite"]
}
},
"tools": {
"grep": {
"provides": "code_graph",
"kind": "builtin",
"version": null,
"enabled": true,
"detect": { "type": "always" }
}
},
"settings": { }
}
Top-level fields¶
| Field | Type | Notes |
|---|---|---|
manifest_version |
int | currently 1 |
mokata.version |
string | the mokata version that wrote it |
profile |
string | minimal / standard / full / custom |
layers.<name>.enabled |
bool | one of engine, knowledge, memory, governance |
capabilities.<need> |
object | description, optional layer, required fallback[] |
tools.<id> |
object | provides, kind, version, optional enabled, detect |
settings |
object | the generic toggle store (below) |
Capability fields¶
fallback— ordered provider ids (most-preferred first); this is the precedence the router honors (H6).layer— the owning layer; the capability is routable only while that layer is enabled (K1). If a layer is declared on a capability it must exist inlayers.
Tool fields¶
provides— the capability id this tool serves.kind— one ofmcp,cli,library,builtin,external. (mcp/externalare the network-capable kinds for local-first accounting.)enabled— per-tool toggle (defaulttrue); a disabled tool is treated as absent and the router degrades to the next provider (K1).detect—{ "type": "command"|"python_module"|"path"|"obsidian"|"always", "name": "…" }(namerequired forcommand/python_module/path; not used byobsidian/always). Theobsidianstrategy detects a real Obsidian config dir (macOS~/Library/Application Support/obsidian, Linux~/.config/obsidian+ Flatpak, Windows%APPDATA%\obsidian) or a configuredconfig.vaultthat exists.config— optional per-tool block read by the backend builders (Stage 24A). Defaults are unchanged when it's absent: | Tool | Key | Effect | |---|---|---| |obsidian|config.vault| point the Obsidian backend at an external vault directory | |sqlite|config.path| custom SQLite database path (~is expanded) | |postgres|config.dsn_env| name of an env var holding the DSN for the hosted Postgres backend |
Never put a secret (an inline DSN, password, or token) in the manifest — it's a
committed, reviewable artifact, and the secret-guard hard-blocks any write that contains
one. A remote store (Postgres) is opt-in external, accounted by local-first netguard,
and degrades to the SQLite floor if dsn_env is unset, psycopg (the optional
mokata[postgres] extra) is absent, or the database is unreachable.
Settings (the generic toggle store)¶
settings is an open-ended key/value block. The keys mokata reads:
| Key | Shape | Default | Feature |
|---|---|---|---|
memory |
{persistent: bool, decision: bool, episodic: bool} |
all on | per-type memory toggles (C9) |
ux.progress |
"terminal"/"dashboard"/"both" |
terminal |
run-observability tier (Stage 40) |
ux.statusline |
bool | true |
the always-on pipeline-stage badge (Stage 54b) — opt-out |
ux.badge_verbosity |
"full"/"minimal" |
full |
badge detail: full (everything on) or minimal (just the current stage) — opt-DOWN; any other value reads as full |
review.independent |
"on"/"off" |
on |
run the closing /mokata:review as a fresh-context subagent (on) or the inline two-pass (off); any other value reads as on |
brainstorm.auto |
"on"/"off"/"ask" |
on |
auto-engage brainstorm when exploring: on (dive in), ask (offer first), off (never) |
governance.output_density |
bool | false |
output-density compression (F4) |
governance.karpathy.<id> |
bool per gate id | all on | Karpathy gate toggles (G3) — ids: think-first, simplicity, surgical-scope, verify |
trust.<tool> |
"read-only"/"propose-only"/"gated-write" |
gated-write |
per-adapter trust dial (K3) |
The store is intentionally open-ended so future settings (e.g. an execution-mode default) read from it the same way.
Profiles (deterministic enabled sets)¶
| Profile | Layers | code_graph chain |
memory_store chain |
Network |
|---|---|---|---|---|
minimal |
engine, governance | — | — | zero egress |
standard (default) |
all | ripgrep → grep | sqlite | local-only |
full |
all | code-review-graph → serena → ripgrep → grep | native-memory → obsidian → sqlite | only present tools, all gated |
custom |
all | full chains (hand-tune) | full chains (hand-tune) | — |
grep is the universal floor for code_graph; SQLite (stdlib) is the guaranteed floor for
memory_store. See how-to: configure a profile.
Reading & setting config¶
mokata config get <dotted.key> prints a value; mokata config set <dotted.key> <value>
updates it. set is human-gated — it previews the old→new change and waits for
confirmation (--yes to skip), validates the result, and hard-blocks any secret. For
example:
mokata config set tools.sqlite.config.path ~/data/mokata.db
mokata config set tools.postgres.config.dsn_env MOKATA_PG_DSN # env-var name, not a DSN
See how-to: configure storage backends & paths.
Sharing a stack¶
mokata export [file] writes the current manifest as a shareable artifact;
mokata import <file> validates it and applies it as this repo's config (human-gated;
rejects an invalid manifest). See how-to: share a stack.