Config reference
Every key in .autofeat/config.yml, with type, default, and notes.
File: .autofeat/config.yml on the default branch. Unknown keys are errors. The pull request branch cannot change the policy that judges that pull request.
autonomy.auto_approve false forces autonomy.merge_mode to stop_before_merge, even if the file says approve_only or auto. Set auto_approve: true before either of those modes will stick. See Merge modes.
Keys
| Key | Type | Default | Notes |
|---|---|---|---|
version | literal 1 | 1 | Only version 1. |
identity | app | app | Only value. |
runner | string | nixos | Recorded on the decision. |
autonomy.merge_target | string | main | Base branch name. |
autonomy.auto_approve | bool | false | When false, merge mode is forced to stop_before_merge. |
autonomy.merge_mode | stop_before_merge, approve_only, auto | stop_before_merge | approve_only and auto require auto_approve: true. |
autonomy.dry_run | bool | true | No push, review, merge, or ready label. Journal, sticky, and checks still write. |
autonomy.require_green_checks | bool | true | When false, an empty check set can count as success. When true, it does not. |
entry_action | action name | review | Must be in policy.allowed_actions. |
agents.default | string | opencode | Must be in agents.allowed. |
agents.allowed | list of strings | opencode, claude, codex, grok-build | kimi is recognised for subscription login and is not in this default list. |
agents.billing | map of agent to api_key or subscription | {} | Missing agent means api_key. Keys must be in agents.allowed. |
agents.models.<agent>.model | string or omitted | omitted | CLI model id, for example sonnet. |
agents.models.<agent>.provider | string or omitted | omitted | Requires model. A provider and model pair is accepted for opencode only. |
models.default.provider | string | openrouter | |
models.default.model | string | deepseek-v4-pro | Must appear in models.allowed. |
models.allowed | list of {provider, model} | the default, when the key is omitted | An explicit [] is invalid. An opencode provider and model pair must equal models.default or sit in this list. |
budget.turns | int >= 1 | 12 | Hard ceiling. |
budget.usd | number > 0 | 25.0 | Hard ceiling. |
budget.alert_usd | number >= 0 | 10.0 | Must be <= budget.usd. Warning only. |
budget.minutes | int >= 1 | 240 | Hard ceiling. |
budget.tokens | int >= 1 | 2000000 | Hard ceiling. |
subscription.max_concurrent | int >= 1 | 2 | Subscription agents. |
subscription.max_runs_per_day | int >= 1 | 50 | Alert at 80 percent. Not a stop by itself. |
security.allow_same_uid | bool | false | true requires autonomy.dry_run: true. Hosted launcher refuses it. |
security.allow_forks | bool | false | Write actions on a fork are refused. Review can still start. |
security.require_signature | bool | true | Directives must verify. |
security.trusted_actors | list of strings | a-x-c | GitHub logins trusted to drive the run. |
methods | map of action to method | {} | Method must be legal for the action and listed in policy.allowed_methods. |
orchestrate.max_workers | int >= 1 | 4 | Used when method is orchestrate. |
labels.go | string | autofeat:go | Admit a turn. |
labels.stop | string | autofeat:stop | Kill switch. |
labels.pause | string | autofeat:pause | Pause. Removing it does not resume. |
labels.ready | string | autofeat:ready | Added when stopping before merge. |
checks.required_checks | list of strings | [] | Names that casefold-start with autofeat/ are refused. |
checks.required_producers | map of name to int or string | {} | App id (int) or slug (string). Same autofeat/ refusal. |
checks.allow_missing_checks | bool | false | Zero checks is a refusal when false. |
policy.mode | review_only or full | review_only | review_only forbids plan, implement, and test. |
policy.allowed_actions | list of actions | derived from mode | Omit the key to take the mode default. |
policy.allowed_methods | map of action to list of methods | derived | Each action's list must include that action's default method. |
policy.reviewer.provider | string or null | null | |
policy.reviewer.model | string or null | null | Must not appear in must_differ_from. |
policy.reviewer.must_differ_from | list of strings | [] | Producer model ids the reviewer must not share. |
policy.reviewer.severity_threshold | info, low, medium, high, critical | high |
Action names: plan, implement, test, review, gate, merge, halt.
Default method per action:
| Action | Default method | Also legal |
|---|---|---|
plan | single | orchestrate |
implement | orchestrate | single |
test | single | orchestrate |
review | delegate | native is parseable and refused |
gate | native | native only |
merge | native | native only |
halt | native | native only |
Method flow exists in the enum and policy refuses it. Do not set it.
review_only derived actions are review, gate, merge, halt. Derived methods: review is delegate; gate, merge, and halt are native.
Annotated example
This file matches the schema defaults. Comments are not part of the data.
version: 1
identity: app
runner: nixos
autonomy:
merge_target: main
auto_approve: false
# Ignored while auto_approve is false. The loader stores stop_before_merge.
merge_mode: stop_before_merge
dry_run: true
require_green_checks: true
entry_action: review
policy:
mode: review_only
reviewer:
severity_threshold: high
agents:
default: opencode
allowed: [opencode, claude, codex, grok-build]
billing:
claude: subscription
# models:
# claude: { model: sonnet }
# opencode: { provider: openrouter, model: deepseek-v4-pro }
models:
# Omitted allowed becomes [default]. Explicit [] is invalid.
default: { provider: openrouter, model: deepseek-v4-pro }
budget:
turns: 12
usd: 25.0
alert_usd: 10.0
minutes: 240
tokens: 2000000
subscription:
max_concurrent: 2
max_runs_per_day: 50
security:
allow_same_uid: false
allow_forks: false
require_signature: true
trusted_actors: [a-x-c]
methods: {}
orchestrate:
max_workers: 4
labels:
go: "autofeat:go"
stop: "autofeat:stop"
pause: "autofeat:pause"
ready: "autofeat:ready"
checks:
required_checks: []
required_producers: {}
allow_missing_checks: falseTo leave dry run, set autonomy.dry_run: false on the default branch after a clean dry run. To let the App approve and then stop, set auto_approve: true and merge_mode: approve_only. To merge, set auto_approve: true and merge_mode: auto. See Budgets and billing.
The deployment-wide API-key ceiling daily_api_key_ceiling_usd (default 25.0) is host config. It is not a key in this file.