On the herdr backend, bin/fm-supervise-daemon.sh has never delivered an away-mode escalation in this home. Not "wedged once" - zero deliveries across five days and three daemon sessions.
Evidence
From state/.supervise-daemon.log, spanning 2026-08-19T23:47:41+1000 to 2026-08-24T07:39:57+0800:
| Count |
Line |
| 4721 |
inject deferred: supervisor pane busy (agent mid-turn) |
| 223 |
ERROR: away-mode escalation undelivered <N>s |
| 39 |
escalations raised (24 escalate: signal:, 15 escalate: inactive terminal outcome) |
| 0 |
successful deliveries |
Every one of the 4721 deferrals carries the same single reason. There is no second reason anywhere in the file.
First deferral: 2026-08-22T22:48:04+0800. First max-defer alarm twelve minutes later: 2026-08-22T23:00:19+0800. The last alarm before the owner returned reported 32057 seconds - almost nine hours - undelivered.
All three daemon sessions resolved the same way:
daemon starting (pid 94946); target=default:w2:p1; target_source=HERDR_ENV(HERDR_PANE_ID); backend=herdr; ...
daemon starting (pid 61810); target=default:w15:p1; target_source=HERDR_ENV(HERDR_PANE_ID); backend=herdr; ...
daemon starting (pid 74724); target=default:w15:p1; target_source=HERDR_ENV(HERDR_PANE_ID); backend=herdr; ...
Where it stops
bin/fm-supervise-daemon.sh:1140, the first of the two injection guards:
# (3) Busy-guard: never inject into an in-use supervisor pane.
if pane_is_busy "$target" "$backend"; then
log "inject deferred: supervisor pane busy (agent mid-turn)"
return 1
fi
The composer guard immediately after it is never reached, so this is not a composer-classification problem.
Per the afk skill, pane_is_busy "trusts Herdr native busy when available". The suspicion this evidence points to is that a herdr pane hosting an attached agent reports busy continuously, including while that agent sits idle at its prompt waiting for input - which is exactly and only when an injection could ever land. If so the guard can never open on this backend, and the deferral is structural rather than a race.
That is a hypothesis about the cause. The 4721/0 split is not.
Why the max-defer escape did not save it
FM_MAX_DEFER_SECS behaved as documented: it retried, failed to confirm a submit, and raised a loud alarm. But the alarm is an ERROR line in the daemon log plus a durable marker file. Both are surfaces the owner only sees after returning - which is the one moment the escalation was no longer needed. It fired 223 times into a log nobody was reading.
The design intent, stated in the skill, is that "a guard false-positive becomes a visible stall, never an unbounded silent no-op". On this backend it became an unbounded silent no-op that was scrupulously logged.
Impact as observed
Five completed pieces of work sat idle overnight awaiting the one instruction only the primary session can give. Nothing was lost - every durable record survived and all five resumed on return - but roughly nine hours of unattended capacity was spent waiting on a message that was written 39 times and sent none.
Suggested direction
- Establish whether herdr native
busy can ever report not-busy for a pane with an attached idle agent. If it cannot, that source is unusable as a delivery guard on this backend and should fall back to the rendered-signature check the tmux path uses.
- Make the max-defer escape reach a channel the absent owner actually sees. A log line and a marker file are inert by construction in away mode;
docs/wedge-alarm.md already owns an active alert channel, and this is precisely its case.
- Consider a floor on consecutive identical deferrals - 4721 in a row with one reason is not a race being waited out, and the daemon has enough information to say so.
Environment
- firstmate at
e518906 (51 commits behind origin/main at time of filing; the catch-up has not yet been applied, so a fix may already exist upstream)
- primary harness: claude; runtime backend: herdr
state/.afk present throughout each episode
On the herdr backend,
bin/fm-supervise-daemon.shhas never delivered an away-mode escalation in this home. Not "wedged once" - zero deliveries across five days and three daemon sessions.Evidence
From
state/.supervise-daemon.log, spanning2026-08-19T23:47:41+1000to2026-08-24T07:39:57+0800:inject deferred: supervisor pane busy (agent mid-turn)ERROR: away-mode escalation undelivered <N>sescalate: signal:, 15escalate: inactive terminal outcome)Every one of the 4721 deferrals carries the same single reason. There is no second reason anywhere in the file.
First deferral:
2026-08-22T22:48:04+0800. First max-defer alarm twelve minutes later:2026-08-22T23:00:19+0800. The last alarm before the owner returned reported 32057 seconds - almost nine hours - undelivered.All three daemon sessions resolved the same way:
Where it stops
bin/fm-supervise-daemon.sh:1140, the first of the two injection guards:The composer guard immediately after it is never reached, so this is not a composer-classification problem.
Per the
afkskill,pane_is_busy"trusts Herdr nativebusywhen available". The suspicion this evidence points to is that a herdr pane hosting an attached agent reports busy continuously, including while that agent sits idle at its prompt waiting for input - which is exactly and only when an injection could ever land. If so the guard can never open on this backend, and the deferral is structural rather than a race.That is a hypothesis about the cause. The 4721/0 split is not.
Why the max-defer escape did not save it
FM_MAX_DEFER_SECSbehaved as documented: it retried, failed to confirm a submit, and raised a loud alarm. But the alarm is an ERROR line in the daemon log plus a durable marker file. Both are surfaces the owner only sees after returning - which is the one moment the escalation was no longer needed. It fired 223 times into a log nobody was reading.The design intent, stated in the skill, is that "a guard false-positive becomes a visible stall, never an unbounded silent no-op". On this backend it became an unbounded silent no-op that was scrupulously logged.
Impact as observed
Five completed pieces of work sat idle overnight awaiting the one instruction only the primary session can give. Nothing was lost - every durable record survived and all five resumed on return - but roughly nine hours of unattended capacity was spent waiting on a message that was written 39 times and sent none.
Suggested direction
busycan ever report not-busy for a pane with an attached idle agent. If it cannot, that source is unusable as a delivery guard on this backend and should fall back to the rendered-signature check the tmux path uses.docs/wedge-alarm.mdalready owns an active alert channel, and this is precisely its case.Environment
e518906(51 commits behindorigin/mainat time of filing; the catch-up has not yet been applied, so a fix may already exist upstream)state/.afkpresent throughout each episode