# Anti-Busy-Wait Discipline

Cross-cutting design surface for agent-turn safety while a background process runs.
Closes the 2026-05-22 incident class (v1.5.7 Phase 59 closure — 50-minute false hang
from 100+ `echo wait` no-op tool calls while a backgrounded harness id stalled in
notification-deliver).

Authoritative rule source: `agents/gmd-executor.md` (commit `29f3ef4` iron-rules
addition; shipped as v1.5.7.1 hotfix). This doc is the single SoT; agent files cite
back here via 3-line stubs.

## The rule

When a background process is running (closure script, audit harness, build, vault
sweep), the agent's tool calls in the meantime MUST NOT be no-ops whose only purpose
is to spend a turn while waiting. Each no-op tool call burns context for zero
progress: 100 `echo wait` calls is 100 turns for 100 seconds of wait. One
`sleep 300` is 1 turn for 5 minutes. Prefer the second, always.

**Empirical seed:** the v1.5.7 Phase 59 closure incident (2026-05-22; commit
`29f3ef4` shipped as v1.5.7.1 hotfix). A backgrounded harness id stalled in
notification-deliver while the orchestrating agent emitted 100+ `echo wait` /
`echo "still waiting"` no-op tool calls between polls. Wall-clock cost: ~50
minutes of false hang plus context exhaustion. The rule below prevents the
failure class.

## Forbidden patterns

- **>=2 consecutive `echo wait*` / `echo "still waiting"` / `echo "polling"` calls.**
  Each is a no-op shell command whose only output is the literal string — zero
  progress signal, zero notification value. The string was already in the
  agent's prompt; repeating it costs a turn for nothing.
- **>=2 consecutive `date; kill -0 PID; tail -N <log>` polling chains at
  sub-minute cadence.** Liveness plus log-tail in a tight loop is a polling
  spinlock by another name. If you genuinely need to check, do it ONCE per
  >=5-min interval per Section 3.
- **Chained `sleep N` with N < 30.** Sub-30-second sleeps between tool calls
  are sub-minute polling cadence by another route. If you need to wait, wait
  meaningfully (`sleep 300`) once instead of `sleep 5` ten times.
- **ANY tool call whose only purpose is to spend a turn while waiting on a
  background process.** This is the load-bearing rule; the three above are
  empirically observed instances. New instances of the failure class are
  forbidden by this rule whether or not they match the curated regex list in
  `bin/lib/anti-busy-wait-patterns.js`.

## Allowed patterns

1. **Do non-blocking work in parallel.** While a background process runs, the
   agent has a full toolbox available. Author the next phase's plan, draft the
   milestone audit, prep release notes, run independent grep/Read against
   unrelated files. The harness wakes you on completion; in the meantime,
   make progress on something else.
2. **ONE `BashOutput` per long interval.** A single `BashOutput` check
   >=5 minutes apart is information-bearing (it reports actual stdout). The
   forbidden pattern is chaining many such checks at sub-minute cadence;
   one per long interval is fine.
3. **`sleep 300` over `echo wait` x 100.** One turn for 5 minutes of wait
   beats 100 turns for 100 seconds of wait — strictly better on context, on
   wall-clock, and on observability. Sleep meaningfully or do parallel work;
   do not poll-spam.
4. **Surface to orchestrator.** After 3 consecutive busy-waits with no
   progress (per the mechanical hook backstop at `hooks/gmd-anti-busy-wait-hook.js`
   threshold-3 warning gate), halt and emit one line:
   `Waiting on background <id>; suspect notification failure.`
   The orchestrator decides whether to wait, kill, or investigate. This is
   the escape valve; the rule is not punitive.

## Self-check + cross-references

At the end of each turn while a background process is running, ask:
**"have my last 2 tool calls done anything except poll?"** If the answer is
no, switch pattern immediately — Section 3 enumerates the alternatives.
The hook at `hooks/gmd-anti-busy-wait-hook.js` (HOOK-02, v1.5.8) is the
mechanical backstop; this doc is the rule of conduct. Two-layer defense.

**Complementary discipline:** `references/long-running-scripts.md` covers
the orthogonal concern of shell-script orchestration — how to launch a
long-running script (PID capture, log redirection), how to poll its log
(`sleep 10` plus stall detector), and what to do on stall (read the existing
log, do not re-invoke). This doc (anti-busy-wait-discipline) covers what
your TOOL CALLS may not do while you wait. The two are complementary,
not duplicative; both are mandatory reading for agents that orchestrate
shell work.

---

*Audit: `tests/audit-anti-busy-wait-citations.sh` (Phase 63 EXT-03).*
*Source material: commit `29f3ef4` (v1.5.7.1) -- `agents/gmd-executor.md:41`.*
