Skip to content

About

failproofai policy pack — stop agents burning wall clock on sleeps that watch nothing

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

wait-guard

Policies for agents that sit there sleeping instead of checking anything.

failproofai policies add xevrion/wait-guard

An agent that runs sleep 300; echo timer has spent five minutes and learned one thing: that five minutes passed. Nothing was polled, no condition was tested, and if whatever it was waiting for finished in twenty seconds it waits out the other two hundred and eighty anyway.

I found this in my own failproofai audit and went looking for how bad it was. Across 538 commands containing a sleep, the unobserved ones came to about four hours of blocked wall clock, and the worst run was sixteen consecutive timers in a single session.

Waiting

policy default
warn-unobserved-wait — a long sleep, or a counted loop, that watches nothing on
warn-unbounded-wait-loop — while/until around a sleep with no attempt limit on

Both are instruct rather than deny. Sometimes a fixed sleep really is what you want (deliberate rate limiting), and blocking the call leaves the agent with no way forward. The instruction names the alternative instead: a bounded retry that polls the real condition, or timeout around the work itself.

Why it is not just a duration check

The thing that decides whether a wait is wasteful is not how long it is, it is whether anything is being observed. These are all fine and none of them fire:

npm run dev & sleep 3; curl -s localhost:3000      # settle, then check
sleep 60; curl -s localhost:3000/health            # long, but it polls
sleep 120; cat build.log                           # long, but it reads
for i in $(seq 1 30); do curl -s x && break; sleep 1; done   # bounded retry

These do:

sleep 300; echo timer                              # nothing observed
for i in $(seq 1 10); do sleep 150; echo "tick $i"; done     # counts, observes nothing
until grep -q ready log.txt; do sleep 15; done     # no attempt limit, can hang forever

That middle one is worth calling out. A counted loop is bounded, so it always terminates, but bounding a wait is not the same as watching something: seventeen of those in my history cost 267 minutes between them, which is more than the plain timers did. It is a twenty-five minute sleep wearing a for loop.

The 30s threshold comes from the same corpus. Sleep durations there run p50=4s and p75=22s, so 30s sits above three quarters of ordinary shell usage. Below it you are almost always looking at settle-time after starting a process, and a policy that fires on sleep 2 gets switched off the same day.

Testing

31 cases through failproofai's runner, weighted toward the things that must stay silent, including one replayed as Codex:

node "$SKILL_DIR/scripts/test-policy.mjs" --policy waiting-policies.mjs --cases cases.json

backtest.mjs replays both policies over local Claude Code history. Against mine: 538 commands containing a sleep, 116 instructed (21.6%), 422 left alone, 262 minutes of wall clock inside the ones it caught. Reading the longest sleeps it deliberately ignored, every one of them runs a command or reads a file afterward, which is the line the policy is drawing.

About

failproofai policy pack — stop agents burning wall clock on sleeps that watch nothing

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages