Configuration reference
Every key stamity config addresses, rendered from the closed registry the command reads.
The registry is the whole surface: config set refuses any key not listed here by name,
so a key absent from this table cannot be written even if the manifest would accept it.
Values live in .stamity/manifest.json. Editing that file by hand is not the supported
path — config set validates the result against the manifest schema before it writes,
and prints the same refusal the writer would have produced.
On a terminal, stamity config with no subcommand opens a navigable picker over the same
rows config list prints, and applies the one key it settles per run through the validation
and write path config set uses. Scripts, pipes and CI see no prompt — there, bare config
is config list.
Stored and effective
A key reads two ways, and they disagree whenever a key is unset.
| Reading | What it is | Where you see it |
|---|---|---|
| Stored | the value the manifest carries, or nothing at all | stamity config get <key> — an unset key prints its default in parentheses |
| Effective | what binds after engine defaults are applied | stamity config list — every key, marked (set) or (default) |
An unset key is not an absent opinion: an engine default is deciding, and the third column below is that decision. Setting a key to the same value it already resolves to changes nothing except that the choice becomes yours and survives a default change.
Some of those decisions are per client, because the model and effort rows resolve through
each selected client's own projection. The column is measured against a manifest that
selects every supported client and persists nothing else, so where the clients disagree the
cell names each one — and stamity config list prints that same shape for whichever
clients your own manifest selects.
Keys
| Key | Accepted value | Effective when unset |
|---|---|---|
tools | a comma-separated subset of claude, cursor, copilot, codex | always set — the manifest schema requires it |
platform | one of github | azure-devops | gitlab | none |
maturityTier | one of solo | team | scaleup | enterprise | solo |
ruleDelivery | one of always-on | on-demand | on-demand |
communicationStyle | one of plain | technical | plain |
learnings.maxCount | a positive integer | 150 |
hooks.userHooksDir | a repo-relative directory path | none |
mcp.servers | a comma-separated list of server ids this repo can resolve — curated, or supplied by an installed pack | none |
mcp.protocolVersion | an MCP protocol revision string | none |
model.frontier | a model id your client accepts — passed through verbatim, shape-checked only (non-empty, one line) | (client default) |
model.advanced | a model id your client accepts — passed through verbatim, shape-checked only (non-empty, one line) | claude=opus, cursor=(client default), copilot=(client default), codex=(client default) |
model.standard | a model id your client accepts — passed through verbatim, shape-checked only (non-empty, one line) | claude=sonnet, cursor=(client default), copilot=(client default), codex=(client default) |
model.economy | a model id your client accepts — passed through verbatim, shape-checked only (non-empty, one line) | claude=haiku, cursor=(client default), copilot=(client default), codex=(client default) |
effort.frontier | one of minimal | low | medium | high | xhigh | max — carried on claude, cursor, codex, omitted on copilot; the levels are the union of the clients' documented scales, so one a selected client cannot express is refused here | claude=high, cursor=(not expressed), copilot=(not expressed), codex=high |
effort.advanced | one of minimal | low | medium | high | xhigh | max — carried on claude, cursor, codex, omitted on copilot; the levels are the union of the clients' documented scales, so one a selected client cannot express is refused here | claude=high, cursor=(not expressed), copilot=(not expressed), codex=high |
effort.standard | one of minimal | low | medium | high | xhigh | max — carried on claude, cursor, codex, omitted on copilot; the levels are the union of the clients' documented scales, so one a selected client cannot express is refused here | claude=medium, cursor=(not expressed), copilot=(not expressed), codex=medium |
effort.economy | one of minimal | low | medium | high | xhigh | max — carried on claude, cursor, codex, omitted on copilot; the levels are the union of the clients' documented scales, so one a selected client cannot express is refused here | claude=low, cursor=(not expressed), copilot=(not expressed), codex=low |
review.maxIterations | a whole number of review rounds within 1..10 | 4 |
gates.test | a shell command line, or none to clear | detected: npm run test |
gates.lint | a shell command line, or none to clear | detected: npm run lint |
gates.typecheck | a shell command line, or none to clear | detected: npm run typecheck |
gates.all | a shell command line, or none to clear | detected: npm run lint && npm run typecheck && npm run test |
One row is recorded but not yet consumed. communicationStyle is validated, persisted and
carried through migrations, and no generated file reads it, so setting it changes what the
manifest records rather than how any emitted file asks an agent to write.
The four model.* rows are classes, not model ids. Each names a rung, and each selected
client's own projection maps that rung to an id it accepts, so one setting travels across
clients instead of being restated per client. The top rung ships mapped nowhere: with
model.frontier unset, every supported client resolves it to that client's default, which is
what its cell above says. Nothing is broken by that — the deepest work simply runs on whatever
the client would have picked anyway — and pinning model.frontier to an id your client accepts
is how an operator opts into the rung.
For a Codex setup with access to GPT-6 Astra, pin its exact id to the classes you want:
stamity config set model.advanced gpt-6-astra
stamity config set model.frontier gpt-6-astra
stamity sync
The same id is accepted for model.standard and model.economy. Pins are global per class
across the selected clients: Stamity checks their shape, and each client must support the
model you name. Codex emits model = "gpt-6-astra"; effort remains the class's existing
level unless you set its effort.* key. A pin configures emitted agents; eval runners
configure their scenario and judge model pins separately.
mcp.servers is the one row whose closed list is kept on a page of its own rather than spelled
in its cell, and the MCP server reference is that page: every id this
repo resolves on its own, with the version each is pinned to, the credentials it needs and the
blast radius of handing it to an agent. An id absent from that page resolves only when an
installed pack supplies it.
Changing one
Config edits state; it never regenerates output. Apply a change with stamity sync.
The verbs, their flags and the exit model are in the CLI reference.
Regenerate this page with node scripts/generate-docs.mjs.