stallguard
Your coding agent says "done". Did it do anything? stallguard is a drop-in wrapper that streams agent steps, kills stalls and retry-loops, and flags fake-GOAL finishes — with a shareable trace for every run.
pipx install stallguard
stallguard run -- npx claude-code "fix the login bug"
# [stallguard] status=ok exit=0 duration=42.1s trace=traces/stallguard-....html
No code changes. Just prefix your agent command with stallguard run --.
The problem
AI coding agents fail in three boring, expensive ways:
- Stalls — no output for 20 minutes while your CI minute-burn ticks.
- Loops — the same tool call retried 500 times (
retrying with same args...). - Fake-GOALs — prints
DONE ✅whilegit diffis empty.
Logs scroll by, nobody watches, green checkmarks lie. stallguard turns each run
into a verdict: ok, error, stalled, looped, or fake-goal — enforced
by exit code, so CI can act on it.
30-second quickstart
# any agent, any command — just prefix it
stallguard run -- python -u your_agent.py
stallguard run --stall-timeout 90 --require-diff -- ./run.sh
# inspect a run later
stallguard view traces/stallguard-*.jsonl
# open traces/stallguard-*.html in a browser for the full step-by-step trace
What it catches
| flag | default | catches | exit |
|---|---|---|---|
--stall-timeout N |
120 | no output for N seconds → SIGKILL |
124 |
--repeat-limit K |
15 | K identical lines in a row → SIGKILL |
125 |
--require-diff |
off | exit 0 + "done" text but empty git diff |
3 |
--expect-file PATH |
— | required file missing after run (repeatable) | 3 |
--trace-dir DIR |
traces |
JSONL + summary JSON + self-contained HTML per run | — |
0 = ok, 1 = agent errored, 3 = fake-goal, 124 = stalled, 125 = looped.
Why not just timeout?
timeout 300 ./agent kills a hung run but tells you nothing: was it a stall, a
loop, or nearly done? And it can't catch the worst case — the agent that
finishes fast, prints success, and changed zero files. stallguard records
timestamped evidence for every run and verifies the goal actually happened.
CI: fail on fake success
- name: Run agent under stallguard
run: stallguard run --stall-timeout 300 --require-diff -- ./run-agent.sh
- name: Upload traces
uses: actions/upload-artifact@v4
with:
name: stallguard-traces
path: traces/
Or use the bundled composite action (see action.yml). Every failed run links its HTML trace — debugging starts from evidence, not from re-running and hoping.
Works with any agent
stallguard sees stdout, not APIs, so it works with everything:
Claude Code, Codex CLI, OpenHands, AutoGPT, your own Python script — if it
prints steps, stallguard can supervise it. Zero dependencies, stdlib only.
Dev
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
python -m stallguard run -- python -u examples/ok.py
python -m stallguard run --stall-timeout 1 -- python -u examples/hang.py; echo $?
python -m stallguard run --repeat-limit 3 -- python -u examples/loop.py; echo $?
python -m unittest discover -s tests
Roadmap
- Token/step budgets (
--max-lines,--max-minutes) - Semantic loop detection (same tool call, different formatting)
- Live web dashboard for parallel agent fleets
- PyPI release + Homebrew formula
PRs welcome — especially real traces of agents failing in new and creative ways.
MIT. If stallguard caught your agent slacking, leave a ⭐.
Metadata
Release files for stallguard 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| stallguard-0.1.0.tar.gz | 11.5 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| stallguard-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.3 kB
Release files / stallguard-0.1.0.tar.gz
| Download URL | stallguard-0.1.0.tar.gz |
|---|---|
| Size | 11.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d54f5a7f7c41d6b4b8f4ebbb123d215868532bfbd47661cfc72e86ec222d1e2f
|
|
BLAKE2b-256 checksum How to use checksums |
232812b01fc2385bf74a11806409bb35f7e04a72d6fd81a36d3ef6059de2f53d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency logRelease files / stallguard-0.1.0-py3-none-any.whl
| Download URL | stallguard-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cbb9d49f3dd0d9f60548bdea048ac006bc8ada7adffbe50986bd8936d4f4af08
|
|
BLAKE2b-256 checksum How to use checksums |
52b96cdf79785a05f76a2061f3a5d48d101d879b1ad24d65cf2347da809790ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency logSecurity for stallguard 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for stallguard-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.