[FEATURE] Long Monitor watches > 30-minutes without a model turn to re-arm
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Since 2.1.271, every Monitor watch has a deadline of at most 30 minutes, and the no-timeout persistent option is gone. When a watch expires, Claude gets a notice and has to re-arm it, which is a full model turn.
That's fine for short waits. But I use Monitor to park work that waits on other people: a PR watcher that wakes Claude only when CI fails, a reviewer comments, or the PR merges. Those waits last hours, often overnight or across a weekend. While nothing happens, the session still wakes every 30 minutes, re-reads its whole context, re-arms the same command and goes back to sleep.
Measured from 30 days of my own local transcripts (Opus, 1M context):
- 1,630 turns were started by Monitor notifications.
- 560 were expiry notices, and another 362 were the re-armed watch announcing itself. Nearly all of them did nothing else.
- Parked sessions average ~450k tokens of context, and each expiry re-reads all of it.
- That's ~48 wasted turns a day per watched PR: about $19/day at API list prices, and ~27% of everything Monitor wakes cost me.
- On weekends, 100% of my usage was idle watchers.
Proposed Solution
Let a watch continue past the deadline without a model turn, as long as the command hasn't changed. For example, an opt-in flag:
Monitor({
command: "scripts/watch-pr.sh --pr 123",
description: "CI and review on PR 123",
timeout_ms: 1800000,
rearm: "auto" // at the deadline the harness restarts the same command; no notification
})
How it would behave:
- At the deadline, the harness quietly restarts the same command instead of notifying Claude.
- Claude is only woken by real output from the script, by the script exiting on its own, or by
TaskStop. - If the restart fails, or the watch is reaped on idle/suspend, Claude gets a "watch died" notification, so failures stay visible.
- An overall cap (for example 24 hours, or until the session ends) still bounds forgotten watches.
Alternative Solutions
- Claude re-arms itself every 30 minutes (what I do now). It works, but every re-arm is a full-context model turn.
- A background Bash watcher that exits on the first actionable event. Since 2.1.288 this avoids the re-arms in terminal sessions. But that limit has changed twice in a week (2.1.285, then 2.1.288). It's also not documented whether a subagent inside an interactive session counts as attended. And it delivers only one event before it has to be restarted.
ScheduleWakeuppolling. Worse: every tick is a full-context turn, and events arrive late.- Bring back
persistent: true. This would also work. I understand it had silent-reaping problems (#63023, #65968), which the "watch died" notification above would help fix.
Priority
Medium - Would be very helpful
Feature Category
Other
Use Case Example
- Claude opens a PR, gets CI and automated review green, and parks it to wait for a human reviewer.
- It arms a Monitor running a PR watcher script. The script prints a line only when something actionable happens: CI fails, a review comment arrives, or the PR merges.
- The reviewer replies the next morning, 16 hours later.
- Today, that costs 32 expiry turns, each re-reading ~450k tokens, before the one wake that matters.
- With auto re-arm, it costs one turn: when the reviewer replies.
Additional Context
- Changelog for 2.1.271: "Changed Monitor watches to always have a deadline (at most 30 minutes; 10 in single-prompt
-pruns) and notify Claude to re-arm, replacing the no-timeoutpersistentoption". - Related: #63023 (background tasks die on pause/resume), #65968 (persistent monitors reaped on idle), #99965 (background command limit in SDK /
-phosts). - The figures come from my local
~/.claude/projectstranscripts, priced at API list rates as a proxy for subscription usage. - Claude Code 2.1.292 on macOS.