Skip to content

Repository files navigation

gauntlet

Run your codebase through the gauntlet: ~50 specialized review prompts, dispatched to whichever AI coding agents you have installed, applying fixes directly to the working tree.

CIlatest releaselicenseplatformsgo

The gauntlet dashboard: an activity chart, one lane per agent with live token rates, the review grid, and a normalized feed

One static binary loops ~50 review prompts over your repository, hands each one to an agent CLI you already have installed, and applies what it finds.

  • Isolation when it runs in parallel.--jobs N gives every review its own git worktree on its own branch, merged back one at a time. Concurrent agents never share a working tree.
  • Unmerged review stacks.--stacked-prs runs reviews in one isolated worktree and opens each changed review as a child PR of the previous one. The branch in your editor is never changed.
  • Many repositories at once.--dirs a,b,c reviews several trees, each with its own lock, baseline, and lane. --jobs applies within each.
  • A dashboard.--tui puts lanes, throughput, the review grid, and a normalized feed on one screen.
  • Readable output. Spinner frames, escape sequences, repainted progress lines, tool gutters, and duplicate narration are collapsed rather than echoed, per agent.
  • Measured, never guessed. Token counts come from what the agent prints, its session transcript, and its machine-readable mode; an agent that reports nothing shows no rate.
  • A record. Every run is JSONL under ~/.gauntlet, replayable with gauntlet show.
  • Self-updating, hot-reloading. A running loop takes a new binary between reviews without losing its counters.

Quick start

Check which installed agents gauntlet can use, then compose a run:

gauntlet doctor
gauntlet pick

Run one isolated, unmerged PR stack from main:

gauntlet -r quick --stacked-prs --pr-base main

Everything below is detail: installation, execution modes, and references.

Install

Install the latest release binary:

