fix(zulip-monitor): read nested zulip.connected; probe failures alert and never restart #69

Merged
abiba-bot merged 2 commits from fm/zulip-monitor-false-selfheal-20260909 into master 2026-09-09 11:09:14 +00:00
2 Commits
Author SHA1 Message Date
root f57923b4fa no-mistakes(document): test shellcheck hygiene; flagged monitor contract doc drift
PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Successful in 1s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Failing after 4s
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Skipped
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Skipped
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Skipped
2026-09-09 10:26:35 +00:00
root 7ed2e4e923 fix(zulip-monitor): Abiba leg reads nested zulip.connected; probe failures never restart
The monitor's Abiba leg parsed the :9200/health payload at the top level
(d.get('connected',False)) while the pi Zulip extension serves connection
state NESTED at zulip.connected / zulip.last_error (verified against the
extension's startHealthServer handler and the live endpoint). PI_CONNECTED
was therefore always False and every run took the DISCONNECTED path,
restarting a healthy bot: pm2 restarts=8 with the process created
2026-09-09T09:35:09Z, four ❌ Abiba verdicts today (04:23/05:35/06:55/09:35
UTC) and zero ✅, while the Zulip server answered HTTP 200 and the bot kept
heartbeating. The watchdog was the fault, not the connection.

Changes (Abiba leg only; every other leg byte-identical):
- Read the real nested shape: zulip.connected, zulip.last_error and
  zulip.messages_processed. The old retry_count branch is DROPPED — the
  payload exposes no retry counter (the extension keeps retryCount internal
  and never serialises it), so the branch is fabricated and cannot stay.
- Fail-safe restart decision: a fetch error (HTTP 000), non-2xx response,
  empty/unparseable body, or payload missing a boolean zulip.connected is a
  clearly-labelled PROBE FAILURE (🟠 alert + ⚠️ log line naming reason and
  HTTP code) and NEVER calls pm2 restart. pm2 restart runs only on
  affirmative zulip.connected=false (🔴/❌ path unchanged in wording).
  connected=true with last_error keeps the degraded 🟡 warn-no-restart path.

Regression test (new tests/zulip-monitor-abiba.sh, 36 checks): extracts the
real Abiba leg from between the # -- abiba-leg-start/-end markers in the
shipped script and executes it verbatim with stubbed curl/notify/pm2 against
fixtures of the real payload shape — asserts connected=true → no restart,
connected=false → restart, and empty/garbage/missing-key/non-boolean/HTTP
000/HTTP 500 bodies → probe-failure alert with zero restarts. The suite
fails loudly on the pre-fix base and on a marker-intact top-level-parse
variant, so this class of bug cannot return silently.
2026-09-09 09:51:46 +00:00