Skip to main content

stallguard

License: MIT Python 3.9+ No dependencies CI

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.

stallguard demo

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:

  1. Stalls — no output for 20 minutes while your CI minute-burn ticks.
  2. Loops — the same tool call retried 500 times (retrying with same args...).
  3. Fake-GOALs — prints DONE ✅ while git diff is 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 ⭐.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stallguard-0.1.0.tar.gz (11.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stallguard-0.1.0-py3-none-any.whl (10.8 kB view details)

Uploaded Python 3

File details

Details for the file stallguard-0.1.0.tar.gz.

File metadata

  • Download URL: stallguard-0.1.0.tar.gz
  • Upload date:
  • Size: 11.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for stallguard-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d54f5a7f7c41d6b4b8f4ebbb123d215868532bfbd47661cfc72e86ec222d1e2f
MD5 3863fdf1dee4e62eaaed61faa0af6737
BLAKE2b-256 232812b01fc2385bf74a11806409bb35f7e04a72d6fd81a36d3ef6059de2f53d

See more details on using hashes here.

Provenance

The following attestation bundles were made for stallguard-0.1.0.tar.gz:

Publisher: publish.yml on gpt4omni/stallguard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file stallguard-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: stallguard-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for stallguard-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cbb9d49f3dd0d9f60548bdea048ac006bc8ada7adffbe50986bd8936d4f4af08
MD5 6c4715842592d51fd8421b8048ec512e
BLAKE2b-256 52b96cdf79785a05f76a2061f3a5d48d101d879b1ad24d65cf2347da809790ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for stallguard-0.1.0-py3-none-any.whl:

Publisher: publish.yml on gpt4omni/stallguard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page