mkdir -p ~/.local/bin
ver=$(curl -fsSL https://api.github.com/repos/maci0/gauntlet/releases/latest | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
curl -fsSL "https://github.com/maci0/gauntlet/releases/latest/download/gauntlet_${ver}_$(uname -s | tr A-Z a-z)_$(uname -m | sed -e s/x86_64/amd64/ -e s/aarch64/arm64/)" -o ~/.local/bin/gauntlet
chmod +x ~/.local/bin/gauntlet

Or build and install from source:

make install

Check or update the installation:

gauntlet doctor
gauntlet update

Upgrading from the Python version: the flags are the same, --target-dirs is still accepted, and pip/uv are no longer involved. Uninstall the old one with uv tool uninstall gauntlet-review (or pipx uninstall gauntlet-review).

Linux and macOS. The runner leans on POSIX semantics that Windows has no equivalent for: process groups to kill an agent's whole tree on timeout, flock for the directory lock, O_NOFOLLOW for prompt reads, and execve for hot reload.

Supported agents: claude, codex, gemini, qwen, grok, agy, cursor-agent, kimi, opencode, crush, clanker, dsh, plus the pi family (pi, prime-agent, feynman, omp), which ships as editable definitions rather than code. At least one must be on PATH.

Any other agent can be added without a new binary: --agent-cmd for one run, ~/.gauntlet/agents.json to keep it. gauntlet doctor lists every agent it knows, defined ones included. See docs/CLI.md.

The reviews

Every review is one prompt file. Run all of them, a named set (-r quick, -r security, -r backend, -r frontend, -r shipping, -r agents), or any list you like. gauntlet --list prints this table with what is scheduled.

ReviewFinds
a11y-reviewkeyboard, screen readers, contrast, motion, WCAG 2.2 AA
agentrules-reviewthe CLAUDE.md and AGENTS.md files every session pays for
api-reviewREST, GraphQL, and gRPC surfaces: consistency, correctness
arch-reviewmodule boundaries, dependency direction, layering
authz-reviewIDOR, unprotected admin routes, cross-tenant leakage
build-reviewreproducible, hermetic builds and a pinned toolchain
cache-reviewstale reads, cross-tenant bleed, stampedes, growth
cli-reviewexit codes, stdout vs stderr, piping, --help
code-reviewmaintainability, correctness, consistency, simplicity
compat-reviewpath separators, bashisms, endianness, musl vs glibc
concurrency-reviewraces, deadlocks, and corruption under load
config-reviewprecedence, validation, secrets in the wrong place
container-reviewprobes, graceful shutdown, image hygiene on Kubernetes
db-reviewschema, queries, migrations, data integrity
deps-reviewnecessity, supply-chain risk, maintenance burden
design-reviewtradeoffs, alternatives, data modeling, fit to scale
doc-reviewdocs and comments that disagree with the code
dr-reviewwhat is backed up, and has restore ever been proven
dst-reviewcan a single seed replay the whole run byte-for-byte
dx-reviewclone to passing tests without losing an afternoon
error-reviewsilent data loss, misleading behavior, cascading failure
functionality-reviewthe gap between intended and actual behavior
fuzz-reviewuntrusted-input surfaces with no fuzz harness
i18n-reviewtranslations, locale formatting, layout in other scripts
idempotency-reviewwhat happens when the operation runs twice
infra-reviewCI/CD, IaC, deployment, environment wiring
lint-reviewlinters present, strict enough, and blocking CI
llm-reviewprompt injection, cost, and unvalidated model output
minimalism-reviewprove every line is needed, or delete it
mobile-reviewlifecycle, offline, battery, permissions, store readiness
numerics-reviewmoney in floats, truncating casts, negative modulo
o11y-reviewlogs, metrics, traces, alerts, and whether they connect
perf-reviewalgorithms, memory, I/O, startup: measured, not guessed
pkg-reviewdeb, rpm, Flatpak, wheels, images: what actually ships
privacy-reviewpersonal data collected, shared, retained, deleted
prompt-reviewwhether these prompts work as instructions to an agent
release-reviewsemver honesty, breaking changes, changelog, migration
resource-reviewhandles, goroutines, listeners, maps that only grow
sdk-reviewthe integrating developer's experience of the surface
sec-reviewexploitable vulnerabilities and missing controls
skills-reviewdoes the skill fire, teach, and stay cheap when loaded
slop-reviewmachine-written noise: dead code, restating comments
specs-reviewrequirements and decision records the code contradicts
test-reviewtests that give false confidence or miss real bugs
threat-reviewattack surface, trust boundaries, a living threat model
time-reviewDST, leap days, wall-clock durations, cron that misfires
uislop-reviewthe interchangeable generated look, no visual identity
unicode-reviewencodings, NFC/NFD, length in the wrong units
ux-reviewfriction and confusion from the user's side
webperf-reviewbytes on the wire, blocking the first paint

How a run works

Reviews run one at a time against your working tree, forever, until you stop them. --jobs N buys parallelism with isolation instead: every review gets its own git worktree on its own branch, and the runner (never the agent) commits each one and merges them back one at a time.

Stack mode is sequential for a different reason: every review must see the commits below it. From base main, changed reviews produce review-1 → main, then review-2 → review-1, and so on. The PRs stay open; gauntlet removes only the scratch checkout. It fetches the remote base without moving your local branch. If the original checkout has uncommitted files, gauntlet names them and asks before leaving them out of the review. See stacked pull requests for the branch lifecycle and recovery rules.

flowchart LR
T[your branch<br/>clean tree] --> S[scheduler]
S --> W1[worktree<br/>sec-review]
S --> W2[worktree<br/>perf-review]
S --> W3[worktree<br/>doc-review]
W1 --> C1[runner commits]
W2 --> C2[runner commits]
W3 --> C3[runner commits]
C1 --> M[merge --squash<br/>one at a time]
C2 --> M
C3 --> M
M --> T2[your branch]
M -. conflict .-> R[agent resolves<br/>in a scratch checkout]
R -. merged .-> T2
R -. unresolved .-> K[branch kept<br/>run exits nonzero]
Loading

--jobs counts per directory, so --dirs a,b,c -j 4 is up to 12 agents at once. A branch that will not merge is handed to an agent, which resolves it in a scratch checkout; what it cannot resolve stays on its branch for you (--resolve-conflicts=false skips the attempt). Everything lands on the branch you are already on; --merge-into BRANCH is what carries a loop's committed work anywhere else. The details, plus the run journal and hot reload, are in docs/RUNS.md.

Dashboard

--tui renders the screen at the top of this page: header, activity chart, one lane per agent, the full review grid, and the feed. gauntlet pick composes a run before it starts, and shows the command it is building while you do:

The gauntlet launcher: review sets with descriptions, the installed agents, concurrency against the CPU count, and the composed command line

KeyAction
q, escquit (stops the run, killing what is running)
sfinish: no new reviews, then commit, publish or merge as configured, and exit
spacepause the feed; output keeps collecting and reviews keep running
j / kscroll the feed
fnarrow the feed to results, errors, and diffs, and back
g / Gjump to oldest / newest
?help, and the list of unmerged branches

Review glyphs: · pending, running, ok, fail, timeout, merge conflict, skipped, interrupted.

Trust model

Agents run with their permission prompts disabled. That is the point of the tool, and it is why the containment rules exist: prompts are read with O_NOFOLLOW and size-capped, agent binaries resolve on a PATH without cwd-relative entries, git runs with core.fsmonitor, core.hooksPath, diff.external, and the pager forced empty, untrusted text is stripped of control and bidi characters before display, and a flock on .gauntlet.lock keeps two runs out of one directory.

Reviewing a repository you do not trust still means running it in a container. The boundaries are drawn one by one in docs/THREAT_MODEL.md.

Token counts

Counts come from what the agent prints, its machine-readable mode (--stream), its own session transcript, and, for the two agents that keep databases instead (crush, opencode), those. All of it is on in a default build; make build TAGS=notoktop drops transcript reading and make build TAGS= drops the database driver too. gauntlet doctor says which build you have. Per-agent coverage, and the public reading API, are in docs/TOKEN_TELEMETRY.md.

Documentation

PageWhat is in it
docs/CLI.mdevery flag, environment variable, and exit code; defining your own agent
docs/RUNS.mdworktree isolation and merging, the run journal, updating and hot reload
docs/DESIGN.mdarchitecture, concurrency model, and what each decision costs
docs/TOKEN_TELEMETRY.mdwhere token counts come from, per agent, and the public reading API
docs/THREAT_MODEL.mdtrust boundaries, what is validated where, and what is out of scope
docs/IDEAS.mdthings deliberately not built yet, and why
CONTRIBUTING.mdbuilding, testing, and the checks a pull request runs

License

AGPL-3.0-or-later.

About

Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - maci0/gauntlet: Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed. · GitHub
Skip to content

Repository files navigation

gauntlet

Run your codebase through the gauntlet: ~50 specialized review prompts, dispatched to whichever AI coding agents you have installed, applying fixes directly to the working tree.

CIlatest releaselicenseplatformsgo

The gauntlet dashboard: an activity chart, one lane per agent with live token rates, the review grid, and a normalized feed

One static binary loops ~50 review prompts over your repository, hands each one to an agent CLI you already have installed, and applies what it finds.

  • Isolation when it runs in parallel.--jobs N gives every review its own git worktree on its own branch, merged back one at a time. Concurrent agents never share a working tree.
  • Unmerged review stacks.--stacked-prs runs reviews in one isolated worktree and opens each changed review as a child PR of the previous one. The branch in your editor is never changed.
  • Many repositories at once.--dirs a,b,c reviews several trees, each with its own lock, baseline, and lane. --jobs applies within each.
  • A dashboard.--tui puts lanes, throughput, the review grid, and a normalized feed on one screen.
  • Readable output. Spinner frames, escape sequences, repainted progress lines, tool gutters, and duplicate narration are collapsed rather than echoed, per agent.
  • Measured, never guessed. Token counts come from what the agent prints, its session transcript, and its machine-readable mode; an agent that reports nothing shows no rate.
  • A record. Every run is JSONL under ~/.gauntlet, replayable with gauntlet show.
  • Self-updating, hot-reloading. A running loop takes a new binary between reviews without losing its counters.

Quick start

Check which installed agents gauntlet can use, then compose a run:

gauntlet doctor
gauntlet pick

Run one isolated, unmerged PR stack from main:

gauntlet -r quick --stacked-prs --pr-base main

Everything below is detail: installation, execution modes, and references.

Install

Install the latest release binary:

mkdir -p ~/.local/bin
ver=$(curl -fsSL https://api.github.com/repos/maci0/gauntlet/releases/latest | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
curl -fsSL "https://github.com/maci0/gauntlet/releases/latest/download/gauntlet_${ver}_$(uname -s | tr A-Z a-z)_$(uname -m | sed -e s/x86_64/amd64/ -e s/aarch64/arm64/)" -o ~/.local/bin/gauntlet
chmod +x ~/.local/bin/gauntlet

Or build and install from source:

make install

Check or update the installation:

gauntlet doctor
gauntlet update

Upgrading from the Python version: the flags are the same, --target-dirs is still accepted, and pip/uv are no longer involved. Uninstall the old one with uv tool uninstall gauntlet-review (or pipx uninstall gauntlet-review).

Linux and macOS. The runner leans on POSIX semantics that Windows has no equivalent for: process groups to kill an agent's whole tree on timeout, flock for the directory lock, O_NOFOLLOW for prompt reads, and execve for hot reload.

Supported agents: claude, codex, gemini, qwen, grok, agy, cursor-agent, kimi, opencode, crush, clanker, dsh, plus the pi family (pi, prime-agent, feynman, omp), which ships as editable definitions rather than code. At least one must be on PATH.

Any other agent can be added without a new binary: --agent-cmd for one run, ~/.gauntlet/agents.json to keep it. gauntlet doctor lists every agent it knows, defined ones included. See docs/CLI.md.

The reviews

Every review is one prompt file. Run all of them, a named set (-r quick, -r security, -r backend, -r frontend, -r shipping, -r agents), or any list you like. gauntlet --list prints this table with what is scheduled.

ReviewFinds
a11y-reviewkeyboard, screen readers, contrast, motion, WCAG 2.2 AA
agentrules-reviewthe CLAUDE.md and AGENTS.md files every session pays for
api-reviewREST, GraphQL, and gRPC surfaces: consistency, correctness
arch-reviewmodule boundaries, dependency direction, layering
authz-reviewIDOR, unprotected admin routes, cross-tenant leakage
build-reviewreproducible, hermetic builds and a pinned toolchain
cache-reviewstale reads, cross-tenant bleed, stampedes, growth
cli-reviewexit codes, stdout vs stderr, piping, --help
code-reviewmaintainability, correctness, consistency, simplicity
compat-reviewpath separators, bashisms, endianness, musl vs glibc
concurrency-reviewraces, deadlocks, and corruption under load
config-reviewprecedence, validation, secrets in the wrong place
container-reviewprobes, graceful shutdown, image hygiene on Kubernetes
db-reviewschema, queries, migrations, data integrity
deps-reviewnecessity, supply-chain risk, maintenance burden
design-reviewtradeoffs, alternatives, data modeling, fit to scale
doc-reviewdocs and comments that disagree with the code
dr-reviewwhat is backed up, and has restore ever been proven
dst-reviewcan a single seed replay the whole run byte-for-byte
dx-reviewclone to passing tests without losing an afternoon
error-reviewsilent data loss, misleading behavior, cascading failure
functionality-reviewthe gap between intended and actual behavior
fuzz-reviewuntrusted-input surfaces with no fuzz harness
i18n-reviewtranslations, locale formatting, layout in other scripts
idempotency-reviewwhat happens when the operation runs twice
infra-reviewCI/CD, IaC, deployment, environment wiring
lint-reviewlinters present, strict enough, and blocking CI
llm-reviewprompt injection, cost, and unvalidated model output
minimalism-reviewprove every line is needed, or delete it
mobile-reviewlifecycle, offline, battery, permissions, store readiness
numerics-reviewmoney in floats, truncating casts, negative modulo
o11y-reviewlogs, metrics, traces, alerts, and whether they connect
perf-reviewalgorithms, memory, I/O, startup: measured, not guessed
pkg-reviewdeb, rpm, Flatpak, wheels, images: what actually ships
privacy-reviewpersonal data collected, shared, retained, deleted
prompt-reviewwhether these prompts work as instructions to an agent
release-reviewsemver honesty, breaking changes, changelog, migration
resource-reviewhandles, goroutines, listeners, maps that only grow
sdk-reviewthe integrating developer's experience of the surface
sec-reviewexploitable vulnerabilities and missing controls
skills-reviewdoes the skill fire, teach, and stay cheap when loaded
slop-reviewmachine-written noise: dead code, restating comments
specs-reviewrequirements and decision records the code contradicts
test-reviewtests that give false confidence or miss real bugs
threat-reviewattack surface, trust boundaries, a living threat model
time-reviewDST, leap days, wall-clock durations, cron that misfires
uislop-reviewthe interchangeable generated look, no visual identity
unicode-reviewencodings, NFC/NFD, length in the wrong units
ux-reviewfriction and confusion from the user's side
webperf-reviewbytes on the wire, blocking the first paint

How a run works

Reviews run one at a time against your working tree, forever, until you stop them. --jobs N buys parallelism with isolation instead: every review gets its own git worktree on its own branch, and the runner (never the agent) commits each one and merges them back one at a time.

Stack mode is sequential for a different reason: every review must see the commits below it. From base main, changed reviews produce review-1 → main, then review-2 → review-1, and so on. The PRs stay open; gauntlet removes only the scratch checkout. It fetches the remote base without moving your local branch. If the original checkout has uncommitted files, gauntlet names them and asks before leaving them out of the review. See stacked pull requests for the branch lifecycle and recovery rules.

flowchart LR
T[your branch<br/>clean tree] --> S[scheduler]
S --> W1[worktree<br/>sec-review]
S --> W2[worktree<br/>perf-review]
S --> W3[worktree<br/>doc-review]
W1 --> C1[runner commits]
W2 --> C2[runner commits]
W3 --> C3[runner commits]
C1 --> M[merge --squash<br/>one at a time]
C2 --> M
C3 --> M
M --> T2[your branch]
M -. conflict .-> R[agent resolves<br/>in a scratch checkout]
R -. merged .-> T2
R -. unresolved .-> K[branch kept<br/>run exits nonzero]
Loading

--jobs counts per directory, so --dirs a,b,c -j 4 is up to 12 agents at once. A branch that will not merge is handed to an agent, which resolves it in a scratch checkout; what it cannot resolve stays on its branch for you (--resolve-conflicts=false skips the attempt). Everything lands on the branch you are already on; --merge-into BRANCH is what carries a loop's committed work anywhere else. The details, plus the run journal and hot reload, are in docs/RUNS.md.

Dashboard

--tui renders the screen at the top of this page: header, activity chart, one lane per agent, the full review grid, and the feed. gauntlet pick composes a run before it starts, and shows the command it is building while you do:

The gauntlet launcher: review sets with descriptions, the installed agents, concurrency against the CPU count, and the composed command line

KeyAction
q, escquit (stops the run, killing what is running)
sfinish: no new reviews, then commit, publish or merge as configured, and exit
spacepause the feed; output keeps collecting and reviews keep running
j / kscroll the feed
fnarrow the feed to results, errors, and diffs, and back
g / Gjump to oldest / newest
?help, and the list of unmerged branches

Review glyphs: · pending, running, ok, fail, timeout, merge conflict, skipped, interrupted.

Trust model

Agents run with their permission prompts disabled. That is the point of the tool, and it is why the containment rules exist: prompts are read with O_NOFOLLOW and size-capped, agent binaries resolve on a PATH without cwd-relative entries, git runs with core.fsmonitor, core.hooksPath, diff.external, and the pager forced empty, untrusted text is stripped of control and bidi characters before display, and a flock on .gauntlet.lock keeps two runs out of one directory.

Reviewing a repository you do not trust still means running it in a container. The boundaries are drawn one by one in docs/THREAT_MODEL.md.

Token counts

Counts come from what the agent prints, its machine-readable mode (--stream), its own session transcript, and, for the two agents that keep databases instead (crush, opencode), those. All of it is on in a default build; make build TAGS=notoktop drops transcript reading and make build TAGS= drops the database driver too. gauntlet doctor says which build you have. Per-agent coverage, and the public reading API, are in docs/TOKEN_TELEMETRY.md.

Documentation

PageWhat is in it
docs/CLI.mdevery flag, environment variable, and exit code; defining your own agent
docs/RUNS.mdworktree isolation and merging, the run journal, updating and hot reload
docs/DESIGN.mdarchitecture, concurrency model, and what each decision costs
docs/TOKEN_TELEMETRY.mdwhere token counts come from, per agent, and the public reading API
docs/THREAT_MODEL.mdtrust boundaries, what is validated where, and what is out of scope
docs/IDEAS.mdthings deliberately not built yet, and why
CONTRIBUTING.mdbuilding, testing, and the checks a pull request runs

License

AGPL-3.0-or-later.

About

Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - maci0/gauntlet: Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed. · GitHub
Skip to content

Repository files navigation

gauntlet

Run your codebase through the gauntlet: ~50 specialized review prompts, dispatched to whichever AI coding agents you have installed, applying fixes directly to the working tree.

CIlatest releaselicenseplatformsgo

The gauntlet dashboard: an activity chart, one lane per agent with live token rates, the review grid, and a normalized feed

One static binary loops ~50 review prompts over your repository, hands each one to an agent CLI you already have installed, and applies what it finds.

  • Isolation when it runs in parallel.--jobs N gives every review its own git worktree on its own branch, merged back one at a time. Concurrent agents never share a working tree.
  • Unmerged review stacks.--stacked-prs runs reviews in one isolated worktree and opens each changed review as a child PR of the previous one. The branch in your editor is never changed.
  • Many repositories at once.--dirs a,b,c reviews several trees, each with its own lock, baseline, and lane. --jobs applies within each.
  • A dashboard.--tui puts lanes, throughput, the review grid, and a normalized feed on one screen.
  • Readable output. Spinner frames, escape sequences, repainted progress lines, tool gutters, and duplicate narration are collapsed rather than echoed, per agent.
  • Measured, never guessed. Token counts come from what the agent prints, its session transcript, and its machine-readable mode; an agent that reports nothing shows no rate.
  • A record. Every run is JSONL under ~/.gauntlet, replayable with gauntlet show.
  • Self-updating, hot-reloading. A running loop takes a new binary between reviews without losing its counters.

Quick start

Check which installed agents gauntlet can use, then compose a run:

gauntlet doctor
gauntlet pick

Run one isolated, unmerged PR stack from main:

gauntlet -r quick --stacked-prs --pr-base main

Everything below is detail: installation, execution modes, and references.

Install

Install the latest release binary:

mkdir -p ~/.local/bin
ver=$(curl -fsSL https://api.github.com/repos/maci0/gauntlet/releases/latest | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
curl -fsSL "https://github.com/maci0/gauntlet/releases/latest/download/gauntlet_${ver}_$(uname -s | tr A-Z a-z)_$(uname -m | sed -e s/x86_64/amd64/ -e s/aarch64/arm64/)" -o ~/.local/bin/gauntlet
chmod +x ~/.local/bin/gauntlet

Or build and install from source:

make install

Check or update the installation:

gauntlet doctor
gauntlet update

Upgrading from the Python version: the flags are the same, --target-dirs is still accepted, and pip/uv are no longer involved. Uninstall the old one with uv tool uninstall gauntlet-review (or pipx uninstall gauntlet-review).

Linux and macOS. The runner leans on POSIX semantics that Windows has no equivalent for: process groups to kill an agent's whole tree on timeout, flock for the directory lock, O_NOFOLLOW for prompt reads, and execve for hot reload.

Supported agents: claude, codex, gemini, qwen, grok, agy, cursor-agent, kimi, opencode, crush, clanker, dsh, plus the pi family (pi, prime-agent, feynman, omp), which ships as editable definitions rather than code. At least one must be on PATH.

Any other agent can be added without a new binary: --agent-cmd for one run, ~/.gauntlet/agents.json to keep it. gauntlet doctor lists every agent it knows, defined ones included. See docs/CLI.md.

The reviews

Every review is one prompt file. Run all of them, a named set (-r quick, -r security, -r backend, -r frontend, -r shipping, -r agents), or any list you like. gauntlet --list prints this table with what is scheduled.

ReviewFinds
a11y-reviewkeyboard, screen readers, contrast, motion, WCAG 2.2 AA
agentrules-reviewthe CLAUDE.md and AGENTS.md files every session pays for
api-reviewREST, GraphQL, and gRPC surfaces: consistency, correctness
arch-reviewmodule boundaries, dependency direction, layering
authz-reviewIDOR, unprotected admin routes, cross-tenant leakage
build-reviewreproducible, hermetic builds and a pinned toolchain
cache-reviewstale reads, cross-tenant bleed, stampedes, growth
cli-reviewexit codes, stdout vs stderr, piping, --help
code-reviewmaintainability, correctness, consistency, simplicity
compat-reviewpath separators, bashisms, endianness, musl vs glibc
concurrency-reviewraces, deadlocks, and corruption under load
config-reviewprecedence, validation, secrets in the wrong place
container-reviewprobes, graceful shutdown, image hygiene on Kubernetes
db-reviewschema, queries, migrations, data integrity
deps-reviewnecessity, supply-chain risk, maintenance burden
design-reviewtradeoffs, alternatives, data modeling, fit to scale
doc-reviewdocs and comments that disagree with the code
dr-reviewwhat is backed up, and has restore ever been proven
dst-reviewcan a single seed replay the whole run byte-for-byte
dx-reviewclone to passing tests without losing an afternoon
error-reviewsilent data loss, misleading behavior, cascading failure
functionality-reviewthe gap between intended and actual behavior
fuzz-reviewuntrusted-input surfaces with no fuzz harness
i18n-reviewtranslations, locale formatting, layout in other scripts
idempotency-reviewwhat happens when the operation runs twice
infra-reviewCI/CD, IaC, deployment, environment wiring
lint-reviewlinters present, strict enough, and blocking CI
llm-reviewprompt injection, cost, and unvalidated model output
minimalism-reviewprove every line is needed, or delete it
mobile-reviewlifecycle, offline, battery, permissions, store readiness
numerics-reviewmoney in floats, truncating casts, negative modulo
o11y-reviewlogs, metrics, traces, alerts, and whether they connect
perf-reviewalgorithms, memory, I/O, startup: measured, not guessed
pkg-reviewdeb, rpm, Flatpak, wheels, images: what actually ships
privacy-reviewpersonal data collected, shared, retained, deleted
prompt-reviewwhether these prompts work as instructions to an agent
release-reviewsemver honesty, breaking changes, changelog, migration
resource-reviewhandles, goroutines, listeners, maps that only grow
sdk-reviewthe integrating developer's experience of the surface
sec-reviewexploitable vulnerabilities and missing controls
skills-reviewdoes the skill fire, teach, and stay cheap when loaded
slop-reviewmachine-written noise: dead code, restating comments
specs-reviewrequirements and decision records the code contradicts
test-reviewtests that give false confidence or miss real bugs
threat-reviewattack surface, trust boundaries, a living threat model
time-reviewDST, leap days, wall-clock durations, cron that misfires
uislop-reviewthe interchangeable generated look, no visual identity
unicode-reviewencodings, NFC/NFD, length in the wrong units
ux-reviewfriction and confusion from the user's side
webperf-reviewbytes on the wire, blocking the first paint

How a run works

Reviews run one at a time against your working tree, forever, until you stop them. --jobs N buys parallelism with isolation instead: every review gets its own git worktree on its own branch, and the runner (never the agent) commits each one and merges them back one at a time.

Stack mode is sequential for a different reason: every review must see the commits below it. From base main, changed reviews produce review-1 → main, then review-2 → review-1, and so on. The PRs stay open; gauntlet removes only the scratch checkout. It fetches the remote base without moving your local branch. If the original checkout has uncommitted files, gauntlet names them and asks before leaving them out of the review. See stacked pull requests for the branch lifecycle and recovery rules.

flowchart LR
T[your branch<br/>clean tree] --> S[scheduler]
S --> W1[worktree<br/>sec-review]
S --> W2[worktree<br/>perf-review]
S --> W3[worktree<br/>doc-review]
W1 --> C1[runner commits]
W2 --> C2[runner commits]
W3 --> C3[runner commits]
C1 --> M[merge --squash<br/>one at a time]
C2 --> M
C3 --> M
M --> T2[your branch]
M -. conflict .-> R[agent resolves<br/>in a scratch checkout]
R -. merged .-> T2
R -. unresolved .-> K[branch kept<br/>run exits nonzero]
Loading

--jobs counts per directory, so --dirs a,b,c -j 4 is up to 12 agents at once. A branch that will not merge is handed to an agent, which resolves it in a scratch checkout; what it cannot resolve stays on its branch for you (--resolve-conflicts=false skips the attempt). Everything lands on the branch you are already on; --merge-into BRANCH is what carries a loop's committed work anywhere else. The details, plus the run journal and hot reload, are in docs/RUNS.md.

Dashboard

--tui renders the screen at the top of this page: header, activity chart, one lane per agent, the full review grid, and the feed. gauntlet pick composes a run before it starts, and shows the command it is building while you do:

The gauntlet launcher: review sets with descriptions, the installed agents, concurrency against the CPU count, and the composed command line

KeyAction
q, escquit (stops the run, killing what is running)
sfinish: no new reviews, then commit, publish or merge as configured, and exit
spacepause the feed; output keeps collecting and reviews keep running
j / kscroll the feed
fnarrow the feed to results, errors, and diffs, and back
g / Gjump to oldest / newest
?help, and the list of unmerged branches

Review glyphs: · pending, running, ok, fail, timeout, merge conflict, skipped, interrupted.

Trust model

Agents run with their permission prompts disabled. That is the point of the tool, and it is why the containment rules exist: prompts are read with O_NOFOLLOW and size-capped, agent binaries resolve on a PATH without cwd-relative entries, git runs with core.fsmonitor, core.hooksPath, diff.external, and the pager forced empty, untrusted text is stripped of control and bidi characters before display, and a flock on .gauntlet.lock keeps two runs out of one directory.

Reviewing a repository you do not trust still means running it in a container. The boundaries are drawn one by one in docs/THREAT_MODEL.md.

Token counts

Counts come from what the agent prints, its machine-readable mode (--stream), its own session transcript, and, for the two agents that keep databases instead (crush, opencode), those. All of it is on in a default build; make build TAGS=notoktop drops transcript reading and make build TAGS= drops the database driver too. gauntlet doctor says which build you have. Per-agent coverage, and the public reading API, are in docs/TOKEN_TELEMETRY.md.

Documentation

PageWhat is in it
docs/CLI.mdevery flag, environment variable, and exit code; defining your own agent
docs/RUNS.mdworktree isolation and merging, the run journal, updating and hot reload
docs/DESIGN.mdarchitecture, concurrency model, and what each decision costs
docs/TOKEN_TELEMETRY.mdwhere token counts come from, per agent, and the public reading API
docs/THREAT_MODEL.mdtrust boundaries, what is validated where, and what is out of scope
docs/IDEAS.mdthings deliberately not built yet, and why
CONTRIBUTING.mdbuilding, testing, and the checks a pull request runs

License

AGPL-3.0-or-later.

About

Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - maci0/gauntlet: Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed. · GitHub
Skip to content

Repository files navigation

gauntlet

Run your codebase through the gauntlet: ~50 specialized review prompts, dispatched to whichever AI coding agents you have installed, applying fixes directly to the working tree.

CIlatest releaselicenseplatformsgo

The gauntlet dashboard: an activity chart, one lane per agent with live token rates, the review grid, and a normalized feed

One static binary loops ~50 review prompts over your repository, hands each one to an agent CLI you already have installed, and applies what it finds.

  • Isolation when it runs in parallel.--jobs N gives every review its own git worktree on its own branch, merged back one at a time. Concurrent agents never share a working tree.
  • Unmerged review stacks.--stacked-prs runs reviews in one isolated worktree and opens each changed review as a child PR of the previous one. The branch in your editor is never changed.
  • Many repositories at once.--dirs a,b,c reviews several trees, each with its own lock, baseline, and lane. --jobs applies within each.
  • A dashboard.--tui puts lanes, throughput, the review grid, and a normalized feed on one screen.
  • Readable output. Spinner frames, escape sequences, repainted progress lines, tool gutters, and duplicate narration are collapsed rather than echoed, per agent.
  • Measured, never guessed. Token counts come from what the agent prints, its session transcript, and its machine-readable mode; an agent that reports nothing shows no rate.
  • A record. Every run is JSONL under ~/.gauntlet, replayable with gauntlet show.
  • Self-updating, hot-reloading. A running loop takes a new binary between reviews without losing its counters.

Quick start

Check which installed agents gauntlet can use, then compose a run:

gauntlet doctor
gauntlet pick

Run one isolated, unmerged PR stack from main:

gauntlet -r quick --stacked-prs --pr-base main

Everything below is detail: installation, execution modes, and references.

Install

Install the latest release binary:

mkdir -p ~/.local/bin
ver=$(curl -fsSL https://api.github.com/repos/maci0/gauntlet/releases/latest | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
curl -fsSL "https://github.com/maci0/gauntlet/releases/latest/download/gauntlet_${ver}_$(uname -s | tr A-Z a-z)_$(uname -m | sed -e s/x86_64/amd64/ -e s/aarch64/arm64/)" -o ~/.local/bin/gauntlet
chmod +x ~/.local/bin/gauntlet

Or build and install from source:

make install

Check or update the installation:

gauntlet doctor
gauntlet update

Upgrading from the Python version: the flags are the same, --target-dirs is still accepted, and pip/uv are no longer involved. Uninstall the old one with uv tool uninstall gauntlet-review (or pipx uninstall gauntlet-review).

Linux and macOS. The runner leans on POSIX semantics that Windows has no equivalent for: process groups to kill an agent's whole tree on timeout, flock for the directory lock, O_NOFOLLOW for prompt reads, and execve for hot reload.

Supported agents: claude, codex, gemini, qwen, grok, agy, cursor-agent, kimi, opencode, crush, clanker, dsh, plus the pi family (pi, prime-agent, feynman, omp), which ships as editable definitions rather than code. At least one must be on PATH.

Any other agent can be added without a new binary: --agent-cmd for one run, ~/.gauntlet/agents.json to keep it. gauntlet doctor lists every agent it knows, defined ones included. See docs/CLI.md.

The reviews

Every review is one prompt file. Run all of them, a named set (-r quick, -r security, -r backend, -r frontend, -r shipping, -r agents), or any list you like. gauntlet --list prints this table with what is scheduled.

ReviewFinds
a11y-reviewkeyboard, screen readers, contrast, motion, WCAG 2.2 AA
agentrules-reviewthe CLAUDE.md and AGENTS.md files every session pays for
api-reviewREST, GraphQL, and gRPC surfaces: consistency, correctness
arch-reviewmodule boundaries, dependency direction, layering
authz-reviewIDOR, unprotected admin routes, cross-tenant leakage
build-reviewreproducible, hermetic builds and a pinned toolchain
cache-reviewstale reads, cross-tenant bleed, stampedes, growth
cli-reviewexit codes, stdout vs stderr, piping, --help
code-reviewmaintainability, correctness, consistency, simplicity
compat-reviewpath separators, bashisms, endianness, musl vs glibc
concurrency-reviewraces, deadlocks, and corruption under load
config-reviewprecedence, validation, secrets in the wrong place
container-reviewprobes, graceful shutdown, image hygiene on Kubernetes
db-reviewschema, queries, migrations, data integrity
deps-reviewnecessity, supply-chain risk, maintenance burden
design-reviewtradeoffs, alternatives, data modeling, fit to scale
doc-reviewdocs and comments that disagree with the code
dr-reviewwhat is backed up, and has restore ever been proven
dst-reviewcan a single seed replay the whole run byte-for-byte
dx-reviewclone to passing tests without losing an afternoon
error-reviewsilent data loss, misleading behavior, cascading failure
functionality-reviewthe gap between intended and actual behavior
fuzz-reviewuntrusted-input surfaces with no fuzz harness
i18n-reviewtranslations, locale formatting, layout in other scripts
idempotency-reviewwhat happens when the operation runs twice
infra-reviewCI/CD, IaC, deployment, environment wiring
lint-reviewlinters present, strict enough, and blocking CI
llm-reviewprompt injection, cost, and unvalidated model output
minimalism-reviewprove every line is needed, or delete it
mobile-reviewlifecycle, offline, battery, permissions, store readiness
numerics-reviewmoney in floats, truncating casts, negative modulo
o11y-reviewlogs, metrics, traces, alerts, and whether they connect
perf-reviewalgorithms, memory, I/O, startup: measured, not guessed
pkg-reviewdeb, rpm, Flatpak, wheels, images: what actually ships
privacy-reviewpersonal data collected, shared, retained, deleted
prompt-reviewwhether these prompts work as instructions to an agent
release-reviewsemver honesty, breaking changes, changelog, migration
resource-reviewhandles, goroutines, listeners, maps that only grow
sdk-reviewthe integrating developer's experience of the surface
sec-reviewexploitable vulnerabilities and missing controls
skills-reviewdoes the skill fire, teach, and stay cheap when loaded
slop-reviewmachine-written noise: dead code, restating comments
specs-reviewrequirements and decision records the code contradicts
test-reviewtests that give false confidence or miss real bugs
threat-reviewattack surface, trust boundaries, a living threat model
time-reviewDST, leap days, wall-clock durations, cron that misfires
uislop-reviewthe interchangeable generated look, no visual identity
unicode-reviewencodings, NFC/NFD, length in the wrong units
ux-reviewfriction and confusion from the user's side
webperf-reviewbytes on the wire, blocking the first paint

How a run works

Reviews run one at a time against your working tree, forever, until you stop them. --jobs N buys parallelism with isolation instead: every review gets its own git worktree on its own branch, and the runner (never the agent) commits each one and merges them back one at a time.

Stack mode is sequential for a different reason: every review must see the commits below it. From base main, changed reviews produce review-1 → main, then review-2 → review-1, and so on. The PRs stay open; gauntlet removes only the scratch checkout. It fetches the remote base without moving your local branch. If the original checkout has uncommitted files, gauntlet names them and asks before leaving them out of the review. See stacked pull requests for the branch lifecycle and recovery rules.

flowchart LR
T[your branch<br/>clean tree] --> S[scheduler]
S --> W1[worktree<br/>sec-review]
S --> W2[worktree<br/>perf-review]
S --> W3[worktree<br/>doc-review]
W1 --> C1[runner commits]
W2 --> C2[runner commits]
W3 --> C3[runner commits]
C1 --> M[merge --squash<br/>one at a time]
C2 --> M
C3 --> M
M --> T2[your branch]
M -. conflict .-> R[agent resolves<br/>in a scratch checkout]
R -. merged .-> T2
R -. unresolved .-> K[branch kept<br/>run exits nonzero]
Loading

--jobs counts per directory, so --dirs a,b,c -j 4 is up to 12 agents at once. A branch that will not merge is handed to an agent, which resolves it in a scratch checkout; what it cannot resolve stays on its branch for you (--resolve-conflicts=false skips the attempt). Everything lands on the branch you are already on; --merge-into BRANCH is what carries a loop's committed work anywhere else. The details, plus the run journal and hot reload, are in docs/RUNS.md.

Dashboard

--tui renders the screen at the top of this page: header, activity chart, one lane per agent, the full review grid, and the feed. gauntlet pick composes a run before it starts, and shows the command it is building while you do:

The gauntlet launcher: review sets with descriptions, the installed agents, concurrency against the CPU count, and the composed command line

KeyAction
q, escquit (stops the run, killing what is running)
sfinish: no new reviews, then commit, publish or merge as configured, and exit
spacepause the feed; output keeps collecting and reviews keep running
j / kscroll the feed
fnarrow the feed to results, errors, and diffs, and back
g / Gjump to oldest / newest
?help, and the list of unmerged branches

Review glyphs: · pending, running, ok, fail, timeout, merge conflict, skipped, interrupted.

Trust model

Agents run with their permission prompts disabled. That is the point of the tool, and it is why the containment rules exist: prompts are read with O_NOFOLLOW and size-capped, agent binaries resolve on a PATH without cwd-relative entries, git runs with core.fsmonitor, core.hooksPath, diff.external, and the pager forced empty, untrusted text is stripped of control and bidi characters before display, and a flock on .gauntlet.lock keeps two runs out of one directory.

Reviewing a repository you do not trust still means running it in a container. The boundaries are drawn one by one in docs/THREAT_MODEL.md.

Token counts

Counts come from what the agent prints, its machine-readable mode (--stream), its own session transcript, and, for the two agents that keep databases instead (crush, opencode), those. All of it is on in a default build; make build TAGS=notoktop drops transcript reading and make build TAGS= drops the database driver too. gauntlet doctor says which build you have. Per-agent coverage, and the public reading API, are in docs/TOKEN_TELEMETRY.md.

Documentation

PageWhat is in it
docs/CLI.mdevery flag, environment variable, and exit code; defining your own agent
docs/RUNS.mdworktree isolation and merging, the run journal, updating and hot reload
docs/DESIGN.mdarchitecture, concurrency model, and what each decision costs
docs/TOKEN_TELEMETRY.mdwhere token counts come from, per agent, and the public reading API
docs/THREAT_MODEL.mdtrust boundaries, what is validated where, and what is out of scope
docs/IDEAS.mdthings deliberately not built yet, and why
CONTRIBUTING.mdbuilding, testing, and the checks a pull request runs

License

AGPL-3.0-or-later.

About

Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - maci0/gauntlet: Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed. · GitHub
Skip to content

Repository files navigation

gauntlet

Run your codebase through the gauntlet: ~50 specialized review prompts, dispatched to whichever AI coding agents you have installed, applying fixes directly to the working tree.

CIlatest releaselicenseplatformsgo

The gauntlet dashboard: an activity chart, one lane per agent with live token rates, the review grid, and a normalized feed

One static binary loops ~50 review prompts over your repository, hands each one to an agent CLI you already have installed, and applies what it finds.

  • Isolation when it runs in parallel.--jobs N gives every review its own git worktree on its own branch, merged back one at a time. Concurrent agents never share a working tree.
  • Unmerged review stacks.--stacked-prs runs reviews in one isolated worktree and opens each changed review as a child PR of the previous one. The branch in your editor is never changed.
  • Many repositories at once.--dirs a,b,c reviews several trees, each with its own lock, baseline, and lane. --jobs applies within each.
  • A dashboard.--tui puts lanes, throughput, the review grid, and a normalized feed on one screen.
  • Readable output. Spinner frames, escape sequences, repainted progress lines, tool gutters, and duplicate narration are collapsed rather than echoed, per agent.
  • Measured, never guessed. Token counts come from what the agent prints, its session transcript, and its machine-readable mode; an agent that reports nothing shows no rate.
  • A record. Every run is JSONL under ~/.gauntlet, replayable with gauntlet show.
  • Self-updating, hot-reloading. A running loop takes a new binary between reviews without losing its counters.

Quick start

Check which installed agents gauntlet can use, then compose a run:

gauntlet doctor
gauntlet pick

Run one isolated, unmerged PR stack from main:

gauntlet -r quick --stacked-prs --pr-base main

Everything below is detail: installation, execution modes, and references.

Install

Install the latest release binary:

mkdir -p ~/.local/bin
ver=$(curl -fsSL https://api.github.com/repos/maci0/gauntlet/releases/latest | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
curl -fsSL "https://github.com/maci0/gauntlet/releases/latest/download/gauntlet_${ver}_$(uname -s | tr A-Z a-z)_$(uname -m | sed -e s/x86_64/amd64/ -e s/aarch64/arm64/)" -o ~/.local/bin/gauntlet
chmod +x ~/.local/bin/gauntlet

Or build and install from source:

make install

Check or update the installation:

gauntlet doctor
gauntlet update

Upgrading from the Python version: the flags are the same, --target-dirs is still accepted, and pip/uv are no longer involved. Uninstall the old one with uv tool uninstall gauntlet-review (or pipx uninstall gauntlet-review).

Linux and macOS. The runner leans on POSIX semantics that Windows has no equivalent for: process groups to kill an agent's whole tree on timeout, flock for the directory lock, O_NOFOLLOW for prompt reads, and execve for hot reload.

Supported agents: claude, codex, gemini, qwen, grok, agy, cursor-agent, kimi, opencode, crush, clanker, dsh, plus the pi family (pi, prime-agent, feynman, omp), which ships as editable definitions rather than code. At least one must be on PATH.

Any other agent can be added without a new binary: --agent-cmd for one run, ~/.gauntlet/agents.json to keep it. gauntlet doctor lists every agent it knows, defined ones included. See docs/CLI.md.

The reviews

Every review is one prompt file. Run all of them, a named set (-r quick, -r security, -r backend, -r frontend, -r shipping, -r agents), or any list you like. gauntlet --list prints this table with what is scheduled.

ReviewFinds
a11y-reviewkeyboard, screen readers, contrast, motion, WCAG 2.2 AA
agentrules-reviewthe CLAUDE.md and AGENTS.md files every session pays for
api-reviewREST, GraphQL, and gRPC surfaces: consistency, correctness
arch-reviewmodule boundaries, dependency direction, layering
authz-reviewIDOR, unprotected admin routes, cross-tenant leakage
build-reviewreproducible, hermetic builds and a pinned toolchain
cache-reviewstale reads, cross-tenant bleed, stampedes, growth
cli-reviewexit codes, stdout vs stderr, piping, --help
code-reviewmaintainability, correctness, consistency, simplicity
compat-reviewpath separators, bashisms, endianness, musl vs glibc
concurrency-reviewraces, deadlocks, and corruption under load
config-reviewprecedence, validation, secrets in the wrong place
container-reviewprobes, graceful shutdown, image hygiene on Kubernetes
db-reviewschema, queries, migrations, data integrity
deps-reviewnecessity, supply-chain risk, maintenance burden
design-reviewtradeoffs, alternatives, data modeling, fit to scale
doc-reviewdocs and comments that disagree with the code
dr-reviewwhat is backed up, and has restore ever been proven
dst-reviewcan a single seed replay the whole run byte-for-byte
dx-reviewclone to passing tests without losing an afternoon
error-reviewsilent data loss, misleading behavior, cascading failure
functionality-reviewthe gap between intended and actual behavior
fuzz-reviewuntrusted-input surfaces with no fuzz harness
i18n-reviewtranslations, locale formatting, layout in other scripts
idempotency-reviewwhat happens when the operation runs twice
infra-reviewCI/CD, IaC, deployment, environment wiring
lint-reviewlinters present, strict enough, and blocking CI
llm-reviewprompt injection, cost, and unvalidated model output
minimalism-reviewprove every line is needed, or delete it
mobile-reviewlifecycle, offline, battery, permissions, store readiness
numerics-reviewmoney in floats, truncating casts, negative modulo
o11y-reviewlogs, metrics, traces, alerts, and whether they connect
perf-reviewalgorithms, memory, I/O, startup: measured, not guessed
pkg-reviewdeb, rpm, Flatpak, wheels, images: what actually ships
privacy-reviewpersonal data collected, shared, retained, deleted
prompt-reviewwhether these prompts work as instructions to an agent
release-reviewsemver honesty, breaking changes, changelog, migration
resource-reviewhandles, goroutines, listeners, maps that only grow
sdk-reviewthe integrating developer's experience of the surface
sec-reviewexploitable vulnerabilities and missing controls
skills-reviewdoes the skill fire, teach, and stay cheap when loaded
slop-reviewmachine-written noise: dead code, restating comments
specs-reviewrequirements and decision records the code contradicts
test-reviewtests that give false confidence or miss real bugs
threat-reviewattack surface, trust boundaries, a living threat model
time-reviewDST, leap days, wall-clock durations, cron that misfires
uislop-reviewthe interchangeable generated look, no visual identity
unicode-reviewencodings, NFC/NFD, length in the wrong units
ux-reviewfriction and confusion from the user's side
webperf-reviewbytes on the wire, blocking the first paint

How a run works

Reviews run one at a time against your working tree, forever, until you stop them. --jobs N buys parallelism with isolation instead: every review gets its own git worktree on its own branch, and the runner (never the agent) commits each one and merges them back one at a time.

Stack mode is sequential for a different reason: every review must see the commits below it. From base main, changed reviews produce review-1 → main, then review-2 → review-1, and so on. The PRs stay open; gauntlet removes only the scratch checkout. It fetches the remote base without moving your local branch. If the original checkout has uncommitted files, gauntlet names them and asks before leaving them out of the review. See stacked pull requests for the branch lifecycle and recovery rules.

flowchart LR
T[your branch<br/>clean tree] --> S[scheduler]
S --> W1[worktree<br/>sec-review]
S --> W2[worktree<br/>perf-review]
S --> W3[worktree<br/>doc-review]
W1 --> C1[runner commits]
W2 --> C2[runner commits]
W3 --> C3[runner commits]
C1 --> M[merge --squash<br/>one at a time]
C2 --> M
C3 --> M
M --> T2[your branch]
M -. conflict .-> R[agent resolves<br/>in a scratch checkout]
R -. merged .-> T2
R -. unresolved .-> K[branch kept<br/>run exits nonzero]
Loading

--jobs counts per directory, so --dirs a,b,c -j 4 is up to 12 agents at once. A branch that will not merge is handed to an agent, which resolves it in a scratch checkout; what it cannot resolve stays on its branch for you (--resolve-conflicts=false skips the attempt). Everything lands on the branch you are already on; --merge-into BRANCH is what carries a loop's committed work anywhere else. The details, plus the run journal and hot reload, are in docs/RUNS.md.

Dashboard

--tui renders the screen at the top of this page: header, activity chart, one lane per agent, the full review grid, and the feed. gauntlet pick composes a run before it starts, and shows the command it is building while you do:

The gauntlet launcher: review sets with descriptions, the installed agents, concurrency against the CPU count, and the composed command line

KeyAction
q, escquit (stops the run, killing what is running)
sfinish: no new reviews, then commit, publish or merge as configured, and exit
spacepause the feed; output keeps collecting and reviews keep running
j / kscroll the feed
fnarrow the feed to results, errors, and diffs, and back
g / Gjump to oldest / newest
?help, and the list of unmerged branches

Review glyphs: · pending, running, ok, fail, timeout, merge conflict, skipped, interrupted.

Trust model

Agents run with their permission prompts disabled. That is the point of the tool, and it is why the containment rules exist: prompts are read with O_NOFOLLOW and size-capped, agent binaries resolve on a PATH without cwd-relative entries, git runs with core.fsmonitor, core.hooksPath, diff.external, and the pager forced empty, untrusted text is stripped of control and bidi characters before display, and a flock on .gauntlet.lock keeps two runs out of one directory.

Reviewing a repository you do not trust still means running it in a container. The boundaries are drawn one by one in docs/THREAT_MODEL.md.

Token counts

Counts come from what the agent prints, its machine-readable mode (--stream), its own session transcript, and, for the two agents that keep databases instead (crush, opencode), those. All of it is on in a default build; make build TAGS=notoktop drops transcript reading and make build TAGS= drops the database driver too. gauntlet doctor says which build you have. Per-agent coverage, and the public reading API, are in docs/TOKEN_TELEMETRY.md.

Documentation

PageWhat is in it
docs/CLI.mdevery flag, environment variable, and exit code; defining your own agent
docs/RUNS.mdworktree isolation and merging, the run journal, updating and hot reload
docs/DESIGN.mdarchitecture, concurrency model, and what each decision costs
docs/TOKEN_TELEMETRY.mdwhere token counts come from, per agent, and the public reading API
docs/THREAT_MODEL.mdtrust boundaries, what is validated where, and what is out of scope
docs/IDEAS.mdthings deliberately not built yet, and why
CONTRIBUTING.mdbuilding, testing, and the checks a pull request runs

License

AGPL-3.0-or-later.

About

Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - maci0/gauntlet: Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed. · GitHub
Skip to content

Repository files navigation

gauntlet

Run your codebase through the gauntlet: ~50 specialized review prompts, dispatched to whichever AI coding agents you have installed, applying fixes directly to the working tree.

CIlatest releaselicenseplatformsgo

The gauntlet dashboard: an activity chart, one lane per agent with live token rates, the review grid, and a normalized feed

One static binary loops ~50 review prompts over your repository, hands each one to an agent CLI you already have installed, and applies what it finds.

  • Isolation when it runs in parallel.--jobs N gives every review its own git worktree on its own branch, merged back one at a time. Concurrent agents never share a working tree.
  • Unmerged review stacks.--stacked-prs runs reviews in one isolated worktree and opens each changed review as a child PR of the previous one. The branch in your editor is never changed.
  • Many repositories at once.--dirs a,b,c reviews several trees, each with its own lock, baseline, and lane. --jobs applies within each.
  • A dashboard.--tui puts lanes, throughput, the review grid, and a normalized feed on one screen.
  • Readable output. Spinner frames, escape sequences, repainted progress lines, tool gutters, and duplicate narration are collapsed rather than echoed, per agent.
  • Measured, never guessed. Token counts come from what the agent prints, its session transcript, and its machine-readable mode; an agent that reports nothing shows no rate.
  • A record. Every run is JSONL under ~/.gauntlet, replayable with gauntlet show.
  • Self-updating, hot-reloading. A running loop takes a new binary between reviews without losing its counters.

Quick start

Check which installed agents gauntlet can use, then compose a run:

gauntlet doctor
gauntlet pick

Run one isolated, unmerged PR stack from main:

gauntlet -r quick --stacked-prs --pr-base main

Everything below is detail: installation, execution modes, and references.

Install

Install the latest release binary:

mkdir -p ~/.local/bin
ver=$(curl -fsSL https://api.github.com/repos/maci0/gauntlet/releases/latest | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
curl -fsSL "https://github.com/maci0/gauntlet/releases/latest/download/gauntlet_${ver}_$(uname -s | tr A-Z a-z)_$(uname -m | sed -e s/x86_64/amd64/ -e s/aarch64/arm64/)" -o ~/.local/bin/gauntlet
chmod +x ~/.local/bin/gauntlet

Or build and install from source:

make install

Check or update the installation:

gauntlet doctor
gauntlet update

Upgrading from the Python version: the flags are the same, --target-dirs is still accepted, and pip/uv are no longer involved. Uninstall the old one with uv tool uninstall gauntlet-review (or pipx uninstall gauntlet-review).

Linux and macOS. The runner leans on POSIX semantics that Windows has no equivalent for: process groups to kill an agent's whole tree on timeout, flock for the directory lock, O_NOFOLLOW for prompt reads, and execve for hot reload.

Supported agents: claude, codex, gemini, qwen, grok, agy, cursor-agent, kimi, opencode, crush, clanker, dsh, plus the pi family (pi, prime-agent, feynman, omp), which ships as editable definitions rather than code. At least one must be on PATH.

Any other agent can be added without a new binary: --agent-cmd for one run, ~/.gauntlet/agents.json to keep it. gauntlet doctor lists every agent it knows, defined ones included. See docs/CLI.md.

The reviews

Every review is one prompt file. Run all of them, a named set (-r quick, -r security, -r backend, -r frontend, -r shipping, -r agents), or any list you like. gauntlet --list prints this table with what is scheduled.

ReviewFinds
a11y-reviewkeyboard, screen readers, contrast, motion, WCAG 2.2 AA
agentrules-reviewthe CLAUDE.md and AGENTS.md files every session pays for
api-reviewREST, GraphQL, and gRPC surfaces: consistency, correctness
arch-reviewmodule boundaries, dependency direction, layering
authz-reviewIDOR, unprotected admin routes, cross-tenant leakage
build-reviewreproducible, hermetic builds and a pinned toolchain
cache-reviewstale reads, cross-tenant bleed, stampedes, growth
cli-reviewexit codes, stdout vs stderr, piping, --help
code-reviewmaintainability, correctness, consistency, simplicity
compat-reviewpath separators, bashisms, endianness, musl vs glibc
concurrency-reviewraces, deadlocks, and corruption under load
config-reviewprecedence, validation, secrets in the wrong place
container-reviewprobes, graceful shutdown, image hygiene on Kubernetes
db-reviewschema, queries, migrations, data integrity
deps-reviewnecessity, supply-chain risk, maintenance burden
design-reviewtradeoffs, alternatives, data modeling, fit to scale
doc-reviewdocs and comments that disagree with the code
dr-reviewwhat is backed up, and has restore ever been proven
dst-reviewcan a single seed replay the whole run byte-for-byte
dx-reviewclone to passing tests without losing an afternoon
error-reviewsilent data loss, misleading behavior, cascading failure
functionality-reviewthe gap between intended and actual behavior
fuzz-reviewuntrusted-input surfaces with no fuzz harness
i18n-reviewtranslations, locale formatting, layout in other scripts
idempotency-reviewwhat happens when the operation runs twice
infra-reviewCI/CD, IaC, deployment, environment wiring
lint-reviewlinters present, strict enough, and blocking CI
llm-reviewprompt injection, cost, and unvalidated model output
minimalism-reviewprove every line is needed, or delete it
mobile-reviewlifecycle, offline, battery, permissions, store readiness
numerics-reviewmoney in floats, truncating casts, negative modulo
o11y-reviewlogs, metrics, traces, alerts, and whether they connect
perf-reviewalgorithms, memory, I/O, startup: measured, not guessed
pkg-reviewdeb, rpm, Flatpak, wheels, images: what actually ships
privacy-reviewpersonal data collected, shared, retained, deleted
prompt-reviewwhether these prompts work as instructions to an agent
release-reviewsemver honesty, breaking changes, changelog, migration
resource-reviewhandles, goroutines, listeners, maps that only grow
sdk-reviewthe integrating developer's experience of the surface
sec-reviewexploitable vulnerabilities and missing controls
skills-reviewdoes the skill fire, teach, and stay cheap when loaded
slop-reviewmachine-written noise: dead code, restating comments
specs-reviewrequirements and decision records the code contradicts
test-reviewtests that give false confidence or miss real bugs
threat-reviewattack surface, trust boundaries, a living threat model
time-reviewDST, leap days, wall-clock durations, cron that misfires
uislop-reviewthe interchangeable generated look, no visual identity
unicode-reviewencodings, NFC/NFD, length in the wrong units
ux-reviewfriction and confusion from the user's side
webperf-reviewbytes on the wire, blocking the first paint

How a run works

Reviews run one at a time against your working tree, forever, until you stop them. --jobs N buys parallelism with isolation instead: every review gets its own git worktree on its own branch, and the runner (never the agent) commits each one and merges them back one at a time.

Stack mode is sequential for a different reason: every review must see the commits below it. From base main, changed reviews produce review-1 → main, then review-2 → review-1, and so on. The PRs stay open; gauntlet removes only the scratch checkout. It fetches the remote base without moving your local branch. If the original checkout has uncommitted files, gauntlet names them and asks before leaving them out of the review. See stacked pull requests for the branch lifecycle and recovery rules.

flowchart LR
T[your branch<br/>clean tree] --> S[scheduler]
S --> W1[worktree<br/>sec-review]
S --> W2[worktree<br/>perf-review]
S --> W3[worktree<br/>doc-review]
W1 --> C1[runner commits]
W2 --> C2[runner commits]
W3 --> C3[runner commits]
C1 --> M[merge --squash<br/>one at a time]
C2 --> M
C3 --> M
M --> T2[your branch]
M -. conflict .-> R[agent resolves<br/>in a scratch checkout]
R -. merged .-> T2
R -. unresolved .-> K[branch kept<br/>run exits nonzero]
Loading

--jobs counts per directory, so --dirs a,b,c -j 4 is up to 12 agents at once. A branch that will not merge is handed to an agent, which resolves it in a scratch checkout; what it cannot resolve stays on its branch for you (--resolve-conflicts=false skips the attempt). Everything lands on the branch you are already on; --merge-into BRANCH is what carries a loop's committed work anywhere else. The details, plus the run journal and hot reload, are in docs/RUNS.md.

Dashboard

--tui renders the screen at the top of this page: header, activity chart, one lane per agent, the full review grid, and the feed. gauntlet pick composes a run before it starts, and shows the command it is building while you do:

The gauntlet launcher: review sets with descriptions, the installed agents, concurrency against the CPU count, and the composed command line

KeyAction
q, escquit (stops the run, killing what is running)
sfinish: no new reviews, then commit, publish or merge as configured, and exit
spacepause the feed; output keeps collecting and reviews keep running
j / kscroll the feed
fnarrow the feed to results, errors, and diffs, and back
g / Gjump to oldest / newest
?help, and the list of unmerged branches

Review glyphs: · pending, running, ok, fail, timeout, merge conflict, skipped, interrupted.

Trust model

Agents run with their permission prompts disabled. That is the point of the tool, and it is why the containment rules exist: prompts are read with O_NOFOLLOW and size-capped, agent binaries resolve on a PATH without cwd-relative entries, git runs with core.fsmonitor, core.hooksPath, diff.external, and the pager forced empty, untrusted text is stripped of control and bidi characters before display, and a flock on .gauntlet.lock keeps two runs out of one directory.

Reviewing a repository you do not trust still means running it in a container. The boundaries are drawn one by one in docs/THREAT_MODEL.md.

Token counts

Counts come from what the agent prints, its machine-readable mode (--stream), its own session transcript, and, for the two agents that keep databases instead (crush, opencode), those. All of it is on in a default build; make build TAGS=notoktop drops transcript reading and make build TAGS= drops the database driver too. gauntlet doctor says which build you have. Per-agent coverage, and the public reading API, are in docs/TOKEN_TELEMETRY.md.

Documentation

PageWhat is in it
docs/CLI.mdevery flag, environment variable, and exit code; defining your own agent
docs/RUNS.mdworktree isolation and merging, the run journal, updating and hot reload
docs/DESIGN.mdarchitecture, concurrency model, and what each decision costs
docs/TOKEN_TELEMETRY.mdwhere token counts come from, per agent, and the public reading API
docs/THREAT_MODEL.mdtrust boundaries, what is validated where, and what is out of scope
docs/IDEAS.mdthings deliberately not built yet, and why
CONTRIBUTING.mdbuilding, testing, and the checks a pull request runs

License

AGPL-3.0-or-later.

About

Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - maci0/gauntlet: Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed. · GitHub
Skip to content

Repository files navigation

gauntlet

Run your codebase through the gauntlet: ~50 specialized review prompts, dispatched to whichever AI coding agents you have installed, applying fixes directly to the working tree.

CIlatest releaselicenseplatformsgo

The gauntlet dashboard: an activity chart, one lane per agent with live token rates, the review grid, and a normalized feed

One static binary loops ~50 review prompts over your repository, hands each one to an agent CLI you already have installed, and applies what it finds.

  • Isolation when it runs in parallel.--jobs N gives every review its own git worktree on its own branch, merged back one at a time. Concurrent agents never share a working tree.
  • Unmerged review stacks.--stacked-prs runs reviews in one isolated worktree and opens each changed review as a child PR of the previous one. The branch in your editor is never changed.
  • Many repositories at once.--dirs a,b,c reviews several trees, each with its own lock, baseline, and lane. --jobs applies within each.
  • A dashboard.--tui puts lanes, throughput, the review grid, and a normalized feed on one screen.
  • Readable output. Spinner frames, escape sequences, repainted progress lines, tool gutters, and duplicate narration are collapsed rather than echoed, per agent.
  • Measured, never guessed. Token counts come from what the agent prints, its session transcript, and its machine-readable mode; an agent that reports nothing shows no rate.
  • A record. Every run is JSONL under ~/.gauntlet, replayable with gauntlet show.
  • Self-updating, hot-reloading. A running loop takes a new binary between reviews without losing its counters.

Quick start

Check which installed agents gauntlet can use, then compose a run:

gauntlet doctor
gauntlet pick

Run one isolated, unmerged PR stack from main:

gauntlet -r quick --stacked-prs --pr-base main

Everything below is detail: installation, execution modes, and references.

Install

Install the latest release binary:

mkdir -p ~/.local/bin
ver=$(curl -fsSL https://api.github.com/repos/maci0/gauntlet/releases/latest | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
curl -fsSL "https://github.com/maci0/gauntlet/releases/latest/download/gauntlet_${ver}_$(uname -s | tr A-Z a-z)_$(uname -m | sed -e s/x86_64/amd64/ -e s/aarch64/arm64/)" -o ~/.local/bin/gauntlet
chmod +x ~/.local/bin/gauntlet

Or build and install from source:

make install

Check or update the installation:

gauntlet doctor
gauntlet update

Upgrading from the Python version: the flags are the same, --target-dirs is still accepted, and pip/uv are no longer involved. Uninstall the old one with uv tool uninstall gauntlet-review (or pipx uninstall gauntlet-review).

Linux and macOS. The runner leans on POSIX semantics that Windows has no equivalent for: process groups to kill an agent's whole tree on timeout, flock for the directory lock, O_NOFOLLOW for prompt reads, and execve for hot reload.

Supported agents: claude, codex, gemini, qwen, grok, agy, cursor-agent, kimi, opencode, crush, clanker, dsh, plus the pi family (pi, prime-agent, feynman, omp), which ships as editable definitions rather than code. At least one must be on PATH.

Any other agent can be added without a new binary: --agent-cmd for one run, ~/.gauntlet/agents.json to keep it. gauntlet doctor lists every agent it knows, defined ones included. See docs/CLI.md.

The reviews

Every review is one prompt file. Run all of them, a named set (-r quick, -r security, -r backend, -r frontend, -r shipping, -r agents), or any list you like. gauntlet --list prints this table with what is scheduled.

ReviewFinds
a11y-reviewkeyboard, screen readers, contrast, motion, WCAG 2.2 AA
agentrules-reviewthe CLAUDE.md and AGENTS.md files every session pays for
api-reviewREST, GraphQL, and gRPC surfaces: consistency, correctness
arch-reviewmodule boundaries, dependency direction, layering
authz-reviewIDOR, unprotected admin routes, cross-tenant leakage
build-reviewreproducible, hermetic builds and a pinned toolchain
cache-reviewstale reads, cross-tenant bleed, stampedes, growth
cli-reviewexit codes, stdout vs stderr, piping, --help
code-reviewmaintainability, correctness, consistency, simplicity
compat-reviewpath separators, bashisms, endianness, musl vs glibc
concurrency-reviewraces, deadlocks, and corruption under load
config-reviewprecedence, validation, secrets in the wrong place
container-reviewprobes, graceful shutdown, image hygiene on Kubernetes
db-reviewschema, queries, migrations, data integrity
deps-reviewnecessity, supply-chain risk, maintenance burden
design-reviewtradeoffs, alternatives, data modeling, fit to scale
doc-reviewdocs and comments that disagree with the code
dr-reviewwhat is backed up, and has restore ever been proven
dst-reviewcan a single seed replay the whole run byte-for-byte
dx-reviewclone to passing tests without losing an afternoon
error-reviewsilent data loss, misleading behavior, cascading failure
functionality-reviewthe gap between intended and actual behavior
fuzz-reviewuntrusted-input surfaces with no fuzz harness
i18n-reviewtranslations, locale formatting, layout in other scripts
idempotency-reviewwhat happens when the operation runs twice
infra-reviewCI/CD, IaC, deployment, environment wiring
lint-reviewlinters present, strict enough, and blocking CI
llm-reviewprompt injection, cost, and unvalidated model output
minimalism-reviewprove every line is needed, or delete it
mobile-reviewlifecycle, offline, battery, permissions, store readiness
numerics-reviewmoney in floats, truncating casts, negative modulo
o11y-reviewlogs, metrics, traces, alerts, and whether they connect
perf-reviewalgorithms, memory, I/O, startup: measured, not guessed
pkg-reviewdeb, rpm, Flatpak, wheels, images: what actually ships
privacy-reviewpersonal data collected, shared, retained, deleted
prompt-reviewwhether these prompts work as instructions to an agent
release-reviewsemver honesty, breaking changes, changelog, migration
resource-reviewhandles, goroutines, listeners, maps that only grow
sdk-reviewthe integrating developer's experience of the surface
sec-reviewexploitable vulnerabilities and missing controls
skills-reviewdoes the skill fire, teach, and stay cheap when loaded
slop-reviewmachine-written noise: dead code, restating comments
specs-reviewrequirements and decision records the code contradicts
test-reviewtests that give false confidence or miss real bugs
threat-reviewattack surface, trust boundaries, a living threat model
time-reviewDST, leap days, wall-clock durations, cron that misfires
uislop-reviewthe interchangeable generated look, no visual identity
unicode-reviewencodings, NFC/NFD, length in the wrong units
ux-reviewfriction and confusion from the user's side
webperf-reviewbytes on the wire, blocking the first paint

How a run works

Reviews run one at a time against your working tree, forever, until you stop them. --jobs N buys parallelism with isolation instead: every review gets its own git worktree on its own branch, and the runner (never the agent) commits each one and merges them back one at a time.

Stack mode is sequential for a different reason: every review must see the commits below it. From base main, changed reviews produce review-1 → main, then review-2 → review-1, and so on. The PRs stay open; gauntlet removes only the scratch checkout. It fetches the remote base without moving your local branch. If the original checkout has uncommitted files, gauntlet names them and asks before leaving them out of the review. See stacked pull requests for the branch lifecycle and recovery rules.

flowchart LR
T[your branch<br/>clean tree] --> S[scheduler]
S --> W1[worktree<br/>sec-review]
S --> W2[worktree<br/>perf-review]
S --> W3[worktree<br/>doc-review]
W1 --> C1[runner commits]
W2 --> C2[runner commits]
W3 --> C3[runner commits]
C1 --> M[merge --squash<br/>one at a time]
C2 --> M
C3 --> M
M --> T2[your branch]
M -. conflict .-> R[agent resolves<br/>in a scratch checkout]
R -. merged .-> T2
R -. unresolved .-> K[branch kept<br/>run exits nonzero]
Loading

--jobs counts per directory, so --dirs a,b,c -j 4 is up to 12 agents at once. A branch that will not merge is handed to an agent, which resolves it in a scratch checkout; what it cannot resolve stays on its branch for you (--resolve-conflicts=false skips the attempt). Everything lands on the branch you are already on; --merge-into BRANCH is what carries a loop's committed work anywhere else. The details, plus the run journal and hot reload, are in docs/RUNS.md.

Dashboard

--tui renders the screen at the top of this page: header, activity chart, one lane per agent, the full review grid, and the feed. gauntlet pick composes a run before it starts, and shows the command it is building while you do:

The gauntlet launcher: review sets with descriptions, the installed agents, concurrency against the CPU count, and the composed command line

KeyAction
q, escquit (stops the run, killing what is running)
sfinish: no new reviews, then commit, publish or merge as configured, and exit
spacepause the feed; output keeps collecting and reviews keep running
j / kscroll the feed
fnarrow the feed to results, errors, and diffs, and back
g / Gjump to oldest / newest
?help, and the list of unmerged branches

Review glyphs: · pending, running, ok, fail, timeout, merge conflict, skipped, interrupted.

Trust model

Agents run with their permission prompts disabled. That is the point of the tool, and it is why the containment rules exist: prompts are read with O_NOFOLLOW and size-capped, agent binaries resolve on a PATH without cwd-relative entries, git runs with core.fsmonitor, core.hooksPath, diff.external, and the pager forced empty, untrusted text is stripped of control and bidi characters before display, and a flock on .gauntlet.lock keeps two runs out of one directory.

Reviewing a repository you do not trust still means running it in a container. The boundaries are drawn one by one in docs/THREAT_MODEL.md.

Token counts

Counts come from what the agent prints, its machine-readable mode (--stream), its own session transcript, and, for the two agents that keep databases instead (crush, opencode), those. All of it is on in a default build; make build TAGS=notoktop drops transcript reading and make build TAGS= drops the database driver too. gauntlet doctor says which build you have. Per-agent coverage, and the public reading API, are in docs/TOKEN_TELEMETRY.md.

Documentation

PageWhat is in it
docs/CLI.mdevery flag, environment variable, and exit code; defining your own agent
docs/RUNS.mdworktree isolation and merging, the run journal, updating and hot reload
docs/DESIGN.mdarchitecture, concurrency model, and what each decision costs
docs/TOKEN_TELEMETRY.mdwhere token counts come from, per agent, and the public reading API
docs/THREAT_MODEL.mdtrust boundaries, what is validated where, and what is out of scope
docs/IDEAS.mdthings deliberately not built yet, and why
CONTRIBUTING.mdbuilding, testing, and the checks a pull request runs

License

AGPL-3.0-or-later.

About

Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - maci0/gauntlet: Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed. · GitHub
Skip to content

Repository files navigation

gauntlet

Run your codebase through the gauntlet: ~50 specialized review prompts, dispatched to whichever AI coding agents you have installed, applying fixes directly to the working tree.

CIlatest releaselicenseplatformsgo

The gauntlet dashboard: an activity chart, one lane per agent with live token rates, the review grid, and a normalized feed

One static binary loops ~50 review prompts over your repository, hands each one to an agent CLI you already have installed, and applies what it finds.

  • Isolation when it runs in parallel.--jobs N gives every review its own git worktree on its own branch, merged back one at a time. Concurrent agents never share a working tree.
  • Unmerged review stacks.--stacked-prs runs reviews in one isolated worktree and opens each changed review as a child PR of the previous one. The branch in your editor is never changed.
  • Many repositories at once.--dirs a,b,c reviews several trees, each with its own lock, baseline, and lane. --jobs applies within each.
  • A dashboard.--tui puts lanes, throughput, the review grid, and a normalized feed on one screen.
  • Readable output. Spinner frames, escape sequences, repainted progress lines, tool gutters, and duplicate narration are collapsed rather than echoed, per agent.
  • Measured, never guessed. Token counts come from what the agent prints, its session transcript, and its machine-readable mode; an agent that reports nothing shows no rate.
  • A record. Every run is JSONL under ~/.gauntlet, replayable with gauntlet show.
  • Self-updating, hot-reloading. A running loop takes a new binary between reviews without losing its counters.

Quick start

Check which installed agents gauntlet can use, then compose a run:

gauntlet doctor
gauntlet pick

Run one isolated, unmerged PR stack from main:

gauntlet -r quick --stacked-prs --pr-base main

Everything below is detail: installation, execution modes, and references.

Install

Install the latest release binary:

mkdir -p ~/.local/bin
ver=$(curl -fsSL https://api.github.com/repos/maci0/gauntlet/releases/latest | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
curl -fsSL "https://github.com/maci0/gauntlet/releases/latest/download/gauntlet_${ver}_$(uname -s | tr A-Z a-z)_$(uname -m | sed -e s/x86_64/amd64/ -e s/aarch64/arm64/)" -o ~/.local/bin/gauntlet
chmod +x ~/.local/bin/gauntlet

Or build and install from source:

make install

Check or update the installation:

gauntlet doctor
gauntlet update

Upgrading from the Python version: the flags are the same, --target-dirs is still accepted, and pip/uv are no longer involved. Uninstall the old one with uv tool uninstall gauntlet-review (or pipx uninstall gauntlet-review).

Linux and macOS. The runner leans on POSIX semantics that Windows has no equivalent for: process groups to kill an agent's whole tree on timeout, flock for the directory lock, O_NOFOLLOW for prompt reads, and execve for hot reload.

Supported agents: claude, codex, gemini, qwen, grok, agy, cursor-agent, kimi, opencode, crush, clanker, dsh, plus the pi family (pi, prime-agent, feynman, omp), which ships as editable definitions rather than code. At least one must be on PATH.

Any other agent can be added without a new binary: --agent-cmd for one run, ~/.gauntlet/agents.json to keep it. gauntlet doctor lists every agent it knows, defined ones included. See docs/CLI.md.

The reviews

Every review is one prompt file. Run all of them, a named set (-r quick, -r security, -r backend, -r frontend, -r shipping, -r agents), or any list you like. gauntlet --list prints this table with what is scheduled.

ReviewFinds
a11y-reviewkeyboard, screen readers, contrast, motion, WCAG 2.2 AA
agentrules-reviewthe CLAUDE.md and AGENTS.md files every session pays for
api-reviewREST, GraphQL, and gRPC surfaces: consistency, correctness
arch-reviewmodule boundaries, dependency direction, layering
authz-reviewIDOR, unprotected admin routes, cross-tenant leakage
build-reviewreproducible, hermetic builds and a pinned toolchain
cache-reviewstale reads, cross-tenant bleed, stampedes, growth
cli-reviewexit codes, stdout vs stderr, piping, --help
code-reviewmaintainability, correctness, consistency, simplicity
compat-reviewpath separators, bashisms, endianness, musl vs glibc
concurrency-reviewraces, deadlocks, and corruption under load
config-reviewprecedence, validation, secrets in the wrong place
container-reviewprobes, graceful shutdown, image hygiene on Kubernetes
db-reviewschema, queries, migrations, data integrity
deps-reviewnecessity, supply-chain risk, maintenance burden
design-reviewtradeoffs, alternatives, data modeling, fit to scale
doc-reviewdocs and comments that disagree with the code
dr-reviewwhat is backed up, and has restore ever been proven
dst-reviewcan a single seed replay the whole run byte-for-byte
dx-reviewclone to passing tests without losing an afternoon
error-reviewsilent data loss, misleading behavior, cascading failure
functionality-reviewthe gap between intended and actual behavior
fuzz-reviewuntrusted-input surfaces with no fuzz harness
i18n-reviewtranslations, locale formatting, layout in other scripts
idempotency-reviewwhat happens when the operation runs twice
infra-reviewCI/CD, IaC, deployment, environment wiring
lint-reviewlinters present, strict enough, and blocking CI
llm-reviewprompt injection, cost, and unvalidated model output
minimalism-reviewprove every line is needed, or delete it
mobile-reviewlifecycle, offline, battery, permissions, store readiness
numerics-reviewmoney in floats, truncating casts, negative modulo
o11y-reviewlogs, metrics, traces, alerts, and whether they connect
perf-reviewalgorithms, memory, I/O, startup: measured, not guessed
pkg-reviewdeb, rpm, Flatpak, wheels, images: what actually ships
privacy-reviewpersonal data collected, shared, retained, deleted
prompt-reviewwhether these prompts work as instructions to an agent
release-reviewsemver honesty, breaking changes, changelog, migration
resource-reviewhandles, goroutines, listeners, maps that only grow
sdk-reviewthe integrating developer's experience of the surface
sec-reviewexploitable vulnerabilities and missing controls
skills-reviewdoes the skill fire, teach, and stay cheap when loaded
slop-reviewmachine-written noise: dead code, restating comments
specs-reviewrequirements and decision records the code contradicts
test-reviewtests that give false confidence or miss real bugs
threat-reviewattack surface, trust boundaries, a living threat model
time-reviewDST, leap days, wall-clock durations, cron that misfires
uislop-reviewthe interchangeable generated look, no visual identity
unicode-reviewencodings, NFC/NFD, length in the wrong units
ux-reviewfriction and confusion from the user's side
webperf-reviewbytes on the wire, blocking the first paint

How a run works

Reviews run one at a time against your working tree, forever, until you stop them. --jobs N buys parallelism with isolation instead: every review gets its own git worktree on its own branch, and the runner (never the agent) commits each one and merges them back one at a time.

Stack mode is sequential for a different reason: every review must see the commits below it. From base main, changed reviews produce review-1 → main, then review-2 → review-1, and so on. The PRs stay open; gauntlet removes only the scratch checkout. It fetches the remote base without moving your local branch. If the original checkout has uncommitted files, gauntlet names them and asks before leaving them out of the review. See stacked pull requests for the branch lifecycle and recovery rules.

flowchart LR
T[your branch<br/>clean tree] --> S[scheduler]
S --> W1[worktree<br/>sec-review]
S --> W2[worktree<br/>perf-review]
S --> W3[worktree<br/>doc-review]
W1 --> C1[runner commits]
W2 --> C2[runner commits]
W3 --> C3[runner commits]
C1 --> M[merge --squash<br/>one at a time]
C2 --> M
C3 --> M
M --> T2[your branch]
M -. conflict .-> R[agent resolves<br/>in a scratch checkout]
R -. merged .-> T2
R -. unresolved .-> K[branch kept<br/>run exits nonzero]
Loading

--jobs counts per directory, so --dirs a,b,c -j 4 is up to 12 agents at once. A branch that will not merge is handed to an agent, which resolves it in a scratch checkout; what it cannot resolve stays on its branch for you (--resolve-conflicts=false skips the attempt). Everything lands on the branch you are already on; --merge-into BRANCH is what carries a loop's committed work anywhere else. The details, plus the run journal and hot reload, are in docs/RUNS.md.

Dashboard

--tui renders the screen at the top of this page: header, activity chart, one lane per agent, the full review grid, and the feed. gauntlet pick composes a run before it starts, and shows the command it is building while you do:

The gauntlet launcher: review sets with descriptions, the installed agents, concurrency against the CPU count, and the composed command line

KeyAction
q, escquit (stops the run, killing what is running)
sfinish: no new reviews, then commit, publish or merge as configured, and exit
spacepause the feed; output keeps collecting and reviews keep running
j / kscroll the feed
fnarrow the feed to results, errors, and diffs, and back
g / Gjump to oldest / newest
?help, and the list of unmerged branches

Review glyphs: · pending, running, ok, fail, timeout, merge conflict, skipped, interrupted.

Trust model

Agents run with their permission prompts disabled. That is the point of the tool, and it is why the containment rules exist: prompts are read with O_NOFOLLOW and size-capped, agent binaries resolve on a PATH without cwd-relative entries, git runs with core.fsmonitor, core.hooksPath, diff.external, and the pager forced empty, untrusted text is stripped of control and bidi characters before display, and a flock on .gauntlet.lock keeps two runs out of one directory.

Reviewing a repository you do not trust still means running it in a container. The boundaries are drawn one by one in docs/THREAT_MODEL.md.

Token counts

Counts come from what the agent prints, its machine-readable mode (--stream), its own session transcript, and, for the two agents that keep databases instead (crush, opencode), those. All of it is on in a default build; make build TAGS=notoktop drops transcript reading and make build TAGS= drops the database driver too. gauntlet doctor says which build you have. Per-agent coverage, and the public reading API, are in docs/TOKEN_TELEMETRY.md.

Documentation

PageWhat is in it
docs/CLI.mdevery flag, environment variable, and exit code; defining your own agent
docs/RUNS.mdworktree isolation and merging, the run journal, updating and hot reload
docs/DESIGN.mdarchitecture, concurrency model, and what each decision costs
docs/TOKEN_TELEMETRY.mdwhere token counts come from, per agent, and the public reading API
docs/THREAT_MODEL.mdtrust boundaries, what is validated where, and what is out of scope
docs/IDEAS.mdthings deliberately not built yet, and why
CONTRIBUTING.mdbuilding, testing, and the checks a pull request runs

License

AGPL-3.0-or-later.

About

Run your codebase through the gauntlet: an auto-fix review loop of 50 specialized review prompts dispatched to whatever AI coding agents you have installed.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages