Silent alert-loss fix in scripts/zulip-monitor.sh, found by firstmate on 2026-09-09 while cross-checking a false "fleet degraded" report; the defect reached master through PR #66 (merge 028f276).
Defect.notify()'s second delivery path (the #agent-hub / zulip-health stream post) built its body with urllib.parse.quote(str()), which evaluates to the empty string, and used backslash-escaped \& separators inside a double-quoted -d argument (Zulip rejects that form with 400 Invalid type). Both failures were swallowed by > /dev/null 2>&1 || true, so stream alerts never arrived and nothing reported it. The private-DM path above it worked, which is why no one noticed.
Change (script-only + 2 doc lines).
Stream post now carries the real message text, piped through the encoder rather than interpolated into a python literal, with plain & parameter separators.
Delivery failure now appends exactly one WARN line (with curl's exit status) to the monitor's own log; it stays non-fatal so an alert-delivery failure can never read as a fleet fault. No retries, no new channel, no other behaviour touched (probes, the any-HTTP-response alive rule from #66, pct exec 112 Tanko vantage, DM path, exit codes, log format all unchanged).
Header comment corrected: it said "Alerts via Telegram"; alerts go by Zulip DM plus the #agent-hub stream.
README.md: dropped the unsupported claim that agent-health-check.py "Replaced zulip-monitor.sh" (the zulip-health contract still maintains it as executor). Deliberately not replaced with the opposite claim - live deployment truth is not verifiable from the diff, and reconciling infrastructure-control.prose.md's parallel claim is filed as separate follow-up work.
CLAUDE.md: scaffold-mandated fm-ensure-agents-md.sh pointer conversion (symlink -> @AGENTS.md file). Unrelated to the fix; called out here so the net diff is honest.
Proof. no-mistakes run passed: review 0 findings, test clean, lint clean, document gate answered (firstmate authority, run 01M221Y6V1TDAA1X46VR3G7XGX). bash -n clean. Behavioural checks green via a curl-stub recorder proving the posted content decodes to the real alert text, plus a forced-failure case proving the WARN line lands and the exit status stays non-fatal. Branch pushed: git ls-remote origin fm/zulip-monitor-stream-body-20260909 -> 7ff7ce5b336964100c23c91a385aada7e49863dc.
Silent alert-loss fix in `scripts/zulip-monitor.sh`, found by firstmate on 2026-09-09 while cross-checking a false "fleet degraded" report; the defect reached master through PR #66 (merge 028f276).
**Defect.** `notify()`'s second delivery path (the `#agent-hub` / `zulip-health` stream post) built its body with `urllib.parse.quote(str())`, which evaluates to the empty string, and used backslash-escaped `\&` separators inside a double-quoted `-d` argument (Zulip rejects that form with `400 Invalid type`). Both failures were swallowed by `> /dev/null 2>&1 || true`, so stream alerts never arrived and nothing reported it. The private-DM path above it worked, which is why no one noticed.
**Change (script-only + 2 doc lines).**
- Stream post now carries the real message text, piped through the encoder rather than interpolated into a python literal, with plain `&` parameter separators.
- Delivery failure now appends exactly one `WARN` line (with curl's exit status) to the monitor's own log; it stays non-fatal so an alert-delivery failure can never read as a fleet fault. No retries, no new channel, no other behaviour touched (probes, the any-HTTP-response alive rule from #66, `pct exec 112` Tanko vantage, DM path, exit codes, log format all unchanged).
- Header comment corrected: it said "Alerts via Telegram"; alerts go by Zulip DM plus the #agent-hub stream.
- `README.md`: dropped the unsupported claim that `agent-health-check.py` "Replaced zulip-monitor.sh" (the zulip-health contract still maintains it as executor). Deliberately not replaced with the opposite claim - live deployment truth is not verifiable from the diff, and reconciling `infrastructure-control.prose.md`'s parallel claim is filed as separate follow-up work.
- `CLAUDE.md`: scaffold-mandated `fm-ensure-agents-md.sh` pointer conversion (symlink -> `@AGENTS.md` file). Unrelated to the fix; called out here so the net diff is honest.
**Proof.** no-mistakes run passed: review 0 findings, test clean, lint clean, document gate answered (firstmate authority, run 01M221Y6V1TDAA1X46VR3G7XGX). `bash -n` clean. Behavioural checks green via a curl-stub recorder proving the posted `content` decodes to the real alert text, plus a forced-failure case proving the WARN line lands and the exit status stays non-fatal. Branch pushed: `git ls-remote origin fm/zulip-monitor-stream-body-20260909` -> `7ff7ce5b336964100c23c91a385aada7e49863dc`.
The #agent-hub / zulip-health stream post in notify() encoded content with
python quote(str()) (always empty), so every stream alert posted empty
content and Zulip rejected it silently behind '|| true'. The merged body
also used backslash-escaped ampersands inside double quotes, which curl
transmits literally (type=stream\ -> Zulip 400 'Invalid type').
Stream post now percent-encodes the real message text by piping it through
the encoder (locale-proof: quote_from_bytes on stdin.buffer), uses plain &
separators, and on failure appends one WARN line to the monitor log with
the curl exit status instead of silently swallowing it. Delivery failure
stays non-fatal and unretried. DM path, probes, alive rule, exit codes and
log format unchanged.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Silent alert-loss fix in
scripts/zulip-monitor.sh, found by firstmate on 2026-09-09 while cross-checking a false "fleet degraded" report; the defect reached master through PR #66 (merge028f276).Defect.
notify()'s second delivery path (the#agent-hub/zulip-healthstream post) built its body withurllib.parse.quote(str()), which evaluates to the empty string, and used backslash-escaped\&separators inside a double-quoted-dargument (Zulip rejects that form with400 Invalid type). Both failures were swallowed by> /dev/null 2>&1 || true, so stream alerts never arrived and nothing reported it. The private-DM path above it worked, which is why no one noticed.Change (script-only + 2 doc lines).
¶meter separators.WARNline (with curl's exit status) to the monitor's own log; it stays non-fatal so an alert-delivery failure can never read as a fleet fault. No retries, no new channel, no other behaviour touched (probes, the any-HTTP-response alive rule from #66,pct exec 112Tanko vantage, DM path, exit codes, log format all unchanged).README.md: dropped the unsupported claim thatagent-health-check.py"Replaced zulip-monitor.sh" (the zulip-health contract still maintains it as executor). Deliberately not replaced with the opposite claim - live deployment truth is not verifiable from the diff, and reconcilinginfrastructure-control.prose.md's parallel claim is filed as separate follow-up work.CLAUDE.md: scaffold-mandatedfm-ensure-agents-md.shpointer conversion (symlink ->@AGENTS.mdfile). Unrelated to the fix; called out here so the net diff is honest.Proof. no-mistakes run passed: review 0 findings, test clean, lint clean, document gate answered (firstmate authority, run 01M221Y6V1TDAA1X46VR3G7XGX).
bash -nclean. Behavioural checks green via a curl-stub recorder proving the postedcontentdecodes to the real alert text, plus a forced-failure case proving the WARN line lands and the exit status stays non-fatal. Branch pushed:git ls-remote origin fm/zulip-monitor-stream-body-20260909->7ff7ce5b336964100c23c91a385aada7e49863dc.