Skip to main content
When your agent finishes editing code, IronBee runs verification cycles to confirm the change actually works before the task can complete. ironbee install walks you through three setup choices in this order — and each section below shows that install step first, then the command to change it later:
  1. Mode — enforce, assist, or monitoring-only (and, for enforce, how strict to be and whether a failing verdict blocks or just reports).
  2. Platforms — which runtime cycles gate a change (browser, node, python, backend, android, terminal).
  3. Project checks — deterministic lint / test / typecheck commands to run first.
The rest of the page covers how the verifier runs, verify-vs-fix, N/A verdicts, and custom scenarios.

Verification modes

IronBee runs in one of three modes, set by two switches: the master toggle (verification enable / disable) and the automatic-enforcement sub-toggle (verification auto enable / disable). The default is assist — the verifier is installed but never blocks completion.
You normally pick the mode while you install — the arrow-key pickers shown in this section are exactly what ironbee install presents (mode, then, for enforce, strictness). Pass --mode enforce|assist|monitor to skip the prompt, or use the verification commands below to switch afterward.

Assist mode (default)

The machinery is installed the /ironbee-verify command, the verifier sub-agent, the devtools MCP server, and permissions so the agent (or you) can verify manually, but nothing is enforced: no verify gate blocks completion, the pre-edit hooks run non-blocking, and the always-on skill/rule are omitted. This is what a fresh install resolves to. Verification-mode picker with the cursor on assist, described as tools installed but not enforced Assist keeps verification available but never required — the agent can verify on demand (and every manual cycle is recorded to the Collector) without a gate that blocks task completion. Assist is also manual-trigger-only: the installed commands are marked user-only (the model can’t auto-invoke them, and their descriptions don’t cost context tokens) and the verifier/scenario sub-agents carry a non-proactive stance, so nothing fires unless you ask — see Claude Code → Assist mode: commands are user-only. To switch to it later:

Enforce mode

The agent must pass every active cycle before it can mark a task complete. The blocking verify gate, the always-on skill and rule, the /ironbee-verify command, the verifier sub-agent, and the devtools MCP server are all installed. Verification-mode picker with the cursor on auto verify (enforce), described as block task completion until changes are verified Enforce is opt-in — turn on the automatic-enforcement sub-toggle:
ironbee verification enable only flips the master toggle; the mode it resolves to still depends on auto (assist unless you’ve also run verification auto enable).

Strict mode

Enforce has two follow-up choices at install — how strict the gate is about N/A verdicts, and whether a failing verdict blocks or just reports (assist and monitoring skip both — there’s no gate to enforce). The first is how strict the gate is about N/A verdicts — the verifier’s way of declaring a change has no runtime surface to exercise (a type-only refactor, a docs tweak). When you pick enforce, install shows its picker right away. Non-strict (default) lets the agent skip changes with nothing to exercise — refactors, type-only edits, docs: Picker titled 'How strict should verification be?' with the cursor on non-strict Strict always makes the agent actually exercise the change — no cycle can be skipped: Picker titled 'How strict should verification be?' with the cursor on strict To set it later (rather than at install):
With strict on, a verdict that tries to mark a cycle not-applicable is blocked, and the agent has to produce the cycle’s required tools. Strict only matters in enforce mode (in assist and monitoring-only there’s no gate to enforce it). It’s read live by the gate, so it takes effect on the next session without re-rendering artifacts. Strict maps to the verification.strict config key and accepts the usual -g/--global and --local target flags. For how N/A verdicts work in the first place, see N/A verdicts below.

Fix enforcement (block on a fail, or just report it)

Enforce mode actually enforces two things: that the agent verifies at all (it can’t edit code and finish without running the cycle), and that the outcome is a pass (a failing verdict blocks completion until the agent fixes the issues, up to maxRetries). The second follow-up choice — fix enforcement — decouples them. Install shows it as a picker right after strictness, with two options: fix-enforce (default) and report-only. With fix enforcement off (report-only), the agent still must run every active cycle and submit a real verdict — but a fail verdict no longer loops it. The gate lets the turn end, records the verdict as reported, not enforced, and instructs the agent to state the unresolved issues plainly rather than claim the change works. Retries aren’t consumed. Think of it as a third point between full enforce (auto-verify + fix until pass) and assist (nothing enforced): verification is mandatory, fixing is your call.
It maps to the verification.fix config key (default true), accepts the usual -g/--global and --local target flags, is read live by the gate, and only matters in enforce mode. At install, pass --fix / --no-fix with --mode enforce to skip the picker.
The manual /ironbee-verify fix token escalates a single run to fix-until-pass regardless of this setting — the config is the sticky default, and the token only ever escalates (it never downgrades an enforced fix loop).

