From 414490fa5a439b20136d2a8b70c268e97496a81d Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 20:56:26 +0100 Subject: [PATCH] Close batches 6 and 7 by review round 3, ADR 0675 and ADR 0676, and develop's D-33 to D-49 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every must of the last review round is written as its reviewer proposed or as the narrowest line: the gated call keyed by its own call id with one ask per act across instances, the holder granted from its want, the keeper's protected restore on a standing grant with a cancel and its partial stream removed, the node-engine's kept entries in its composition state, the indexer ordered before the parts that ask its entries, and G's own deletions moving the gate's copy mark. Develop's D-33 to D-49 are §698 to §704. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- 00-META/glossary.md | 5 +- .../G-12-develop-answers-fourth.md | 4 +- .../47-milestones/G-13-review-round-3.md | 2 +- .../G-14-recovery-module-and-review.md | 4 +- .../G-17-develop-answers-seventh.md | 15 +- .../47-milestones/G-18-fix-round-six-seven.md | 409 ++++++++++++------ .../G-8-findings-heard-as-events.md | 3 +- 03-DESIGN/01-to-be/47-milestones/G.md | 2 +- 8 files changed, 304 insertions(+), 140 deletions(-) diff --git a/00-META/glossary.md b/00-META/glossary.md index 09d27f4e..84fd47fa 100644 --- a/00-META/glossary.md +++ b/00-META/glossary.md @@ -976,8 +976,9 @@ becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283, 0564, 0668. (ADR 0235). - **recovery module** — the holder of the seat `mesh-recovery`, held once for the mesh: under an account of its own it takes a restore point of a module's kept data on the live bus before the module moves across a `form` change, sets - the live data aside and restores the point at a revert, and lists and removes restore points; the bus module and - the snapshot account restore nothing into the live bus, and the backup holder only stores copies (design 47 G §554). + the live data aside and restores the point at a revert, and lists and removes restore points; the snapshot + account restores nothing into the live bus, the bus module only the stream snapshot it took before a `drop` or + `recreate` of a protected stream, in place (design 47 G §681), and the backup holder only stores copies (design 47 G §554). **aside** — live kept data a restore set aside, removed only by the hand tool `recovery_discard_aside`, which the operator and sessions call. *Not:* ~~restorer~~, ~~restore account~~ - **disk readings** — the size of each data item a node's modules declare, measured by its `measure` and kept diff --git a/03-DESIGN/01-to-be/47-milestones/G-12-develop-answers-fourth.md b/03-DESIGN/01-to-be/47-milestones/G-12-develop-answers-fourth.md index e61a4c62..c4696164 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-12-develop-answers-fourth.md +++ b/03-DESIGN/01-to-be/47-milestones/G-12-develop-answers-fourth.md @@ -504,12 +504,12 @@ that round are written into the lines they name, here. Questions that an earlier is the seat `mesh-module-assigner`'s state. The state is an old `state` section of the builder, a foundation part, one key per node and language, about 12 keys of about 0.3 KiB each, capped at 1 MiB, so it adds no objects store to §607's count (§58 plans one only for a state of the template); `builder_toolchains` reads it and - `builder_toolchains_drop`, of class `act` with §391's default callers (`operator`, `sessions`), deletes one key, + `builder_toolchains_drop`, of class `act`, taking its default (§610), deletes one key, with why, written in the hand-act log of the seat `mesh-hand-acts`; a holder says the key again at its start and on each change (§492). This amends §604's "when the node leaves the catalog's placements". Why: the builder reads no other module's state (ADR 0596 §2; round 3, seams and tools: R4). How it is checked: whole (builder), a build module stopped on a node deletes that node's key, and the drop tool - deletes one key and logs it; a drop by another caller is refused by the bus. + deletes one key and logs it. - §547 **The sum of the bus's caps is read against its limit.** Measured on 2026-11-11 against an embedded bus (nats-server 2.11.17): an account's storage limit reserves each stream's maximum size when the stream is made (a second stream of 64 MiB under an account limit of 100 MiB is refused, "insufficient storage resources"), and a diff --git a/03-DESIGN/01-to-be/47-milestones/G-13-review-round-3.md b/03-DESIGN/01-to-be/47-milestones/G-13-review-round-3.md index 1df54617..f20a97e7 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-13-review-round-3.md +++ b/03-DESIGN/01-to-be/47-milestones/G-13-review-round-3.md @@ -77,7 +77,7 @@ takes §600 on, since §516 on are those of batch 4's file G-12. - §604 **The builder keeps the toolchains it heard.** (§546) The builder writes each `toolchain-reported` (§492) in a state of its own, `toolchains-heard`, one key `.` holding the version, the recipe, the digest and when it was said, and agrees the version from those keys, read back at its start, so a restart needs no node to report - again. Its manifest `consumes` the three build seats' `toolchain-reported`; its tool `builder_toolchains` lists the + again. Its manifest `consumes` the Go and node build seats' `toolchain-reported` (§702); its tool `builder_toolchains` lists the keys; a key is deleted when the node leaves the catalog's placements (§365's reason). Why: a durable consumer does not deliver an acknowledged event again (review round 2, seams and tools 1). How it is checked: whole (builder), a restarted builder agrees the same version with no new report. diff --git a/03-DESIGN/01-to-be/47-milestones/G-14-recovery-module-and-review.md b/03-DESIGN/01-to-be/47-milestones/G-14-recovery-module-and-review.md index c1b01e9d..35713f16 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-14-recovery-module-and-review.md +++ b/03-DESIGN/01-to-be/47-milestones/G-14-recovery-module-and-review.md @@ -96,8 +96,8 @@ are written into the lines of G-12 they name.* only for the bus names of a module's kept data; the subjects its seat says and its hand-act log write; its consumers of `node-backup`'s `item-started` and `item-ended`, filtered to those two events, each with the ordered consumer §556 needs, from the process's `consumes`; its calls of `node-backup`'s `restore`, which takes its class's default with no own-item limit (§610, §555), and - of `mesh-broker`'s `snapshot-get` and `snapshot-restore` with `snapshot-get`'s chunk subjects (§681); and nothing - else. The bus names granted are those of every kept data + of `mesh-broker`'s `snapshot-get` and `snapshot-restore` with `snapshot-get`'s chunk subjects, and the hearing + of `snapshot-restored` from its `consumes` (§681); and nothing else. The bus names granted are those of every kept data of every catalog graph entry the catalog half keeps (§443) and of every entry a restore point names (an old section's name before a form change, a template's binding after), read by the grants part through `kept-points` (§565); no stream of the mesh's own (`CONTROL`, `NODES`, `EVENTS`, `DEAD_LETTER_NOTICES`, `DEAD_LETTERS`, diff --git a/03-DESIGN/01-to-be/47-milestones/G-17-develop-answers-seventh.md b/03-DESIGN/01-to-be/47-milestones/G-17-develop-answers-seventh.md index ca3f3847..6e18e571 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-17-develop-answers-seventh.md +++ b/03-DESIGN/01-to-be/47-milestones/G-17-develop-answers-seventh.md @@ -100,6 +100,9 @@ for several build maps is answered once, and the maps' names for it are given in serves anything, for each of the four whose old section's last revision is newer than that key, it copies every key changed since: a key whose write in the old section is newer than its template key's replaces it, a key deleted in the old section after its template key's write is deleted in the template, and an older one is left. + A deletion G's gate makes itself in an old section (below) moves that state's mark in `copies` to the + deletion's revision in the same step, so the next start copies only what another gate wrote after it and never + deletes G's ended records from the template. It then writes the mark, and says in its journal and in `gate_records` how many keys it copied and deleted of each. So forward, a revert (whose gate of before G writes the old sections), and forward again carry every change made while reverted, and nothing older overwrites a newer write. @@ -112,7 +115,8 @@ for several build maps is answered once, and the maps' names for it are given in How it is checked: unit (manifest validator), the gate's manifest of G's heads declares `merges` and `source` old and the five templates; whole (gate), forward, then a revert's write and deletion in the old sections, then forward: the template holds the reverted gate's write, the key it deleted is gone, and a key written in the - template after the revert is kept; a delivery G ended is not in the old section the reverted gate reads. + template after the revert is kept; a delivery G ended is not in the old section the reverted gate reads; a delivery ended, then a restart of G's + gate: its ended record is still in the template. ## Reading the catalog half, every part alike - §614 **How a part reads the catalog half per watched branch, once for every part.** (§196, §199, §443, §459, §479, @@ -490,14 +494,13 @@ for several build maps is answered once, and the maps' names for it are given in - **Heard.** The indexer's manifest `consumes` `operator-channel.decided`, on `mesh.seat.operator-channel.event.decided.`, through a durable consumer. A warrant is applied only when its ask's id is the key's current ask and its digest the key's, and when the router's own - record of that ask, read under the indexer's module's name, holds it with `Warrant.For` (ADR 0286 §26, §27, §36), + record of that ask, read under the indexer's module's name on §700's path, holds it with `Warrant.For` (ADR 0286 §26, §27, §36), never the decided event's body alone: it writes the version by compare-and-set and ends the key `applied`. A warrant of a replaced ask writes nothing, said in its journal. A Decline, an expiry or a refusal ends the key with that outcome; the seed's keeps `seed-waits` (§8). - **Ended keys stay readable.** An ended key keeps its outcome, its ask and when, until the next change of the same key replaces it. - - **A restart.** At its start the indexer reads each open key and the seat `operator-channel`'s `asks` for its - ask: a decided one is applied or ended as above, an open one waited on, and one the router no longer holds ended + - **A restart.** At its start the indexer reads each open key and the router's record of its ask on §700's path: a decided one is applied or ended as above, an open one waited on, and one the router no longer holds ended `lost`, said. - **Its tools.** `indexer_proposals` (class `read`) lists the open and ended keys with their asks and outcomes; `indexer_proposal_drop` (`key`, `why`; class `act`, in the hand-act log) cancels the key's open ask and ends it @@ -537,12 +540,12 @@ for several build maps is answered once, and the maps' names for it are given in (each token escaped as a key's name is, §73), capped at 4 MiB, deleted when the wait ends. - **Its events.** It says `wait-held` and `wait-ended` on its own old `streams` section `waits`, on `mesh.stream.mesh-delivery-builder.event.wait-held..` and `.wait-ended..`, - kept last per subject, 7 days, 16 MiB; the body the fields of §629's wait with `step` `building`, `on` + kept last per subject, 7 days, 16 MiB; the body the fields of §629's wait with `step` `build` (§702), `on` `toolchain:@`, `module` and `fingerprint`, and `wait-ended` its `how` (`ran` when a `toolchain-agreed` names that version, `released` by `builder_release`). At its start it says `wait-held` again for every key of `waits`. G-4's table reads so. - **Its bound.** 60 minutes, its setting `toolchain-wait-minutes`; past it the builder writes the finding - `toolchain-waits` (scope the builder, id `.`), cleared when the wait ends. + `toolchain-waits` (scope `build`, id `.`, §702), cleared when the wait ends. - **Its tools.** `builder_waits` reads the state, and `builder_release` builds the entry with the running build module, written in the hand-act log (§276). diff --git a/03-DESIGN/01-to-be/47-milestones/G-18-fix-round-six-seven.md b/03-DESIGN/01-to-be/47-milestones/G-18-fix-round-six-seven.md index 1a5d6fcc..c36b121b 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-18-fix-round-six-seven.md +++ b/03-DESIGN/01-to-be/47-milestones/G-18-fix-round-six-seven.md @@ -38,66 +38,94 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli 2026-11-11): the approval mark once no verb names its callers (the operator's answer of about 16:10 CET, §610); the keeper's snapshots, with the operator's answer O-7 of 20:22 CET (§681); the recovery module's verbs, the entries the node-engine keeps and the grants part's first composition (§682 to §684); the gate before a marked verb's running -(§677, the operator's O-8); and develop's D-16 to D-31, of internal form only. The rounds' other fixes are written in the lines they correct.* +(§677, the operator's O-8); and develop's D-16 to D-49, of internal form only. The rounds' other fixes are written in the lines they correct.* ## 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 0286 §10 to §13, §24, §26 to §31, §36, §37, §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) 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, just with a - 'gate' between the call and the execution"; so a module's call of a marked verb is one call, and the caller never - calls again: - - **The holder keeps the call and asks, under its own module's name.** On a call of a marked verb it serves, - 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`), keeps the - waiting call whole with the caller the bus proved (ADR 0286 §24), asks it through `operatorchannelclient` under - the holder's module's name at level `approve` (ADR 0286 §13, §15 to §23), unless an open ask of that act exists, - and answers the call at once `{asked: , act: }`. Its grants to ask, hear its warrants and read its - own asks are those ADR 0286 §6 and ADR 0259 §3 compose for a module with a mark. - - **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, 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), and runs the kept call, once. - - **The caller hears the outcome on its own subject.** The holder says the act's end on its seat's event - `gated-ended`, subject `mesh.seat..event.gated-ended..`, `` the account the bus - proved, escaped as a key's name is (§73): `{act, ask, verb, outcome, answer, error}`, `outcome` one of `ran` (with - the verb's `answer`), `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; no argument is in it. Every seat definition - with a marked verb gains the event through the seat generator; the grants part grants hearing - `gated-ended..>` to that caller alone, from its `invokes` of the marked verb, as it composes a `by-caller` - verb. mesh-sdk's seat client, in `go/seats` beside the seat server, waits on that subject as a kept wait (ADR - 0668 §1) and reads it whole at its start, so a restart of either side loses no outcome; it makes no second call. + 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) + 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, + just with a 'gate' between the call and the execution"; so a module's call of a marked verb is one call: + - **Only Go holds the gate, and every marked verb is `by-caller`.** The gate is mesh-sdk's Go seat server's; 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). + - **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 + `act.`: it writes that key with the bus's create, naming a new ask, and raises the ask through + `operatorchannelclient` under the holder's module's name at level `approve` (ADR 0286 §13, §15 to §23) only when + 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.`, `` 128 random bits, holding the call + whole, the caller the bus proved and its ask (ADR 0286 §24), and answers at once `{asked: , call: }`. + - **A second call of the same act.** Every call is kept as its own `call.`, 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, + 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 + 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), + 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). + - **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..event.gated-ended..`, `` 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 + 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..>` to that caller alone, 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 `` 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. - **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), so a call whose proved account is a tool runner's is answered with ADR 0286 §37's refusal - naming the ask, and keeps nothing; the same call made again after the Approve is checked as above and runs. + 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 + §37's refusal naming the ask and keeps no call, its ask found and written through `act.` 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 + leaves it out only takes the person's path. - **The holder claims, once, in its own state.** The holder's template state `approvals` (a `requires` entry, 48 - hours to live, 64 MiB) keeps `ask.` (the waiting call whole), `act.` (the newest ask of that act) and - `claimed.`, 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. 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. + hours to live, 64 MiB) keeps `call.`, `act.` and `claimed.`, 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, + 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 + 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 the - node-engine says `running` declares that `approvals` entry, which only a build of G's seat server passes the - validator with; 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: no ordering edge is needed, and nothing runs - unchecked. - - **Before develop.** These lines rest on the record of the approval gate (number to come; its draft is with - lead-47), which changes ADR 0286 §13, §24, §33 and §37 for a module's call and decides §47's question of how a - module's call passes a verb's mark. It is accepted before G's seat server is built from them. + a marked verb, the subscription of that verb's subjects only when the catalog graph entry of the build its want + names (heard by `wanted`, §344) declares that `approvals` entry, which only a build of G's seat server passes 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). 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 round 2: security and upgrade 1 to 3). How it is checked: whole (a fixture marked verb, its holder - and a module's process), one call answered `asked` and run once on the Approve, its outcome heard on - `gated-ended` by that caller and no other; a decline and an expiry run nothing and say so; a restart of the holder - between the ask and the Approve runs the kept call once; a warrant replayed runs nothing; a call through the tool - runner refused with the ask and run on the same call made again; unit (grants part), a holder whose running entry - declares no `approvals` composed with the deny of its marked subjects and named in `withheld`. + own name (review rounds 2 and 3). How it is checked, as cases of the seat server's one whole test (a fixture marked + verb, its holder and a module's process): one call answered `asked` and run once on the Approve, its outcome heard + 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 ``; 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.` 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 + 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. ## 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 @@ -116,19 +144,24 @@ node-engine keeps and the grants part's first composition (§682 to §684); the ## Round 2 of the review: the keeper's snapshots, the recovery module's verbs, the entries the node-engine keeps - §681 **The keeper's snapshot is listed by a tool, sent by the keeper, and never sent when it holds a protected - stream.** (§554, §567, §610; ADR 0626 §1, §3, §4; ADR 0436 §3, §5; ADR 0672 §1, §8; ADR 0667 §12) This replaces - §666 whole. [D-1; review round 2, security and upgrade 4 and 6, seams and tools 6.] + stream.** (§554, §567, §610; ADR 0675; ADR 0626 §1, §3, §4; ADR 0436 §3, §5; ADR 0672 §1, §8; ADR 0667 §12) This + replaces §666 whole. [D-1; review rounds 2 and 3.] - **When it is taken.** The bus module's keeper, taking the snapshot before a `drop` or `recreate` (ADR 0595 §5), writes into that request's record in its state `requests` the snapshot's `path` (under its snapshots directory), - `size`, `digest` (`sha256:` of its bytes) and `protected`, true when the entry has a stream that ADR 0436 §3 lets - no other account hear (the mail passwords' among them), before it touches the live data. A snapshot it cannot - write whole and record so, or one that would pass the directory's cap `snapshots-cap` (a setting, 20 GiB unless - set), makes the `drop` or `recreate` refuse, naming why, before anything is removed; past 80 % of the cap it - writes the finding `snapshots-filling`. + `size`, `digest` (`sha256:` of its bytes) and `protected`, true when the entry has a stream ADR 0436 §3 lets no + other account hear (the mail passwords' among them), before it touches the live data. A snapshot it cannot write + whole and record so, or one that would pass the directory's cap `snapshots-cap` (a setting, 20 GiB unless set), + makes the `drop` or `recreate` refuse, naming why, before anything is removed. Only the snapshots it recorded + count against the cap; one of before G does not. + - **Its fill.** Past 80 % of the cap the keeper writes the finding `snapshots-filling` (scope the bus module, id + `snapshots`), naming the fill and the cap, and clears it once the fill is back under 80 %, each judged at every + snapshot taken and removed and at its start. - **Who deletes it.** The keeper alone, a snapshot and its record kept `snapshot-keep-days` (90 unless set, ADR 0667 §12) after its request: it removes those older at its start and at each new request, each removal written in its journal; nothing waits on a timer, so one may outlive its days until then, which `nats_snapshots` says as - `expired`. + `expired`. By hand, the seat `mesh-broker`'s verb `snapshot-remove` (`request`, or `expired: true` for every + expired one; `why`; class `act`, its default; `by-caller`), written in the hand-act log first, removes one now; a + snapshot of before G it removes only by `request`. - **Listed.** The tools bundle's `nats_snapshots` (class `read`) reads the keeper's state `requests`, as ADR 0626 §4 has the bundle read it, and lists each snapshot: its request, module, local name, stream, `size`, `digest`, `at`, `protected`, `expired` and `recorded`. @@ -137,53 +170,74 @@ node-engine keeps and the grants part's first composition (§682 to §684); the answers `{request, module, local, stream, size, digest, at, chunks}`, then sends the file in chunks of at most 512 KiB on `mesh.seat.mesh-broker.chunk.snapshot-get..`, each acknowledged by the caller on `mesh.seat.mesh-broker.ack.snapshot-get..` within 30 seconds before the next, a missed one ending the - send, said in its journal. The keeper is granted publish of the chunk subjects and subscribe of the - acknowledgement subjects; an account that names `seat:mesh-broker.snapshot-get` in `invokes` is granted the - reverse. Since every such account may ask any snapshot it could hear by the read default, hearing another's - chunks gains it nothing more; a protected one is never sent. A caller granted no chunk subjects (a session - through the tool runner) is answered the fields alone, with `chunks` 0, and no file is sent. The verb answers `error`: `snapshot damaged`, naming - the request, when the file's digest differs from the recorded one; `snapshot missing` when no file is there; + send, said in its journal. The verb says so in its seat definition by the field `chunks: true`, a word of the + definition format that §494's second reader release reads (§621, §697), costing no rebuild beyond that release's. + From it the grants part composes the holder's publish of `mesh.seat..chunk..>` and subscribe of + `.ack..>`, and the reverse for an account that names the verb by name in `invokes`; a `*` entry grants no + chunk subject. Since every such account may ask any snapshot it could hear by the read default, hearing another's + chunks gains it nothing it could not read with the read default, and a protected snapshot's chunks are never + published. A caller granted no chunk subjects (a session through the tool runner) is answered + the fields alone, with `chunks` 0, and no file is sent. The verb answers `error`: `snapshot damaged`, naming the + request, when the file's digest differs from the recorded one; `snapshot missing` when no file is there; `snapshot protected` when `protected` is true; and `snapshot taken before milestone G` for a request record that - holds no `digest`. + holds no `digest`. The read default widens who reads a dropped or recreated module's data beyond its owner (ADR + 0595's kept data reached only by its owner), for this snapshot alone (ADR 0675). - **A protected snapshot is restored in place.** The operator, 2026-11-11 20:22 CET at lead-47's terminal (O-7): - a protected stream's snapshot is never handed out, and is restored only in place by the bus module on the - recovery module's request. The keeper's process serves `mesh-broker`'s verb `snapshot-restore`, `by-caller`, - class `act`, taking its default (§610): it takes `request`, `verify` and `why`, checks the file against its - recorded digest, and with `verify` true answers that and restores nothing; otherwise it restores the snapshot's - stream under its own name only when no live object of that name exists, refusing `names live` before anything - else, and says the outcome on `mesh.seat.mesh-broker.event.snapshot-restored.` (`{request, outcome, - error}`, kept last per subject, 90 days). It is granted the bus's stream restore subjects and their chunk - subjects for that one stream, at that one call. - - **Its use.** `recovery_restore` names a snapshot by `request` (§682). For one that is not protected the - recovery module reads it through `snapshot-get`, checks the bytes against `digest` before it takes any aside - (§567), and restores it itself (§516). For a protected one it asks `snapshot-restore` with `verify` true, then sets - the live data aside (§516), then asks `snapshot-restore`, and waits on `snapshot-restored` of that request, bounded - at 90 minutes; a failure restores the aside under the live names (§516). + the stream snapshot the keeper took before a `drop` or `recreate` of a protected stream is never handed out, and + is restored only in place by the bus module on the recovery module's request; the recovery module's own asides + of restricted streams stay as ADR 0672 §8 and §9 have them. The keeper's process serves `mesh-broker`'s verb + `snapshot-restore`, `by-caller`, class `act`, taking its default (§610): it takes `request`, `verify` and `why`, + answers at once `accepted` with an act id, `busy` or `error` (as §691's form), checks the file against its + recorded digest, and with `verify` true says that and restores nothing; otherwise it refuses `names live` while a + live object of the stream's name exists, before anything else, and restores the snapshot's stream under its own + name, bounded at 60 minutes. It says the outcome on `mesh.seat.mesh-broker.event.snapshot-restored..` + (`{request, act, outcome, error}`, kept last per subject, 90 days), so a retried restore is told apart from an + earlier one. A restore that fails, passes its bound or is cancelled removes the keeper's own partial stream (it + held no live data, since `names live` came first) and then says `snapshot-restored` with `outcome` `failed` + under that act, before the keeper answers anything more of it; one cut off by the keeper's restart is ended so at + its start. `mesh-broker`'s verb `snapshot-restore-cancel` (`act`, `why`; class `act`, its default, `by-caller`) + cancels a running restore so and answers `accepted`, or `error` when that act has ended. "Protected" means a + stream ADR 0436 §3 restricts. The keeper holds a standing grant of the bus's + stream restore subjects and their chunk subjects for the bus names of the streams ADR 0436 §3 restricts, and only + those, and uses them only on a `snapshot-restore` call. + - **Its use.** `recovery_restore` names a snapshot by `request` (§682). For one that is not protected the recovery + module reads it through `snapshot-get` into `incoming/` in its own data directory, refusing before the + first chunk when `size` would pass `points-cap` (§554), checks the bytes against `digest` before it takes any aside + (§567), restores it itself (§516), and deletes the file when the act ends, done or failed, and at its start any + file left there. For a protected one it asks `snapshot-restore` with `verify` true, then sets the live data aside + (§516), then asks `snapshot-restore`, and waits on `snapshot-restored` of that request and the act it was answered, + bounded at 90 minutes, past the keeper's 60. It puts its aside back under the live names (§516) only on that + event's `failed`. At its bound it first asks `snapshot-restore-cancel` and waits on the same event for the + cancel's outcome; only when the keeper answers neither, it puts nothing back, ends `failed` with + `snapshot-restore unanswered` and writes `aside-unrestored` (§561), which `recovery_restore_aside` (§566) clears, + refused while the names are live. Its + account (§554) hears `snapshot-restored`, from its `consumes`. - **A snapshot of before G.** A request record with no `path` or `digest` was written by a keeper of before G: it is listed with `recorded` false, `snapshot-get` and `snapshot-restore` refuse it as above, and the keeper of G - neither sends nor deletes it: it stays where the keeper before G wrote it, as that keeper left it. - - **Before develop.** These lines rest on the record of the keeper's snapshots (number to come; its draft is with - lead-47), which changes ADR 0626 §1 and §3 (the keeper answers the two verbs, publishes their chunks and the event, - and restores a protected snapshot in place), ADR 0436 §3 for that process (it answers a seat's verb), ADR 0672 - §1 (the bus module restores a protected snapshot in place; the read is a verb of the keeper, not a tool) and ADR - 0672 §8 (the recovery module calls `snapshot-get` and `snapshot-restore`), and keeps ADR 0436 §3 and §5 for - every other account: no snapshot of a protected stream leaves the keeper. It is accepted before G's bus module and - recovery module are built from them. + neither sends nor deletes it by age: it stays where the keeper before G wrote it until `snapshot-remove` names it. + - **Its record.** ADR 0675, which changes ADR 0626 §1 and §3, ADR 0436 §3 for the keeper's process, and ADR 0672 + §1, §8 (its read opened to the read default) and §10 (a protected snapshot restored under the stream's own name by + the keeper), keeping ADR 0436 §3 and §5 for every other account. Why: the operator's answers O-6 and O-7; the tools bundle runs as the tool runner and cannot read the keeper's - directory, and a get session resolves objects in a module's binding, not a file (review round 2). How it is - checked: whole (bus module, recovery module, with small settings), a snapshot larger than 256 MiB sent and restored - whole; one asked eight days after its `drop` restored; a file altered on disk refused `snapshot damaged`; a - protected snapshot refused by `snapshot-get` and restored in place by `snapshot-restore`, refused `names live` - while its live stream exists; a request record of before G listed `recorded` false and refused; a `drop` past - `snapshots-cap` refused before it removes anything; unit (grants part), only the keeper publishes the chunk - subjects, and a protected stream's restore subject is granted to the keeper for that call alone. - + directory (review rounds 2 and 3). How it is checked, as cases of the bus module's one whole test and the recovery + module's one whole test, adding no test function to either (with small settings): a snapshot of three chunks sent + and restored whole; a missed acknowledgement ending the send; `snapshot missing`; a file altered on disk refused + `snapshot damaged`; a session through the tool runner answered `chunks` 0; a snapshot removed after + `snapshot-keep-days` at the next request; `snapshots-filling` raised past 80 % and cleared under it; a protected + snapshot refused by `snapshot-get` and restored in place by `snapshot-restore`, refused `names live` while its live + stream exists, a retried restore woken by its own act; no chunk of a protected snapshot ever published; a restore + stopped midway leaving no partial stream; the recovery module's bound cancelling first, then restoring the aside; a request record of before G listed `recorded` false and + refused; a `drop` past `snapshots-cap` refused before it removes anything; unit (grants part), only the keeper + publishes the chunk subjects, a `*` entry gets none, and the keeper alone holds the restore subjects of the + restricted streams' names and of no other stream. - §682 **The seat `mesh-recovery`'s hand verbs: their fields, their answers, and who asked.** (§516, §554, §566, §656; ADR 0672 §4 to §6, §12; ADR 0386 §8) [D-19; review round 2, seams and tools 8.] Each hand verb is `by-caller`, of class `act` taking its default (§610), defined in mesh-contracts with fixtures, and takes, beside its own fields, `why` (required) and `asker`, the caller the tool runner proved and recorded for that call (ADR 0386 §8: who@node, - or `operator`), which the tools bundle's `recovery_*` tool passes and which a module's process leaves out. The + or `operator`), which the tools bundle's `recovery_*` tool passes and which a module's process leaves out. `asker` is a stamp, + no boundary (as ADR 0626 §4 has it): it is taken from any caller and logged beside the account the bus proved, so + a false one is seen. The hand-act log's entry names both the account the bus proved and `asker`: the bus's is the boundary, `asker` names who asked, for the record (as ADR 0626 §4 has the stamp). Each answers at once, as `snapshot-kept` does (§554): one of `accepted` (the act's id), `busy` (the id of the act that runs) or `error` set alone (§691); the result @@ -208,26 +262,37 @@ node-engine keeps and the grants part's first composition (§682 to §684); the Why: the developer's D-19; the bundle calls on the tool runner's account, so the log would name the runner, not the asker (review round 2). How it is checked: unit (mesh-recovery's contract), each verb's fields and answers read - from its fixtures, `restore` with both `snapshot` and `request` refused; whole (recovery module), a hand act's log + from its fixtures, `restore` with both `snapshot` and `request` refused by the schema's `oneOf` (§701); `retry` + with nothing failed answered `nothing to retry`; `cancel` of a begun act refused naming its step; whole (recovery module), a hand act's log entry names the tool runner's account and the asker. -- §683 **The node-engine keeps the entries it composes from on its node.** (§421, §614, §627, §422) [review round 2, - seams and tools 2 and 3.] The node-engine, a foundation part (§627), composes the bus module and the indexer that - serves `mesh-catalog.entry`, so it never relies on `entry` answering to compose: - - **Kept on the node.** Each entry it holds (§614, *An older build's entry*) is kept in its data directory as one - file per fingerprint, written whole and synced before it replaces the old one, and removed when no want or - `running` it holds names that fingerprint; it keeps the wants of its last composition on its node the same way, - one file per module, replaced whole at each composition. At its start it reads both before it asks anything, so a restart composes the bus - module and the indexer while both are down; only a fingerprint it holds no file for is asked of `entry`. - - **Its rows and its ask again, on its seat.** It serves no module tools (§422): its kept entries, with their state - (`asked`, `answered`, `not-found`) and since when, are rows of the seat `node-engine`'s verb `first-views`, and - the seat gains the verb `entry-again` (`fingerprint`, `why`; class `act`, taking its default, §610), both in - mesh-contracts with fixtures, in place of §614's `_first_views` and `_entry_again` for it. +- §683 **The node-engine keeps the entries and wants it composes from in its composition state.** (§421, §614, + §627, §422, §693; ADR 0593 §6) [review rounds 2 and 3.] The node-engine, a foundation part (§627), composes the bus + module and the indexer that serves `mesh-catalog.entry`, so it never relies on `entry` answering at a restart: + - **Kept on the node.** Each entry it holds (§614, *An older build's entry*) and the wants of its last composition + are kept in its composition state on the node (ADR 0593 §6), beside the composition, written whole before the + composition that uses them; an entry is removed when no want or `running` it holds names its fingerprint, and a + module's want when `wanted` says it `removed` (§693). At its start it reads them before it asks anything, so a + restart composes the bus module and the indexer while both are down; only a fingerprint it holds no entry for is + asked of `entry`. + - **They give way to the bus.** The kept wants stand only until the seat `mesh-wants`' stream answers its read of + §556; from then the stream's wants are the ones it composes from, so a revert then an upgrade never composes from + a want older than the stream's. Until its first live answer its have says it composes from kept wants and + entries, and a kept part it cannot read is said in its have and its log, that module composed as its running + composition stands and its entry asked of `entry`. + - **Its first start.** The node-engine of G names `seat:mesh-catalog.entry` in its `invokes` (§614), so by §558's + kind 6 its G version runs on a node only after the indexer of G answers `entry`; the bus module and the indexer + of G are composed by the node-engine of before G, as on main. A node-engine of G at its first start, or on a newly + adopted node, holds nothing kept and asks `entry` of the indexer that runs. + - **Its rows and its ask again, on its seat.** It serves no module tools (§422): its kept entries and kept wants + are rows of the seat `node-engine`'s verb `first-views` (§698), and the seat gains the verb `entry-again` + (`fingerprint`, `why`; class `act`, taking its default, §610), both in mesh-contracts with fixtures, in place of + §614's `_first_views` and `_entry_again` for it. Why: the node-engine composes before the bus answers (§627). How it is checked: whole (node-engine), a node-engine - restarted with the bus module and the indexer stopped composes both from its kept files; unit (the seat's - contract), `first-views` rows of kept entries and `entry-again` read from fixtures. - + restarted with the bus module and the indexer stopped composes both from its composition state; a kept part made + unreadable is said and asked again; a revert then an upgrade composes from the stream's wants once it answers; + unit (the seat's contract), `first-views` rows and `entry-again` read from fixtures. - §684 **The grants part composes a want's account before any branch view.** (§614, §507, §558, §374) [review round 2, seams and tools 1.] The grants part follows the branches as §614 has it, from the gate's `source` with no branch (named in its `invokes` in the long form, `{verb: seat:mesh-delivery.source, fields: [branches]}`, §558), so its @@ -239,26 +304,35 @@ node-engine keeps and the grants part's first composition (§682 to §684); the 7-approval-mark §19); it writes that account into the user list it keeps, and says in its log and in `_first_views` that it composed it before its first views. Its full pass, once the first views are in, composes every account again as always. So the gate's G version is granted before it answers, and no cycle stands. + - **The indexer's own account.** `entry` is served only by the indexer of G, so the grants part of G names + `seat:mesh-catalog.entry` in its `invokes` and, by §558's kind 6, runs only after the indexer of G answers; + the indexer of G's account is composed by the grants part of before G, as on main, so no cycle runs through the + indexer. + How it is checked: whole (grants part, gate), with the gate of before G running and a want of the gate's G - version, the grants part composes that account before any branch view, and its full pass once `source` answers. + version, the grants part composes that account before any branch view, and its full pass once `source` answers; + whole (delivery plan), G's indexer is composed while the grants part of before G runs, and the grants part's G + version is ordered after it. ## Develop's D-20 to D-23 - §685 **A condition carries `owner` and `waiting-on`.** (§451, §540, §678) [D-20, mesh-catalog COND7.] The seat `mesh-conditions`' definition gives a condition, in its state `conditions` and in every condition event, the - fields `owner` and `waiting-on`, beside `resolver`, which keeps its own meaning (who resolves it: `self`, + fields `owner` and `waiting-on`, both optional, beside `resolver`, which keeps its own meaning (who resolves it: `self`, `operator`, `agent` or `healer:`). Each takes §678's three forms, refused otherwise, naming the field. The keeper sets both from the finding when it raises the condition, and changes them only as §540 says (the two hours' handover to `operator-channel`, and `conditions_owner`), saying each change as it says any change of a condition. + A condition kept from before G carries neither and is read as having none; the keeper writes them into it at its + next change. How it is checked: unit (mesh-conditions' contract), both fields read in the state and the events in each form; whole (keeper), a `pipeline-failed` raised with the author's `forge:` owner and changed to `operator-channel`. - §686 **The generated finding type carries its accessors; the writer takes it through an interface.** (§439, §640) [D-21.] The seat generator emits, beside each Go type generated from the finding layout of `mesh-conditions`' `bodies`, in the same generated package of mesh-contracts, methods on its pointer: one getter and one setter per field the writer reads or fills (`kind`, `scope`, `id`, `at`, `since`, `severity`, `summary`, `headline`, `source`, - `subject`, `observer`). mesh-sdk's Go writer defines the interface `findings.Body` with those methods and takes a - `findings.Body` and a constructor of one (`func() findings.Body`, the generated `New`); it uses no generics. In + `subject`, `observer`). mesh-sdk's Go writer defines, in `go/views`, the interface `views.FindingBody` with those methods and takes a + `views.FindingBody` and a constructor of one (`func() views.FindingBody`, the generated `New`); it uses no generics. In TypeScript the generated type is structural: the writer's interface names those fields as properties, set by assignment, and no setter is generated. How it is checked: unit (seat generator), the methods generated; unit (writer, both languages), a generated body written, its `observer`, `at` and `since` set by the writer. @@ -281,7 +355,8 @@ node-engine keeps and the grants part's first composition (§682 to §684); the `FindingFor`, `FindingWriter` and `FindingState`, `FindingVersion`, `Observation` (with its `Key` and `Finding`), `EncodeFinding`, `DecodeFinding`, `Says`, `FindingBucket`, `FindingsBucket`, `Raise`, `Clear` and `CallUnanswered`. `CheckFinding`'s rules (the key's parts, the kind, §678's forms) live only in mesh-sdk's writer, which refuses a - finding breaking them before it writes, and which exports that check for the keeper. What concerns conditions + finding breaking them before it writes, and which exports that check for the keeper as `views.CheckFinding(b views.FindingBody) error`, in `go/views`, returning the + first rule broken, naming its field (§686; D-35). What concerns conditions stays: `Key`, `EventFor`, `ShowKeeper`, `SilenceAction`, `Order`, `SilencedAt`, `Escalated`, `ResolverHealer`, the scope, resolver and severity words, `KindCallUnanswered`, `CallUnansweredAfter` and the package `heard`. The importers move in G's change: every part that writes findings writes them through mesh-sdk's writer and the @@ -302,16 +377,23 @@ node-engine keeps and the grants part's first composition (§682 to §684); the reader (§614), the part's new entry, it stops reading the old source and keeps the part's open conditions. - **The keeper takes the new source.** For a template stream on the seat `mesh-broker`'s `created` of the part's new `finding-events` entry, for an old section's stream from the catalog half, as §663 has it; it binds the - consumer the grants part makes as a kept call (ADR 0668 §1), so a consumer made after `created` is bound once it - exists, the source said waiting in its log meanwhile; once bound it asks `findings-asked` there once (§663). - - **The gate's `source` in the seat's definition.** The seat `mesh-delivery`'s definition in mesh-contracts gives + consumer the grants part makes as a kept call (ADR 0668 §1: a call made again on its schedule until it succeeds, + kept in the keeper's state), so a consumer made after `created` is bound once it exists, the source said waiting + in its log meanwhile; once bound it asks `findings-asked` there once (§663). Past 10 minutes unbound it writes the + finding `consumer-unbound` (scope the keeper, id the part's module), cleared once bound. + - **The message on a template stream.** A finding event on `mesh.bus..finding-events..` is + mesh-sdk's event envelope that every event publisher writes, its body under `body`; the keeper reads the module + and the node from the subject's tokens and the event's name from ``. [D-36.] + - **The gate's `source` in the seat's definition.** The seat `mesh-delivery`'s definition in mesh-delivery's + contracts (built there, not in mesh-contracts) gives `source` the optional input `branch` and two answers: with `branch`, that branch's source revision, as on main; without, `{branches}`, the list of the branch names of the `source.` keys the gate keeps (§614), the field `branches` that §684's long-form `invokes` names; with a fixture of each. How it is checked: unit (grants part), an entry whose finding stream moved composes the old consumer's deletion and the new one's making; whole (keeper, grants part, bus module), a part whose findings move to a template is bound on - the new stream after its consumer is made, its condition raised once; unit (`mesh-delivery`'s contract), both + the new stream after its consumer is made, its condition raised once, and `consumer-unbound` raised past 10 + minutes while unbound; unit (`mesh-delivery`'s contract), both answers of `source` read from their fixtures. ## The operator's O-8, and develop's D-26 to D-31 @@ -335,8 +417,11 @@ node-engine keeps and the grants part's first composition (§682 to §684); the `removed`, a boolean, true when the assigner removes the want of that node and module (the node left, or the module was unplaced); `fp` is then the fingerprint last wanted there, and the subject is the one that want was said on, so the stream kept last per subject keeps the removal as that want's last word. The assigner says it in the same - write that removes the want. How it is checked: unit (assigner), an unplaced module's want said `removed`; unit - (indexer), a `removed` empties that member from `named`. + write that removes the want. Every consumer of `wanted` reads `removed` in G's change: the indexer (§675) removes + the member from `named`; the grants part (G-9 §344) composes no account for that want; every §614 reader removes + that want from what names a kept entry; the node-engine (§683) removes its kept want. How it is checked: unit (assigner), an unplaced module's want said `removed`; unit + (indexer), a `removed` empties that member from `named`; unit (grants part, each §614 reader, node-engine), each + reads a `removed` so. - §694 **An image's package name is its module's and its artifact's.** (§676, §491) [D-28.] An image artifact's `package` is `{ecosystem: image, name: /}`, its module's name and its artifact's name from the manifest joined by `/`, unique as module names are; the indexer writes it at take-in, reading no file for it, and @@ -345,7 +430,7 @@ node-engine keeps and the grants part's first composition (§682 to §684); the - §695 **An old state section's cap is its `max-mib`.** (§469, §494, §588, §667, §672, §675) [D-29.] A cap the design gives an old `state` section is declared in that section's entry of the part's manifest as `max-mib`, the word §469 added to the old section and §494's reader release reads: the indexer's `entry-index` 8, `named` 4 and `proposals` - 4, the builder's `publish-queue` 4, `acted` 1 and `waits` 16, each in G's change of that manifest; the grants part + 4, the builder's `publish-queue` 4, `acted` 1 and `waits` 4 (§672; its stream `waits` keeps its 16 MiB), each in G's change of that manifest; the grants part makes the bucket with it (§494). How it is checked: unit (manifest validator), each of those manifests at G's heads declares its caps; whole (grants part), a bucket made with its cap. - §696 **A pipeline wait's `on`.** (§534, §498, §266) [D-31, mesh-contracts CT14.] A wait with `step` `pipeline` @@ -360,3 +445,79 @@ node-engine keeps and the grants part's first composition (§682 to §684); the which blocks only new claims of the seat (ADR 0636 §3). How it is checked: G's check reads every definition with `by-caller` through the release's reader. +## The final fix: develop's D-33 to D-38 + +- §698 **The node-engine's `first-views` rows and `entry-again`'s answer.** (§683, §422) [D-33.] `first-views` + answers `{first-views, entries, wants}`: `first-views` as today; `entries` a list of `{fingerprint, state, since}`, + `state` one of `asked`, `answered` and `not-found`; `wants` a list of `{module, fingerprint, kept-since}`, the kept + wants of §683. `entry-again` answers as `first-view-again` does: `asked` `{v, fingerprint, why, by, at}` and `read` + `first-views`. How it is checked: unit (the seat's contract), both answers read from fixtures. +- §699 **A state a seat offers as a view says so.** (§616; ADR 0571 §6) [D-34.] A state entry of a seat definition + takes the optional field `view: true`; the seat `mesh-module-assigner`'s states `assignments` and `seat-holders` + carry it. The definition format's schema and mesh-sdk's `seatdef` reader gain the field, read first by §494's + second reader release (§621, §697); the manifest validator refuses a `seat:` view in `consumes` naming a state + without it. How it is checked: unit (`seatdef`), `view` read and an unknown field still refused; unit (manifest + validator), a view of a state without `view` refused. +- §700 **A process reads the router's record of its asks from the bus, under its own name.** (§667, §677; ADR 0259 + §3; ADR 0286 §26) [D-37.] The one path: the read of the seat `operator-channel`'s state `asks` under + `.`, which the grants part composes for every user of the seat (ADR 0259 §3; design 46 7-approval-mark + §7), on the process's own account; its value carries the ask's `warrant` (7-approval-mark §14). mesh-sdk's + `operatorchannelclient.Client` is given, as its `Record`, a get of that key on the process's own bus connection + (`go/process`), as the tool runner gives it the runtime's `mesh/seat.record`; `Where` and `Warrant.For` are the + same. The indexer (§667, its *Heard* and *A restart*) and every holder of §677 read so; the verb `asks` stays as it + answers. How it is checked: unit (`operatorchannelclient`), `Where` through a process's get; whole (indexer), a + warrant applied from that read. +- §701 **`resync`'s and `retire`'s classes; `restore`'s one of two.** (§610, §682) [D-38.] The seat + `mesh-conditions`' `resync` is of class `act`, and the seat `mesh-vault`'s `retire` of class `warrant`, since its + definition binds it to the operator's warrant on exactly its node, module and name; each takes its class's default. + The seat `mesh-recovery`'s `restore` input holds `snapshot` and `request` under a `oneOf`, so the schema refuses + both or neither, and the holder answers that refusal as `error`. How it is checked: unit (each seat's contract), + the classes read; `restore` with both refused by the schema. + +## The final fix: the builder's D-39 to D-44, and two fields + +- §702 **The builder's toolchain wait, in the contract's words.** (§672, §629, §546, §604) [D-39 to D-44.] + - **Its finding's scope** is `build` (a scope the finding layout has), id `.`; §672 reads so. + - **Its step** is `build`, the contract's word; §672's `building` reads `build`. + - **Its body is the contract's wait.** The seat `mesh-wants`' wait in mesh-delivery's contracts gains `owner`, + `on` and `words` (§629, §512 name them), and `module`, `fingerprint` and `how` as optional fields; the builder + says its `wait-held` and `wait-ended` with that type and keeps no body of its own. + - **The build module of a language** is read through the builder's language mapping as it stands + (`buildrun.BuildModuleOf`, from the seats' `acts` rules in the seat list); §546's words name that read. + - **A superseded wait ends.** When the builder holds an entry of a newer fingerprint of the same module, it ends + the older wait with `how` `superseded` and deletes its key. + - **Two build seats report a toolchain.** §604's "the three build seats' `toolchain-reported`" reads "the Go and + node build seats'": the image build seat's builds name no toolchain and it reports none. + + How it is checked: unit (builder), a wait said with the contract's type, scope `build` and step `build`; a newer + fingerprint ends the older wait `superseded`. +- §703 **A stream kept last per subject says so in its manifest, and `running` says `stopped`.** (§695, §396, §365) + A manifest's `streams` entry takes `last-per-subject` (yes or no, no unless set), as a seat event's `keep` does + (§396), read by §494's second reader release beside `max-mib`; every old `streams` section the design keeps last + per subject (the builder's `waits`, §672, among them) declares it in G's change. The node-engine seat's `running` + body says a module no longer held by `stopped: true`, with no `fingerprint`, as §365 has it; the seat's definition + gains the field. How it is checked: unit (manifest validator), `last-per-subject` read; unit (the seat's + contract), a `running` with `stopped` read. +- §704 **The indexer's seed, `unwatch`, its asks and its history, in the contract's words.** (§2, §8, §402, §667) + [D-45 to D-49.] + - **The seed's `steps`.** For each artifact of a module's entry the indexer asks `steps` of the build seat whose + `acts` rule `build` has `on` matching that artifact's language or kind (§203, §324), read from the seat list as + the builder's mapping reads it (§702), with `{module, artifact, fingerprint, fetch}`: the artifact's key in the + entry, the entry's build-input fingerprint and the entry's `fetch` of its source, as the entry carries them. + - **Its findings.** `call-unanswered` has scope `call`, id `.steps`, cleared when that seat answers; + `seed-waits` has scope `seat`, id `mesh-catalog.seed`, cleared by the warrant and kept after a Decline or an + expiry (§8). + - **`unwatch`'s placements** are read through the seat `mesh-module-assigner`'s verb `placement`, named in the + indexer's `invokes`: a placement names the branch when its `build` is a fingerprint listed by that branch's newest + revision and by no other watched branch's. + - **An ask's lifetime** is the router's approval maximum less ten minutes, as mesh-config's asks are. + - **A branch named `candidate` or `entry`** is refused with the reason `reserved branch name`, which the seat + `mesh-catalog`'s contract gains, not `unprotected branch`. + - **`registration-history`** is declared with no age limit and a cap of 64 MiB (`max-mib`), discarding a new + message when full rather than dropping an old one, so no version is lost unsaid: a registration change whose + history write is refused fails, naming the stream, and past 80 % the indexer writes the finding + `registration-history-filling` (scope `seat`, id `mesh-catalog.registration-history`), cleared under it. + + How it is checked: unit (indexer), the seed's `steps` input per artifact; `unwatch` refused through a fixture + `placement`; `candidate` refused with `reserved branch name`; a full history refusing a change and naming it. + diff --git a/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md b/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md index cd16538d..99d5d9e4 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md +++ b/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md @@ -157,8 +157,7 @@ record says so in its Why. Round 3 of the review by architectural domain (2026-1 (`mesh.seat.mesh-conditions.event.findings-asked`, carrying `ask`, `at`, `by` and, to ask one, `module`), declared in the seat's definition, kept 7 days and 16 MiB; an observer hears it through mesh-sdk's writer on a consumer that starts from the newest ask, so an old ask is never answered again. The keeper asks after its start (§388) and on - `resync` (ADR 0564 §12), which gains an optional `module` and so reads no state; its callers are the operator, the - healers and agent sessions, and each call is written in the hand-act log of the seat `mesh-hand-acts`. An observer + `resync` (ADR 0564 §12), which gains an optional `module` and so reads no state; it is of class `act`, taking its default (§610, §701), and each call is written in the hand-act log of the seat `mesh-hand-acts`. An observer that states nothing within five minutes of an ask, its machine not away (§389), is the keeper's finding `findings-unstated`, naming the module and the node, cleared by its next `findings-stated`; its conditions stand meanwhile. `findings-unstated` is held under ADR 0564 §13's hold while its module is being delivered, and G's diff --git a/03-DESIGN/01-to-be/47-milestones/G.md b/03-DESIGN/01-to-be/47-milestones/G.md index d7ef65a2..1a119cca 100644 --- a/03-DESIGN/01-to-be/47-milestones/G.md +++ b/03-DESIGN/01-to-be/47-milestones/G.md @@ -101,6 +101,6 @@ The part is eighteen files, each read whole, its design lines numbered across th - [G-15-develop-answers-fifth](G-15-develop-answers-fifth.md): develop's fifth batch, round 3's notes on §516 to §559, the knowledge base's review of the recovery module's record, and the operator's answers of 2026-11-11 about 14:05, 14:15 and 14:30 CET (§560 to §586). - [G-16-develop-answers-sixth](G-16-develop-answers-sixth.md): develop's sixth batch: the ledger's upkeep calls, the builder's publishes again and its read of a module's builds, one event of a node's capabilities, the object stores' caps, the gate's merge path from G's delivery, and the readers of a module's manifest (§587 to §594). - [G-17-develop-answers-seventh](G-17-develop-answers-seventh.md): develop's seventh batch: the operator's answers of 2026-11-11 15:14 to 15:42 CET (callers by class, the five parts' findings, the forge and image registry's other entries, the gate's kept data), how every part reads the catalog half per watched branch, and the refreshed build maps' questions (§610 to §676). -- [G-18-fix-round-six-seven](G-18-fix-round-six-seven.md): the fix round of §587 to §676: the approval mark once no verb names its callers, the keeper's snapshots, the recovery module's verbs, the node-engine's kept entries, the gate before a marked verb's running, and develop's D-16 to D-31 (§677 to §697). +- [G-18-fix-round-six-seven](G-18-fix-round-six-seven.md): the fix round of §587 to §676: the approval mark once no verb names its callers, the keeper's snapshots, the recovery module's verbs, the node-engine's kept entries, the gate before a marked verb's running, and develop's D-16 to D-49 (§677 to §704). Design 34's milestone [every-event](../34-milestones/every-event.md) and design 46's milestone [7-approval-mark](../46-milestones/7-approval-mark.md) ship in milestone G's release, built in its repositories beside G's lines (lead-47, 2026-11-11 15:30 CET); where one of their lines and a line of G differ, G's later line holds and the other is corrected in place (§624 to §626).