From 51c6dcbe4603f19668cb43f4858d541968539f94 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 20:35:34 +0100 Subject: [PATCH] Fix design 47 G's batches 6 and 7 by review round 2, O-7 and develop's D-19 to D-25 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The holder of a marked verb a process serves now asks, checks and claims the warrant itself, under its own name and in its own state, and a holder of before G is never reached (§677). The keeper's snapshot is sent by the keeper's own verb and a protected stream's never leaves it, restored in place (§681, the operator's O-7). The recovery module's hand verbs get their fields, answers and asker (§682); the node-engine keeps its entries on its node (§683); the grants part composes a want's account before its first views, so no cycle stands (§684). The republish queue is kept on the bus, §588 rests on ADR 0674, and D-20 to D-25 are §685 to §690. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- .../G-12-develop-answers-fourth.md | 2 +- .../G-14-recovery-module-and-review.md | 32 +-- .../G-16-develop-answers-sixth.md | 32 ++- .../G-17-develop-answers-seventh.md | 81 +++--- .../47-milestones/G-18-fix-round-six-seven.md | 264 ++++++++++++++++-- .../G-4-revision-view-and-steps.md | 4 +- .../47-milestones/G-9-prepare-answers.md | 5 +- 03-DESIGN/01-to-be/47-milestones/G.md | 2 +- 8 files changed, 329 insertions(+), 93 deletions(-) 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 9d135f14..e61a4c62 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 @@ -255,7 +255,7 @@ that round are written into the lines they name, here. Questions that an earlier finding raised before their move is still raised after it. - §540 **The keeper hands a failed head to the operator after two hours.** The condition keeper raises `pipeline-failed` (§33) with `owner` the commit's author, as the runner's finding names it, and two hours after the - finding's `since` sets the condition's `owner` to `operator-channel`, the seat the operator is asked through (a + finding's `since` sets the condition's `owner` (a field of the condition, §685) to `operator-channel`, the seat the operator is asked through (a seat's name, §451), and says that change as it says any change of a condition; the runner's finding keeps the author. §451's `owner` and `waiting-on` gain a third form, `forge:`, the commit's author as the forge names it. A `pipeline-failed` for a newer failing head is a finding of its own, its id naming that commit, so it is 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 aba7ee3b..994bc278 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 @@ -41,14 +41,14 @@ are written into the lines of G-12 they name.* - §554 **The recovery module takes, sets aside and restores kept data on the live bus.** The operator, 2026-11-11 12:55 and 13:02 CET at lead-47's terminal: a module of its own, on a seat of its own, with an account of its own, owns snapshotting, setting aside and restoring a module's kept data on the live bus, each act in the - hand-act log; the bus module keeps no restore permission (ADR 0626 §1 stays as it is), the snapshot account stays + hand-act log; the bus module keeps no restore permission but a protected snapshot's restore in place (§681, O-7), the snapshot account stays limited to the nightly dump (ADR 0626 §2), and the backup holder only stores copies. ADR 0672 decides the account, its grants and its callers; this line is written to it. - **What it alone does.** It alone takes a restore point before a module moves across a `form` change, and alone restores into the live bus. The bus module's snapshot before its own `recreate` or `drop` (ADR 0595 §5, ADR 0626 §4) and the nightly dump (ADR 0626 §2) stay theirs. The restore ADR 0667 §12 tests of the snapshot `drop` takes is - the recovery module's `recovery_restore` naming that snapshot, which it reads through the bus module's tool - `nats_snapshot_get` (class `read`, taking its default, §610; its arguments and answer §666). + the recovery module's `recovery_restore` naming that snapshot, which it reads through the seat `mesh-broker`'s + verb `snapshot-get`, or has the keeper restore in place by `snapshot-restore` when it is protected (§681). - **Its seat, module and node.** The seat `mesh-recovery`, held once for the mesh, is defined in mesh-contracts beside `mesh-broker`, and the module `mesh-recovery`, in mesh-catalog, claims it; its glossary word is the *recovery module*. It runs on the node of the holder of `mesh-broker`, read from the catalog half and the seat @@ -77,8 +77,8 @@ are written into the lines of G-12 they name.* no person's warrant, the data staying in the aside until the operator discards it; setting aside without restoring is the operator's hand tool `recovery_aside`, and discarding an aside the hand tool `recovery_discard_aside`, both of class `act`, taking its default (§610), written in the hand-act log first, each a verb of the seat (§656); `restore-kept` refuses - `aside-only` and `discard-aside`, naming them (§516). The hand tools are checked by the identity of who asked: they are taken only from the operator's account as the bus proves it, and from sessions - acting on it as for every `act` tool (§391), with no warrant asked per act. Each act is written in the hand-act log of the seat `mesh-hand-acts` first, with the caller the + `aside-only` and `discard-aside`, naming them (§516). The hand tools are checked by the identity of who asked: each takes its class's default (§610), the bus proves the + calling account and the verb logs it with the `asker` the tool runner proved (§682), with no warrant asked per act. Each act is written in the hand-act log of the seat `mesh-hand-acts` first, with the caller the bus proved and `why`; an act whose log write fails does nothing and answers `error`, naming the log (as §480). - **The operator's hand tools.** `recovery_take` (take a point of one module and kept data now), `recovery_restore` (restore one point) and `recovery_retry` (ask again the last failed act of a module and kept data), each of class @@ -87,17 +87,17 @@ are written into the lines of G-12 they name.* - **Its account.** The operator, 2026-11-11 about 14:15 CET at lead-47's terminal (the knowledge base's review of ADR 0672, R3): the recovery module is one process with a bus account of its own (ADR 0436 §1, as ADR 0626 §1 has the bus module's keeper), which holds the seat `mesh-recovery` and answers its verbs itself; each verb is one its - caller names (`by-caller`, ADR 0259 §3), so the bus proves who calls: a node-engine's account for `snapshot-kept` - and `restore-kept`, and the tool runner's account, which the sessions and the operator reach the bus as, for its - hand acts. Its tools bundle, carried by the tool runner, calls those verbs and holds no grant of its own. ADR 0672 + caller names (`by-caller`, ADR 0259 §3), so the bus proves who calls, each taking its class's default (§610): a + node-engine's account for `snapshot-kept` and `restore-kept`, and the tool runner's account, which the sessions and + the operator reach the bus as, for its hand acts, are the callers it serves in practice. Its tools bundle, carried by the tool runner, calls those verbs and holds no grant of its own. ADR 0672 §4 records that this changes ADR 0436 §3 and §5 for this process alone. The account is composed by the grants part from the seat's definition and the process's `bus` declaration: the bus's stream snapshot and restore subjects with their chunk subjects, a stream's deletion and a durable consumer's creation, 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` as the caller `holder:mesh-recovery@same-node`, which - `node-backup`'s definition names for `restore` and which the backup holder takes only for the recovery module's - own item `points` (the operator, 13:02 CET); and nothing else. The bus names granted are those of every kept data + 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 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`, @@ -133,7 +133,7 @@ are written into the lines of G-12 they name.* design's (review rounds 1 and 2; ADR 0672). How it is checked: test 36 with the real backup holder and the recovery module; unit (grants part), the recovery module's account holds exactly the grants above, a call outside its names refused, both a point's old-section names and a template's binding granted, and the bus module's and the snapshot - account's hold no restore; whole (recovery module), a call from an account that is no node-engine's refused, a + account's hold no restore; whole (recovery module), a hand act's log naming the account the bus proved and the asker, a `busy` answer then the act on the other's `ended`, a second form change not woken by the first's `ended`, a dump asked during a restore starting after `restored`, a restart during the dump starting no restore, an act whose hand-act log write fails doing nothing, an unrestored aside failing the health check, a node-engine's `restore-kept` with `aside-only` or `discard-aside` @@ -143,13 +143,13 @@ are written into the lines of G-12 they name.* the recovery module's data item as any item, and the restore points and asides are listed by `kept-points` (§517), an aside discarded by the hand tool `recovery_discard_aside` (§554); §303 and test 36 name the recovery module where they named the backup holder and the bus module; §337's and §405's callers `holder:node-backup@same-node` go with the two verbs of - `mesh-broker`, which gains none; the seat `node-backup` gains nothing for kept data on the bus: its `aside` and + `mesh-broker`, which gains only §681's `snapshot-get` and `snapshot-restore`; the seat `node-backup` gains nothing for kept data on the bus: its `aside` and `discard-aside`, the arguments `kept`, `form` and `fingerprint` of its `now` and `restore`, and its events `ended...` and `restored...` go from its definition in mesh-contracts, and - it gains only `item-started` and `item-ended` with their `` token, and names `holder:mesh-recovery@same-node` - among `restore`'s callers for the recovery module's own item (§554); §450's `aside` answer is `recovery_aside`'s; + it gains only `item-started` and `item-ended` with their `` token, its `restore` taking its class's default + with no own-item limit (§610); §450's `aside` answer is `recovery_aside`'s; §406's catch-up is recorded in the point as before. Why: one owner of the acts (§554). How it is checked: unit - (definitions), `node-backup` and `mesh-broker` hold none of the moved verbs; test 36. + (definitions), `node-backup` and `mesh-broker` hold none of the moved verbs, `mesh-broker` only §681's two; test 36. ## The review of §516 to §553, round 1 diff --git a/03-DESIGN/01-to-be/47-milestones/G-16-develop-answers-sixth.md b/03-DESIGN/01-to-be/47-milestones/G-16-develop-answers-sixth.md index dcfadc5e..85de420e 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-16-develop-answers-sixth.md +++ b/03-DESIGN/01-to-be/47-milestones/G-16-develop-answers-sixth.md @@ -68,20 +68,30 @@ answer of 2026-11-11, between 15:14 and 15:42 CET. A line of another file that o artifacts the build stored, by their digests, to the holder of the registry seat of their kind, under the same version, and builds nothing, so it takes no build capacity. - **By itself, on an event.** The operator, 2026-11-11 between 15:14 and 15:42 CET at lead-47's terminal, decided by - the record of the builder's publish again (number to come), which extends ADR 0673 to publishes: the builder + ADR 0674 (the builder's publish again), which extends ADR 0673 to publishes: the builder publishes again, by itself, every reserved version `version-unreleased` names (§369), on the node-engine seat's `running` of a module whose catalog graph entry claims the registry seat of the missing artifacts' kind, on any node, and on the node-engine seat's `manifest-reads-changed` with `why` `returned` of the node that holder runs on (ADR 0673 §2, §590); one with `why` `started`, or with none, publishes nothing. No timer. The builder's manifest `consumes` both events (it does for ADR 0673 already). - **Each event once.** The builder acts on a message of those subjects at most once, by its stream sequence: it - keeps, in its old `state` section `acted`, the last sequence it acted on per subject, so the read of §556 at its - start acts on each subject's last message only when that is newer than the kept one, and a message read again - after a restart starts nothing. - - **One queue per holder.** Each registry seat holder has one queue of versions to publish, sent one at a time, - each bounded by §369's 10 minutes; a version already queued or being published is not queued again. One event - queues at most `republish-max-versions` versions (a setting, §633, 50 unless set), at most one per `MAJOR.MINOR` - of each module (§369's key), the newest keys first; the rest wait for the next event or the tool. + keeps, in its old `state` section `acted`, one key per subject holding the last sequence it acted on, so the read + of §556 at its start acts on each subject's last message only when that is newer than the kept one, and a message + read again after a restart starts nothing. The keys are one per subject of those two events, at most one per + module and node, about 0.1 KiB each; the section is capped at 1 MiB. + - **One queue per holder, kept on the bus.** Each registry seat holder has one queue of versions to publish, sent + one at a time, each bounded by §369's 10 minutes; a version already queued or being published is not queued + again. The queues are kept in the builder's old `state` section `publish-queue`, one key per queued version, + `..` (each token escaped as a key's name is, §73), holding its artifacts' digests, + when it was queued and whether its publish has begun; a key is deleted when its outcome is said. At its start the + builder reads the section whole and takes up every queued version again, a begun one sent anew (a publish of the + same digests under the same version, which the holder takes as it takes §52's), so a restart loses none. The + section is capped at 4 MiB (about 0.5 KiB a key); a version that would pass it is not queued, said in + `version-unreleased` as `queue full`, and waits for the next event or the tool. One event queues at most + `republish-max-versions` versions (a setting, §633, 50 unless set), at most one per `MAJOR.MINOR` of each module + (§369's key), the newest keys first; the rest wait for the next event or the tool. `builder_publish_queue` (class + `read`) lists the queued versions per holder, in order, with when each was queued and whether it has begun, and + the `acted` keys with their sequences. - **An artifact no store holds.** It is named once in `version-unreleased` as not stored, and is not tried again on events: its build key is built again by `builder_build_again`, which reserves anew. - **The failure still said.** A publish that fails again keeps `version-unreleased` with the holder's words and @@ -92,8 +102,7 @@ answer of 2026-11-11, between 15:14 and 15:42 CET. A line of another file that o `MAJOR.MINOR`; with neither, every version `version-unreleased` names, one module after another, the newest key first. It queues as the events do and answers at once with the versions it queued; each outcome is said as `package-published`, or left in `version-unreleased` with the holder's words. - - **Before develop.** These lines rest on the record of the builder's publish again, accepted before G's builder - is built from them; its number replaces "number to come" here. + - **Before develop.** These lines rest on ADR 0674, accepted before G's builder is built from them. Why: the operator's answer; §369 gave the tool one version, and a recovery of a registry holder away for hours left many (issue 1966 note 206); the queue, the sequence, the cap and the unstored artifact are the design's @@ -102,7 +111,8 @@ answer of 2026-11-11, between 15:14 and 15:42 CET. A line of another file that o `why`, once per message: a restart reading the same last message starts nothing; a version queued is not queued twice; one event queues at most the setting's number; an unstored artifact is named once and not tried on the next event; whole (builder, a fake registry holder away and back), every unreleased version published with no hand act, - one at a time; one call with neither argument publishes three modules' versions. + one at a time; a restart with three versions queued publishes the three; a fourth past the cap is said `queue full`; + one call with neither argument publishes three modules' versions. - §589 **`builder_build` answers a module's build keys whole.** (§348, §568, §575; *one-question-one-tool*) The builder's tool `builder_build` (class `read`) takes `module` and, optional, `fingerprint`. With `fingerprint`, it answers that key whole; with `module` alone, the module's build keys newest first, at most 20, each with its 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 3b40b411..22ccd735 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 @@ -54,8 +54,8 @@ for several build maps is answered once, and the maps' names for it are given in validator refuse the field, naming the verb or tool, and every `callers` G's heads carry goes in G's change. So `git`'s `tag` (§370), the build seats' `run` (§229), `node-backup`'s `now`, `restore`, `aside` and `discard-aside` (§405, §555), `restore` taking any module's item (no own-item limit), `mesh-recovery`'s `snapshot-kept` and - `restore-kept` (§554, §659), the bus module's `nats_snapshot_get` (§554, §666), the node-engine's eleven verbs - (§393), `operator-channel`'s `ask-again` (§394), the indexer's `indexer_unpin` (§579) and every hand tool of G + `restore-kept` (§554, §659), `mesh-broker`'s `snapshot-get` and `snapshot-restore` (§681), the node-engine's eleven verbs + (§393) and its `first-views` and `first-view-again` (§422), `operator-channel`'s `ask-again` (§394), the indexer's `indexer_unpin` (§579) and every hand tool of G take their class's default. §392's prefixed forms and `holder:@same-node` (§336) are no longer written in a definition; a part that must tell callers apart reads the account the bus proved (`by-caller`, ADR 0259 §3). - **What stays.** Who may publish an event or a step's result stays its owner's alone (ADR 0363 §2, ADR 0666 @@ -103,13 +103,16 @@ for several build maps is answered once, and the maps' names for it are given in 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. + - **What G ended, a revert does not take up.** When G's gate ends a delivery, a group or an owed act, it deletes + that key in the old section, the ended record staying in its template; so a revert's gate of before G finds only + what G left open, and never acts again on what G ended. [mesh-catalog Q-G1.] This corrects §15's "the gate's other kept data stay in ADR 0595's templates". Why: the operator's answer; the copy at every start is the design's (review: security and upgrade 5, running and testing 2). 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. + template after the revert is kept; a delivery G ended is not in the old section the reverted gate reads. ## 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, @@ -132,7 +135,7 @@ for several build maps is answered once, and the maps' names for it are given in - **The manifest entries every such part declares.** In `consumes`: `mesh-catalog.catalog-revision`, `mesh-catalog.registration-changed` and `mesh-delivery.source-moved`. In `invokes`: `seat:mesh-catalog.revision` (with the field `none-yet`, §617), `seat:mesh-catalog.registrations`, - `seat:mesh-delivery.source`, and `seat:mesh-catalog.entry` for a part that reads an entry by its fingerprint. + `{verb: seat:mesh-delivery.source, fields: [branches]}` in the long form (§558), and `seat:mesh-catalog.entry` for a part that reads an entry by its fingerprint. - **An older build's entry.** A part that resolves an entry by fingerprint (§459's reader, the node-engine's want, §421) keeps beside its views the entries by fingerprint it asked of `mesh-catalog.entry`. When it hears a `running` or a `wanted` naming a fingerprint that no branch's newest revision lists and it does not hold, it asks @@ -147,7 +150,8 @@ for several build maps is answered once, and the maps' names for it are given in nothing it holds names that fingerprint or a later ask answers it. `_first_views` lists these entries with their state and since when, and the part's tool - `_entry_again` (`fingerprint`; class `act`) asks one again now. + `_entry_again` (`fingerprint`; class `act`) asks one again now; the node-engine's are its seat's verbs + (§683). - **A branch at `none yet`.** A view whose `revision` answered `none-yet` (§530) is ready and empty: the reader's answer for that branch lists no entry. - **The first pass.** A part acts on nothing until every branch it follows has its first view, `none-yet` @@ -156,7 +160,8 @@ for several build maps is answered once, and the maps' names for it are given in - **The node-engine follows no branch.** It reads the catalog half only by the fingerprints its wants name (§421), through the entries above, and declares none of the branch entries; it never waits on a branch's view, the registrations or the gate's `source`, so it composes the gate (and every part) before any of them answers, and no - cycle runs through it at G's delivery. + cycle runs through it at G's delivery. It keeps those entries on its node and serves their rows and ask again as + its seat's verbs (§683). The grants part composes a want's account before its first views (§684). - **A dropped branch.** When `go/views` drops a branch's view (§532), it clears, through the part's mesh-sdk writer (§639: a views reader writes its findings through the part's writer, never a writer of its own), every finding that view raised (`first-view-unanswered`, `view-waits`, `view-unsaid`, `view-too-large`), says the drop and each cleared finding in the part's log, and removes the view's row of `_first_views` [D-12]. @@ -181,13 +186,20 @@ for several build maps is answered once, and the maps' names for it are given in - §616 **The assigner's views are named by the seat, in the code and in the manifest.** (§428, §7) The tool runner's code reads the module that holds `mesh-module-assigner` from the catalog half's claims of that seat (§614) and names the views `.assignments` and `.seat-holders` from it, never by a name fixed in code. - Its manifest's `consumes` names them by the seat, `mesh-module-assigner.views.assignments` and - `mesh-module-assigner.views.seat-holders`, which the grants part resolves to the seat's holder from the catalog - half as it resolves a seat's events, so a new holder is granted with no change of the manifest. Design 46 + Its manifest's `consumes` names them by the seat, marked so as `invokes` marks a seat: + `seat:mesh-module-assigner.views.assignments` and `seat:mesh-module-assigner.views.seat-holders`, which the grants + part resolves to the seat's holder from the catalog half as it resolves a seat's events, so a new holder is + granted with no change of the manifest. The seat `mesh-module-assigner`'s definition declares its states + `assignments` and `seat-holders` as views (ADR 0571 §6), and the manifest validator refuses a seat-named view the + definition does not declare, naming it. The edge is of kind 6 from the seat's holders to the consumer, held until a + holder runs a build whose seat definition declares the view, as §558 derives it for a field. mesh-sdk's manifest + reader reads the `seat:` form in `consumes`, first in §494's second reader release (§621), which the parts reading + manifests take before G's merge. Design 46 7-approval-mark §19's holder of `operator-channel` is read from that view so found. [mesh-tools Q-R3, Q-R17.] Why: §428 removes the name from code, and the catalog half says who claims a seat (review: seams and tools' note). How it is checked: unit (tool runner), a fixture catalog half naming another holder of the seat gives views of that - name; unit (grants part), a seat-named view granted for the seat's new holder; the code review finds no assigner + name; unit (grants part), a seat-named view granted for the seat's new holder; unit (manifest validator), a + seat-named view the definition lacks refused; the code review finds no assigner name in the tool runner's code or manifest. - §617 **The long form of an `invokes` entry stands beside `*`.** (§558, §545) A manifest's `invokes` may hold `*` and long-form entries together: the tool runner's is `*`, then `{verb: "seat:mesh-catalog.revision", fields: @@ -224,7 +236,8 @@ for several build maps is answered once, and the maps' names for it are given in - §621 **What the second reader release reads, and how it is released.** (§494, §545, §605, §508, §554) §494's release reads, beside `calls` (§605) and the long form (§617), the tool runner's artifact word `states` [mesh-tools Q-R8, mesh-sdk 3] and `by-caller` on a verb, which the seat definition's format gains for `snapshot-kept` and - `restore-kept` (§554) [mesh-contracts DQ-1]. Since it also carries §508's validator rule, which is the indexer's, + `restore-kept` (§554) [mesh-contracts DQ-1] and every verb G gives the form (§681, §682), and the `seat:` form + of a seat-named view in `consumes` (§616). Since it also carries §508's validator rule, which is the indexer's, the release is a delivery group of mesh-sdk (the reader's words) and mesh-delivery (the rule), checked and delivered together [mesh-sdk 5]. Why: the running reader refuses an unknown word, and the rule is mesh-delivery's code. How it is checked: unit (the release's reader), `states` and a verb's `by-caller` read; the group's one check. @@ -391,15 +404,17 @@ for several build maps is answered once, and the maps' names for it are given in 6 its `consumes` gives (§558); its durable consumer is made from the stream's first message, so no merge said before it began is missed, and no catch-up through `git.pull` is needed. - **mesh-issues** invokes `seat:git.pull` and `seat:git.contains`, and reads a pull request's steps from the - runner's `show` given the repository and the pull request's head commit (`seat:mesh-pipeline-runner.show` in its - `invokes`), which answers that commit's pipelines with each step's result, the review step's among them (ADR - 0666 §22); a commit with no pipeline is answered `none`, which mesh-issues shows as "no run". The forge's own + runner, `seat:mesh-pipeline-runner.list` and `seat:mesh-pipeline-runner.show` in its `invokes`: `list` given the + pull request's head commit answers that commit's pipelines, one per module of the repository it builds (G-6), + and `show` of each answers it whole with each step's result, the review step's among them (ADR 0666 §22). For a + repository of several modules mesh-issues shows one row per module's pipeline, each with its steps; a commit + `list` answers with no pipeline is shown as "no run". The forge's own reviews are read nowhere: G keeps no review record (ADR 0659 §1). Its read of `seat:mesh-delivery.checks` and `gitea_pull_reviews` go. How it is checked: unit (manifest validator), each manifest of G's heads names none of the old events or tools; unit (mesh-config, records), each acts on a `git.pull-merged` fixture; unit (mesh-issues), a commit with no - pipeline shown as "no run". + pipeline shown as "no run", and one of a repository of two modules shown as two rows. - §655 **The take and restore of one stream is shared code in mesh-sdk.** (§554, §464; ADR 0672 §1) The code that takes and restores one stream's snapshot moves whole from the bus module's `bussnap` into mesh-sdk's `go/bussnap`, imported by the bus module (its snapshot before `recreate` and `drop`), by the recovery module (its points and @@ -414,7 +429,8 @@ for several build maps is answered once, and the maps' names for it are given in named in its `invokes`, and hold no grant of their own; the bus proves the tool runner's account, as ADR 0672 §7 has the bundle call the seat's verbs. [mesh-catalog Q-R2.] Why: ADR 0672 §7 (review: seams and tools 2). How it is checked: unit (mesh-recovery's contract), each verb read; whole (recovery module), each hand tool acts through its - verb. + verb. Each verb's fields and answers, and the `asker` each hand verb takes and logs beside the account the bus + proved, are §682's. - §657 **The recovery module's health check is a tool.** (§554, §468, §561) The recovery module serves the read tool `recovery_kept_points`, answering what `kept-points` answers, its bundle naming `seat:mesh-recovery.kept-points` in `invokes`, and its declared health check names it. The check fails while an aside's record ends at `removed` and no @@ -440,7 +456,7 @@ for several build maps is answered once, and the maps' names for it are given in `finding-events` entry, named in its `consumes`, and a foundation part's old finding stream from the catalog half (§614); at its start it reads both by `list` and the catalog half. When a part's catalog graph entry no longer declares the stream the keeper follows for it (its findings moved to a template, §611, or to an old section, §612), - the keeper drops that source and its consumer, keeps the part's open conditions, and asks `findings-asked` on the + the keeper drops that source (the grants part its consumer, §690), keeps the part's open conditions, and asks `findings-asked` on the new stream once it is a source; the part's statement there settles them (§384). §515 is corrected so. [mesh-contracts DQ-12; D-7's COND9.] Why: the grants part makes the consumers (§386), and no binding names one; a moved stream must neither raise twice nor leave a condition open (review: health and events 1). How it is @@ -458,30 +474,9 @@ for several build maps is answered once, and the maps' names for it are given in condition kept; whole (healers), a full stream raises `attempt-unsaid`. ## Met in develop -- §666 **`nats_snapshot_get`: the snapshot recorded with its digest, and sent on the call's own session.** (§554, - §567, §518, §620; ADR 0672 §1, §8; ADR 0667 §12) [D-1.] - - **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` and `digest` (`sha256:` of its bytes) before it touches the live data. A snapshot it cannot write whole and - record so makes the `drop` or `recreate` refuse, naming why, before anything is removed. - - **Who deletes it.** The keeper alone: the snapshot file and its record are kept 90 days (ADR 0667 §12, as the - delivery records), its setting `snapshot-keep-days`, and removed at the keeper's start and at each new request - once older, each removal written in its journal. - - **The call.** It takes `request`, the request's id. It reads the file, computes its digest, and answers `error` - `snapshot damaged`, naming the request, when it differs from the recorded one, or `snapshot missing` when no file - is there. Otherwise it answers `{request, module, local, stream, size, digest, at, chunked: true}` and sends the - file on the call's own get session, `.get.`, in chunks under the bus's - per-message limit, each acknowledged by the caller before the next, as §518 and §620 have a get session; only the - bus module's account publishes the chunks and only the caller's account answers them, granted so (§489). No size - limit applies and nothing goes through the sent store. - - **Its use.** `recovery_restore` names it by `request`, and the recovery module checks the bytes it received - against `digest` before it takes any aside (§567). - - Why: a snapshot larger than the sent store's cap, or asked after its 7 days, could never be restored, and the - sent store's read grant is wider than this one caller (review: all four domains). How it is checked: whole (bus - module, recovery module, with small settings), a snapshot larger than 256 MiB restored whole; one asked eight days - after its `drop` with `snapshot-keep-days` 90 restored; a file altered on disk after the `drop` refused `snapshot - damaged`; a `drop` whose snapshot cannot be written refuses before it removes anything. +- §666 **`nats_snapshot_get`.** Replaced whole by §681 (G-18): the keeper serves the seat `mesh-broker`'s + `snapshot-get` and `snapshot-restore`, the bundle lists by `nats_snapshots`, and a protected stream's snapshot is + never sent (the operator, O-7). [D-1.] - §667 **Where a trusted change and the seed wait for their warrant.** (§3, §8; ADR 0666 §2, §12; ADR 0259 §6; ADR 0286 §10) [D-2, D-3.] - **Kept.** The indexer keeps each change of `register`, `policy`, `watch` and `unwatch` awaiting its warrant in its @@ -494,7 +489,9 @@ for several build maps is answered once, and the maps' names for it are given in change's `digest`, so the warrant approves those exact values (ADR 0286 §10). - **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: it writes the version by + 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), + 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 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 2be6e4cb..bbd27f85 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 @@ -5,6 +5,7 @@ design: 47 milestone: G updated: 2026-11-11 decisions: + - "ADR 0674" - "ADR 0673" - "ADR 0672" - "ADR 0668" @@ -20,6 +21,7 @@ decisions: - "ADR 0579" - "ADR 0573" - "ADR 0448" + - "ADR 0436" - "ADR 0429" - "ADR 0363" - "ADR 0286" @@ -32,28 +34,58 @@ decisions: One file of milestone G's part of [design 47](../47-delivery-from-commit-to-delivered.md); the part opens at [G.md](G.md). Its design lines are numbered across every file of the part and cited as "design 47 G §n". -*§677 to §680 come from the fix round of the review by architectural domain of §587 to §676 (lead-47's input of -2026-11-11): the approval mark once no verb names its callers (the operator's answer of about 16:10 CET, §610), and -develop's D-16 to D-18, of internal form only. The round's other fixes are written in the lines they correct.* +*§677 to §690 come from the fix rounds of the review by architectural domain of §587 to §676 (lead-47's inputs of +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); and develop's D-16 to D-25, of internal +form only. The rounds' other fixes are written in the lines they correct.* ## The approval mark, with no named callers -- §677 **A module's process that calls a marked verb carries the operator's warrant for that one call.** (§610; ADR - 0286, ADR 0259 §6, ADR 0626 §4) A call through the tool runner is asked, judged and claimed by the tool runner as - ADR 0286 and design 46 7-approval-mark have it. A module's process may now call a marked verb directly (§610); then: - - **The caller asks.** It makes the act of that call as ADR 0286 §10 and §11 make one (the address, the node that - serves it, the build and every argument, digested with `ActDigest`), asks it through `operatorchannelclient` - under its own module's name, at level `approve`, and calls only once the warrant is given, naming the ask in the - call. - - **The holder checks.** The marked verb's holder takes the call only with a warrant whose act's digest is the - digest of the call it received, claims it once (`Take`), and refuses any other call before acting, naming the - ask the caller must make, as the bus module's keeper checks a warrant (ADR 0626 §4). mesh-sdk's seat server does - this for every marked verb, read from the definition's or the manifest's mark, so no holder builds it. - - Why: the mark stays while no caller list does (O-6; review: security and upgrade 2). How it is checked: whole - (a fixture marked verb, its holder and a module's process), a call with no warrant refused, one with a warrant for - other arguments refused, one with its warrant run once, and the same warrant used twice refused. +- §677 **A marked verb a module's process serves is asked, checked and claimed by its holder alone.** (§610; ADR + 0286 §10 to §13, §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, a session through the tool runner included: + - **The holder asks, under its own module's name.** On a call of a marked verb it serves with no warrant for its + act, 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`), 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 with ADR 0286 §37's refusal naming the ask. 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. + - **The caller calls again.** When the holder hears its own `operator-channel.decided` of that ask, it says the + choice on its seat's event `approval-decided`, `mesh.seat..event.approval-decided.` (`{ask, choice}`, + kept last per subject, one day), which every seat definition with a marked verb gains through the seat + generator. A module's process that calls a marked verb names that event in its manifest's `consumes`; mesh-sdk's + seat client, beside the seat server in `go/seats`, keeps the refused call as a kept call (ADR 0668 §1), waits on + that event and makes the same call again, with the same arguments, on Approve, and ends it with the decline + otherwise. A person through the tool runner calls again as ADR 0286 §37 says. + - **The holder checks.** On a call whose act has an ask that was chosen, the seat server 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), and holds the warrant to it with `Warrant.For` and `Option.Performs` (ADR 0286 §27, §28), within 30 minutes + of the choice (§29), the act being the one it composes from the call it received. + - **The holder claims, once, in its own state.** The claim store is the holder's template state `approvals` (a + `requires` entry, 48 hours to live, 64 MiB): keys `ask.` (the asked call), `act.` (the newest ask of + that act) and `claimed.`, the claim, written with the bus's create, which refuses a key that exists, so two + calls at once, on one instance or two, cannot both claim it (ADR 0286 §30, §31). 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. + - **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, and a call finds no responder, until its G version runs: no ordering edge is + needed, and nothing runs unchecked. + Why: the mark stays while no caller list does (O-6); the holder alone can read the router's record of an ask made + under its own name, and one ask and one claim per call keep ADR 0286 §31 (review round 2: security and upgrade 1 + to 3, seams and tools' note). How it is checked: whole (a fixture marked verb, its holder and a module's process), + a call with no warrant answered with the ask and called again by the seat client on `approval-decided`, run once; + a warrant for other arguments refused; the same warrant used twice refused; two calls at once with one warrant, + one run; the same through the tool runner, asked once; unit (grants part), a holder whose running entry declares + no `approvals` composed with the deny of its marked subjects and named in `withheld`. ## 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 @@ -69,3 +101,199 @@ develop's D-16 to D-18, of internal form only. The round's other fixes are writt compare". The build modules' shared conformance kit is `sdk/steprun/conformance` in the delivery SDK, which mesh-catalog's build modules and their checks import. [D-18.] How it is checked: the code review. +## 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.] + - **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`. + - **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`. + - **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`. + - **Sent by the keeper.** The keeper's process serves the seat `mesh-broker`'s verb `snapshot-get`, `by-caller`, + class `read`, taking its default (§610). It takes `request` and `call`, 128 random bits the caller chooses, and + 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; + `snapshot protected` when `protected` is true; and `snapshot taken before milestone G` for a request record that + holds no `digest`. + - **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). + - **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. + + 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. + +- §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 + 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): + `{outcome: accepted, act}`, `{outcome: busy, act}` naming the act that runs, or `{outcome: error, error}`; the + result comes on the act's ending event (§554, §560), under its `act` id. + - `take` (`module`, `kept`, `fingerprint`): takes a point of that kept data at that fingerprint's form, as + `snapshot-kept` does with no `catch-up`; ends with `ended`. + - `restore` (`module`, `kept`, and exactly one of `snapshot`, a point's name, or `request`, a keeper's snapshot + by its request, §681; `from-backup`, yes or no, only with `snapshot`): restores as `restore-kept` does; ends with + `restored`. + - `retry` (`module`, `kept`): asks again the last failed act of that module and kept data, with its fields; + `error` `nothing to retry` when its last act did not fail; ends with that act's ending event. + - `aside` (`module`, `kept`): sets the live kept data aside without restoring (§516); ends with `set-aside`. + - `discard-aside` (`module`, `kept`, `id`): removes that aside's directory; ends with `aside-discarded`. + - `expire-points` (no field of its own): runs §551's removal of points past their 90 days now; ends with + `expiry-ended`. + - `restore-aside` (`module`, `kept`, `id`) and `cancel` (`act`) as §566 has them; `cancel` answers `{outcome: + cancelled, act}` or `error` naming the step the act has begun. + + 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 + 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. + + 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. + +- §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 + full pass waits on the gate's G version (kind 6), while the gate's G version waits on the grants part composing its + account (kind 5). So, until every branch it follows has its first view, the grants part keeps the user list it last + wrote and composes, for a want whose account it holds none of or whose fingerprint changed, that one account from + the want's catalog graph entry by fingerprint (§614, *An older build's entry*) and the assigner's views alone, as it + composes any account, every marked subject in it denied while the marks are unread (design 46 + 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. + 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. + + +## 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`, + `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. + 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 + 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. +- §687 **mesh-sdk lays out the views reader's findings itself.** (§639, §686) [D-22.] The reader's four findings are + laid out by mesh-sdk, through §686's constructor and setters, and the part supplies only the constructor: `kind` + the finding's; `scope` the writer's own, as every finding it writes; `id` the view's name + `..`, escaped as a key's name is (§73); `severity` `warning`, but `urgent` for + `view-too-large`, which the part cannot read past; `source` `views`; `subject` `{scope: module, id: , machine: }`; `summary` and `headline` fixed texts naming the view and what it waits on. The + part-supplied body function goes. How it is checked: unit (`go/views`, and the TypeScript follower), each of the + four written with those fields. +- §688 **The views reader's four kinds are always its writer's.** (§580, §639) [D-23.] The writer of a part that + holds a views reader always owns `view-waits`, `first-view-unanswered`, `view-unsaid` and `view-too-large`, added + to its stated kinds when `Kinds` is set, so its statement covers them (§580). A module whose bundles share one state + `findings` holds a views reader in one bundle only (in G the forge module's TypeScript tools, §196), which the code + review checks. How it is checked: unit (writer), a writer made with `Kinds` states the four with them. +- §689 **The hand-written finding helpers go; mesh-sdk's writer is the one writer.** (§461, §503, §640, §660) [D-24, + mesh-contracts K15.] With the state `findings` holding `#/bodies/Finding` under `..` (§660), the + finding helpers of mesh-contracts' `meshconditionsclient` go, as its `findings` package does (§503): `CheckFinding`, + `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 + 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 + generated type (§686), its texts written into `summary` and `headline` where `Says` made them: in mesh-catalog + `artifact-store-tools`, `claude-code`, `distribution` and `distribution-tools`, `package-registry`, `mesh-build-go`, + `mesh-config`, `mesh-healers`, `mesh-provisioner`, `mesh-self-check`, `mesh-vault`, `mesh-watcher`, `object-store` + and `nfs-server`; in mesh-delivery the assigner, the builder, the checker, the indexer and its tools, the teller, + the status view and the watchman; in `mesh-host` the node-engine; in mesh-tools `node-tools/internal/firstview`. The + keeper (`mesh-conditions`) reads the findings others write into the generated type and judges them with mesh-sdk's + exported check. How it is checked: the code review finds none of the removed helpers at G's heads; unit (writer), + a finding breaking each rule `CheckFinding` held refused before it is written. +- §690 **Who drops the keeper's consumer of a moved finding stream, and the gate's `source` in mesh-contracts.** + (§386, §611, §612, §614, §663, §684) [D-25, mesh-catalog COND9.] + - **The grants part drops it.** The grants part, which makes the keeper's consumers (§386), deletes the keeper's + durable consumer on a part's stream at its first composition from a catalog graph entry of that part that no + longer declares the stream, and makes the consumer on the new stream from the same entry, as §386 does for a + module that declares the events later. The keeper deletes no consumer: when it hears, through its catalog half + 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 + `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 + answers of `source` read from their fixtures. diff --git a/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md b/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md index 96d9b947..5d0dc6e3 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md +++ b/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md @@ -72,7 +72,9 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli under ADR 0656 §6: one form of the fact, never `modules` kept beside the catalog graph for these readers, which would be a second source of the same fact. How it is checked: test 61. - **The forge module's tools come from mesh-sdk's TypeScript side.** mesh-sdk's TypeScript side has no view - today; milestone G adds there a view follower with its read and ask-again tools, beside the proved caller, a + today; milestone G adds there a view follower with its read and ask-again tools, which adopts and drops a branch's + view as `go/views` does (§532, §614) and follows the branches through the TypeScript form of `meshcatalogclient` + (§614), beside the proved caller, a verb's `callers` and a seat's publish, so the forge module, reading through the seat's TypeScript contract, answers `_first_views` and `_first_view_again` as the Go parts do from `go/views`, with no follower or tool of its own. Its cost: a release of the TypeScript side rebuilds every TypeScript module, which diff --git a/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md b/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md index b16132b6..86705bf9 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md +++ b/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md @@ -217,9 +217,8 @@ line says so.* (node-engine), a want naming an entry the half does not hold says `entry-missing`. - §422 **The node-engine's first-view tools are seat verbs.** The node-engine serves its view's two tools as the seat `node-engine`'s verbs `first-views` and `first-view-again`, beside its seat-list verbs, since it serves no module - tools: `first-views` a `read`, its callers any person and the healers, and `first-view-again` an `act`, its callers - the operator and the healers, as §204 names them. Why: the design's choice (Q-H4). How it is checked: the seat's - fixtures; whole (node-engine), a call from another caller is refused by the bus. + tools: `first-views` a `read` and `first-view-again` an `act`, each taking its class's default (§610). Why: the design's choice (Q-H4). How it is checked: the seat's + fixtures; whole (node-engine), each verb answers a session's call. - §423 **A kept-build wait says the existing words.** A have waiting for a kept build (§271) says the existing phase and words; its one new field is §629's `wait`. Why: the design's choice (Q-H10). How it is checked: whole (node-engine). - §424 **Each process's own build, and each bundle's.** (§519) A process says `own build unknown` in its diff --git a/03-DESIGN/01-to-be/47-milestones/G.md b/03-DESIGN/01-to-be/47-milestones/G.md index 6196aca2..73a0e7f0 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, and develop's D-16 to D-18 (§677 to §680). +- [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, and develop's D-16 to D-25 (§677 to §690). 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).