Monitoring-only mode

The agent is never blocked and none of the verification machinery is installed no enforcement hook, skill, rule, command, verifier sub-agent, or MCP server but session lifecycle, tool calls, and timing still flow to the IronBee Collector. Use this when you want the analytics without changing how the agent works. Verification-mode picker with the cursor on monitor only, described as no enforcement, only track sessions / activity / tools for analytics Switch to it (or back) anytime:
auto only matters while verification is enabled. If verification.enable is false (monitoring-only), the mode is monitoring regardless of auto, and ironbee verification auto … warns that it has no effect until you re-enable verification.
The master and auto toggles accept the same target flags as everything else (-g/--global, --local; default is the project config) and warn when a higher-priority layer is shadowing the layer you wrote to.
Restart your editor or agent session after toggling; the change takes effect on the next session.

Verification platforms

Each platform is a separate cycle with its own tools. IronBee installs all six, but only some are active by default:
Every enabled cycle’s tools are served by a single ironbee-devtools MCP server (a “compose” server that multiplexes them under their fixed per-platform prefixes). The completion gate still routes each tool call to its cycle by that prefix — so browser-devtools, node-devtools, etc. remain the logical cycle names even though there’s just one physical server. Enabling or disabling a cycle changes which prefixes that one server exposes.
The browser cycle covers most frontend work out of the box. The Node, Python, backend, Android, and terminal cycles stay off until you opt in, so those changes aren’t gated until you ask for it.

Choosing platforms at install

You pick which platforms to verify while you install, from an arrow-key multi-select — space toggles a cycle, a toggles all, Enter confirms. (You can also flip any cycle afterward with the enable / disable commands below.) The picker also offers an s “suggest” key. Press it and IronBee analyzes your project with your client’s model — Claude Code, Codex, and Cursor can all run it (when several are selected it uses the highest-priority one, claude > codex > cursor): Platform multi-select with the 's suggest (claude)' key highlighted and 'Analysing project with claude…' shown while IronBee inspects the project …then replaces your selection with the cycles it recommends — still editable before you press Enter: Platform multi-select after suggestion with browser, node, and backend checked as the recommended set
Suggestion is opt-in — nothing runs until you press s. It runs a one-shot headless prompt through your client (claude -p, codex exec, or cursor-agent -p), so the client must be signed in. If the analysis is cancelled (Esc), times out, or fails, your current selection is kept.
Here’s each platform, and what its row looks like in that picker. Browser (on by default) — a real browser: navigate pages, take screenshots, and check the console and accessibility. It covers most frontend work with no setup, and is the only cycle enabled out of the box. Platform multi-select with browser checked and the cursor on the browser row Node — Node.js runtime (tracepoints, logpoints, exceptions, variables, logs) plus outbound HTTP capture (axios, got, node-fetch, fetch/undici, http2, gRPC): Platform multi-select with node checked and the cursor on the node row Python — a running Python process over debugpy (the Debug Adapter Protocol): tracepoints, logpoints, exceptions, watches, stdout/stderr logs, an all-thread thread dump (py-spy-style, for deadlock / GIL / hang diagnosis), plus outbound HTTP capture (urllib/http.client, requests, httpx, aiohttp). It attaches to an already-running process without blocking it — an already-listening debugpy at host:port (default 127.0.0.1:5678), a PID (POSIX), a process name, or a docker container — and never modifies the target’s source. Platform multi-select with python checked and the cursor on the python row
The Python cycle needs debugpy installed in the target’s Python environment (pip install debugpy). Unlike Node’s built-in inspector, debugpy is a third-party package, so IronBee can’t attach without it.
Backend — HTTP, gRPC, GraphQL, WebSocket, DB, and logs: Platform multi-select with backend checked and the cursor on the backend row Android — device/emulator drive, taps, swipes, screenshots, UI snapshots, Logcat, HTTP capture: Platform multi-select with android checked and the cursor on the android row Terminal — CLI / REPL / TUI driving over a PTY: spawn a program, send keystrokes, capture output and exit codes. There are no screenshots here, so terminal is not a recording cycle. Platform multi-select with terminal checked and the cursor on the terminal row

Enable or disable a platform

To change platforms after install (rather than re-running it), each has an enable / disable subcommand:
Re-enabling is the inverse: ironbee browser enable, ironbee node disable, and so on. Changes are written to the project config and your client’s hooks/tools are re-rendered automatically. By default these write to the project config (<project>/.ironbee/config.json). To target a different layer:
Enabling a platform applies sensible built-in file patterns automatically; you don’t have to list which files to verify. To fine-tune which files trigger each cycle (custom verify patterns, ignored paths, devtools settings), see Configuration.

Project checks run first (lint, tests, types)

