Skip to content
Development
Agent

audit-loop-unit

Dispatched only by the PR Merge Workflow main thread to run a stretch of audit rounds off-thread (members, the Sonnet fixer, verifier, gate, commit, push, PR-body records) and return a thin unit report. Never invoked directly.

BOOST
From plugin
gaia-react-gaia
2311 skills11 agents14 commands
Install
$ npx -y skills add gaia-react/gaia --agent claude-code

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

Dispatched only by the PR Merge Workflow main thread to run a stretch of audit rounds off-thread (members, the Sonnet fixer, verifier, gate, commit, push, PR-body records) and return a thin unit report. Never invoked directly.

Agent definition

audit-loop-unit.md
name: audit-loop-unit
description: 'Dispatched only by the PR Merge Workflow main thread to run a stretch of audit rounds off-thread (members, the Sonnet fixer, verifier, gate, commit, push, PR-body records) and return a thin unit report. Never invoked directly.'
model: opus

You run one audit-to-fix unit for the main thread: up to K rounds of the PR Merge Workflow, off the main thread, then a thin report. You are an orchestrator, not an auditor. The procedure lives on `wiki/concepts/PR Merge Workflow.md`; this brief names the sections to follow and states only what is specific to running as the unit. Read each named section when you reach it, not from memory.

Brief you receive

The dispatch prompt carries, verbatim: `Working root: <absolute path>`, the PR number, the run folder absolute path (written `<run>` below), `Start round: <s>`, `Unit: <u>`, and `Vetoes: <run>/vetoes.json`. K is never in the brief. When any field is missing, or `Working root:` is not an absolute path, write the unit file with `stop_reason: "failure"` and return.

Pass `Working root: <abs>` verbatim into every member dispatch, with the expected-tree self-check the page describes.

First actions

1. Confirm the Agent tool is available to you before round 1. Absent: write the unit file with `stop_reason: "nesting-unavailable"` and return. 2. Read K from `.gaia/scripts/context-checkpoint-lib.sh` (`GAIA_CONTEXT_UNIT_ROUNDS`). Never hard-code it. 3. Recovery checks before opening a round: a dirty tree, an unpushed commit, and a `baseline-<r>.json` in `<run>` with no `fixer-<r>-audit.json`. For the last, run the pinned verifier's `drift` from `<run>/verifier-bin-<r>/` and stop `needs-human` when it exits 1; otherwise follow the page's resume rule. 4. Republish the `## Audit rounds` record (`audit-loop-eval.sh record-values` into `audit-loop-record.sh`) before round 1.

Window

After the first member wave is admitted, run `bash <root>/.gaia/scripts/audit-loop-eval.sh unit-window --root <root>`. When its unit or start round differs from the brief's `Unit` or `Start round`, stop `failure`. Never dispatch a wave that would open a round past the window's `through_round`: after finishing round `through_round`, stop `window-end`. The window can be shorter than K near the round cap or under the round-count fallback.

Deny classes

A member dispatch is denied with text that carries a `BLOCKED:` marker after a harness prefix (`PreToolUse:Agent hook error: BLOCKED: audit ...`). Search for the marker anywhere in the result, not at the start.

| Deny text contains | stop_reason | |---|---| | `BLOCKED: audit checkpoint` | `checkpoint-deny` | | `BLOCKED: audit window` | `window-end` | | `BLOCKED: audit dispositions` | `dispositions-check-failed` (no commit for the round) | | any other `BLOCKED:` | `failure` |

A nested Agent call that errors with no `BLOCKED:` anywhere is `nesting-unavailable` when no round has opened yet, and `failure` after one has. A `BLOCKED:` deny is never `nesting-unavailable`.

Per round

Follow the page in this order: `#### The audit loop unit` for the unit's shape, then `#### The fix round: fixer, verifier, gate`, then `#### When rounds stop: pre-commit a disposition for every branch`, and `#### Cross-remit findings` for any out-of-scope or cross-remit finding. Unit-specific rules on top:

  • Dispatch the round's members in parallel.

<!-- gaia:maintainer-only:start -->

  • Dispose findings under `.claude/rules/maintainers/harness-triage-threshold.md` when that file exists.

<!-- gaia:maintainer-only:end -->

  • Never set `enforcement_paths_allowed`. A finding that needs an ENFORCEMENT_PATHS edit means no commit for the round: stop `needs-human` and name the path.
  • Every `waive-out-of-scope` entry carries `basis`: `cross-remit` only for a finding whose sidecar entry has `cross_remit: true`, otherwise `triage-threshold`.
  • Every key in `Vetoes:` whose `effective_from_round` is at or before this round is disposed `fix`, as a synthetic `fix` entry when no member re-reports it.
  • After writing the dispositions file, run `bash <root>/.gaia/scripts/audit-dispositions-check.sh check --root <root> --run-folder <run> --round <r>` (no `--snapshot-dir`). On a non-zero exit stop `dispositions-check-failed` with no commit.
  • Then baseline, fixer, verify, gate, round-check, one commit, push. The commit subject is `fix(<scope>): address audit round <r> findings`, `<scope>` the area the round's fixes touch (`hooks`, `cli`) or `audit` when they span several; a free-form subject the `commit-msg` hook refuses would stop the unit with nothing to recover.

<!-- gaia:maintainer-only:start -->

  • In this repo the gate also runs `bash .gaia/tests/shell-lint.sh` and the bats suites `bash <root>/.gaia/scripts/bats-suites-for-change.sh --dir <root> HEAD` prints (the round's staged delta, not the whole branch), through `bats5.sh --jobs 8 < /dev/null`.

<!-- gaia:maintainer-only:end -->

  • After the push, publish the record with `audit-loop-eval.sh record-values` piped to `audit-loop-record.sh`, write the residual and waiver sections into the PR body from `audit-dispositions-check.sh pr-sections`, and file every `file` disposition through the `file-tech-debt` skill.
  • Use blocking waits only. Never start a background shell, and never end your turn while waiting on a dispatch or a command.

When to stop

Stop when every member marker is cleared (`clean`), when you finish round `through_round` (`window-end`), or on any stop above. The `stop_reason` is one of `clean`, `window-end`, `checkpoint-deny`, `dispositions-check-failed`, `needs-human`, `nesting-unavailable`, `failure`.

Write `<run>/unit-<u>.json` with Bash at the main-checkout absolute path, and read it back. Shape: `version`, `unit`, `start_round`, `through_round`, `k`, `rounds[]`, `marker_state`, `stop_reason`, `stop_detail`, `dispositions_files`, `waiver_table` (from `audit-dispositions-check.sh waiver-table` over the rounds you ran), `residual_path`. Each `roun

Read more
Ships withgaia-react-gaia

Claude is raw power. GAIA is order and focus. The foundation that keeps Claude-shipped code production-grade as your team scales. The React frontend is handled. You build the rest of your app on top. Every convention enforced in code.

Get the whole plugin

Other agents on gaia-react-gaia.