config.toml
Path: <repo-root>/.kasmos/config.toml
This is the project-local configuration file. It is the authoritative source for agent profiles, lifecycle phase mappings, UI behavior, orchestration tuning, and webhook hooks.
kasmos generates this file on first boot via kas setup. You can safely edit it by hand — it is re-read on each startup.
top-level fields
| field | type | default | description |
|---|---|---|---|
default_program | string | auto-detected (opencode → claude) | fallback agent executable when a role has no profile |
auto_yes | bool | false | when true, the daemon automatically accepts all agent prompts |
daemon_poll_interval | int (ms) | 1000 | how often the daemon checks session state (milliseconds) |
branch_prefix | string | <username>/ | prefix prepended to git branch names created by kasmos |
notifications_enabled | bool? | true | desktop notifications; null defaults to enabled |
claude_no_flicker | bool? | false | set CLAUDE_CODE_NO_FLICKER=1 on spawned claude agents; reduces TUI flicker but may affect prompt detection |
database_url | string | — | remote task store URL (e.g. http://host:7433); local SQLite used when empty |
[phases] — lifecycle phase-to-role mapping
Maps lifecycle phase names to agent role names. kasmos uses this to look up which [agents.<role>] profile to use for each phase.
[phases]
planning = "planner"
elaborating = "architect"
implementing = "coder"
spec_review = "reviewer"
quality_review = "reviewer"
fixer = "fixer"
readiness_review = "master" # also accepted as master_review (backward-compat alias)
The phase names on the left are fixed lifecycle identifiers. The role names on the right must match keys in the [agents] table.
readiness_reviewvsmaster_review:readiness_reviewis the canonical phase key — it maps to the master agent role that runs during theverifyingFSM status. The old keymaster_reviewis accepted as a backward-compatible alias and is resolved toreadiness_reviewat profile resolution time (not at load time). New configs should usereadiness_review.
[agents.<role>] — agent profiles
Each role is configured in its own [agents.<role>] subsection. See the agent profiles reference for all available fields.
[agents.coder]
enabled = true
program = "claude"
model = "claude-sonnet-4-5"
execution_mode = "tmux"
flags = ["--permission-mode bypassPermissions"]
[agents.planner]
enabled = true
program = "opencode"
execution_mode = "tmux"
effort = "high"
permission_default can be set per profile to "prompt" or "bypass", or left unset to inherit the spawn-source default. "inherit" is accepted as an alias for unset, but normalized configs usually omit it; see agent profiles: permission_default for resolution details.
[ui] — UI behavior
| field | type | default | description |
|---|---|---|---|
animate_banner | bool | false | enable idle banner animation |
auto_advance | bool? | true | skip the planner→architect confirmation dialog; start elaboration automatically after planning finishes |
auto_advance_waves | bool? | true | skip confirmation dialog after a clean wave |
auto_review_fix | bool? | true | automatically start the review→fix→re-review loop |
max_review_fix_cycles | int? | 0 (unlimited) | cap the review-fix loop iterations; 0 means no cap |
auto_readiness_review | bool? | true | when true, reviewer approval transitions the task to verifying status and spawns the master agent for a holistic readiness check before done. When false, review_approved flows directly to done and no master agent is spawned. |
readiness_self_fix_max_lines | int? | 80 | maximum number of net lines the master agent may change in a single self-fix attempt; findings that would require more are escalated via verify_failed instead |
readiness_max_verify_cycles | int? | 2 | maximum number of verify-round attempts before the loop is force-promoted to verify_approved. Must be a positive integer — values ≤ 0 are rejected at load time and fall back to the default. To disable the readiness gate entirely, set auto_readiness_review = false instead. |
theme_source | string | "static" | color palette source: empty/"static" uses the built-in Rose Pine Moon palette; "system" resolves a Linux system-derived palette |
system_theme_provider | string | "auto" | provider used when theme_source = "system": empty/"auto", "file", "caelestia", "freedesktop", or "gnome" |
theme_palette_file | string | — | palette JSON file used by the "file" and "caelestia" providers; ~ is expanded, and relative paths resolve from .kasmos/config.toml's directory |
[ui]
animate_banner = false
auto_advance = true
auto_advance_waves = true
auto_review_fix = true
max_review_fix_cycles = 3
auto_readiness_review = true # set to false to skip verifying status and go directly to done
readiness_self_fix_max_lines = 80 # master agent self-fix ceiling (net lines changed)
readiness_max_verify_cycles = 2 # force-promote after this many verify rounds
system theme example:
[ui]
theme_source = "system"
system_theme_provider = "file"
theme_palette_file = "~/.config/caelestia/kasmos-theme.json"
Omitting all three theme keys keeps the built-in Rose Pine Moon palette. Setting theme_source = "" or theme_source = "static" also disables system theming. When theme_source = "system" and system_theme_provider is empty or "auto", kasmos uses the Linux desktop color-scheme preference when it can and safely falls back to the built-in palette when it cannot. System theme providers are Linux-only; unsupported platforms, unreadable files, unknown providers, and invalid palette JSON all fall back to Rose Pine Moon.
The "file" and "caelestia" providers read a JSON palette with kasmos semantic role names. A top-level object is supported, and so is a nested colors or colours object. Missing roles inherit the default palette.
{
"base": "#232136",
"surface": "#2a273f",
"overlay": "#393552",
"text": "#e0def4",
"muted": "#6e6a86",
"subtle": "#908caa",
"iris": "#c4a7e7",
"foam": "#9ccfd8",
"gold": "#f6c177"
}
For Caelestia, configure Caelestia to generate a kasmos-specific palette/template target at the file path you set in theme_palette_file; the path above is only an example. Relative paths are resolved from the directory containing .kasmos/config.toml, so theme_palette_file = "themes/kasmos-theme.json" points at .kasmos/themes/kasmos-theme.json. Use system_theme_provider = "file" for a plain generated JSON file, or system_theme_provider = "caelestia" when you want the config to document that Caelestia owns the generated target. kasmos resolves the palette on startup only, so restart kasmos after regenerating the file.
[telemetry] — crash reporting
| field | type | default | description |
|---|---|---|---|
enabled | bool? | true | Sentry crash reporting; null defaults to enabled |
[telemetry]
enabled = false
[resources] — agent resource controls
Controls the CPU and I/O priority of kasmos-managed agent processes. The block is entirely optional — omitting it leaves default scheduling unchanged.
| field | type | default | description |
|---|---|---|---|
profile | string | "normal" | preset to apply: normal (no-op), interactive, or custom |
nice | int | (profile preset) | process niceness value: 0–19 (higher = lower priority). Negative values are rejected. |
ionice_class | string | (profile preset) | Linux I/O scheduling class: none, best-effort, or idle. realtime is rejected. |
ionice_level | int | (profile preset) | I/O priority level 0–7; only valid for ionice_class = "best-effort" |
build_jobs | int | (profile preset) | -j parallelism hint injected into build tool environment; 0 = unset |
go_package_parallelism | int | (profile preset) | sets GOFLAGS=-p=<n> for go build/go test; 0 = unset |
gomaxprocs | int | (profile preset) | overrides GOMAXPROCS for agent processes; 0 = unset |
max_parallel_wave_tasks | int | (profile preset) | caps concurrent wave tasks; 0 = unset/unlimited |
[resources.env] | table | — | extra environment variables injected into every agent process; keys must be valid shell names and must not overwrite kasmos control variables |
profiles:
normal(default) — no wrapper, no environment injection, no wave cap. Identical to omitting the block.interactive— preset for latency-sensitive desktop workloads:nice = 10,ionice_class = "best-effort",ionice_level = 7,build_jobs = 1,go_package_parallelism = 1,gomaxprocs = 2,max_parallel_wave_tasks = 1. Individual keys override the preset.custom— starts fromnormaland enables only the keys you supply explicitly. At least one control key must be set.
minimal example (interactive preset):
[resources]
profile = "interactive"
# optional overrides
build_jobs = 1
go_package_parallelism = 1
max_parallel_wave_tasks = 1
custom example:
[resources]
profile = "custom"
nice = 15
max_parallel_wave_tasks = 2
See the interactive resource controls guide for a step-by-step walkthrough including how to confirm the profile is active and how pending wave tasks behave.
[orchestration] — wave orchestration tuning
| field | type | default | description |
|---|---|---|---|
blueprint_skip_threshold | int? | 2 | when a plan has ≤ this many tasks, kasmos skips elaboration and wave orchestration and runs a single-agent "blueprint" mode instead |
parallel_planner_architect | bool | true | plan start launches a cache-only architect baseline session beside the planner by default; set to false to disable and restore planner-first behavior where the planner finishes first and the architect pass derives its own baseline inline |
[orchestration]
blueprint_skip_threshold = 2
Setting this to 0 forces multi-agent wave orchestration for every plan, including single-task ones. Setting it higher causes more plans to run in single-agent mode.
parallel_planner_architect is default-on. When unset or true, plan start launches the planner and an advisory cache-only architect baseline session together. To opt out and restore planner-first behavior where the planner finishes before the architect pass starts, set:
[orchestration]
parallel_planner_architect = false
The runtime sequence when active (the default) is:
- plan start clears stale
.kasmos/cache/<planSlug>-architect-baseline.json - the planner starts
- an
architect-baselineruntime session starts separately - the planner writes the draft and emits
planner-finished - the final architect reads the planner draft plus a valid cached baseline, or falls back to its inline self-baseline when the cache is absent or invalid
- coder waves proceed normally
The baseline cache is advisory, safe to delete, and not task-store state. The baseline session writes the cache artifact only; it does not mutate task content, change lifecycle status, or emit lifecycle signals. Signal names are unchanged.
Blueprint skip still applies after the planner draft is available. A small planner draft can skip the final architect pass, so a baseline cache may be produced but unused.
[[hooks]] — FSM transition hooks
Hooks fire when a task transitions between lifecycle states. They are defined as an array of tables.
webhook hook
[[hooks]]
type = "webhook"
url = "https://your-server.example.com/webhook"
events = ["implement_start", "implement_finished", "review_approved"]
[hooks.headers]
Authorization = "Bearer your-secret-token"
X-Source = "kasmos"
command hook
[[hooks]]
type = "command"
command = "/usr/local/bin/notify-team.sh"
events = ["review_approved"]
hook fields
| field | type | description |
|---|---|---|
type | string | "webhook" or "command" |
url | string | (webhook) full URL to POST to |
headers | table | (webhook) additional HTTP headers |
command | string | (command) shell command to execute |
events | []string | FSM event names that trigger this hook |
Valid event names: plan_start, planner_finished, implement_start, implement_finished, request_review, review_approved, review_changes_requested, start_over, reimplement, cancel, reopen.
full example
# Generated by kas setup
default_program = "opencode"
auto_yes = false
daemon_poll_interval = 1000
branch_prefix = "alice/"
notifications_enabled = true
claude_no_flicker = false
[phases]
planning = "planner"
elaborating = "architect"
implementing = "coder"
spec_review = "reviewer"
quality_review = "reviewer"
fixer = "fixer"
readiness_review = "master"
[agents.planner]
enabled = true
program = "opencode"
execution_mode = "tmux"
effort = "high"
[agents.architect]
enabled = true
program = "claude"
model = "claude-sonnet-4-5"
execution_mode = "sdk"
[agents.coder]
enabled = true
program = "claude"
model = "claude-sonnet-4-5"
execution_mode = "tmux"
flags = ["--permission-mode bypassPermissions"]
[agents.reviewer]
enabled = true
program = "claude"
model = "claude-opus-4-5"
execution_mode = "sdk"
[agents.master]
enabled = true
program = "claude"
model = "claude-opus-4-5"
execution_mode = "sdk"
[agents.fixer]
enabled = true
program = "claude"
model = "claude-sonnet-4-5"
execution_mode = "tmux"
[ui]
animate_banner = false
auto_advance = true
auto_advance_waves = true
auto_review_fix = true
max_review_fix_cycles = 3
auto_readiness_review = true
readiness_self_fix_max_lines = 80
readiness_max_verify_cycles = 2
theme_source = "system"
system_theme_provider = "file"
theme_palette_file = "~/.config/caelestia/kasmos-theme.json"
[telemetry]
enabled = true
[orchestration]
blueprint_skip_threshold = 2
parallel_planner_architect = true
[[hooks]]
type = "webhook"
url = "https://hooks.example.com/kasmos"
events = ["implement_finished", "review_approved"]
troubleshooting
If kasmos does not seem to pick up your config changes, run:
kas debug
This prints the resolved config path and the fully-parsed configuration, so you can confirm the right file is being read.