@@ -121,8 +121,11 @@ that holds its mark reach the machines together.
## The tool runner (module `node-tools`)
11.**Its manifest loses `waits`.**`node-tools/module.json` drops the key `waits` and its five entries; nothing else
in it changes, its `version` stays `2` (ADR 0670 §2).
11.**Its manifest's changes, every one.**`node-tools/module.json` drops the key `waits` and its five entries (ADR
0670 §2); gains `operator-channel` in `uses`, for the asks of marked waits (§35; design 46 7-approval-mark §7); gains
in `requires` the state `approvals` of design 46 7-approval-mark §13; and gains the stream `node-tools-findings` and
the `consumes` of `mesh-conditions.findings-asked` that design 47 G §387 writes. Its `version` stays `2`, a label
no reader judges. Nothing else in it changes.
12.**The publication time is kept.**`bus.Heard` gains `Published`, read from the event's header `x-time`, which
mesh-sdk's emit sets (`go/process/emit.go`) and the status view's own emit too; `HearFirst` reads it from the
message's headers, and leaves it empty for an event that carries none.
@@ -135,11 +138,12 @@ that holds its mark reach the machines together.
named by `buscompose.EventName` of the subject it arrived on. The timeout, the filter and the timed-out answer are
unchanged (ADR 0367 §1). The refusal of names outside a list, and its words naming the manifest, go (ADR 0670 §2).
14.**A misspelt name is refused, not waited on for ever.** Before it subscribes, `waitAnswer` refuses a name whose
emitter is neither a seat of the seat list the tool runner reads through the seat `mesh-catalog` nor a module of
the indexer's manifests it holds as a first view (`mesh-delivery-indexer.views.manifests`), naming both sources.
emitter is neither a seat nor a module of the catalog half the tool runner holds from G (its first view by
`mesh-catalog.revision`, followed on `catalog-revision`; design 47 G §196), naming that source and its revision.
A name whose emitter is known but whose event no seat definition and no manifest's `emits` declares is waited on,
and its timed-out answer says that no declaration names that event. While either source is not yet read (the
first views' state, `mesh_first_views`), names are not checked, and the answer says `unchecked` with why.
and its timed-out answer says that no declaration names that event. While the catalog half is not yet read (the
first views' state, `mesh_first_views`), names are not checked, and the answer says `unchecked` with why; a
marked wait is then held as §34 says.
15.**The answer names the heard event.** A heard event is answered as today, `heard` with `subject`, `body` and
`at`, where `subject` is now the heard event's whole name (`mesh-delivery-view.delivered`,
`operator-channel.decided.claude-code`), with two new fields: `from`, `seat` or `module`, the namespace it
@@ -176,8 +180,9 @@ that holds its mark reach the machines together.
a name with `*`, with `>`, of one token, 17 names, an emitter no source knows (§14), and a bus-refused subscription
answered after the timeout with §16's words; `TestMeshWaitWithNoFamiliesIssuedWaitsOnNothing` is deleted. In
`bus/wait_test.go`, `TestTheBusRefusesAWaitOutsideTheGrant` stays as §16's refusal test, with a timeout of a
fraction of a second, its comment citing ADR 0670 §1. No test function is added: the module stays within its
budget.
fraction of a second, its comment citing ADR 0670 §1. The manifest test also holds each change of §11: no `waits`,
`operator-channel` in `uses`, the state `approvals` in `requires` with its options, and the finding stream. No test
function is added: the module stays within its budget.
## The claude-code module's Stop hook
@@ -190,8 +195,9 @@ that holds its mark reach the machines together.
21.**The prepare lists every event.** The milestone file's prepare (playbook 07, step 0) gains a section *Events and
their fields*: every event each module's manifest `emits` and each seat's definition declares, read from the
indexer's modules (`mesh-delivery-view.indexer_modules`) and the seat definitions (`mesh-catalog.seat-definitions`),
each a holder's event with its subject form; and every event mesh-sdk publishes on a module's behalf (the
manifests and the seat definitions at the group's heads, not only from what the live bus holds, so the events G
and design 46's milestone 7 add are listed (the finding streams of design 47 G §383 among them), each a holder's
event with its subject form; and every event mesh-sdk publishes on a module's behalf (the
announcement's `states` on `mesh.mod.<module>.event.states`, found by the callers of its subject builders); each
with the fields of its body as the emitting code builds it, by file and line (ADR 0670 §4).
22.**The code review confirms none carries a secret, before the grant is delivered.** The milestone's code review
@@ -242,8 +248,10 @@ that holds its mark reach the machines together.
## Delivery
28.**One delivery group, no order named between its members.** The members are pushed and checked as one group. No
order is named between them, and no transitional field is kept (the operator, 2026-11-03: a change is designed as
28.**In G's delivery group, no order named beyond the module graph's.** The members are pushed and checked in design
47 milestone G's group, with design 46's milestone 7, whose edges (design 46 7-approval-mark §23) order the gate
before the seat definition that marks `execute`; this milestone adds no order of its own between its members, and no
transitional field is kept (the operator, 2026-11-03: a change is designed as
it should be, its delivery is the delivery system's): a part built with the new mesh-sdk reads a stored manifest of
the tool runner that still carries `waits` without it (ADR 0578 §3), and a node-engine is given a want only for a
manifest whose words it reads (ADR 0614 §4).
@@ -253,7 +261,7 @@ that holds its mark reach the machines together.
that it was issued no event families. Both are loud. A watcher reads its owner after every answer (ADR 0367 §4) and
ends at a call failed twice (its definition), so neither becomes a loop; a laptop asleep through the window gets
its new tool runner when it wakes, and its watchers read their owners meanwhile in the same way.
30.**Going back is going forward.** A fault met after the delivery is fixed by a new change delivered the same way.
30.**Going back is going forward** (design 46 7-approval-mark §24 for the gate's part). A fault met after the delivery is fixed by a new change delivered the same way.
Reverting the group instead reverts every member, the indexer first, since the manifest validator delivered here
sets aside the old tool runner's manifest carrying `waits` (§10); until the revert reaches a node, `mesh_wait`
there answers as §29 says.
@@ -288,22 +296,30 @@ approves, for a marked event or a restricted stream.
`events` carry, naming the event, as ADR 0286 §4 refuses a mark on a tool the module does not serve (design 46
7-approval-mark §4's table gains the row). A module that marks only events needs neither `operator-channel` in
`uses` nor `approval-mark/1`: the tool runner asks for the wait, not the module.
33.**The tool runner reads the marks from the manifests on the bus.** The tool runner derives each module's marked
subjects from the indexer's manifests it already holds as a first view (`mesh-delivery-indexer.views.manifests`,
§14): for a marked event `<event>` of module `<module>`,`mesh.mod.<module>.event.<event>` and
`mesh.stream.<module>.event.<event>`, each event pattern as the bus spells it (`WirePattern`); for a stream with a
`grant`, every subject of `ModuleStream.Subjects()`. It derives them again on every change of that view, and no
module's name is written in its code; it is design 46 7-approval-mark §5's derivation, extended to events. *Why:*
33.**The tool runner reads the marks from the catalog half on the bus.** The tool runner derives each module's marked
subjects from the catalog half it holds (§14; the catalog graph entry carries `needs-approval` and each stream's
`grant`, design 46 7-approval-mark §5): for a marked event `<event>` of module `<module>`,
`mesh.mod.<module>.event.<event>` and `mesh.stream.<module>.event.<event>`, each event pattern as the bus spells it
(`WirePattern`); for a stream with a `grant`, every subject of `ModuleStream.Subjects()`; and each of these also
followed by `.>`, since an event may name its node or asker after its name (design 47 G §383) and
`ModuleStream.Subjects()` answers only the patterns the stream stores. It derives them again on every revision it
hears, and no module's name is written in its code; it is design 46 7-approval-mark §5's derivation, extended to
events, following the running version as that line says. A mark added while a wait waits applies from the next
call, which that call's answer says. *Why:*
ADR 0286 §5 had the mark issued in a membership; no controller issues one now, a membership names no event (ADR
0670 §2), and the judged manifest on the bus keeps the mark out of any bundle as §5 required (the operator,
2026-11-11: the mark read from the manifests on the bus); §14 already reads this view.
2026-11-11: the mark read from the manifests on the bus); from G the catalog half is where the tool runner reads
which modules exist (design 47 G §196).
34.**Which wait is marked.** A wait is marked when any subject it subscribes (§13, §26, after `from`) overlaps a
marked subject of §33, that is, some subject matches both, a wildcard on either side. mesh-sdk's `events.go` (§1)
gains `Overlaps(a, b)` for it. While the manifests view is not yet read (`mesh_first_views`), a wait with any
subject outside `mesh.seat.`is marked and its refusal says the marks are not yet read, since a mark that cannot
be read runs nothing (ADR 0286 §40; design 46 7-approval-mark §19); a wait `from: seat` is never marked.
gains `Overlaps(a, b)` for it. Before the catalog half is read (`mesh_first_views`), a wait with any subject
outside `mesh.seat.`waits, within its own timeout, for the first view and is then judged; nothing is asked while
the marks are unread, and a wait still unjudged when its timeout ends is refused then, saying the marks are not
yet read, since a mark that cannot be read runs nothing (ADR 0286 §40; design 46 7-approval-mark §19). A wait
`from: seat` is never marked.
35.**A marked wait runs only on the operator's warrant for that one wait.** The call is an act as design 46
7-approval-mark §8 makes one: the address `mesh_wait`, the node, the module `node-tools`, its build, and every
7-approval-mark §8 makes one: the address `mesh_wait`, the node, the module `node-tools` and the tool `mesh_wait`,
its build (the digest of the tool runner's own artifact), and every
argument given (`subjects`, `from`, `filter`, `timeout`), so the warrant binds the exact names, the filter and the
bound. The tool runner refuses, asks, judges and claims it as that part's §9, §10, §11 and §13 to §17 do for a
marked tool, asking on the seat `operator-channel` under its own module's name, `node-tools`, whose manifest gains
@@ -317,18 +333,24 @@ approves, for a marked event or a restricted stream.
shown with the exact names it waits on and its bound.
36.**A refused marked wait is said, and never a hot loop.** A marked wait with no warrant the tool runner accepts
subscribes to nothing. Its first call publishes the ask at once; every such call answers, as an error, design 46
7-approval-mark §12's or §17's words with "this wait" for "the call", only after its timeout or its caller's going, as §16
answers a refused subscription. *Why:* ADR 0286 §14 answers within 5 seconds, which a watcher's loop would turn
into a call every few seconds for the ask's hour; a call made again after the operator's Approve, within 30
minutes of it, runs. An unmarked wait is heard as §13 to §16 say, with no ask.
37.**The tests hold it.** §19's table of refusals in `console/wait_test.go` gains rows, no test function: a wait on a
fixture module's marked event, and one on a fixture stream with a `grant`, each with no warrant, subscribes
nothing, asks once and answers ADR 0286 §37's words after its timeout; the same wait with a warrant bound to its
exact names, filter and timeout subscribes and answers the event published after it, so the restricted stream's
event is heard only after the warrant; with a warrant for other names, another filter or another timeout it is
refused; the same names `from: seat` ask nothing; and before the manifests view is read, a module's name is
refused as §34 says. They run on the tool runner's test bus (`meshtest`), the warrant written there as the
router's record. `Overlaps` gains rows in §1's table (`mesh.stream.mail.event.mail.>` overlaps
7-approval-mark §12's or §17's words with "this wait" for "the call", when its timeout ends or its caller goes, as
§16 answers a refused subscription, or as soon as the router's record of its ask says it was chosen: the wait hears
the warrant event `operator-channel.decided.node-tools` for its ask's id and then reads the record, an event only
waking it, and answers at once, so the same call made again runs within the warrant's 30 minutes. *Why:* ADR 0286
§14 answers within 5 seconds, which a watcher's loop would turn into a call every few seconds for the ask's hour;
ending at the choice keeps a long wait from spending the warrant's window. An unmarked wait is heard as §13 to §16
say, with no ask.
37.**The tests hold it.** Unit, as the budget counts them (`meshtest` runs its bus in the test's process): §19's table
of refusals in `console/wait_test.go` gains rows, no test function: a wait on a fixture module's marked event, and
one on a fixture stream with a `grant`, each with no warrant, subscribes nothing, asks once and answers design 46
7-approval-mark §12's words after its timeout; a wait with the most timeout a wait takes (ten minutes, ADR 0367
§1), its ask chosen at its second minute, answers at the choice, and the same call made then runs; the same wait
with a warrant bound to its exact names, filter and timeout subscribes and answers the event published after it,
so the restricted stream's event is heard only after the warrant; with a warrant for other names, another filter
or another timeout it is refused; the same names `from: seat` ask nothing; a wait named `<module>.<event>.<node>`
under a marked `<module>.<event>` is marked; and before the catalog half is read, a marked wait asks nothing, is
judged when the first view comes within its timeout, and is refused at its timeout when it does not. The warrant is
written on the test bus as the router's record. `Overlaps` gains rows in §1's table (`mesh.stream.mail.event.mail.>` overlaps
`mesh.stream.mail.event.mail.*.message`; `mesh.mod.mail.event.x` does not overlap `mesh.stream.mail.event.x`), and
§32's refusal a row in the indexer's `judge/rules_test.go`.
@@ -353,4 +375,8 @@ approves, for a marked event or a restricted stream.
`mesh-delivery-checker.verdict` wakes on the checker's next verdict (§25, §26; ADR 0671 §1).
- **The grant does not follow a restricted stream's grant value** (integration on a real bus): §27's cases pass
(ADR 0671 §2).
- **A marked wait runs only on the operator's warrant** (unit, and on the test bus): §37's rows pass.
- **A marked wait runs only on the operator's warrant** (unit): §37's rows pass.
- **A wait on mail, as the operator sees it** (live, read by tool call and on the phone): a session's `mesh_wait` on
`mesh-mail.mail`, the mail module's restricted stream, asks "Wait on mesh-mail.mail on <node>?" on the phone with
its bound, and hears nothing before; it ends refused when its timeout ends or as soon as the operator chooses; the
same call made after the Approve hears the next mail, and the next call asks again (§32 to §36).
@@ -143,7 +143,7 @@ reads the state once from the verb that owns it: an event only wakes it (ADR 036
flowchart LR
E[a seat's, a module's or a module stream's event<br/>mesh.seat.<seat>.event.… / mesh.mod.<module>.event.… / mesh.stream.<module>.event.…] -->|heard for the call| TR[the tool runner's account]
G[seat mesh-grants] -->|grants the three event subjects| TR
M[the indexer's manifests] -->|the marked events and restricted streams| TR
TR -->|a marked wait only on the operator's warrant| OC[seat operator-channel]
TR -->|mesh_wait answers it by name| S[a session]
S -->|then reads the state| O[the verb that owns it]
@@ -169,7 +169,7 @@ needs no `consumes` and no entry in that value, and keeps no consumer of it.
**A marked event is heard only on the operator's warrant** (the operator, 2026-11-11). The approval mark (ADR 0286) covers a module's events and streams as well as its tools and
verbs: a module may mark one of its events in `needs-approval`, and a restricted stream is marked whole. The tool
runner reads the marks from the indexer's manifests on the bus, and a `mesh_wait` on a marked event, or on any subject
runner reads the marks from the catalog half on the bus (seat `mesh-catalog`), and a `mesh_wait` on a marked event, or on any subject
of a marked stream, runs only on the operator's warrant for that one wait, asked on the seat `operator-channel` with
the exact names it waits on and its bound, and checked before the tool runner subscribes; without one it is refused
and says so. The bus grants the subjects, and the tool runner's own gate holds the mark, as the operator chose; the
@@ -569,8 +569,9 @@ said on the away channel, with its why.
*Added 2026-10-10, ADR 0286; amended 2026-11-11 to the mesh as built and as design 47's milestone G leaves it.*
A module's manifest marks a tool, or a seat verb it serves, in **`needs-approval`**; a seat's definition may mark
a verb for every holder. The tool runner reads the marks from the manifests and the seat list on the bus, never from
the bundle, and a marked module runs only on a machine whose tool runner states that it honours the mark.
a verb for every holder. The tool runner reads the marks from the catalog half on the bus (seat `mesh-catalog`), never from
the bundle, and on a machine whose tool runner does not state that it honours the mark the grants part withholds every
marked subject from its account.
```
agent ──call──► tool runner (serving node) ──ask, under the module's name──► seat operator-channel ──► Telegram
Reference in New Issue
Block a user
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.