runaway: warm-wait check-ins are not empty wakes (GST-1597) (#4069)

* runaway: warm-wait check-ins are not empty wakes (GST-1597)

lib/runaway.ts counted each 240-second warm-wait check-in (docs/captain.md,
#4060) as an empty wake, so /runaway-stopper could flag a lane that follows
the rule. A turn whose only call re-issues the wait on the same operation, or
a 240-second timer, within 30 minutes of the wait that started the run is
now left out of the rate.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes

Review-Finding: p1/specialist-batched#1 reader=red-team
Review-Finding: p1/specialist-batched#2 reader=testing
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: note the warm-wait exclusion in the /runaway-stopper summary; rewrap captain.md (GST-1597 docs audit)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* runaway: keep wait input in the skill collector; 240 s timers chain only on the run's operations; status reads keep the warm window (GST-1597)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
Garry Tanandcapy-ai[bot] authored and GitHub committed 2026-11-06 13:40:49 +00:00
1 parent bd36aa0b46
commit ff65fb0c48
7 files changed
+120 -12

No files matched your search

+7 -4
View File
@@ -152,10 +152,13 @@ cheap:
operation with `duration_seconds: 240`, and on a timer wake that brings nothing new it
re-issues the same wait silently, with no message. Once a warm wait has run about 30
minutes, or past the end the lane expected, the lane stops re-issuing the timer and
sleeps on the operation or pull request watch alone. A wait expected to run longer sleeps
on its operations alone. For short lane waits this overrides "waits go on operations,
never on polling wakes" ([unattended.md](unattended.md#report-length)). The controller
never warm-waits, and a lane still sleeps while /ship runs
sleeps on the operation or pull request watch alone. `gstack-runaway scan` leaves these
check-ins out of its empty-wake rate: a turn whose only call re-waits on the same
operation, or a 240-second timer on it or on nothing, within 30 minutes of the first wait.
A status read in between counts and does not restart the 30 minutes. A wait expected to run
longer sleeps on its operations alone. For short lane waits this overrides "waits go on
operations, never on polling wakes" ([unattended.md](unattended.md#report-length)). The
controller never warm-waits, and a lane still sleeps while /ship runs
([the lane's /ship sequence](#the-lanes-ship-sequence-before-ready)).
- **Batched reads.** Independent reads (files, greps, pull request and thread state) go in
one parallel program, not one call each. Each call returns 4k characters or less; long
+1 -1
View File
@@ -1020,7 +1020,7 @@ sets the defaults that keep it from coming back.
- **Detect.** One program fetches each crew thread (`tools.thread.get`, with its transcript) to files, then
`gstack-runaway scan --dir <dir>` prints a `RUNAWAY:` line per thread and a `FLAG:` line per limit crossed:
own tokens past 500M or active past 3 days (rotate), a subagent past 100M (stop), empty wakes past 25% of the
last 40 turns, and review rounds past 2 per PR. Captains are reported, never rotated.
last 40 turns (warm-wait check-ins are left out), and review rounds past 2 per PR. Captains are reported, never rotated.
- **Stop.** A live subagent past 100M is stopped with its reason. A thread is rotated at a clean point through
a handoff file and a successor brief (`runaway-stopper/templates/`), then archived by its own Captain. A thread
mid-/ship or mid-merge gets `DEFER:` and nothing happens until that work finishes.