Skip to Content

Correctness: verify, review, ground

The three stages a run must clear to count as verified: the checks gate, an independent review and grounding.

A run that changes files is not verified until it clears three stages:

  1. Verification gate. verify_commands or per-path [[verify_rules]] ({files} = changed files, {tests} = related unit specs). Checks cover only the changed files, never a build or the whole suite. Failures go back as a repair request (max_repairs, default 2). A note typed during the checks stops them and re-checks the whole diff after.
  2. Independent review (auto_review = true). A read-only reviewer on a different model reads the real diff with search, outline and git. It tests the author's stated root cause against the code and says so when passing checks don't exercise the change. max_reviews (default 2) bounds the loop: review, one fix, review that fix, and whatever the second finds is shown to you instead of looping, because each blind repair round re-sent a 70k context dozens of times.
  3. Grounding.
    • Read before edit: editing a file the agent hasn't read this session is refused, and so is editing one that changed on disk since it was read.
    • Citation check: every path and path:line in the final answer is verified against the tree (guarded mode).
    • Always-on grounded rule: only claim what a tool showed you.

Challenger. Before acting on a risky request (a design choice, a migration, "should we...?"), a read-only agent on a different model argues against the plan. Each objection is [verified] with a real file:line or labelled [guess]; objections with wrong citations are removed, never shown. Always on in the interactive session; --challenge turns it on for one-shot runs.

Advisor. A parameterless tool: the agent calls advisor() and a stronger model reads the whole transcript and returns numbered advice. Fix runs can't make their first edit until the advisor has been consulted, and consult it again before finishing.

Signature guard. When the checks pass but the diff breaks a public signature (a parameter dropped or newly required, positional order changed, an export gone), the agent is sent back once to keep old calls working or say why not. Tests, new files, moved functions and anything the request names are skipped. It exists because of a benchmark miss: unique_by lost its seen= parameter and the run still said verified.

Loop detection catches repeating actions and escalates to a stronger model instead of burning budget.