Configuration
The harness is configured through environment variables — supplied via a per-user credential store, project .env files, or your shell. minima config manages the per-user store.
This page covers the CLI harness. Configuration for the Minima service itself (only relevant when self-hosting) is a separate set of environment variables — the full server reference is docs/configuration.md in the repo.
Managing credentials
minima config # list every configurable key (secrets masked)
minima config set <KEY> <value> # store a credential
minima config get <KEY> # print a stored valueYou don't have to drop to the CLI — the same is available inside the interactive TUI via the /config slash command:
/config # open the config editor / list keys
/config set <KEY> <value> # store a credential
/config get <KEY> # print a stored valueSecrets are stored keychain-first: the OS keychain (macOS Keychain, Linux Secret Service, Windows Credential Manager) via keytar when available, otherwise a ~/.minima-harness/config.env file written mode 0600. Non-secret values (URLs) always live in the file. minima config set reports which backend it used.
The keytar native module does not bundle into the compiled binary, so the Homebrew-installed minima binary transparently falls back to the 0600 file store. That file is plaintext — keep it owner-only (it already is) and prefer project .env files or your shell for CI.
Precedence
When the harness starts it loads configuration in this order — earlier wins, and lower layers never overwrite something already set:
- CLI flags —
--budget,--model, and friends. The user acting now. - Real shell environment — anything already exported in your shell.
- Project
.envfiles in the current directory —.env.harness, then.env. Only fills keys not already set. - Project config —
.minima/config.toml, the one committed layer. Allowlisted keys only, and it may only move a value toward the safer side (see below). - Per-user store — OS keychain +
~/.minima-harness/config.env, materialized into the environment with set-default semantics (lowest precedence).
Put shared, non-secret settings (like MINIMA_URL for a local recommender) in a project .env.harness, and keep secrets in the keychain via minima config set.
Project config (.minima/config.toml)
Every layer above is uncommitted, and therefore trusted because you wrote it. .minima/config.toml is the exception: it is checked in, so it arrives with git clone — written by someone else. That inversion is what the rules below exist for.
# .minima/config.toml — committed, so it may only tighten what you already allow.
[budget]
limit_usd = 2.00 # only ever LOWERS your ceiling
mode = "enforce" # only ever gets STRICTER
[routing]
candidates = ["claude-haiku-4-5", "gemini-2.5-flash"] # intersected with your pool
[compaction]
artifact_spill = true # neutral — plainly shadows, like any other settingThree rules hold:
- The allowlist is the gate. Keys not on the list below are ignored — not blocked, ignored, and the harness says so on startup. A repo cannot set your API keys, and cannot reach any variable outside the four in the table: not a feature flag, not a permission, not a search path.
- A project file may only move a value toward the safer side. Not a spend special case: every allowlisted key declares a direction, or is neutral and plainly shadows.
- The clamp runs in the loader, before anything reaches the environment — so no part of the harness downstream can ever observe an unclamped value.
| Key | Variable | Direction |
|---|---|---|
budget.limit_usd | MINIMA_BUDGET_USD | Lower wins. A project ceiling below yours applies (even one set in your shell, which otherwise outranks it); one above yours is ignored. |
budget.mode | MINIMA_BUDGET_MODE | Strictest wins (shadow < warn < enforce). A project file can tighten enforcement, never relax it — including below the warn default. |
routing.candidates | MINIMA_CANDIDATES | Intersection only. Ids you do not already allow are dropped; a pool disjoint from yours is refused outright, since an empty pool would widen routing rather than narrow it. |
compaction.artifact_spill | MINIMA_TUI_COMPACT2 | Neutral — a team preference with no safer side, so it simply fills a gap you left and loses to your shell and .env files. It is the one allowlisted key a project file can turn off, which is why it had to be argued onto the list as neutral rather than assumed. |
The clamp cuts across precedence in one direction only, and it stops at the flags: --budget, --budget-enforce and --model are you acting right now, so they win over a project file the way they win over everything else.
Thinking level, judge sampling and the default model are deliberately not on the list — not because they are dangerous, but because nobody can yet name their safer side. The list grows by argument, not by default. Search paths are directional too (narrowing is safe, widening is not), which is why the default list is legislated in code rather than configured here.
A file that will not parse is reported and skipped: config never blocks startup. MINIMA_TUI_PROJECT_CONFIG=0 ignores the file entirely.
Environment variables
Mubit / Minima routing
| Variable | Required | Default | Purpose |
|---|---|---|---|
MUBIT_API_KEY | Yes | — | Memory backend + routing auth. Passed through to Mubit for recall/learning. |
MINIMA_URL | No | https://api.minima.sh | The Minima recommender endpoint. Set to http://localhost:8080 for local dev. |
MINIMA_API_KEY | No | falls back to MUBIT_API_KEY | Separate Minima auth, if your deployment uses one. |
MUBIT_ENDPOINT | No | — | Override the Mubit memory backend URL. |
MUBIT_CONSOLE_URL | No | https://console.mubit.ai | Console URL used by minima auth. |
MINIMA_NAMESPACE | No | per-repo project | Memory isolation lane. Overrides the repo's provisioned project. |
MINIMA_TIMEOUT | No | 30 | Recommender request timeout, in seconds. |
MINIMA_CANDIDATES | No | the shipped pool | Comma-separated model ids the recommender may pick from. |
MINIMA_BUDGET_USD | No | — | Session budget ceiling, in USD. --budget wins over it. |
MINIMA_BUDGET_MODE | No | warn | shadow (track only), warn (never blocks), or enforce. --budget-enforce wins over it. |
Per-repo memory isolation. If MINIMA_NAMESPACE is set it wins; otherwise the harness uses the namespace of the Mubit project that minima auth provisioned for this repo (stored in ~/.minima-harness/projects.json). This keeps each project's task → model → outcome history separate.
Harness features
These are on by default — set the variable to 0 to opt out. Every one fails open: with the feature off the harness behaves exactly as it did before it existed.
| Variable | Default | What it turns off |
|---|---|---|
MINIMA_TUI_BIG_PLAN | on | Plan verification — verify commands, gates, confidence tiers. |
MINIMA_TUI_MEMORY | on | The memory ledger and its per-turn injection. |
MINIMA_TUI_NOTIFY | on | Desktop notifications (OSC 9 + terminal bell) when a long turn finishes, a permission prompt is raised, or the question overlay opens. MINIMA_TUI_NOTIFY_AFTER_MS (default 10000) is how long a turn must run before it notifies — 0 notifies on every turn. Nothing is emitted without a TTY, so headless runs stay byte-clean. |
MINIMA_TUI_ARTIFACTS | on | Artifact spill: oversized tool output is written to a content-addressed file the model can page back with read, instead of being truncated into the transcript. |
MINIMA_TUI_ARTIFACT_GC_MB | 512 | LRU cap (in MB) on the artifact directory; the current run is exempt. 0 disables GC entirely. |
MINIMA_TUI_COMPACT2 | on | Lossless compaction: the pre-compaction transcript is kept as an artifact the summary points at, so nothing is unrecoverable. Inert when MINIMA_TUI_ARTIFACTS=0. |
MINIMA_TUI_CONTEXT_METER | on | The corrected context meter: the footer's ctx% counts the whole prompt the provider billed (including cached tokens) and shows absolute tokens, and auto-compaction fires on that same number. Off restores both halves — the footer divides bare uncached input by the window again, and auto-compaction returns to its old chars/4 estimate, so it fires later. |
MINIMA_TUI_EDIT_GUARD | on | Edit guard: read/grep stamp [snap:…] tags and record which lines were actually seen, so an edit against unseen or stale content gets a deterministic re-read instead of a blind write. |
MINIMA_TUI_IMAGES | on | Image input, on both surfaces. (1) Tool results: read on a png/jpeg/webp returns the image itself to models that accept image input, instead of refusing. (2) The composer: Ctrl+V attaches an image from the system clipboard as an [Image #N] token — delete the token to un-attach it — downscaling to 1568 px on the long edge when needed. Attaching an image narrows routing to vision-capable candidates; a model that still cannot see one is told it was omitted rather than sent a payload it would reject. Off restores both halves: the historical "image file not supported" refusal, and a Ctrl+V that pastes text only. |
MINIMA_TUI_STEER | on | Bash steering + replay guard — a command repeated verbatim after failing is steered rather than looped. |
MINIMA_TUI_REWIND | on | The checkpoint / rewind tool pair (context rewind; the DB transcript always keeps every row). |
MINIMA_TUI_GIT_COMMIT | on | Git commit authoring — the git_commit tool and the /commit command. Commits are authored by your git identity, run your pre-commit/commit-msg hooks, and carry a deduped Co-Authored-By per contributing model plus one Minima-Run-Id. Staging is explicit: what you staged, or the paths passed — never -a. Off, both surfaces disappear and committing is reachable only through bash, unattributed. |
MINIMA_TUI_COMMIT_LEDGER | on | The commits ledger — authoring a commit records one row joining its SHA to the run, the recommendations that produced it and their realized cost, so /why <sha> can answer later, by hash, which models wrote a commit, what it cost, and how its gates went. Off, the ledger write and the hash reader disappear; commits still carry their Co-Authored-By and Minima-Run-Id trailers, which never needed a database. |
MINIMA_TUI_BGJOBS | on | bash background jobs (background: true) and the bgjob control tool. Background jobs are killed at session end. |
MINIMA_TUI_TYPED_TASK | on | output_schema on the task tool — typed sub-agent results with a shape check. |
MINIMA_TUI_PLAN_CRITIC | on | The planning critic: one cheap pass over the approved steps at /plan finalize, flagging non-discriminative checks and hidden dependencies. Advisory — it never blocks a plan. |
MINIMA_TUI_DIFF_REVIEW | on | The zero-context diff review that fires when a plan closes fully completed. An objection writes a yellow gate; it can never turn a plan green. |
MINIMA_TUI_AUTO_GATES | on | Auto-gates: steps the model gave no check for are filled with your repo's own commands, mined from package.json / Makefile. With it off those steps stay unverified. |
MINIMA_TUI_PLAN_PREMIUM | on | Premium models for plan synthesis and the design council. Off routes planning through the ordinary session pool. |
MINIMA_TUI_TOOL_ALLOWLIST | on | Per-step tool allowlists — a step naming its tools cannot use others while it is in progress. |
MINIMA_TUI_FAILURE_MATCHER | on | Failure classification on the recovery ladder. Off falls back to the blunt always-escalate behavior. |
MINIMA_TUI_EDITOR | on | Composing the prompt in $EDITOR — Ctrl+X Ctrl+E and /editor. Off restores Ctrl+E as thinking-only. This names a behavior, not an editor: only 0 disables it, and MINIMA_TUI_EDITOR=vim leaves it on with the value ignored — set $EDITOR (or $VISUAL) to choose the binary. |
MINIMA_TUI_GRADED_OUTCOME | on | Graded outcome labels, which report unverified-but-positive evidence distinctly from verified evidence. |
MINIMA_TUI_PROJECT_CONFIG | on | Reading .minima/config.toml. Off, the committed project config is not opened at all and every other layer resolves exactly as before. |
MINIMA_TUI_KEYMAP | on | Your keymap file (~/.minima-harness/keymap.toml). Off ignores the file entirely and uses the built-in keys — exactly as if it did not exist. |
Two variables work the other way — they grant something the harness refuses by default:
| Variable | Default | What setting it does |
|---|---|---|
MINIMA_TUI_FETCH_LOCAL | unset (deny) | =1 lets web_fetch reach loopback, link-local, and private addresses. Default is DENY, so a model-authored URL cannot reach your local network or a cloud metadata endpoint. |
MINIMA_TUI_ALLOW_VERIFY | unset (deny) | =1 lets plan verify commands run in headless (-p / --mode json) runs, where they otherwise fail closed. |
Opt-in features live behind the experimental umbrella — see Experimental features.
LLM provider keys
Set a key for any provider you want the harness to be able to run. The first environment variable listed for a provider wins.
| Provider | Environment variable(s) | Notes |
|---|---|---|
| Anthropic (Claude) | ANTHROPIC_API_KEY, ANTHROPIC_OAUTH_TOKEN | Claude — Opus / Sonnet / Haiku |
| OpenAI | OPENAI_API_KEY | GPT-5.x / GPT-4o |
| Google Gemini | GEMINI_API_KEY, GOOGLE_API_KEY, GOOGLE_GENAI_API_KEY | Gemini 2.5 / 3.5 |
| xAI (Grok) | XAI_API_KEY | Grok 4.x · base URL https://api.x.ai/v1 |
| DeepSeek | DEEPSEEK_API_KEY | Open-weight, cheap · https://api.deepseek.com |
| OpenRouter | OPENROUTER_API_KEY | Aggregator — any model, one key · https://openrouter.ai/api/v1 |
| Groq | GROQ_API_KEY | Fast inference for open models · https://api.groq.com/openai/v1 |
Default model catalog
Out of the box the harness seeds this catalog; /model lets you pin one or add your own.
| Model | Provider | Context |
|---|---|---|
gpt-4o-mini | openai | 128K |
gpt-4o | openai | 128K |
deepseek-chat | deepseek | 64K |
claude-haiku-4-5 | anthropic | 200K |
claude-sonnet-4-6 | anthropic | 200K |
claude-opus-4-8 | anthropic | 200K |
gemini-2.5-flash | 1M | |
gemini-2.5-pro | 2M |
When routing (not pinned), Minima chooses from the candidate set gemini-2.5-flash, claude-haiku-4-5, claude-sonnet-4-6, gemini-2.5-pro, claude-opus-4-8 by default.
To run a model that isn't seeded, pass --model <id> --provider <name> — the harness registers it on the fly against the provider's OpenAI-compatible endpoint. See CLI usage.
Config files at a glance
| Path | What it holds |
|---|---|
~/.minima-harness/config.env | Per-user credentials (file backend, mode 0600). |
~/.minima-harness/projects.json | Repo → Mubit instance / project / namespace mapping (written by minima auth). |
~/.minima-harness/sessions/*.jsonl | Append-only session history. See Sessions. |
./.env.harness, ./.env | Project-scoped environment overrides. Never commit these. |
./.minima/config.toml | Committed project config — allowlisted keys, safer side only. |