Skip to content
styrev0.11.0
GitHub

Configuration

Styre reads one settings file: config.json, at ~/.config/styre/config.json. It holds operator policy — which tracker, which agent, notifications, telemetry. Every key has a default, so the file is optional; you only write the keys you want to change.

config.json is separate from a repo’s profile. The profile describes a project’s shape and is written by styre setup; config is your policy and is written by hand. They never merge into each other.

Key Default What it does
issueTracker "linear" Which tracker to read tickets from: linear or jira.
forge "github" Which code host to push to. Only github is available.
agent Claude The agent provider and its per-tier models. See below.
notifier "none" Outbound notifications: none or slack.
notify "escalations" How much to send: escalations, transitions (also stage changes), or everything (also loopbacks).
slack.channel The Slack channel to post to. Required when notifier is slack.
onPlanDefect "escalate" When review finds a flaw in the plan: escalate to a human, or redesign to loop back and re-plan.
complexityGrading false Opt in to a complexity grader when sizing work. Off means sizing is based on sprawl alone.
implementDisposition "reject" How implementation handles files the plan did not declare: reject (the proven default) or discard.
jira built-in Jira-specific policy. See below.
pricing built-in Price table for the cost estimate in telemetry. See below.
telemetry true Anonymous usage analytics. See Telemetry.

Sets the provider and the model for each of the three tiers Styre uses — deep for planning and review, standard for implementation, cheap for small mechanical steps.

{
"agent": {
"provider": "claude",
"models": {
"deep": "claude-opus-4-8",
"standard": "claude-sonnet-4-6",
"cheap": "claude-haiku-4-5-20251001"
}
}
}

That block is also the default — omit agent entirely and you get exactly this. The Codex equivalent:

{
"agent": {
"provider": "codex",
"models": {
"deep": "gpt-5.6-sol",
"standard": "gpt-5.6-terra",
"cheap": "gpt-5.6-luna"
}
}
}

Only relevant when issueTracker is "jira". Absent, Styre uses built-in defaults.

Key Default What it does
jira.statusMap built-in Maps each Styre ticket state to one of your Jira statuses. See below.
jira.bugTypeNames ["Bug"] Which Jira issue types count as bugs, deciding the fix/ versus feat/ branch prefix.

Styre tracks a ticket through five internal states and projects each one onto a status in your Jira workflow. The default map assumes a fairly standard board:

{
"jira": {
"statusMap": {
"in_progress": { "status": "In Progress" },
"in_review": { "status": "In Review" },
"done": { "status": "Done", "resolution": "Done" },
"canceled": { "status": "Done", "resolution": "Won't Do" },
"blocked": { "status": "In Progress" }
}
}
}

Each entry is a status — the exact name of a status in your Jira project — and an optional resolution set when the issue moves there. The five state keys are fixed; the values are what you change to match your board’s status names.

Unlike the other nested blocks, statusMap is filled in per state: any state you leave out keeps its default from the table above, so you can override just the one or two states whose names differ on your board.

Styre’s telemetry includes a rough cost estimate per run. The pricing block lets you supply your own rates if the built-in table is stale or does not cover a model you use.

{
"pricing": {
"version": "my-rates@2026-07",
"rates": {
"claude-sonnet-4-6": { "input": 3.0, "cacheRead": 0.3, "cacheWrite": 3.75, "output": 15.0 }
}
}
}

Rates are USD per million tokens. Two things to know:

  • This only affects the estimate. The actual cost your provider reports is passed through untouched and never overwritten by this table.
  • rates replaces the whole built-in table, not one entry. A model you do not list becomes unpriced rather than keeping its built-in rate. To adjust one model, copy the full built-in table and change the one line.

There are two ways config is loaded, and they do not mix:

With --config <path> — that file is the only source. Nothing else is read or merged. Use this when you want a run to be fully self-contained and reproducible.

Without it — Styre layers two files: a per-project ~/.config/styre/<slug>/config.json on top of the global ~/.config/styre/config.json, then fills any remaining gaps with the defaults.

Two things that catch people out:

  • There is no per-ticket configuration. A ticket cannot carry settings. Runtime policy lives only in config.json (or --config). Anything you put in a ticket to configure a run is ignored.
  • Telemetry has one env-var override. DO_NOT_TRACK or STYRE_TELEMETRY=0 turns analytics off even if telemetry is true in config. It is the only setting an environment variable can override — see Telemetry.

For where these files live on disk, see Files and paths. For the profile that styre setup writes, see Project setup.