Operate long-running agent loops: define progress signals before launch, monitor them on a schedule, detect stalls, intervene on an escalation ladder, and shut down gracefully. Trigger when launching a background agent loop, checking whether one is still healthy, deciding whether a stuck loop should be nudged or killed, or winding a loop down on purpose.
./install.sh autonomous-loop-opsname: "autonomous_loop_ops" description: "Operate long-running agent loops: define progress signals before launch, monitor them on a schedule, detect stalls, intervene on an escalation ladder, and shut down gracefully. Trigger when launching a background agent loop, checking whether one is still healthy, deciding whether a stuck loop should be nudged or killed, or winding a loop down on purpose."
A long-running agent loop fails silently more often than it fails loudly. This skill is the operator discipline for any loop that runs minutes to days in the background: cron-style agents, worker sweeps, conversion jobs, scheduled checks. It tells you how to watch a loop so you catch stalls, how to tell a stall from normal slowness, what to try before killing anything, and how to shut down cleanly when the work is done or the run is beyond saving.
This covers live loops. If the run is already dead and you need checkpoints, classification, and resume strategies, that is post-mortem recovery, a different job.
A loop is not healthy because its process is alive. It is healthy because something is advancing. Before starting, write down:
If the job prints nothing for long stretches, make it emit a periodic timestamp or progress line. Silence you cannot measure is silence you cannot diagnose.
A background loop is not launched until its monitor is launched. Both start in the same move. The guard is a separate process that watches the progress artifact, not the loop's code:
bash
# launch the loop and capture the real pid, not a name
./the-loop.sh >> loop.log 2>&1 &
LOOP_PID=$!
# arm the guard: pid, stall threshold in seconds, artifact(s) that must move
bin/loop-watch.sh "$LOOP_PID" 1800 loop.log progress.json >> watch.log 2>&1 &
Your launch report states three things: the pid, what the guard watches, and what threshold kills the job. If you cannot say all three, the loop is unguarded.
A health check answers one question: what moved since the last check? Accept any of these as evidence:
If nothing moved, the loop is stalled however busy it looks. CPU pegged at 100% can be a tight loop going nowhere; a live process can be fully deadlocked. Report stalled and diagnose, never report healthy on liveness alone.
Name the state precisely. Active work, expected delay, stall, failure, completion, and intentional pause are six different states. A paused process and a hung one both show frozen artifacts, but only one of them may be restarted.
When the guard fires or a check finds a stall, follow the triage tree in references/stall-recovery-playbook.md. The rules that matter most:
Do not jump to the kill. Work the escalation ladder in order, and stop at the first rung that works:
kill -TERM -<pgid>, then kill -KILL -<pgid> if needed), verify by pgid that nothing survived, clear the run's lock and any partial files. Signal the group, never just the script pid: a shell blocked in a pipeline ignores signals to the script until the foreground command returns.Never restart a paused task without the owner's word. Never launch a duplicate of an uncertain job; one orphaned worker plus a fresh run writing the same destination produces bogus duplicate outputs. Never kill a loop another session started without first looking for its guard and reading its notes.
A graceful shutdown is an ordered teardown, not a signal. Work the checklist in references/graceful-shutdown-checklist.md. The shape of it: stop accepting new work, let the in-flight item finish or checkpoint, flush and checkpoint state, write a shutdown reason code, release resources and locks, verify by pid and pgid that nothing survived. After shutdown, record what happened: root cause, how long detection took, what it cost. That record is what makes the next threshold better.
Whatever happens, the logs, the guard's history, the progress artifacts, and the shutdown reason survive. Safety controls that destroy their own evidence make the next incident unknowable. A kill switch that has never been tested is an assumption, not a control: exercise the guard on a short test run before trusting it on a long one.
Every monitoring report, whether a scheduled check or a final teardown report, carries:
If you cannot fill in the evidence line, you do not have a health report yet.
timeout <duration> --kill-after=10s so one pathological input dies instead of the batch (exit code 124 means the timeout fired).execed away.renice to yield CPU; there is no safe unilateral move for disk contention, report it to the loop's owner.publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.