::docs :: reference

configuration & models

config.yaml: the four model tiers, /models, runtime and trust knobs, the memory, web, RAG, MCP, toolkits, and shell sections, and which settings persist.

Everything lives in one file, config.yaml, seeded on first run from the tracked template config.default.yaml. A clone keeps it beside the install, and pipx/uv installs keep it in ~/.saturn. /config <dotted.key> <value> sets most of it live. Edits persist by default, and --session keeps one for this session only. Trust keys are the exception (see below).

::tiers

Each tier binds one chat model, used for the agent's calls and the background work (compaction, the memory review, /init), plus an embedder. Swapping hardware is a one-line active_tier change.

config.yaml
active_tier: 4b

tiers:
  4b:
    model: "qwen3.5:4b"
    embedder: qwen3-embedding:8b
  9b:
    model: "qwen3.5:9b"
    embedder: qwen3-embedding:8b
  27b:
    model: "qwen3.8:27b"
    embedder: qwen3-embedding:8b
  35b:
    model: "qwen3.6:35b"
    embedder: qwen3-embedding:8b
tiermodelcontext windowsized for
4bqwen3.5:4b32kan 8 GB machine; the install default
9bqwen3.5:9b64ka 16 GB Mac
27bqwen3.8:27b64ka 32 GB Mac
35bqwen3.6:35b128k36 GB or more of unified memory

The ladder is a recommendation, not a gate. Any Ollama model with native tool-calling binds with /models use <id>. capabilities: declares each model's context window, and an unknown model falls back to an 8,192-token window. /config runtime.num_ctx <size|auto> overrides every window at once. Ollama is the only backend.

::/models

The model page reads your machine (on Apple silicon: the chip, its GPU cores, unified memory, and memory bandwidth) and prices two ladders against it, the four chat tiers and three qwen3-embedding sizes: weights, the memory each needs at its window, an estimated decode speed, and whether it's pulled. The recommendation is the largest tier that fits and decodes at 10 tok/s or better. A tier that fits but would crawl reads fits · slow and is never the default. Below the ladders come every other model you've pulled, chat models and embedders in separate sections, each with its size, parameter count, and whether it fits. The rows are numbered: pick a chat model to run it on the active tier, or an embedder to switch to it. A chat model that can't call tools reads no tool calling and can't be picked. The first launch runs this page.

commands
/models                  the page, then pick a row (Enter takes the recommendation)
/models list             the page only
/models use <id>         run any Ollama tool-calling model on this tier
/models embedder <id>    switch the embedding model (re-embeds the corpus)

A pick whose model isn't pulled asks first (y/N, default no) and switches only after the pull succeeds. Every switch persists to config.yaml; --session applies it live only.

::runtime

keydefaultmeaning
max_iterations16agent passes per turn; from this pass on no tool call runs, and the model answers from what it has
thinkautofast never thinks, auto thinks before it acts (and after an error or a steer), deep thinks on every pass; set it with /think. The old off / adaptive / on still read, and anything else runs as auto with a warning at startup
think_budget1024the most tokens one thought may spend before it's cut
auto_approveread_onlytools at or below this tier run without asking (trust key)
num_ctxnull (auto)Ollama context window; null uses each model's declared window
llm_timeout120read timeout per model call, so a wedged daemon can't hang a turn
keep_alive30mhow long Ollama keeps the model loaded between requests
primetruere-send the stable prompt prefix between turns so the next turn prefills only what's new
auto_compact / compact_thresholdtrue / 0.85fold older turns into a summary once the window fills
citationstruethe numbered Sources list under an answer
airgapfalseblock and record every network exit (trust key)
quarantinegateoff / warn / gate for untrusted tool output (trust key)
receipttruethe trust segment on the per-answer receipt
grant_scopetaskhow long a gate a grant lives: task / session / persist (trust key)

::other sections

memory.context_cap / stale_days / review_llm

4000 / 90 / true: the memory block's budget, when an unmatched fact is flagged stale, and whether the review asks the model for proposals

memory.auto_learn

true: keep a fact you state in your own words without asking; false makes every remember ask. Headless runs never auto-learn

web.max_results

results per web_search (default 5); the backend is fixed and keyless

rag.chunk_size / chunk_overlap / k

1000 / 150 / 6; chunking changes force a re-embed

mcp.servers / connect_timeout / call_timeout

see mcp servers

toolkits.<name>

true for every toolkit: false unbinds that group of tools. /tools on|off edits these lines; see toolkits

shell.timeout / shell.env_scrub

60 s per command; secret-shaped variable names stripped from children (trust key)

notify.menubar

false: start the menu bar icon with each launch (macOS)

paths.*

database, documents, workspace (a fallback only), cache, memory, db_sqlite, sessions, snapshots, permissions, exports

::what persists

  • –Ordinary keys set with /config persist to config.yaml by default; --session keeps the change for this session. A save rewrites the key's existing line in place, comments kept. A setting added to Saturn after your config.yaml was written gets its line appended to the end of its section, and nothing else in the file changes. A key Saturn doesn't know is never written.
  • –Trust keys (runtime.auto_approve, runtime.airgap, runtime.quarantine, runtime.grant_scope, and shell.env_scrub) and the /policy toggles are session-only unless you pass --save. A loosened posture is never written to disk silently.
  • –/policy risk --save overrides, the shell prefix allowlist, and the Shortcuts allowlist persist in database/permissions.json. /policy allow <prefix> always persists; a gate a grant follows grant_scope.
  • –The live config.yaml is user data that git doesn't track, so saved settings never dirty the repo or break /update.

note

Environment variables use the SATURN_ prefix (SATURN_HOME, SATURN_DEBUG, …), standing instructions live in SATURN.md, and a tier binds one model:. A config.yaml with an old roles: block is refused with the exact line to write instead.