Why Test First
An agent that sends email, pushes commits, posts to Slack, or deletes rows is hard to debug by running it. The first real run is also the first irreversible one, and reading the agent file only tells you what you wrote, not what the model does with it.agentuse test closes that gap. It runs the agent all the way through, on its
own model, with its own instructions and its own tools, but fabricates the side
effects instead of performing them. You get a full session log of a complete run
and nothing outside the project changed.
The One Command
--quiet, --debug, --no-tty,
--compact, --timeout, -C, --env-file, -m/--model, --json) plus three
of its own, covered below.
A Mock Model Is Required
Mock mode fires an LLM call for every tool result, so it needs a model it can reach:AGENTUSE_MOCK_MODEL in your shell,
~/.agentuse/.env, or the env block of
~/.agentuse/config.json.
The flag wins over all of them.
Scope Adapts to the Agent
How much gets faked depends on what the agent declares.- An agent with
tools.bash.gatedpatterns gets gated scope: only the bash commands matching those patterns, the irreversible subset you already fenced off, are fabricated. Everything else, reads, non-gated bash, MCP calls, skills, runs for real, so the agent grounds itself in genuine project state. - Any other agent gets full mock: every tool result is fabricated.
--scope gated|all, or set AGENTUSE_MOCK_SCOPE once.
tools.bash.gated patterns run under gated scope gets a
warning: nothing is mocked, everything runs real, with gates still auto-resolved.
Approval Gates, Unattended
A test run must finish without a human, so the gate resolves deterministically instead of suspending. No model plays the reviewer.
The comment applies to the first gate only; the re-gate that follows is
approved, so the run exercises the revision path and still finishes. Repeating
it on every gate would loop an obedient agent until it gave up.
What Is Isolated
- Stores. Every store, including the reserved
metricsstore behind the dashboards, is re-rooted at<project-root>/.agentuse/store-mock/<timestamp>-<pid>/. Reads are seeded by copying the real store, so the agent still sees realistic data; writes land in the scratch copy, which is kept for inspection and swept after 7 days. See the store guide. - Operational views. Mock sessions are excluded by default from the serve home dashboard, agent health, and the sessions list, and they never fire push notifications, so a test loop does not buzz anyone’s phone or distort the picture of production.
The Closed Loop
Testing is meant to be iterated, not performed once:- Edit the agent file.
agentuse test my-agent.agentuse.- Read the session log: what the agent actually did, in order, with what arguments.
- Repeat.
only mock (API: ?mock=only). A mock session’s detail page is always
reachable by id whatever the filter says, and the CLI marks these runs with a
trailing · mock (hide them with agentuse sessions list --no-mock).
For a tools.bash.gated flow, the log shows the whole gate sequence: the
await_human call with its changes[], the deterministic decision, and the
fabricated command result. In the effect WAL, a fabricated gated command has a
lease-approved entry but no bash-spawn entry, which is the audit signal
that it never executed.
What a Passing Test Does and Doesn’t Prove
- Mock outputs are non-deterministic. They are LLM-generated, so two runs can hand the agent different plausible results. That is useful for probing how the agent copes with variation, and useless as a regression assertion.
- Mocked approval decisions are deterministic. The branch you asked for is the branch you get, every time.
- MCP servers still connect at startup for tool discovery, but no tool executes and nothing mutates.
- Gate enforcement is still real. Mock mode does not relax the permission model: a gated command the agent tries to run without a lease is still denied, exactly as in production.
Lower-Level Plumbing
agentuse test is the front door. The same machinery is exposed on run for
scripts and unusual cases:
run --mock keeps the approval gate real: await_human still
suspends, which is useful when you specifically want to verify the agent pauses.
Add --mock-approval for the unattended behaviour agentuse test defaults to.
See CLI Commands for the full flag
reference and Environment Variables
for the AGENTUSE_MOCK_* equivalents.
Related
Approval Gates
Gate configuration, reviewer flows, and lease enforcement
Session Logs
Reading what a run actually did
Store
How mock runs isolate persistent state
Creating Agents
Writing the agent you are about to test