Persistent Monitor tasks are reaped on idle/suspend boundaries (~every 30-90 min)
Summary
Persistent Monitor tasks (created with persistent: true) are killed by the harness on idle/suspend boundaries, roughly every 30-90 minutes of user inactivity. The agent receives a <task-notification> with status: killed, but the monitor's bash process is already terminated — requiring a full relaunch.
This is distinct from token expiry or process crashes. The monitor's own output shows no errors before death — no 401s, no stderr, no exit. The harness externally kills the task.
Reproduction
- Start a persistent Monitor with a long-poll loop (e.g. a
curlSSE stream withtimeout_ms=25000in awhile true):
Monitor({
description: "inbox stream",
persistent: true,
timeout_ms: 3600000,
command: 'while true; do curl -sSN -G ... ; done'
})
- Go idle for 30-90 minutes (no user messages).
- The harness kills the Monitor and delivers
<task-notification> status: killed. - The agent must manually relaunch.
Observed frequency
In a single ~3-hour session, the same monitor was reaped 4 times while its auth token was still valid (confirmed by checking the output file — no 401s or errors before death). Across 10+ sessions on the same machine over a week, every session longer than ~40 minutes experiences at least one reap.
Impact
This is the primary reliability issue for agents that use persistent Monitors as a push channel (e.g. long-poll inbox streams for agent-to-agent messaging). Each reap creates a deaf window — the agent misses messages until the next user interaction triggers a restart. The agent-side mitigation is a UserPromptSubmit hook that checks process liveness and injects a restart reminder, but the idle gap between reap and next prompt is inherently unguarded.
Expected behavior
A persistent: true Monitor should survive idle periods and only terminate when:
- The agent calls
TaskStop - The session ends
- The monitor process itself exits
Environment
- macOS (Apple Silicon)
- Claude Code (latest as of 2026-06-06)
- Monitor command: bash
while trueloop withcurllong-poll
Notes
- Token-expiry deaths (401 chains → self-terminate) are a separate, expected mechanism and are handled correctly by the orphan guard in the bash script.
- The harness reap produces
status: killed(notstatus: completed), which is how the agent distinguishes it from a normal process exit. persistent: true+timeout_ms: 3600000are both set. The reap happens well within the timeout window.
🤖 Generated with Claude Code
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