Context
The whole point of /work <issues> is that you fire it and walk away. But when a cycle parks, halts, or stops awaiting a human merge, the only places that say so are the Pi scrollback and a JSON file — both of which require you to already be looking.
grep -rniE 'osascript|terminal-notifier|notify-send|webhook|slack' extension/src/ returns nothing. The GitHub comment + needs-human-attention label exist only on the runHandoff path — not on a queue halt, not on awaiting-human-merge (#380), not on a driver crash.
So the realistic sequence today is: fire /work over eight issues, go to lunch, come back two hours later to find it stopped after twenty minutes on the second group. Everything needed to fix it was known at minute twenty.
What to build
A. One notification hook, configured by the operator. A single command template invoked on terminal states, e.g. PI_ENSEMBLE_NOTIFY_CMD. The driver runs it with the message on stdin (or as $1) and does not care what it is — osascript, terminal-notifier, notify-send, curl to a webhook, say. Choosing the transport is not the harness's job; reaching the human is.
B. Fire on the states that need a human, and only those:
| State |
Message must name |
parked (per issue) |
the issue, the park reason, and the human action |
| queue halted |
why continuing was pointless, and the groups not started |
awaiting-human-merge (#380) |
the PR URL |
| driver crash |
the state file path |
One notification per parked issue, not one per event. A hook that fires on every step is noise, and noise is indistinguishable from no hook at all.
C. Fail open, always. A notification failure must never affect the cycle: no throw, no retry storm, a short timeout, and the failure recorded in the trace only. The hook is an observer, and an observer that can break the thing it observes is worse than none.
D. Say what a human must do that the system cannot. The existing humanActionFor already produces this; the hook should carry it rather than inventing its own wording. "Issue #287 parked" is not actionable; "add acceptance criteria to #287" is.
Acceptance criteria
Out of scope
A hosted notification service, batching/digest logic, and notifying on non-terminal progress.
This work must ship as its own separate PR, independent of any other open issue.
Context
The whole point of
/work <issues>is that you fire it and walk away. But when a cycle parks, halts, or stops awaiting a human merge, the only places that say so are the Pi scrollback and a JSON file — both of which require you to already be looking.grep -rniE 'osascript|terminal-notifier|notify-send|webhook|slack' extension/src/returns nothing. The GitHub comment +needs-human-attentionlabel exist only on therunHandoffpath — not on a queue halt, not onawaiting-human-merge(#380), not on a driver crash.So the realistic sequence today is: fire
/workover eight issues, go to lunch, come back two hours later to find it stopped after twenty minutes on the second group. Everything needed to fix it was known at minute twenty.What to build
A. One notification hook, configured by the operator. A single command template invoked on terminal states, e.g.
PI_ENSEMBLE_NOTIFY_CMD. The driver runs it with the message on stdin (or as$1) and does not care what it is —osascript,terminal-notifier,notify-send,curlto a webhook,say. Choosing the transport is not the harness's job; reaching the human is.B. Fire on the states that need a human, and only those:
parked(per issue)awaiting-human-merge(#380)One notification per parked issue, not one per event. A hook that fires on every step is noise, and noise is indistinguishable from no hook at all.
C. Fail open, always. A notification failure must never affect the cycle: no throw, no retry storm, a short timeout, and the failure recorded in the trace only. The hook is an observer, and an observer that can break the thing it observes is worse than none.
D. Say what a human must do that the system cannot. The existing
humanActionForalready produces this; the hook should carry it rather than inventing its own wording. "Issue #287 parked" is not actionable; "add acceptance criteria to #287" is.Acceptance criteria
PI_ENSEMBLE_NOTIFY_CMDunset, behaviour is byte-identical to today (no spawn attempted).docs/troubleshooting.md).Out of scope
A hosted notification service, batching/digest logic, and notifying on non-terminal progress.
This work must ship as its own separate PR, independent of any other open issue.