Before any devtools verification runs, IronBee can run your own deterministic project checks — linters, type-checkers, unit tests, a build — as the first step of every verification cycle. In enforce mode, a required check that fails (or never ran) blocks completion, so the agent has to fix it and re-run before it can finish. There are two ways to set them up — let IronBee suggest them (at install, or on demand) or write them by hand. Both land in the same verification.checks config key.

Let IronBee suggest your checks

Beta — the suggested commands are a starting point to review, not a finished config.
IronBee can analyze your project with your AI client and propose concrete checks, then let you approve a subset before it writes them. Like the mode and platform steps, this is offered at install first — the last step of ironbee install, behind a yes/no gate (default No), after the mode and platform pickers. Accept the gate and IronBee analyzes the project with the client’s model (Esc cancels): Beta yes/no gate accepted, with 'Analysing project with claude… (Esc to cancel)' shown while IronBee inspects the project for check commands then hands you a per-check approval list, each check tagged required or advisory (from its kind — typecheck and test default to required). Per row, r flips required ⇄ advisory and c flips conclusive (which also forces required): Per-check approval multi-select showing 'lint — npm run lint · advisory' and 'test — npm test · required' with checkboxes Optionally, IronBee then validates your picks by running each once (a [y/N] prompt at install, or the --validate flag on the command) — it shows pass/fail and re-presents the list so you can drop any that broke before it writes: Validate step showing [PASS] lint and [PASS] test, then a confirm-to-save multi-select with each check marked PASS The model reads your package.json scripts, Makefile, justfile, pyproject.toml, Cargo.toml, go.mod, Gradle, turbo/nx, and the like, and returns the concrete command for each kind — preferring your project’s own existing scripts/targets and never modifying any file. This is “discovery LLM, deterministic runtime” — the model runs only at install (or the command below), never during a verification cycle; the gate always just re-runs the committed commands. The same flow, standalone. Run it anytime afterward — to add checks to a project you already set up, or re-suggest after big changes — with ironbee checks suggest:
Re-running is additive and non-destructive — a fresh suggestion is unioned with your existing checks (your hand-tuned entries win on a name clash), so you can re-suggest anytime (or re-run install) without losing customizations.
Resolving the suggestion runs a one-shot headless prompt through your client — Claude Code, Codex, or Cursor (cursor-agent) — so the client must be installed and signed in. With more than one available it uses the highest priority (claude > codex > cursor). If none can run headless, write verification.checks by hand instead.

Write the checks by hand

Or set verification.checks directly — a JSON array where each entry is one command:
Each entry takes:

How a check gates completion

The verifier runs the checks via ironbee hook run-checks at the start of the cycle, and IronBee trusts the recorded exit codes, not the agent’s word for it. In enforce mode, a required check that exits non-zero or times out blocks completion — the agent has to fix it and re-run — and a required check that never ran blocks too, so the agent can’t quietly skip it. Non-required checks are recorded but don’t gate. A failed check counts toward maxRetries like any other block.
Check results stay local to your machine (recorded under .ironbee/, not sent to the Collector), and verification.checks is read live — editing it takes effect on the next session without re-rendering artifacts. In assist and monitoring-only mode there’s no gate, so the checks run during a manual /ironbee-verify but never block.

Conclusive checks (let a check decide the cycle)

By default a check is a gate — it can block completion, but the agent still has to run the devtools verification (screenshots, probes, HTTP calls) to actually pass. A check marked conclusive: true is stronger: it becomes the arbiter of the cycle, so its exit code alone can conclude verification — no devtools step needed. Use it when a deterministic command (a full end-to-end suite, an integration test) is a trustworthy stand-in for driving the app by hand. conclusive implies required, and there are two outcomes:
  • All conclusive checks passironbee hook run-checks auto-submits the pass verdict and closes the cycle. The devtools verification is skipped entirely — the recorded exit codes are the evidence, so this is strict-compatible (a machine result, not an agent claim). The agent just reports and stops.
  • A conclusive check fails → a deferred fail: instead of stopping at the red command, the verifier turns to the devtools tools to diagnose the named failure, then submits a findings-rich fail verdict. IronBee auto-prepends a conclusive check "<name>" failed (exit N) issue and refuses a pass or N/A for that cycle until a fresh cycle re-runs the checks green.
Because it can replace the devtools cycle, conclusive is hand-set only — the suggester never marks a check conclusive. Set it in the config by hand, or flip it in the approval pickers (at install, ironbee checks suggest, or the TUI) with the per-row c key (c toggles conclusive — and forces required; r toggles required/advisory). Give a long conclusive suite an explicit timeoutMs (checks default to 120s).
Conclusive checks only conclude the cycle in enforce mode (assist and monitoring-only never gate). A deferred fail counts toward maxRetries and releases at the cap with the failure reported, like any other block.

