Phase 1 of novox/hq to-be 45 (ADR 0227), the mesh-catalog part: the output channel in its minimal form (research 028 Q1a, Q5a, Q8) and the second-machine watcher (S10). The controller side (condition store, events, doctor) is built in parallel in mesh-controller.
messenger — holder of operator-channel
Declares and claims the mesh seat operator-channel, serving open, history, notify.
Consumes mesh-controller.condition-raised|changed|cleared; decoding isolated in condition.go with its contract assumptions stated and tested.
Telegram (own secret telegram-token, setting telegram-chat-id) and the desktop notifier (seat:node-notifier.send@<machine> for each machine in setting desktop-machines).
Dedup by key; reminder once after 1 h urgent / 12 h warning; clear edits the first message; reopen within 10 min edits back, no new message; silenced sends nothing; warning→urgent said once.
Urgent → both channels; warning → desktop when a session answers, else Telegram.
20 per hour per channel; the excess folded into one message naming them, at most every 10 min, logged when the cap is hit.
Content rule (content.go): addresses, paths, secret shapes refused; logged, emitted as refused, and sent as channel-refused with the words withheld.
Open messages kept in state open, recent sends in sent: a restart forgets nothing.
Tools: messenger_status (verdict first; what is missing), messenger_recent, messenger_test, messenger_check.
mesh-watcher
Consumes mesh-controller.doctor-heartbeat (decoding isolated in heartbeat.go); round trip through the bus every minute (its own watcher_ping).
Silent past the bound (2 × doctor interval; bus 3 min) → Telegram directly over HTTPS; once more after 1 h; again on return. Heard by the heartbeat's own time, so a replayed backlog is not life.
Says MISPLACED when on the controller's or bus's machine; BLIND without token/chat id.
notify is served request/reply, not an accepted work queue: the tool runtime does not yet hand a bundle its seat's queue (mesh-tools), and an untaken queue would hold messages silently.
Channels are inside the holder, not contributing modules: a module-declared seat cannot receive contributions yet.
Checked
go test -race in both modules (dedup, cap and fold, content refusal, reminder bound, clear/reopen, silence, retry, restart, decoding, watcher silence/return/replay/bound).
module check modules over the whole catalogue with a mesh-controller main build: 115 ok.
Not to be merged before the controller emits the events and its grant lets it publish condition-* and doctor-heartbeat on its seat.
Phase 1 of novox/hq to-be 45 (ADR 0227), the mesh-catalog part: the output channel in its minimal form (research 028 Q1a, Q5a, Q8) and the second-machine watcher (S10). The controller side (condition store, events, doctor) is built in parallel in mesh-controller.
## messenger — holder of `operator-channel`
- Declares and claims the mesh seat `operator-channel`, serving `open`, `history`, `notify`.
- Consumes `mesh-controller.condition-raised|changed|cleared`; decoding isolated in `condition.go` with its contract assumptions stated and tested.
- Telegram (own secret `telegram-token`, setting `telegram-chat-id`) and the desktop notifier (`seat:node-notifier.send@<machine>` for each machine in setting `desktop-machines`).
- Dedup by key; reminder once after 1 h urgent / 12 h warning; clear edits the first message; reopen within 10 min edits back, no new message; silenced sends nothing; warning→urgent said once.
- Urgent → both channels; warning → desktop when a session answers, else Telegram.
- 20 per hour per channel; the excess folded into one message naming them, at most every 10 min, logged when the cap is hit.
- Content rule (`content.go`): addresses, paths, secret shapes refused; logged, emitted as `refused`, and sent as `channel-refused` with the words withheld.
- Open messages kept in state `open`, recent sends in `sent`: a restart forgets nothing.
- Tools: messenger_status (verdict first; what is missing), messenger_recent, messenger_test, messenger_check.
## mesh-watcher
- Consumes `mesh-controller.doctor-heartbeat` (decoding isolated in `heartbeat.go`); round trip through the bus every minute (its own `watcher_ping`).
- Silent past the bound (2 × doctor interval; bus 3 min) → Telegram directly over HTTPS; once more after 1 h; again on return. Heard by the heartbeat's own time, so a replayed backlog is not life.
- Says MISPLACED when on the controller's or bus's machine; BLIND without token/chat id.
- Tools: watcher_status, watcher_last_heard, watcher_test, watcher_ping.
## Deviations, stated
- `notify` is served request/reply, not an accepted work queue: the tool runtime does not yet hand a bundle its seat's queue (mesh-tools), and an untaken queue would hold messages silently.
- Channels are inside the holder, not contributing modules: a module-declared seat cannot receive contributions yet.
## Checked
- `go test -race` in both modules (dedup, cap and fold, content refusal, reminder bound, clear/reopen, silence, retry, restart, decoding, watcher silence/return/replay/bound).
- `module check modules` over the whole catalogue with a mesh-controller main build: 115 ok.
Not to be merged before the controller emits the events and its grant lets it publish `condition-*` and `doctor-heartbeat` on its seat.
The mesh noticed 48 core failures in six days and told nobody (ADR 0227).
messenger holds the operator-channel seat: it consumes the controller's
condition events and sends them to Telegram and the desktop notifier,
deduplicated by key, reminded once, edited on clear, capped at 20 an hour
with the rest folded, and refusing anything carrying an address, a path or
a secret. mesh-watcher, on a machine other than the control node, sends to
Telegram directly when the self-check heartbeat or the bus goes silent.
Deliverynovox/mesh-catalog@c12d364a6848 — held since 2026-10-06T23:05:28Z
Held for a person: merged without a passing check: only a person decides that it goes on — mesh-delivery.release with why lets it go on.
Delivery plan — builds mesh-watcher, messenger → novox; no bus step
tier 0: mesh-watcher, messenger
novox: receives messenger
Transitions
2026-10-06 23:05 (new) → proposed (announced): novox/mesh-catalog#86 merged; its head was not heard by this owner, so it is made from the forge's word
2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@c12d364a6848` — **held** since 2026-10-06T23:05:28Z
Held for a person: merged without a passing check: only a person decides that it goes on — `mesh-delivery.release` with why lets it go on.
**Delivery plan** — builds mesh-watcher, messenger → novox; no bus step
- tier 0: mesh-watcher, messenger
- novox: receives messenger
**Transitions**
- 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-catalog#86 merged; its head was not heard by this owner, so it is made from the forge's word
- 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
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.
Phase 1 of novox/hq to-be 45 (ADR 0227), the mesh-catalog part: the output channel in its minimal form (research 028 Q1a, Q5a, Q8) and the second-machine watcher (S10). The controller side (condition store, events, doctor) is built in parallel in mesh-controller.
messenger — holder of
operator-channeloperator-channel, servingopen,history,notify.mesh-controller.condition-raised|changed|cleared; decoding isolated incondition.gowith its contract assumptions stated and tested.telegram-token, settingtelegram-chat-id) and the desktop notifier (seat:node-notifier.send@<machine>for each machine in settingdesktop-machines).content.go): addresses, paths, secret shapes refused; logged, emitted asrefused, and sent aschannel-refusedwith the words withheld.open, recent sends insent: a restart forgets nothing.mesh-watcher
mesh-controller.doctor-heartbeat(decoding isolated inheartbeat.go); round trip through the bus every minute (its ownwatcher_ping).Deviations, stated
notifyis served request/reply, not an accepted work queue: the tool runtime does not yet hand a bundle its seat's queue (mesh-tools), and an untaken queue would hold messages silently.Checked
go test -racein both modules (dedup, cap and fold, content refusal, reminder bound, clear/reopen, silence, retry, restart, decoding, watcher silence/return/replay/bound).module check modulesover the whole catalogue with a mesh-controller main build: 115 ok.Not to be merged before the controller emits the events and its grant lets it publish
condition-*anddoctor-heartbeaton its seat.Delivery
novox/mesh-catalog@c12d364a6848— held since 2026-10-06T23:05:28ZHeld for a person: merged without a passing check: only a person decides that it goes on —
mesh-delivery.releasewith why lets it go on.Delivery plan — builds mesh-watcher, messenger → novox; no bus step
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.