2026-10-06 09:48 UTC: the moment the controller made messenger's durable consumer on EVENTS (mesh-controller #81), the stream handed over every condition event since 08:32 — 96 raised-and-cleared events. messenger said each as new: 20 desktop notifications in one second (the cap), the rest folded. messenger was unassigned. novox/hq issue 271.
The rules now
History is never news. On start, every 10 min, and at once when an old event arrives, the holder reads the open set from seat:mesh-controller.conditions and takes it as state. An event older than that reading (5 s clock slack) is not acted on. An event whose own at is more than 10 min old (FreshFor) is recorded as state, never said. What is open here and not in the controller's set ended meanwhile: ended quietly (Telegram's message edited — edits notify nobody; the desktop is not woken). An urgent condition open and never said is said, all of them in one message. A warning raised in the last 10 min and not heard is said normally; older ones are state.
A clearing of something never said says nothing; a held message whose condition cleared before it went out is dropped. A raise for something already cleared in the state is older than the reading, so not acted on.
Bursts are one message. Each channel holds what is to be said for 30 s from the first item: alone it goes as itself (editable), several go as one digest (WARNING: 5 new warnings, one line each). Urgent goes at once when the channel was quiet for 30 s.
Desktop is gentle: warnings reach it at most once per 15 min; urgent not held to that.
Cap (20/h/channel) is a last line: reached, it is said once in its own message and the rest held for one digest when the hour allows (no more 20 + fold).
Start grace: nothing in the first minute except the one message of urgent conditions open in the synced state.
Reminders are never sooner than their bound after the first message (an old urgent said at a sync is not reminded straight away). A restart drops what was waiting (Pending/Folded from state are history); the sync decides.
The holder is safe on its own: replays, redeliveries and a recreated consumer all say nothing. Controller-side follow-up (not changed here): broker.ConsumerFor makes module consumers from the stream's start; FromNow (issue 248) exists and could be set for consumers of condition events.
Tests (go test -race)
history_test.go replays testdata/backlog-2026-10-06.json — the controller's own record of that morning's 96 event bodies (conditions history, evidence stripped):
synced (open set empty at 09:49) → 0 messages, all 96 events "already in the state";
controller unreachable → 0 messages (all old by their own time, or clears of what was never said);
replayed twice (redelivery) and again an hour later (consumer recreated) → 0;
the same morning with one urgent and three warnings left open → exactly one message per channel naming the urgent; warnings are state.
Plus: an event older than the reading; old event is state; clear of never-said; burst → one digest; desktop rhythm; start grace; ended-while-away is a silent edit; restart says nothing again; DecodeOpen shapes; at. Existing tests adjusted to the 30 s window (the cap test rewritten for rule 5).
module.json invokes seat:mesh-controller.conditions (read only; the grant is per subject, messenger never passes silence).
Removes two compiled binaries committed in #86 (modules/messenger/messenger, modules/mesh-watcher/mesh-watcher, 11 MB each) and ignores them.
Rollout
Merge → pipeline builds the bundle. Before re-assigning: the state bucket open may hold records from the incident — they are cleared ones (deleted after 10 min) or told ones the first sync ends quietly; nothing in it is resent. Re-assign to the same machine; expect zero notifications in the first minute unless an urgent condition is open.
## Why
2026-10-06 09:48 UTC: the moment the controller made messenger's durable consumer on EVENTS (mesh-controller #81), the stream handed over every condition event since 08:32 — 96 raised-and-cleared events. messenger said each as new: 20 desktop notifications in one second (the cap), the rest folded. messenger was unassigned. novox/hq issue 271.
## The rules now
1. **History is never news.** On start, every 10 min, and at once when an old event arrives, the holder reads the open set from `seat:mesh-controller.conditions` and takes it as state. An event older than that reading (5 s clock slack) is not acted on. An event whose own `at` is more than **10 min** old (`FreshFor`) is recorded as state, never said. What is open here and not in the controller's set ended meanwhile: ended quietly (Telegram's message edited — edits notify nobody; the desktop is not woken). An urgent condition open and never said is said, **all of them in one message**. A warning raised in the last 10 min and not heard is said normally; older ones are state.
2. **A clearing of something never said says nothing**; a held message whose condition cleared before it went out is dropped. A raise for something already cleared in the state is older than the reading, so not acted on.
3. **Bursts are one message.** Each channel holds what is to be said for **30 s** from the first item: alone it goes as itself (editable), several go as one digest (`WARNING: 5 new warnings`, one line each). Urgent goes at once when the channel was quiet for 30 s.
4. **Desktop is gentle:** warnings reach it at most once per **15 min**; urgent not held to that.
5. **Cap (20/h/channel)** is a last line: reached, it is said **once** in its own message and the rest held for one digest when the hour allows (no more 20 + fold).
6. **Start grace:** nothing in the first **minute** except the one message of urgent conditions open in the synced state.
7. Reminders are never sooner than their bound after the first message (an old urgent said at a sync is not reminded straight away). A restart drops what was waiting (`Pending`/`Folded` from state are history); the sync decides.
The holder is safe on its own: replays, redeliveries and a recreated consumer all say nothing. Controller-side follow-up (not changed here): `broker.ConsumerFor` makes module consumers from the stream's start; `FromNow` (issue 248) exists and could be set for consumers of condition events.
## Tests (go test -race)
`history_test.go` replays `testdata/backlog-2026-10-06.json` — the controller's own record of that morning's 96 event bodies (`conditions history`, evidence stripped):
- synced (open set empty at 09:49) → **0 messages**, all 96 events "already in the state";
- controller unreachable → **0 messages** (all old by their own time, or clears of what was never said);
- replayed twice (redelivery) and again an hour later (consumer recreated) → **0**;
- the same morning with one urgent and three warnings left open → **exactly one message per channel** naming the urgent; warnings are state.
Plus: an event older than the reading; old event is state; clear of never-said; burst → one digest; desktop rhythm; start grace; ended-while-away is a silent edit; restart says nothing again; `DecodeOpen` shapes; `at`. Existing tests adjusted to the 30 s window (the cap test rewritten for rule 5).
`mesh-controller module check modules/messenger` (built from mesh-controller main, -mod=vendor): ok, invokes `seat:node-notifier.send, seat:mesh-controller.conditions`.
## Also
- `module.json` invokes `seat:mesh-controller.conditions` (read only; the grant is per subject, messenger never passes `silence`).
- Removes two compiled binaries committed in #86 (`modules/messenger/messenger`, `modules/mesh-watcher/mesh-watcher`, 11 MB each) and ignores them.
## Rollout
Merge → pipeline builds the bundle. Before re-assigning: the state bucket `open` may hold records from the incident — they are cleared ones (deleted after 10 min) or told ones the first sync ends quietly; nothing in it is resent. Re-assign to the same machine; expect zero notifications in the first minute unless an urgent condition is open.
A consumer made on 2026-10-06 was handed three hours of raised-and-cleared
conditions at once and the holder said each as new: 20 desktop notifications
in a second. What is said is now decided by the controller's open set and by
an event's own time, never by its arrival; bursts are one message, the
desktop gets warnings at most every 15 min, the cap is said once, and the
first minute after start says only the urgent conditions still open.
Replays of that morning's 96 events are tests. Also drops two committed
binaries. (novox/hq issue 271)
Deliverynovox/mesh-catalog@8c2c9ace0e37 — 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#88 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@8c2c9ace0e37` — **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#88 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.
Why
2026-10-06 09:48 UTC: the moment the controller made messenger's durable consumer on EVENTS (mesh-controller #81), the stream handed over every condition event since 08:32 — 96 raised-and-cleared events. messenger said each as new: 20 desktop notifications in one second (the cap), the rest folded. messenger was unassigned. novox/hq issue 271.
The rules now
seat:mesh-controller.conditionsand takes it as state. An event older than that reading (5 s clock slack) is not acted on. An event whose ownatis more than 10 min old (FreshFor) is recorded as state, never said. What is open here and not in the controller's set ended meanwhile: ended quietly (Telegram's message edited — edits notify nobody; the desktop is not woken). An urgent condition open and never said is said, all of them in one message. A warning raised in the last 10 min and not heard is said normally; older ones are state.WARNING: 5 new warnings, one line each). Urgent goes at once when the channel was quiet for 30 s.Pending/Foldedfrom state are history); the sync decides.The holder is safe on its own: replays, redeliveries and a recreated consumer all say nothing. Controller-side follow-up (not changed here):
broker.ConsumerFormakes module consumers from the stream's start;FromNow(issue 248) exists and could be set for consumers of condition events.Tests (go test -race)
history_test.goreplaystestdata/backlog-2026-10-06.json— the controller's own record of that morning's 96 event bodies (conditions history, evidence stripped):Plus: an event older than the reading; old event is state; clear of never-said; burst → one digest; desktop rhythm; start grace; ended-while-away is a silent edit; restart says nothing again;
DecodeOpenshapes;at. Existing tests adjusted to the 30 s window (the cap test rewritten for rule 5).mesh-controller module check modules/messenger(built from mesh-controller main, -mod=vendor): ok, invokesseat:node-notifier.send, seat:mesh-controller.conditions.Also
module.jsoninvokesseat:mesh-controller.conditions(read only; the grant is per subject, messenger never passessilence).modules/messenger/messenger,modules/mesh-watcher/mesh-watcher, 11 MB each) and ignores them.Rollout
Merge → pipeline builds the bundle. Before re-assigning: the state bucket
openmay hold records from the incident — they are cleared ones (deleted after 10 min) or told ones the first sync ends quietly; nothing in it is resent. Re-assign to the same machine; expect zero notifications in the first minute unless an urgent condition is open.Delivery
novox/mesh-catalog@8c2c9ace0e37— 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.