How verification runs (the verifier sub-agent)

On Claude Code and Codex, IronBee doesn’t let the main agent drive the devtools tools directly. Instead it installs a dedicated ironbee-verifier sub-agent that owns those tools (plus read-only Read / Grep / Glob so it can understand the change it’s verifying — but no edit tools), and the main agent delegates the verification cycle to it — automatically at the completion gate, or manually via /ironbee-verify. The verifier runs every active cycle, submits the verdict, and hands back a short summary. The point is to keep the heavy devtools output (DOM snapshots, console logs, screenshots) inside the sub-agent’s context instead of the main conversation. The sub-agent shares the session, so its events still flow to the Collector and its token/tool usage is folded into the session analytics.
Cursor has no verifier sub-agent — its main agent runs the verification itself, because Cursor’s sub-agents can’t share the verification session.

Picking the verifier model

By default the verifier runs on the same model as the main conversation. Pin it to a specific model — for example to verify on something cheaper or faster than your main coding model — with ironbee verification model:
--client is optional when exactly one verifier-capable client is installed and required when there are two (Claude + Codex), since one model name rarely works for both. To go back to inheriting the session model:
The setting accepts the usual -g/--global and --local target flags and re-renders the verifier artifact when it changes. It maps to the verification.model config key. Cursor is a no-op.
On Codex the verifier needs some resolvable model. It inherits your ~/.codex/config.toml model; if you haven’t set one there, pin verification.model so the sub-agent can spawn.

Verify-only vs. fix mode

When you trigger /ironbee-verify by hand (or $ironbee-verify on Codex), an optional leading word picks what happens on a fail verdict:
In enforce mode the choice is enforced mechanically, not just suggested: a fix run won’t let the agent stop on a fail without addressing it, while a verify-only run is allowed to report a fail and end the turn. A custom scenario can follow the mode word. The fix token escalates just that one run — the sticky default for what a failing verdict does at the gate is the fix enforcement setting.
This only changes the manual command’s behavior. The automatic completion gate is unaffected — when the agent edits code and tries to finish, it must still pass every active cycle. In assist mode nothing blocks the agent, so fix there is advisory; in monitoring-only mode the command isn’t installed.

When a change has nothing to verify (N/A verdicts)

Some edits match a cycle’s file patterns but have no runtime surface to exercise — a type-only change, a behavior-neutral refactor, a config or docs tweak. Rather than fake screenshots or HTTP calls to satisfy the gate, the verifier can submit a not-applicable (N/A) verdict, declaring there’s nothing to verify and explaining why:
  • Global N/A — no active cycle applies to the change. The verifier reports status: not_applicable with a short reason, and the gate lets the task complete without any tool evidence.
  • Per-platform N/A — some cycles apply and some don’t. The verifier verifies the ones that do (a normal pass/fail) and exempts the rest by name, with a reason for each exemption.
N/A verdicts are recorded and observable — they show up in the session’s verdict like any pass or fail, with the exempted cycles and reasons attached, so you can see why a change wasn’t exercised. To guard against abuse, the gate refuses an N/A after a previous fail on the same change (an agent can’t downgrade a real failure to “not applicable” to escape the gate). To refuse N/A entirely — demanding real tool evidence for every active cycle — turn on strict mode (the enforce follow-up choice covered under Verification modes). It’s picked at install right after enforce, or toggled later with ironbee verification strict enable.
N/A is off-limits after a fail and under strict mode — it’s an escape hatch for changes that genuinely have no runtime behavior, not a way around a real verification.

Custom verification scenarios

By default the agent verifies the areas affected by what changed. To tell it exactly what to exercise, pass a custom scenario to /ironbee-verify (or $ironbee-verify on Codex) — either inline or as a path to a file:
When a scenario is supplied it’s authoritative: it replaces the default “exercise the changed pages” guidance, and the verifier drives precisely the flows, states, and endpoints it names. A scenario file is read at run time (any location, any format), so you can keep reusable test scripts in your repo and point at them. The completion gate is unchanged — every active cycle’s required tools still have to run for a pass. To capture a flow once and replay it by name instead of re-typing it every time, save it as a scenario and run it with /ironbee-run-scenario. The old scenario:<name> reference is not accepted by /ironbee-verify anymore — the command will point you at /ironbee-run-scenario instead.

What’s next?

Saved scenarios

Capture reusable verification flows and replay them by name.

Verification context

Give the agent area-specific instructions with .ironbee/VERIFICATION.md files.

Configuration

Fine-tune which files trigger each cycle, retry limits, and more.

Inspecting sessions

Check a session’s verdict and debug why it passes or fails.