Cost guards
Everything that stops Mainark spending money it should not. Each one fails closed: a missing or malformed setting refuses, never falls back to "no limit".
| Guard | Setting | What it stops |
|---|---|---|
| Auto-dispatch off | MAINARK_COORDINATE_AUTO_DISPATCH=0 | Nothing starts unless dispatched by hand, by issue id. |
| Opt-in per issue | issues.auto_dispatch | Even with auto-dispatch on, the sweep only starts issues from a plan submitted with "autoDispatch": true, and after the user confirms it in Cursor. The existing backlog is never swept. |
| Inbox limits | docs/setup/plan-inbox.sql | A plan has at most 10 steps. Submitting needs the inbox secret. The inbox holds at most 20 pending plans. An inbox row is imported once, even if the write-back fails. |
| One run at a time | MAINARK_MAX_INFLIGHT=1 | The sweep never starts a second implement run. |
| Daily cap | MAINARK_DAILY_BUDGET_USD | No paid run (implement or fix) starts once today's recorded spend (UTC) reaches the cap. Implement is refused before the claim (issue stays todo); a fix is refused before the agent is created (the loop ends "needs a human"); the sweep stops at once. Unset = no cap; a typo refuses. |
| Review round cap | MAINARK_COORDINATE_AUTO_REVIEW_MAX_ROUNDS | At most N paid fix rounds per PR. The loop always ends on a review-only check, never on an unchecked fix (#86). |
| Fixes only for MUST FIX | MAINARK_CLOUD_FIX_SHOULD_FIX unset | A PASS with only suggestions never starts a paid fix. Missing tests still do. |
| No repeat on the same head | .reviews/pr-N.cloud-fix.json | A fix that pushed nothing, timed out, or could not be verified blocks a second paid fix against the same head. |
| Per-call budget | --max-budget-usd in the review scripts | Caps a single Claude review call. Budget exhaustion is never retried. |
| Undelivered machine run | MAINARK_MACHINE_HEALTH_URL, MAINARK_MACHINE_CLAIM_TIMEOUT_S | A job the self-hosted worker never picks up is cancelled instead of waiting ~15 min. |
| Daily timer parked | mainark-daily.timer.parked on the box | The once-a-day dispatch cannot be enabled by accident. |
What the cap counts
agent_runs.cost_usd for runs that started today (UTC): implement runs and,
since #87, fix runs. Reviews run on the Claude subscription and record $0. A
run still in flight has no cost yet, so the cap can be overshot by at most the
cost of the runs in flight — one run with MAINARK_MAX_INFLIGHT=1.