---
title: "The repair loop"
description: "What mainsdk check --json --agent prints, how a coding agent reads each field, when it must ask a person, and how to use the same output in CI."
section: "agents"
status: "Planned for 0.3"
spec: "fast-start"
canonical: "https://mainsdk.dev/docs/agents/repair-loop"
updated: "2026-10-28"
---

# The repair loop

> What mainsdk check --json --agent prints, how a coding agent reads each field, when it must ask a person, and how to use the same output in CI.

Status: Planned for 0.3 · Canonical: https://mainsdk.dev/docs/agents/repair-loop · Updated: 2026-10-28

A coding agent fixes what the check finds, runs the check again, and stops after three unresolved rounds on the same finding. This page shows the output it reads and what each field means. It takes about five minutes.

`mainsdk check --json --agent` is planned for 0.3 (spec fast-start). MainSDK is pre-release and the command does not run yet.

## You need

- A project with `main.yaml` (`npx mainsdk init`).
- A coding agent that can run a shell command and read JSON.

## 1. Run the check in agent mode

```bash
npx mainsdk check --json --agent
```

The output is the same document as `mainsdk check --json`, with the fix and the file on every finding and a hint for how many rounds to try. Exit codes: 0 passed, 1 a gate failed, 2 a usage or configuration error (with a `MAIN-CONFIG-` code).

```jsonc
{ "version": 1, "project": "prj_01JC8Q…", "env": "prod", "passed": false,
  "gates": [{ "id": "secrets", "passed": false, "findings": [
    { "code": "MAIN-SECRET-0002", "severity": "critical", "file": "app/lib/pay.ts", "line": 3,
      "rule": "secrets.no_literal", "fix": "Move the key to secrets and use secret:STRIPE_KEY" } ] }] }
```

## 2. Read each field

| Field | What the agent does with it |
| --- | --- |
| `passed` | `true` means stop and report. `false` means there is at least one finding. |
| `gates[].id` | The gate that failed (`secrets` above). Fix the failed gates in the order printed. |
| `code` | The finding. Run `npx mainsdk explain <code>` for the full explanation, offline. |
| `severity` | How serious it is. Fix every severity; do not skip low ones. |
| `file` and `line` | Where to change code. Change only what the finding names. |
| `rule` | The rule that fired. Never edit the rule to make the finding go away. |
| `fix` | What to do. Apply it, then re-run. |
| `ask` | `person` means stop. See step 4. |

The max-iterations hint that `--agent` adds (its field name and place in the document) is [TBD]: the spec fixes the behaviour, not the field. Until it is fixed, count rounds yourself: stop at three.

## 3. An example of two rounds

Round 1. The agent runs the check and gets the finding above. It moves the key into `main.yaml` as `secret:STRIPE_KEY` and reads it through the interface, then runs the check again.

Round 2. The secret is gone, but a new finding in a different gate appears:

```jsonc
{ "version": 1, "project": "prj_01JC8Q…", "env": "prod", "passed": false,
  "gates": [{ "id": "data", "passed": false, "findings": [
    { "code": "MAIN-DATA-0007", "severity": "critical", "file": "app/api/orders/route.ts", "line": 12,
      "rule": "[TBD]", "fix": "Query with db.orders.for(user)" } ] }] }
```

The agent changes line 12 to `db.orders.for(session.user).list()` and runs the check a third time:

```jsonc
{ "version": 1, "project": "prj_01JC8Q…", "env": "prod", "passed": true, "gates": [] }
```

Exit code 0. The agent reports what changed in `main.yaml` and the result. (The `gates` list for a passing run is shown empty here; its exact content on a pass is [TBD].)

## 4. When the check says `ask: person`

If the same finding is still unresolved after three runs, the fourth run returns the finding with `ask: person` and no further `fix` text (fast-start.AC4). The agent stops editing. It tells the developer which finding is stuck, what it tried in each round, and what it thinks the blocker is.

```jsonc
{ "code": "MAIN-DATA-0007", "severity": "critical", "file": "app/api/orders/route.ts", "line": 12,
  "ask": "person" }
```

The agent does not try a fourth fix, and it does not reach for an exception or `raw()`. A person decides: change the design, or accept the finding as an exception with an owner and an expiry date.

How the check knows a round is "the same finding" (by code and file, or code, file and line) and where it keeps the count is [TBD].

## 5. Explain a code

```bash
npx mainsdk explain MAIN-DATA-0007
```

`explain` takes a code or a trace id, and `--json` for machine output. It runs offline. Use it when a `fix` is not clear enough; do not use it to find a way around a rule.

## 6. Use it in CI

Run the same command on every pull request. A non-zero exit fails the build.

```bash
npx mainsdk check --json --sarif out.sarif
```

`--sarif <file>` writes SARIF 2.1.0 so code scanning shows each finding inline at its file and line. `--agent` is the stable output for repair loops. `--fail-on <severity>` sets the severity that fails the run; the severity names are [TBD].

## Verify

```bash
npx mainsdk check --json --agent
```

You should see `"passed": true` and exit code 0.

## If it fails

| Code | Cause | Fix |
| --- | --- | --- |
| `MAIN-CONFIG-…` (exit 2) | `main.yaml` or the command is wrong | Read the code's `fix`, then run `npx mainsdk explain <code>` |
| `MAIN-CHECK-0026` | An interface still resolves to a local driver in production | Set a real driver in `main.env.prod.yaml` |
| `ask: person` | Three unresolved rounds | Stop and ask the developer |

## For agents

```text
Goal:    Reach "passed": true without changing any rule.
Loop:    run `npx mainsdk check --json --agent`; for each finding open `file` at `line`,
         apply `fix`, run `npx mainsdk explain <code>` if unclear; run the check again.
Stop:    after three unresolved rounds on one finding, or when a finding has
         `ask: "person"`. Tell the developer the code, file, line and what you tried.
Never:   edit `rule`, lower a severity, add an exception, delete a test or use raw().
```

## Next

- [Build with agents](https://mainsdk.dev/docs/agents)
- [The check](https://mainsdk.dev/docs/concepts/the-check)
- [Prompts that work](https://mainsdk.dev/docs/agents/prompts)
