Hear O-9's outside cause from the condition keeper, and follow ADR 0676 in the gate

§705 said the assigner hears rewritten and unreachable from the node-engine's
finding events, but the node-engine only states the network; the watchman
raises those findings and the keeper holds them as conditions, and an
unreachable is raised on the machine that cannot be reached. The assigner now
reads the machine's conditions through mesh-conditions' verb at the judging
and judges again on condition-cleared, never reading the watchman's state.

§677 cited ADR 0259 §3, never in force; it now cites ADR 0286 §6 and ADR 0259
§6 with ADR 0676's clauses, says waiting call for the held call, and checks
what ADR 0676 decides. The glossary gains the waiting call and the holder that
asks for a marked verb served from a module's process. §580 gives the writer's
own finding-refused to every bundle within its own key part.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 21:13:37 +01:00
parent 60e99f3875
commit 26f4b1c2a5
3 changed files with 89 additions and 47 deletions
+9 -3
View File
@@ -294,6 +294,12 @@ controller and the store; for module assignment, by the seat `mesh-module-assign
state, naming the callee, the verb and since when, and none while the callee's machine is away (§3); and it calls
again on the callee's event saying its answer changed (§4). mesh-sdk carries its form (§7). A call not marked is
made once and its fault said.
- **waiting call** — a module's call of a marked verb that the verb's holder keeps whole, with the caller the bus
proved and its ask, until the operator's answer: on the Approve the holder runs it once, and it says the call's end
(ran, declined, expired or refused) on its seat's event `gated-ended` to that caller alone (ADR 0676 §2, §3). The
caller calls once and may not mark it safe to repeat; only its wait for the end is kept. Unlike a kept call, it is
never called again.
*Not:* ~~gated call~~ (hq)
*Not:* ~~retried call~~ (hq)
- **the deprecated broker** — the lavinmq module. It was the mesh's bus and is not any more. It keeps
running as an **ordinary provider** of the `amqp` provision, for modules that need a message broker
@@ -1124,9 +1130,9 @@ asking, never the act. **Decided by** ADR 0152, 0175, 0234, 0259, 0272, 0383, 03
0274), a trusted config value (ADR 0277, ADR 0348).
A proposal changes nothing by itself; declined, expired or refused, it is discarded.
- **approval mark** — a tool's or verb's declaration in its manifest (`needs-approval`) that each call to it runs
only on the operator's warrant for that one call, with its exact arguments; the tool runner that serves it, or
the controller for its own verbs, asks and checks
(ADR 0286). It covers a module's events and streams too (the operator, 2026-11-11; design 34 every-event §32): a
only on the operator's warrant for that one call, with its exact arguments; the tool runner that serves it, the
controller for its own verbs, or the holder of a marked verb served from a module's process (ADR 0676 §1) asks and
checks (ADR 0286). It covers a module's events and streams too (the operator, 2026-11-11; design 34 every-event §32): a
module may mark one of its events, a restricted stream is marked whole, and a `mesh_wait` on a marked event runs
only on the operator's warrant for that one wait, with the exact names it waits on and its bound, which the tool
runner asks and checks before it subscribes. The tool runner reads every mark from the catalog half on the bus
@@ -538,10 +538,16 @@ form only. A note that corrects a line of G-12 or G-14 is written in that line;
findings. Its `findings-stated` carries `kinds`, the kinds it states, and the writer's statement deletes only keys of
those kinds. The keeper sets its view of that observer, node and set of kinds from the statement, and clears only
conditions of those kinds that the statement does not name. A statement with no `kinds` (a writer of a part with
one bundle) covers every kind, as before. Why: a statement that deletes every key it does not state would clear
another bundle's findings (develop question of the forge module's developer, GIT14). How it is checked: unit
one bundle) covers every kind, as before. One kind is the writer's own and every bundle's: `finding-refused`, the
finding mesh-sdk's writer itself writes when it refuses a malformed key (design 73 knowledge §1a), keyed within its
bundle's own key part as `module.<observer>.<bundle>.<asked-key>.finding-refused`. Each bundle's writer owns it
within that part only: it writes and clears only `finding-refused` keys of its own bundle, a statement of a bundle
(with `kinds` or without) covers the `finding-refused` keys of that bundle and never another's, and the keeper
clears from that statement only the `finding-refused` conditions of that bundle it does not name. Why: a statement that deletes every key it does not state would clear
another bundle's findings (develop question of the forge module's developer, GIT14). A writer's refusal is that bundle's fault, so it is kept and cleared within that bundle's key part, and no other bundle's statement can clear it (the review of design 73, HE-W2R2-2). How it is checked: unit
(writer, both languages), a statement with `kinds` deletes no key of another kind, and a write of another kind is
refused; whole (keeper), two bundles' statements on one node each keep the other's conditions open.
refused; a statement of bundle A leaves bundle B's `finding-refused` key; whole (keeper), two bundles' statements on
one node each keep the other's conditions open, a `finding-refused` of the other bundle among them.
- §581 **A `seen` key's 30 days are judged on each step end, with no timer.** (§487) The forge module writes `at` in
each `seen` key's value, the time of the `step-ended` that wrote it. On each `step-ended` it handles, and at its
start, it deletes the `seen` keys whose `at` is more than 30 days old, at most 100 for each event, the oldest first,
@@ -5,6 +5,7 @@ design: 47
milestone: G
updated: 2026-11-11
decisions:
- "ADR 0676"
- "ADR 0674"
- "ADR 0673"
- "ADR 0672"
@@ -17,6 +18,7 @@ decisions:
- "ADR 0619"
- "ADR 0618"
- "ADR 0596"
- "ADR 0564"
- "ADR 0595"
- "ADR 0579"
- "ADR 0573"
@@ -27,6 +29,7 @@ decisions:
- "ADR 0286"
- "ADR 0283"
- "ADR 0259"
- "ADR 0241"
---
# 47, milestone G: the fix round of batches 6 and 7
@@ -43,8 +46,8 @@ node-engine keeps and the grants part's first composition (§682 to §684); the
## The approval mark, with no named callers
- §677 **A marked verb a module's process serves is one call with a gate before its running, asked, checked and
claimed by its holder alone.** (§610; ADR 0676; ADR 0286 §10 to §13, §24, §26 to §31, §35, §36, §38, §43; ADR 0259
§3, §6) Once no verb names its callers (§610), a module's process may call a marked verb (ADR 0286 §1, §2)
claimed by its holder alone.** (§610; ADR 0676 §1 to §7; ADR 0286 §6, §10 to §13, §24, §26 to §31, §35, §36,
§38, §43; ADR 0259 §6) Once no verb names its callers (§610), a module's process may call a marked verb (ADR 0286 §1, §2)
directly. Design 46 7-approval-mark's gate wraps only the handlers the tool runner serves (its §20); a marked verb a
module's process serves is judged by that process, as ADR 0286 §43 has the controller judge its own verbs, whoever
calls it. The operator, 2026-11-11 about 20:40 CET at lead-47's terminal (O-8): "the tool call should be the same,
@@ -53,7 +56,7 @@ node-engine keeps and the grants part's first composition (§682 to §684); the
manifest validator refuses a TypeScript process that serves a marked verb, and the seat generator makes every
marked verb `by-caller` (§697).
- **Refused before anything is kept.** A call whose arguments hold anything shaped like a secret or pass 16 KiB is
refused at once, asking nothing and keeping nothing (ADR 0286 §12).
refused at once, asking nothing and keeping nothing (ADR 0286 §12; ADR 0676 §1).
- **The holder keeps the call and asks, under its own module's name.** Otherwise mesh-sdk's seat server makes the
act as ADR 0286 §10 and §11 make one (the address as called, the holder's own node and build, the seat and verb,
every argument, digested with `operatorchannelclient.ActDigest`), and finds or raises its ask through the key
@@ -62,36 +65,37 @@ node-engine keeps and the grants part's first composition (§682 to §684); the
the create succeeds; an instance whose create fails reads the key and takes that ask, so two instances raise one
ask; a key whose ask has ended is replaced by compare-and-set on its revision. When the call says `wait: held`
(below), the holder keeps it as a waiting call of its own, `call.<id>`, `<id>` 128 random bits, holding the call
whole, the caller the bus proved and its ask (ADR 0286 §24), and answers at once `{asked: <ask id>, call: <id>}`.
whole, the caller the bus proved and its ask (ADR 0286 §24; ADR 0676 §2), and answers at once `{asked: <ask id>, call: <id>}`.
- **A second call of the same act.** Every call is kept as its own `call.<id>`, whoever makes it; one made while
that act's ask is open takes the same ask (ADR 0286 §13, §23, §38) and its answer names that ask and its own
call. On the Approve the oldest kept call of the act runs; each other kept call of the act is asked anew at once,
that act's ask is open takes the same ask (ADR 0286 §13, §23, §38; ADR 0676 §4) and its answer names that ask and its own
call. On the Approve the oldest waiting call of the act runs; each other waiting call of the act is asked anew at once,
as a new ask of that act (ADR 0286 §33: a second run takes a second approval), and its end comes when its own ask
ends.
- **On the Approve it runs that same call.** When the holder hears its own `operator-channel.decided` of the ask, it
reads the router's own record of the ask under its module's name, on the one path §700 names, never the decided
event's body nor the caller's word (ADR 0286 §26, §36), holds the warrant to it with `Warrant.For` and
`Option.Performs` against the kept call (ADR 0286 §27, §28), claims it once (below), runs the kept call, once, and
event's body nor the caller's word (ADR 0286 §6, §26, §36; ADR 0676 §3), holds the warrant to it with `Warrant.For`
and `Option.Performs` against the waiting call (ADR 0259 §6; ADR 0286 §27, §28), claims it once (below), runs the
waiting call, once, and
records the run in the hand-act log of the seat `mesh-hand-acts` as a kept call until it is taken (ADR 0286 §35,
ADR 0668 §1). The kept call runs only within 30 minutes of the choice; heard later (the holder away meanwhile),
ADR 0668 §1). The waiting call runs only within 30 minutes of the choice; heard later (the holder away meanwhile),
it ends `expired` and runs nothing (ADR 0286 §29). After a Decline the same act is not asked again for 10
minutes: a call of that act within them ends `declined` at once, with no ask (ADR 0286 §38).
minutes: a call of that act within them ends `declined` at once, with no ask (ADR 0286 §38; ADR 0676 §4).
- **The caller hears the outcome on its own call's subject.** The holder says the call's end on its seat's event
`gated-ended`, subject `mesh.seat.<seat>.event.gated-ended.<caller>.<call>`, `<caller>` the account the bus proved,
escaped as a key's name is (§73): `{call, ask, act, verb, outcome, answer, error}`, `outcome` one of `ran` (with
the verb's `answer`, and in its own field `approval` the line naming the approval, ADR 0286 §34), `declined`, `expired` and `refused` (with the router's or the check's words); a decline or
an expiry runs nothing and says so. Kept last per subject, one day, and no argument is in it: a caller down for
an expiry runs nothing and says so (ADR 0676 §2). Kept last per subject, one day, and no argument is in it: a caller down for
longer than a day loses that outcome, and reads the holder's `approvals` verb (below) for it. Every seat
definition with a marked verb gains the event through the seat generator; the grants part grants hearing
`gated-ended.<caller>.>` to that caller alone, from its `invokes` of the marked verb by name, as it composes a
`gated-ended.<caller>.>` to that caller alone (ADR 0286 §6), from its `invokes` of the marked verb by name, as it composes a
`by-caller` verb. mesh-sdk's seat client, in `go/seats` beside the seat server, sends `wait: held` on every call
of a marked verb, waits as a kept wait (ADR 0668 §1) on its own `<call>` alone and reads it at its start, so a
restart of either side loses no outcome; it makes no second call. A module may not mark its call of a marked
verb safe to repeat (ADR 0668 §2): only the wait on `gated-ended` is kept. The calling module holds no warrant,
and the holder asks once per call; `mesh-delivery.release` stays unmarked (ADR 0286 §46), so ADR 0286 §47's
question is closed.
question is closed (ADR 0676 §7).
- **A person through the tool runner keeps ADR 0286 §37's path for now.** An MCP call cannot be held for an ask's
60 minutes (O-8); this "for now" is tracked by issue 417. A call that does not say `wait: held` (the tool runner sends none) is answered with ADR 0286
60 minutes (O-8; ADR 0676 §5); this "for now" is tracked by issue 417. A call that does not say `wait: held` (the tool runner sends none) is answered with ADR 0286
§37's refusal naming the ask and keeps no call, its ask found and written through `act.<digest>` as above, so the
same call made again after the Approve finds that ask, is checked as above, claimed and run. `wait` is no
boundary: either path runs the act only on the operator's warrant for that act, claimed once, so a module that
@@ -99,13 +103,13 @@ node-engine keeps and the grants part's first composition (§682 to §684); the
- **The holder claims, once, in its own state.** The holder's template state `approvals` (a `requires` entry, 48
hours to live, 64 MiB) keeps `call.<id>`, `act.<digest>` and `claimed.<ask id>`, the claim, written with the
bus's create, which refuses a key that exists, so a warrant runs one call, on one instance or two (ADR 0286 §30,
§31). At its start the holder reads every kept call and acts on each ask already decided as above. A call kept
past its ask's 60 minutes with no decided heard raises the holder's finding `gate-unanswered` (scope the holder,
§31; ADR 0676 §3). At its start the holder reads every waiting call and acts on each ask already decided as above. A waiting
call past its ask's 60 minutes with no decided heard raises the holder's finding `gate-unanswered` (scope the holder,
id the call), cleared when its end is said. The manifest validator refuses a module that serves a marked verb from
a process and declares no such entry. A state that cannot be read or written refuses every marked call of that
holder, said as ADR 0286 §40 has it.
- **Its read.** Every seat with a marked verb gains the verb `approvals` (class `read`, its default), served by the
seat server: the kept calls with their caller, ask and state, the `act.` keys and the claims, never an argument
seat server: the waiting calls with their caller, ask and state, the `act.` keys and the claims, never an argument
of a call it was not asked by that call's caller.
- **A holder that does not check is never reached.** The grants part composes, for a module's process that serves
a marked verb, the subscription of that verb's subjects only when the catalog graph entry of the build its want
@@ -113,7 +117,7 @@ node-engine keeps and the grants part's first composition (§682 to §684); the
validator with, so a G holder is granted before it subscribes; otherwise it composes the subscribe deny design 46
7-approval-mark §6 composes for a runner that does not state `approval-mark/1`, named in `withheld` with "its
holder checks no warrant". So a holder of before G serves none of its marked verbs until its G version runs, and
nothing runs unchecked. This changes ADR 0286 §7 and §8 for a process holder (ADR 0676).
nothing runs unchecked. This changes ADR 0286 §7 and §8 for a process holder (ADR 0676 §6).
Why: the operator's answers O-6 and O-8; the holder alone can read the router's record of an ask made under its
own name (review rounds 2 and 3). How it is checked, as cases of the seat server's one whole test (a fixture marked
@@ -121,11 +125,17 @@ node-engine keeps and the grants part's first composition (§682 to §684); the
on `gated-ended` by that caller and no other; a repeated identical call kept as a second call, asked anew after the
first runs, each waking on its own `<call>`; two callers of one act, one ask, one run, the second asked anew; two
instances of the holder raising one ask and one claim, a race of two at `claimed.<id>` running once; a decline and
an expiry run nothing; a restart of the holder between the ask and the Approve runs the kept call once; a warrant
replayed runs nothing; a call within 10 minutes of a Decline ended `declined` unasked; a kept call heard 31
an expiry run nothing; a restart of the holder between the ask and the Approve runs the waiting call once; a warrant
replayed runs nothing; a call within 10 minutes of a Decline ended `declined` unasked; a waiting call heard 31
minutes after its choice ended `expired`; a secret-shaped argument refused unkept; a call with no `wait` refused with the ask and run
on the same call made again; unit (grants part), a holder whose wanted entry declares no `approvals` composed with
the deny and named in `withheld`, one that declares it granted before it runs.
on the same call made again; a decided event whose body was altered runs nothing, the holder reading the router's
record; a warrant whose act is not the waiting call's runs nothing; the run found in the hand-act log; the `ran`
end read with its `answer` and its `approval` field, and the `refused` end with the router's or the check's words;
the outcome gone from `gated-ended` after one day; a caller holding a warrant of its own for an ask of its own still
asked (ADR 0676 §7); unit (seat client), the module's call client never marks its call safe to repeat; unit
(manifest validator), a module serving a marked verb from a process with no `approvals` entry refused; unit (grants
part), a holder whose wanted entry declares no `approvals` composed with the deny and named in `withheld`, one that
declares it granted before it runs.
## Develop's D-16 to D-18
- §678 **The forms of a finding's `owner` and `waiting-on`.** (§451, §540, §580) Each is one of three forms, written as
@@ -524,36 +534,56 @@ node-engine keeps and the grants part's first composition (§682 to §684); the
## The operator's O-9: a delivery waits on another machine's network
- §705 **A machine whose network names an outside cause holds the delivery there as a wait, not a failure.** (ADR
0241 §25 to §27; the main file's *A failure is held on the canary and fixed forward*; §498, §633) The operator,
0241 §13, §16 to §21, §25 to §27; ADR 0564 §2, §3, §13; ADR 0596; the main file's *A failure is held on the canary and fixed forward*; §498, §633) The operator,
2026-11-11 about 21:05 CET at lead-47's terminal (O-9): a delivered module's own failing health check is the
delivery's; but while the machine's network statement names an outside cause, the delivery waits on that machine,
says from the start what it waits on, judges again once the cause clears and goes on by itself, and after 30
minutes asks the operator to go on or count it as failed. Where the assigner judges a node's health after a want
moves (the canary rule and its hold):
- **An outside cause.** While the node-engine of that machine says a finding `rewritten` naming a file of a module
the delivery did not move (ADR 0241 §25), or `unreachable` toward another machine (ADR 0241 §25), heard by the
assigner's consumer of the node-engine's finding events (§627's stream, in its `consumes`), a failing health check
of a module the delivery moved there is no failure: the assigner holds that move as a wait, said at once on
`mesh-wants`' `wait-held` with `step` `delivery`, `node` that machine and `on` `rewritten:<owner>` or
`unreachable:<machine>`, and writes the finding `delivery-waits-outside` (scope `delivery`, id
`<node>.<module>`), naming the cause.
- **It goes on by itself.** When that finding is cleared, the assigner judges the module's health there again:
healthy, the delivery goes on, `wait-ended` with `how` `cleared`; failing, it is the delivery's failure, held as
the canary rule has it.
- **An outside cause.** The node-engine only states the machine's network in its health report (ADR 0241 §13);
the watchman raises the network findings from every machine's report together (ADR 0241 §16 to §21, observed by
the watchman under ADR 0564 §2), and the condition keeper holds them as conditions, never held while a module is
delivered (ADR 0564 §13 (e)). Two of them name an outside cause for a machine M: `machine.M.<owner>.rewritten`
(or `machine.M.rewritten` when the file is no module's), M being the condition's subject `machine`, whose
`<owner>` is a module the delivery did not move there, or none (ADR 0241 §17, §25); and `machine.<x>.unreachable`
for another machine `<x>` whose subject `also` lists M, the machines that cannot reach `<x>` (ADR 0241 §19 to §21,
§25). When a module the delivery moved fails its health check on M, the assigner reads M's open conditions through
the seat `mesh-conditions`' verb `conditions` with `scope` `machine` and `machine` M, which answers each condition
whose subject's `machine` is M or whose `also` lists M (ADR 0564 §3), a kept call in its `invokes` (ADR 0668 §1);
it never reads the watchman's `findings` nor the keeper's state (ADR 0596). With such a condition open, the
failing check is no failure: the assigner holds that move as a wait, said at once on `mesh-wants`' `wait-held`
with `step` `delivery`, `node` M and `on` `rewritten:<owner>` (`rewritten` alone for no owner) or
`unreachable:<x>`, and writes the finding `delivery-waits-outside` (scope `delivery`, id `<node>.<module>`),
naming the cause by its condition's key. The read is made at the judging and not kept from events, because the
keeper says no event when only a condition's `also` changes (it says `condition-changed` for its severity,
resolver, silence and words), so a copy kept from the events could miss M joining an `unreachable`.
- **It goes on by itself.** The assigner's durable consumer of the seat `mesh-conditions`' event
`condition-cleared` (`mesh-conditions.condition-cleared` in its `consumes`; ADR 0564 §3) hears the cause's key
cleared, and the assigner judges the module's health on M again, reading M's conditions again as above: healthy,
the delivery goes on, `wait-ended` with `how` `cleared`; failing with another outside cause open, the wait stands,
said again on `wait-held` with its new `on`, its bound still counted from its first start; failing with none, it
is the delivery's failure, held as the canary rule has it. A `condition-cleared` of a key no wait names is
dropped. At its start the assigner judges each wait it holds again the same way, so a clearing heard by no
instance is not lost.
- **The bound and the ask.** Past `outside-wait-minutes` (a setting, §633, 30 unless set) from the wait's start,
the assigner asks the operator through `operatorchannelclient`, `about` `<node>.<module>.<fingerprint>`, with
two options, Go on (the module counted healthy there, so the delivery goes on, `how` `go-on`) and Count as
failed (held as the canary rule has it, `how` `failed`); the ask names the cause and since when; the wait stands
until the answer or the cause clears, which ends the ask. The finding clears when the wait ends.
- **What stays the delivery's or the machine's.** A `rewritten` naming a module the delivery moved is that
module's failure (ADR 0241 §26). A machine's own `network` finding holds the machine as a whole: no want moves to
it until it clears (ADR 0241 §27).
- **What stays the delivery's or the machine's.** A `machine.M.<owner>.rewritten` whose `<owner>` the delivery
moved is that module's failure (ADR 0241 §26). A machine's own `machine.M.network` holds the machine as a whole:
no want moves to it until its `condition-cleared` is heard (ADR 0241 §27).
Why: the operator's answer O-9; ADR 0241 §25 had the wait with no bound, which this gives one and an ask, resting on
the record of the outside-cause wait (number to come; its draft is with lead-47), which changes ADR 0241 §25 and
keeps §26 and §27. How it is checked, as cases of the assigner's whole test: an `unreachable` toward
another machine turning a failing check into a wait, said at once, ended `cleared` and the delivery going on when
it clears; one that fails once cleared held as a failure; past the setting the ask, Go on ending `go-on` and Count
as failed ending `failed`; a `rewritten` naming a moved module failing at once; a machine's own `network` moving
no want to it.
keeps §26 and §27. The condition ids are the watchman's on mesh-delivery's main (its node-health findings) and
ADR 0241 §16's. How it is checked, as cases of the assigner's whole test (a fixture keeper answering `conditions`
and saying `condition-cleared`): a `machine.<x>.unreachable` whose `also` lists the delivering machine turning a
failing check into a wait, said at once with `on` `unreachable:<x>`, ended `cleared` and the delivery going on
when its `condition-cleared` is heard; one whose `also` does not list it leaving the failure the delivery's; one
that fails once cleared, with no other cause open, held as a failure; a second cause open at the clearing keeping
the wait with its new `on`; a restart of the assigner during a wait judging it again; past the setting the ask, Go
on ending `go-on` and Count as failed ending `failed`; a `rewritten` naming a moved module failing at once; a
machine's own `network` moving no want to it; unit (grants part), the assigner granted the verb `conditions` and
the event `condition-cleared` and no read of the watchman's `findings`.