BSD userland rejects or silently ignores several GNU spellings the repo used:
- `timeout` is not in a stock macOS at all (Homebrew installs it, and also as
`gtimeout`). Without it every gates.sh check exited 127 and was recorded
NOT-MET whatever the check actually did — a systematic false negative.
The binary is now resolved once, with a pure-bash deadline behind it so the
124 contract still holds where neither binary exists. GATES_TIMEOUT_BIN is
overridable with `-` not `:-`, so an empty value forces that fallback: the
suite passes 64/64 both ways, timeout cases included.
- `touch -d '10 days ago'` is GNU-only; perl's utime is the one spelling both
platforms ship.
- BSD `wc -l` pads its count with leading spaces, so string compares failed as
got[ 48] want[48].
- `sed -i` needs a suffix argument on BSD AND does not expand \n in the
replacement, so the release-candidate CHANGELOG edit silently did nothing
and the assertion failed for the wrong reason. Rewritten in awk; the RC_TAG=0
mode still REDs on the absent tag, so the test keeps its teeth.
- `/bin/grep` does not exist on macOS (grep lives in /usr/bin), and `stat -c`
is GNU-only.
fast-libs 11/11, seo-data 221/221, release-candidate 5 GREEN / 0 RED.
Ending a turn right after spawning a subagent fired the bell and a toast
saying the response was finished, while the work continued. The Stop
payload carries background_tasks, so skip the signal when it is not
empty; the next turn end signals once the work is really done.
Interaction requests still signal during background work. A missing
field still signals, so an older client loses nothing. Also drop the
message suffix when it merely restates the label.
Only turn end and the moments needing the user should signal. Any other
event reaching the hook, such as agent_completed or auth_success, now
exits without emitting, so a subagent finishing rings nothing even if the
Notification matcher is ignored.
The toast body showed Claude's own message when present and the raw
notification_type otherwise, so permission_prompt and idle_prompt reached
the user as snake_case. Map every event the matcher covers to a readable
label, and keep Claude's message as a suffix when it adds detail.
Notification matcher covers input-needed events only; end of turn had no
signal but idle_prompt, ~60s late. Wire notify-attention.sh on Stop too,
branching on hook_event_name for the message. Signal only: returns
terminalSequence + suppressOutput, never blocks (guard vs BDR-083).
Header documents both client-side prerequisites found in BLK-020.
Notification hook (permission_prompt|idle_prompt|agent_needs_input|
elicitation_*) returns BEL x2 + OSC 777 via the terminalSequence JSON
field (hooks have no controlling TTY). Client side over Remote-SSH:
VS Code accessibility.signals.terminalBell sound:on for the beep,
wenbopan.vscode-terminal-osc-notifier extension for the Windows toast.