Stallguard banner
gpt4omni gpt4omni

Stallguard

Development community

Description

Drop-in wrapper that streams agent steps and kills/flags stalls, loops, and fake-GOAL finishes.

Installation

This entry records only its repository, not the path inside it, so there is no exact command to give. Open the source below and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

README

stallguard

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](pyproject.toml) [![No dependencies](https://img.shields.io/badge/deps-zero-brightgreen.svg)](stallguard/) [![CI](https://github.com/gpt4omni/stallguard/actions/workflows/test.yml/badge.svg)](https://github.com/gpt4omni/stallguard/actions/workflows/test.yml)

**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](demo.gif)

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 em