Skip to main content
Version: Next

Tuning the guardrails

Every limit and gate lives in orion.json at the repository root, reviewable like code. Every key is in the configuration reference.

The main settings​

SettingDefaultWhat it stops
limits.max_tool_calls400a session burning budget indefinitely
limits.max_repeat_identical4the same call looping with no new input
limits.max_consecutive_failures3retrying a broken thing forever
limits.max_same_command_failures3one command failing over and over
limits.max_session_minutes90wall-clock runaway
limits.max_edits_without_verify25edits piling up with no passing test or build
limits.max_files_touched60blast radius: a change too wide for one session
limits.max_concurrent_tickets4how many tickets orion watch works at once
limits.no_progress_minutes60a watch cycling all night without achieving anything
qa.max_rounds3QA and the developer arguing until the budget runs out
ci.auto_fixtruea red build going straight to orion-failed instead of back to the agent; false turns the CI fix loop off
ci.max_fix_attempts3an agent re-fixing a red build all night
collect.batch_integrationfalse; true for projects orion plan createsone pull request and CI run per ticket
gates.require_plan_before_editfalse; true for projects orion plan createsimplementation before a written plan
gates.protect_tests_during_fixtruean agent weakening the test that defines "fixed"
gates.production_requires_authorizationtruean unauthorised production deploy
vcs.protected_branches[main, develop]direct pushes to either long-lived branch
vcs.work_branch β‰  vcs.default_branchenforcedOrion merging agent work straight into the release branch

What each breaker limit does when it trips is on Circuit breakers.

Set them with the command​

orion config limits # every bound, with provenance
orion config limits qa.max_rounds 3
orion config limits ci.max_fix_attempts 3
orion config collect # how work lands, and what each switch costs
orion config collect batch_integration true

orion config limits lists every bound with its effective value and where that value came from: orion.json or the shipped default. With a key and value it writes one. It edits the file the runner actually reads, which is not always the one you are standing in, and it leaves the _comment_* keys where they are. The two fix-round ceilings take their block as a prefix (qa., ci.), because that is where they live in the JSON.

The web dashboard's Settings β†’ Limits page runs the same checks, but refuses a value that the terminal would ask you to confirm.

Zero restores the default​

A limit of 0 restores the default; it does not mean unlimited, because in JSON a 0 is indistinguishable from a value nobody set.

The weekly budget is the one exception, and it goes the other way: there, zero means no budget. See Budget and monitoring.

The two fix-round ceilings​

qa.max_rounds and ci.max_fix_attempts bound how many times an agent is handed what went wrong and asked to try again. Both default to 3.

Stopping too early sends a person work that one more exchange would have finished. Each extra round raises the worst case on every ticket that fails to converge, and that spend lands on the implementer, the agent that dominates per-ticket cost. Set them to 2 to spend less.

In the CI loop, an identical repeated failure ends the loop immediately, so a third attempt is only reached by a run producing a different failure each round. Raising the ceiling does not change that.

Neither has an upper clamp. For a value above 5, orion config limits states what it costs and asks you to confirm.

Concurrency​

limits.max_concurrent_tickets bounds how many agents run at once. It defaults to 4. Set it to 1 for a strictly sequential watch.

Concurrent git against one shared clone, a budget checkpoint crossed by runs already in flight, several sessions hitting one rate limit, and tickets that all edit the same files are all absent at one and grow with the number in flight; conflicts grow roughly with its square. A value above 10 asks you to confirm, because these depend on a machine, a repository and a rate limit Orion cannot measure.

Two things to know:

  • It multiplies with limits.max_concurrent_children, the cap on how many subagents one run may fan out to at once (default 2). Four tickets each fanning out is a different load from four processes.
  • Approvals do not parallelise. N tickets finishing means N approvals waiting on one person.

Other limits​

These are in code and in the configuration reference, with shipped defaults you will rarely need to change:

SettingDefaultBounds
limits.max_consecutive_polls12an agent polling a background command with nothing else happening
limits.max_concurrent_children2subagents one run fans out to at once
limits.max_breaker_trips2breaker trips before the planner evicts a ticket
limits.max_stranded2times a ticket's worktree fails to settle before it is evicted

The branch model​

Orion's job ends when work merges into the integration branch (vcs.work_branch, develop). Promotion to the release branch (vcs.default_branch, main) is a person's decision, so setting the two equal is refused at config load, at orion init and by orion doctor. The only way round it is the named opt-in vcs.allow_release_branch_merges. See Adopting an existing repo.

Delegation and its cost​

Some delegated reviews are expensive. /security-deep-review commonly takes 15 to 30 agent calls, and the breaker counts every one against the 400-call budget. Two settings in the delegation block handle that:

SettingDefaultEffect
delegation.extra_tool_calls_for_review200widens the tool-call envelope while a delegated review runs
delegation.deep_security_review_whenhigh-riskruns the deep review only when a change touches high-risk paths; always or never otherwise

See nj-agents and other toolkits.

When a limit is wrong​

If a limit is wrong for a repository, change its value in orion.json. Do not work around the trip itself, since that leaves the breaker with no effect.