Files
mesh-catalog/modules/mesh-watcher
jschoubben b5475cfa5c
mesh/delivery merged: source.main moved to novox/mesh-catalog@5d9cead336ab
mesh/delivery-group group fix/held-module-and-assigner-contract merged: every member is merged
mesh/check checking b5475cfa5c3d on 395a37dddab9 | novox/mesh-catalog#571 in group fix/held-module-and-assigner-contract
Subscribe as soon as the runtime serves, never after a guessed wait, so no event sent at a start is missed (issue 774)
mesh-healers slept 2 s before its first subscribe to the keeper's conditions; its whole test delivered
condition-raised once the lease was read, often before that, and the event was dropped: "never: the would-act
written" in about two runs of three on main, failing the group check. Eight modules had the same shape.

Quick fix: sleep after a failed subscribe in mesh-healers alone.
Thorough fix (chosen, the kind is in eight modules): every loop that asks the runtime for events or a watch
waits for stdio.Served() and subscribes at once, sleeping only after a refusal (mesh-healers, mesh-config,
mesh-mail, mesh-issues, mesh-provisioner, mesh-watcher, mesh-delivery-gate); mesh-knowledge, whose pinned
mesh-sdk has no Served, subscribes first and sleeps after a refusal. The healers' whole test delivers the
event only once the bundle has subscribed it, as the runtime's consumer holds it until then.
2026-10-30 21:57:31 +01:00
..

mesh-watcher

The watcher's watcher (novox/hq to-be 45 §5, signal S10, ADR 0227 rule 6): what tells the operator when the parts that would tell them are what failed.

  • Assigned to one machine that is not the control node. It reads where the controller and the bus run (mesh-controller.seats) every ten minutes; on the same machine its status says MISPLACED.
  • Watches two signals.
    • The self-check: the controller's doctor heartbeat, mesh-controller.doctor-heartbeat. Bound: twice the interval the heartbeat says doctor runs at (five minutes when it says none). Heard by the time the heartbeat says it was made, so a backlog delivered after a restart is not a sign of life. The heartbeat is read in one place, cmd/mesh-watcher/heartbeat.go, which states every assumption it makes about its shape.
    • The bus: a round trip through the bus server — its own watcher_ping on its own machine — every minute. Bound: three minutes.
  • Silent past its bound: it sends to Telegram directly over HTTPS, not through the bus, once; once more an hour later if still silent; and again when the signal returns. Before a signal is first heard it counts from the watcher's start: a heartbeat that never comes is what this is for.
  • Its own health is visible: watcher_status leads with whether it can tell the operator anything at all (BLIND without a token or chat id, or while Telegram fails), whether it is misplaced, and whether heartbeats reach it. A message it could not send is owed and tried every minute.

What the operator gives

  1. The bot token, as this module's own secret: secret accept <machine> mesh-watcher telegram-token, then push that machine. The same bot as the operator-channel's is fine; it is one more machine holding it (ADR 0227, accepted for this one case).
  2. The chat id, as a setting: settings for mesh-watcher with {"telegram-chat-id": "<id>"}.

Tools

tool does
watcher_status its own health, then each signal: last heard, bound, silent, owed
watcher_last_heard when each signal was last heard, and what it sent lately
watcher_test a test message to Telegram now, directly
watcher_ping the bus round trip's other end

Files it does not know

Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416).

  • ${dir:state}: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2).