Design 47 milestone G: develop answers batch 4 (G-12, G-14), the recovery module and the operator's answers of 2026-11-11 #548
@@ -974,6 +974,12 @@ becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283, 0564, 0668.
|
||||
at one moment; **restore** — bringing it back beside the live data, never over it.
|
||||
- **stream snapshot** — the bus's own backup of each stream, taken by the module holding `mesh-broker`
|
||||
(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).
|
||||
**aside** — live kept data a restore set aside, removed only by the operator's `discard-aside`.
|
||||
*Not:* ~~restorer~~, ~~restore account~~
|
||||
- **disk readings** — the size of each data item a node's modules declare, measured by its `measure` and kept
|
||||
with its largest size in seven days by disk-load on that node, in its own state, one key
|
||||
`<node>.<module>.<item>` written only when it changes; the holder of `node-backup`, mounts, nfs-server and the
|
||||
|
||||
@@ -200,7 +200,7 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
|
||||
`operator-channel`'s accepted kind `ask`, on its work queue by the runner's name (design 46 §10, *Asks, warrants and answers on the bus*;
|
||||
the seat has no verb `ask`), and heard on its event `decided` (ADR 0666 §7, §10). A step with nothing to do ends at once as
|
||||
`nothing to run`, never as passed.
|
||||
- §23 **The policy.** Each step's status, per module and per artifact, is `required` (runs; holds the delivery until it
|
||||
- §23 **The policy.** (§553) Each step's status, per module and per artifact, is `required` (runs; holds the delivery until it
|
||||
passes), `optional` (runs; a failure is shown and may be accepted) or `bypass` (nothing runs; said as bypassed),
|
||||
kept in the registration and never in a manifest: the manifest validator refuses a manifest that names a status
|
||||
(ADR 0666 §7; research 086, R3). A `required` step that ends `nothing to run` holds the delivery and names the step.
|
||||
@@ -267,7 +267,7 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
|
||||
prerequisite step `bypass`) ends the pipeline refused within five minutes, naming the step and what it waits for,
|
||||
never as a silent wait (research 086, R5); a step whose seat has no holder ends its pipeline failed, naming the seat
|
||||
(ADR 0666 §17).
|
||||
- §33 **A failed head is said to its author, then to the operator.** A `required` step that failed, or ended `could not
|
||||
- §33 **A failed head is said to its author, then to the operator.** (§540) A `required` step that failed, or ended `could not
|
||||
run`, on a watched branch's head is the runner's finding `pipeline-failed`, naming the module, the branch, the commit
|
||||
and the step; the condition keeper raises it as the commit's author's for two hours and then the operator's, as ADR
|
||||
0505 §5 and §6 have a delivery whose cure is its author's new head, and clears it when a newer revision of that branch
|
||||
|
||||
@@ -42,7 +42,7 @@ each the design's choice with its reason, §468 to §479 those of the runner's,
|
||||
operator, 2026-11-11 at the terminal (develop question D-12): a refusal would be "hard-coded logic for no good
|
||||
reason". How it is checked: unit (definition reader), a row where a verb G adds with no `class` takes `read`'s
|
||||
callers; unit (seat generator), a definition with a verb naming no `class` is generated.
|
||||
- §457 **The put session's wire form.** (§489, §490) §345's put session runs on the subject `<bundle call subject>.put.<call id>`.
|
||||
- §457 **The put session's wire form.** (§489, §490, §518) §345's put session runs on the subject `<bundle call subject>.put.<call id>`.
|
||||
Each chunk is one message whose body is the value's raw bytes, at most half the bus's maximum payload as the
|
||||
connection reads it from the server, with the header `Mesh-Put-Seq` (a decimal from 1, one more each chunk) and, on
|
||||
the last chunk alone, `Mesh-Put-Last: true`. The tool runner answers each chunk with `{seq}`, the sequence it took,
|
||||
@@ -62,7 +62,7 @@ each the design's choice with its reason, §468 to §479 those of the runner's,
|
||||
its own version". Why: the operator, 2026-11-11 at the terminal (develop question D-19); a build without a version
|
||||
is §371's and §373's. How it is checked: whole (Go, TypeScript and image build modules), a built image's tag and
|
||||
label, a Go program's `main.meshVersion` and a Node program's own version are the reserved version.
|
||||
- §459 **`SeatsToPassOn`'s input.** mesh-sdk's `catalogue.SeatsToPassOn` takes the holdings on record, the
|
||||
- §459 **`SeatsToPassOn`'s input.** (§536) mesh-sdk's `catalogue.SeatsToPassOn` takes the holdings on record, the
|
||||
assignments (each a node, a module and its placement's watched branch), what the caller heard of each node and
|
||||
module from the node-engine seat's `running` (a fingerprint, `stopped`, or nothing heard since its consumer began),
|
||||
and a reader of entries the caller passes over its own view of the catalog half, which answers an entry by its
|
||||
@@ -77,7 +77,7 @@ each the design's choice with its reason, §468 to §479 those of the runner's,
|
||||
(ADR 0596 §2), and the function stays a pure rule (develop question D-14). How it is checked: unit
|
||||
(`SeatsToPassOn`), a table with a row per case: a heard fingerprint, nothing heard (the branch's entry taken), a
|
||||
`stopped` holder passing no seat, and an entry not answered keeping the holder on record and saying it.
|
||||
- §460 **An asker says whether its key is still open.** mesh-sdk's kept-call form takes, beside the ask's key, a
|
||||
- §460 **An asker says whether its key is still open.** (§531) mesh-sdk's kept-call form takes, beside the ask's key, a
|
||||
function `open` the asker passes, which reads the asker's own state and answers whether that key is still open, and,
|
||||
where one exists, the event that replaces the ask; it asks again only while `open` answers yes and no replacing
|
||||
event was heard. An error of `open` is written in the asker's journal naming the key, and the form asks again: a
|
||||
@@ -265,7 +265,7 @@ each the design's choice with its reason, §468 to §479 those of the runner's,
|
||||
its own fact (ADR 0596 §2) (develop questions GIT12 and REG1). How it is checked: unit (`mesh-builds` contract),
|
||||
`reserved` with `name` read; whole (builder, registry holder), a Go publish named by its module path is checked
|
||||
against the module's reservation, and an unknown name refused.
|
||||
- §479 **A branch's catalog view is named with its branch.** (§495) In mesh-sdk's `go/views` reader and process reader, a
|
||||
- §479 **A branch's catalog view is named with its branch.** (§495, §521, §532) In mesh-sdk's `go/views` reader and process reader, a
|
||||
first view of a per-branch state is named `<owner>.<state>.<branch>`, the branch escaped as a key's name is (§73),
|
||||
so `mesh-catalog.catalog-revisions.<branch>` names one view per watched branch, a part reads several in one reader,
|
||||
and `<module>_first_views` lists one row per branch (§358, §365). A view of a state that is not per branch keeps
|
||||
|
||||
@@ -62,7 +62,7 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
|
||||
## The review of §456 to §479, round 1
|
||||
|
||||
- §483 **Main's step keys stay readable while main's askers run.** (§600, §601) A build seat's holder of G keys a step whose ask
|
||||
- §483 **Main's step keys stay readable while main's askers run.** (§600, §601, §544) A build seat's holder of G keys a step whose ask
|
||||
came on main's subject `mesh.seat.<seat>.accept.<kind>`, with no asker's name, as main does, `<node>.<id>`, and a
|
||||
step whose ask names its asker as §481 says; so a builder or checker of before G, which asks on main's subject,
|
||||
finds its answer under `<node>.<id>` through the rollout one node first and after a revert. Every asker of G asks
|
||||
@@ -106,7 +106,7 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
(review round 1, running and testing 5, health and events 3). How it is checked: whole (runner), with a fixture's
|
||||
small cap a step ends and is said, `full` is said and a start refused, and on `room` the entry is appended and the
|
||||
start taken.
|
||||
- §487 **The forge module learns a commit's fingerprint from every step end.** §475's `seen.<commit>.<module>` is
|
||||
- §487 **The forge module learns a commit's fingerprint from every step end.** (§548) §475's `seen.<commit>.<module>` is
|
||||
written from every `step-ended`, whatever its commit, a run on request's included, so a commit that failed in a run
|
||||
on request before its pull request was opened is known at its merge. A `seen` key is deleted by §135's rule once
|
||||
its commit has been a watched branch's head or the head an open pull request names and is neither, and otherwise
|
||||
@@ -128,13 +128,13 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
not answer the new calls (ADR 0595 §9; review round 1, security and upgrade 2). How it is checked: unit (tool
|
||||
runner), each word stated with its family; whole (mesh-sdk), against a tool runner that does not state
|
||||
`put-sessions` a large put fails naming it; the delivery plan of G orders the modules after the tool runner.
|
||||
- §489 **Who publishes on a put or get session.** On `<bundle call subject>.put.<call id>` only the module's own
|
||||
- §489 **Who publishes on a put or get session.** (§518) On `<bundle call subject>.put.<call id>` only the module's own
|
||||
account publishes the chunks and only the tool runner of its node answers them; on `<bundle call subject>.get.<call
|
||||
id>` only the tool runner publishes the chunks and only the module's account answers. The grants part grants them
|
||||
so, as it grants a module's call subject today (ADR 0363 §2). Why: §457's subjects lie under a subject the module
|
||||
already owns, so the grant follows the record (review round 1, security and upgrade 3). How it is checked: whole
|
||||
(grants part, tool runner), a chunk published by another module's account is refused by the bus.
|
||||
- §490 **The get side of a session.** A get of a value over the limit (§457) runs so: the bundle subscribes to
|
||||
- §490 **The get side of a session.** (§518) A get of a value over the limit (§457) runs so: the bundle subscribes to
|
||||
`<bundle call subject>.get.<call id>` before it makes the call; the tool runner's answer to the call is
|
||||
`{chunked: <count>, size, digest}`, the value's `sha256:` digest; the tool runner then publishes each chunk as a
|
||||
request on that subject, with `Mesh-Put-Seq` and, on the last, `Mesh-Put-Last: true`, and the bundle answers each
|
||||
@@ -170,7 +170,7 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
release's publish (kind 1), so the runner's manifest is read by every part that takes it in. Why: readers first
|
||||
(ADR 0667 §4; review round 1, security and upgrade's note). How it is checked: G's check reads the runner's and the
|
||||
node-engine's manifests; whole (grants part), the runner's `pipelines` bucket has its cap.
|
||||
- §495 **Small corrections from the review.** §472's "kind 3 is stale (§441)" reads §375. §472's `toolchain-agreed` carries its digests as they stood when the version was agreed; a digest that changes later at that version is read from `toolchain-reported` (§492) and starts nothing. A sent store already over its cap when §477's
|
||||
- §495 **Small corrections from the review.** (§530) §472's "kind 3 is stale (§441)" reads §375. §472's `toolchain-agreed` carries its digests as they stood when the version was agreed; a digest that changes later at that version is read from `toolchain-reported` (§492) and starts nothing. A sent store already over its cap when §477's
|
||||
cap is planned keeps no cap until its seven-day age brings it under, the bus module's plan naming it with its fill
|
||||
meanwhile; a sent store is planned only for a module §344 names, and the plan refuses caps whose sum passes the
|
||||
bus's storage limit, naming the sum. §468's "behind" is the age of the oldest message the consumer has not
|
||||
@@ -197,7 +197,7 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
`branch-unprotected` stands (§17) raises none either. Why: the watchman already times each take-in wait (develop
|
||||
question on §12). How it is checked: whole (watchman), a head behind a pending revision raises nothing for 60
|
||||
minutes, then `take-in-waits`.
|
||||
- §498 **A wait names its clock and its kind.** (§608) `meshwants.Wait`, the runner's wait body and the node-engine seat's
|
||||
- §498 **A wait names its clock and its kind.** (§534, §608, §542) `meshwants.Wait`, the runner's wait body and the node-engine seat's
|
||||
gain `clock-from` (the time the bound counts from, §266, §269) beside `bound`, and `step`, one of the acting steps
|
||||
of §203 or `put`, `delivery`, `kept-build`, `backup`; a put's wait (main file, *A put without hold that stands*)
|
||||
is `step: put` with the node, the module and `fingerprint`; a dependent's delivery wait (§376) is `step: delivery`
|
||||
@@ -205,7 +205,7 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
fingerprint, `held`, since and bound, from which the watchman seeds. Why: one wait form, told apart by `step`
|
||||
(develop questions WM6 and WM10). How it is checked: unit (contracts), each field read; whole (watchman), a put's
|
||||
wait raises `put-stands` and a pipeline's wait raises nothing for it.
|
||||
- §499 **The node-engine says a kept build's wait, and its version is read from the catalog.** (§609) A node-engine of G
|
||||
- §499 **The node-engine says a kept build's wait, and its version is read from the catalog.** (§541, §609) A node-engine of G
|
||||
waiting for a kept build says `wait-held` on its seat with `step: kept-build`, `node` the build node, and why
|
||||
(`node away` or `build no longer kept`), and `wait-ended` when it applies; its have's value carries the same as
|
||||
`waits`. The watchman takes the keeping node from the builder's `build.ended` (§379), never its done key. Each
|
||||
@@ -252,7 +252,7 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
never computed again from the manifest whole, whose encoding may differ; the module's value and §445's
|
||||
`manifests` key are that digest. Why: the bytes, not the map, are what the node-engines before G read (develop
|
||||
question IX16). How it is checked: unit (indexer), the entry's digest is the digest of the bytes read.
|
||||
- §507 **The watched branches before the first registrations.** Every reader of a trunk's source revision reads, per
|
||||
- §507 **The watched branches before the first registrations.** (§532) Every reader of a trunk's source revision reads, per
|
||||
watched branch the registrations name, `source.<branch>` through the gate's verb `source`; before the first
|
||||
registrations (§95, §353), the watched branches are the branches the gate's `source` answers, which G's switch
|
||||
carries in from `source.main` as the branch `main`, read from the key and never fixed in code (§7). The assigner's
|
||||
@@ -260,7 +260,7 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
and one source of the branches for every reader (develop questions Q18 and VW0, and the bridge's FB9). How it is
|
||||
checked: whole (assigner, bridge), before the first registrations a want is written from `source.main`, and no
|
||||
part's code holds `main`.
|
||||
- §508 **The node-engine claims its seat as one module.** (§609) The seat `node-engine`'s definition in mesh-contracts no
|
||||
- §508 **The node-engine claims its seat as one module.** (§527, §609) The seat `node-engine`'s definition in mesh-contracts no
|
||||
longer marks it held by the engine; the manifest validator accepts one module of a revision claiming it and
|
||||
refuses a second, naming both, in place of refusing every claim, and §494's release carries the rule. The
|
||||
node-engine's guard reads the holder from the seat list (§364). Why: §364 has the node-engine's manifest claim the
|
||||
@@ -274,7 +274,7 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
Why: one message per move, the pull request where there is one (develop questions FB1, FB2 and FB7). How it is
|
||||
checked: whole (bridge), an admitted push writes `pushed`, a merge `merged`, and a move of an unprotected branch
|
||||
writes nothing.
|
||||
- §510 **A merge the switch carries is performed.** (§608) A `merges` key the old bridge had not performed, an Approve the
|
||||
- §510 **A merge the switch carries is performed.** (§608, §542) A `merges` key the old bridge had not performed, an Approve the
|
||||
operator gave before G, becomes an act (§169) that the bridge performs through `merge-pull`, judged as every merge;
|
||||
while `merge-pull` refuses it for missing registrations (§95) the act stays unanswered and is performed again on
|
||||
`registration-changed`. No other merge act is made after G (§167). Why: §169 drops nothing the operator approved
|
||||
@@ -301,7 +301,7 @@ reason. What a question of another kind leaves open waits for the operator and i
|
||||
`membership.BusBinding`, built in mesh-sdk. Why: the objects template has no default (develop questions NATS1 and
|
||||
on §399). How it is checked: unit (bus module's plan), each planned objects store has its cap; unit (membership),
|
||||
both fields read.
|
||||
- §514 **The teller tells through `notify`, on every channel.** For `widens` (§71, §335), `recovery-merged` (§81)
|
||||
- §514 **The teller tells through `notify`, on every channel.** (§522) For `widens` (§71, §335), `recovery-merged` (§81)
|
||||
and a `forge-made` record (§170) the teller calls the seat `operator-channel`'s verb `notify`, named in its
|
||||
manifest's `invokes`, with `every-channel: true`, which the router sends on every channel's `send`, as design 46
|
||||
announces a break-glass act. The words are the operator's to approve and wait for them (develop questions TL1 to
|
||||
|
||||
@@ -0,0 +1,573 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
design: 47
|
||||
milestone: G
|
||||
updated: 2026-11-11
|
||||
decisions:
|
||||
- "ADR 0672"
|
||||
- "ADR 0667"
|
||||
- "ADR 0666"
|
||||
- "ADR 0660"
|
||||
- "ADR 0656"
|
||||
- "ADR 0636"
|
||||
- "ADR 0626"
|
||||
- "ADR 0619"
|
||||
- "ADR 0618"
|
||||
- "ADR 0614"
|
||||
- "ADR 0596"
|
||||
- "ADR 0595"
|
||||
- "ADR 0564"
|
||||
- "ADR 0505"
|
||||
- "ADR 0404"
|
||||
- "ADR 0363"
|
||||
- "ADR 0240"
|
||||
- "ADR 0235"
|
||||
---
|
||||
|
||||
# 47, milestone G: the operator's words of 2026-11-11 and develop's fourth batch of questions
|
||||
|
||||
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".
|
||||
|
||||
*§522, §542 and §551 to §553 are the operator's answers of 2026-11-11 at 12:11, 12:33 and 12:41 CET at lead-47's terminal. §543 to §550
|
||||
answer what the four reviewers found in round 3 of [G-13](G-13-review-round-3.md) (§600 to §609), which has no round
|
||||
of its own after it. Every other line answers a question
|
||||
develop met after [G-11](G-11-develop-answers-review.md), of internal form only (playbook 07, step 0b), each the
|
||||
design's choice with its reason. What a question of another kind leaves open waits for the operator and is said in the
|
||||
line. The operator's answer of 12:55 CET (the recovery module, §554 and §555) and the
|
||||
review of §516 to §553, round 1 (§556 to §558), are in [G-14](G-14-recovery-module-and-review.md); the findings of
|
||||
that round are written into the lines they name, here. Questions that an earlier line already answers have no line here: develop reads that line.*
|
||||
|
||||
## Kept data on the bus: restore points and what is set aside
|
||||
|
||||
- §516 **A restore point's bytes, and the forms of `snapshot-kept` and `restore-kept`.** (§551, §554) The seat
|
||||
`mesh-recovery`'s two verbs (§554) take and answer the forms mesh-contracts' definition gave the seat `mesh-broker`'s,
|
||||
which move to `mesh-recovery` and which this line makes the design's: `snapshot-kept` takes `module`, `kept` (the
|
||||
kept data's local name), `form`, `fingerprint`, `why` and `catch-up` as `{tool, arguments}` (§451); its point
|
||||
(the module, the kept data, its form, the fingerprint, `snapshot`, `consumers` with each durable consumer's
|
||||
stream, name and acknowledged sequence, `size` in bytes, `at` and `catch-up`) comes on its event `ended` (§554); `restore-kept` takes
|
||||
`module`, `kept`, `form`, `fingerprint`, `why`, `from-backup` (yes or no) and `snapshot` (the restore point's name),
|
||||
and refuses `aside-only` and `discard-aside`, answering `error` naming them: setting aside without restoring and
|
||||
discarding an aside are the operator's hand tools alone (§554); its result (`restored`, `aside`, `missing`, true when the
|
||||
point is not in the recovery module's directory, and `error`) comes on its event `restored`. Both verbs answer only
|
||||
`accepted`, `busy` or `error` (§554). No argument `local-name` or `from` is taken, and a
|
||||
catch-up is never text.
|
||||
- **Where a point lives.** The recovery module takes a point through the bus's stream snapshot under its own account
|
||||
(§554), one bus object of the kept data at a time (its stream, or the stream under its bucket or object store),
|
||||
with ADR 0235 §10's pacing and §11's bounds, and writes it with the point's record under a temporary name, renamed to its own name only once the point is
|
||||
whole (as ADR 0235 §2 writes the dump), in its own data directory, `points/<module>/<kept>/<form>-<fingerprint>`;
|
||||
at its start it removes every point left under a temporary name, so a point cut off by a restart, the bus away or
|
||||
its bound is never listed nor restored; each token escaped as a key's name is (§73) and a token that is
|
||||
empty, `.` or `..` refused; that name is the point's `snapshot`.
|
||||
- **Its copy.** That directory is an item of the recovery module's manifest `data`, backed up by the holder of
|
||||
`node-backup` on its node as every item is (ADR 0404), which stores the copy and nothing else. When
|
||||
`restore-kept` answers `missing`, the node agent calls it again with `from-backup: yes`: the recovery module asks
|
||||
the seat `node-backup`'s `restore` of its item for that directory, which brings it back beside its path as that
|
||||
verb always does, takes the point from there and restores it; when no repository snapshot holds it, `restored`
|
||||
says `failed` with `restore point missing`, and §300 holds the revert.
|
||||
- **The aside, and a restore that fails.** `restore-kept` sets the live kept data aside by taking a stream snapshot
|
||||
of each of its bus objects into `aside/<module>/<kept>/<at>` in the same directory, reads the aside back to check it (`at` the UTC time written
|
||||
`20261111T121200Z`, with `-2`, `-3` and on added when that name exists), only then removes the live objects, which needs no person's warrant, the data staying in the aside (the operator,
|
||||
13:06 CET, §554),
|
||||
restores the point under their names and sets each consumer to its recorded sequence. Each step is written first
|
||||
in the aside's record (`set aside`, `removed`, `restored`): when a step after the removal fails, `restore-kept`
|
||||
restores the aside under the live names and sets the consumers back before it answers `failed`, and at its start
|
||||
the recovery module does the same for every aside whose record ends at `removed`, so a failed or stopped restore
|
||||
never leaves the kept data gone. The aside's `id` is that directory's name, its `name` the bus name it was live
|
||||
under, its `size` its bytes on disk; nothing of an aside stays on the bus. `recovery_discard_aside` (§554) removes that directory
|
||||
and nothing else, an `id` holding `.`, `..` or `/` refused. A restore point is removed only as §551 says.
|
||||
|
||||
This completes §405 and §406. Why: the operator's answer of 12:55 CET (§554) puts the taking and restoring of a
|
||||
module's kept data on the live bus on a module of its own; the server restores a stream only where no stream of that
|
||||
name exists, so the live data is set aside as a snapshot before the point takes its name (develop questions BKP1,
|
||||
BKP3 and NATS4's argument names; review round 1, running and testing 1, seams and tools' notes). How it is checked:
|
||||
unit (mesh-recovery's contract), each verb's input and answer read, an input naming `from` refused; a node-engine's
|
||||
`restore-kept` with `aside-only` or `discard-aside` refused, naming them; whole (recovery
|
||||
module, backup holder, bus), a point is taken, its directory removed, brought back with `from-backup` and restored,
|
||||
the live data's aside listed with its size and the consumer at its recorded sequence; a point missing from both says
|
||||
`restore point missing`; a restore made to fail after the removal, and one stopped there and started again, leave
|
||||
the live data as before; a point cut off half way is removed at start and never listed.
|
||||
- §517 **The recovery module lists what it holds.** The seat `mesh-recovery`'s read verb `kept-points` (class `read`,
|
||||
§391's default callers) lists every restore point and aside in its directory with its module, kept data, form,
|
||||
fingerprint, size and `at`, and the act that runs, with since when and what it waits on (§554); its tools are `recovery_kept_points`, which reads the same, and
|
||||
`recovery_expire_points`, which runs §551's removal now (class `act`, §391's default callers, written in the
|
||||
hand-act log). The directory is the one place they are kept, so no copy can list less: the backup holder keeps no
|
||||
state of them (its `backed-up` lists the recovery module's item as any item, §302), and no `bus-points` state is
|
||||
made. Why: a module's tools read everything it holds (*Tools are how a module is spoken to*), and the list is the
|
||||
holder's own fact (ADR 0596 §2; develop question BKP2; review round 1, seams and tools 4). How it is checked: whole
|
||||
(recovery module), `kept-points` lists a point and an aside with their sizes, an aside is gone after
|
||||
`recovery_discard_aside`, and a restart lists the same.
|
||||
- §523 **A seat event whose subject has parts.** A seat definition's `subject` with `<part>` tokens (§397), such as
|
||||
`mesh-recovery`'s `ended.<module>.<kept>` and `node-backup`'s `item-started.<node>.<module>` (§554), is said on
|
||||
`mesh.seat.<seat>.event.` followed by the subject, each part filled in the definition's order: the seat
|
||||
generator's subject function for the event takes each part as a string in that order and fills each as one token,
|
||||
escaped as a key's name is (§73), refusing an empty part, `.` and `..`. A reader hears one module's events by the subject with
|
||||
that module's tokens and `>` after them, and every module's by `*` for each part. Such an event has no key of its
|
||||
own and is kept as its definition's `keep` says, or on EVENTS when it names no `keep` (§396). The holder's account
|
||||
publishes it as a seat's holder publishes its seat's events today; no grant changes. Why: §397 fixes the subject's
|
||||
words, not how a part is filled (develop question NATS4's wire). How it is checked: unit (seat generator), a subject
|
||||
of three parts made in order and an empty part refused; whole (recovery module), `ended` heard by a reader of one
|
||||
module's subject.
|
||||
|
||||
## The tool runner and its bundles
|
||||
|
||||
- §518 **A bundle's put and get sessions run on its channel to the tool runner.** A tools bundle reaches the tool runner
|
||||
only over the channel the tool runner starts it with (its standard input and output) and holds no bus account, so
|
||||
§345's put session and §490's get session run on that channel, as every `mesh/` call of a bundle does (ADR 0595
|
||||
§9); `<bundle call subject>` in §457, §489 and §490 names that call, and no bus subject. A value at or under the
|
||||
limit is put and got by one call, as today. Over it:
|
||||
- **Whose object.** A session's `name` names an object of the bundle's own module alone: the tool runner resolves
|
||||
it in that module's binding (its state's `<state>-objects` or its sent store), and refuses a name of another
|
||||
module's, naming it. A put's whole size is bounded by that store's cap, and a put whose chunks pass it is refused
|
||||
at the chunk that does, naming the store.
|
||||
- **Put.** The bundle sends each chunk as the call `mesh/objects.put-chunk` with `name` (the object), `call` (the
|
||||
bundle's id for this put), `seq` (from 1, one more each chunk), `last` (true on the last chunk alone) and `data`
|
||||
(the chunk's bytes in base64, at most half the bus's maximum payload before encoding, §457). The tool runner
|
||||
answers each with `{seq}` or `{error}`, the bundle sends the next only after a `{seq}`, and the answer to the last
|
||||
is the put's answer; a `seq` that is not one more than the last taken is answered `{error}` naming both, and a put
|
||||
not sealed within the call's bound is dropped (§345). The tool runner writes each chunk into the store as it takes it, through the
|
||||
object store's own chunking, holding no more than one chunk in memory, and seals the object on the last. A put dropped at its bound has its written chunks purged by the tool runner,
|
||||
which deletes the unsealed object; until then they count against the store's cap.
|
||||
- **Get.** The tool runner answers the get call `{chunked: <count>, size, digest, call}` (§490), and the bundle asks
|
||||
each chunk in order by the call `mesh/objects.get-chunk` with `call` and `seq`, answered `{seq, last, data}` or
|
||||
`{error}`; the bundle checks the whole against `digest`, and a get not completed within the call's bound fails,
|
||||
naming the object. The tool runner drops a get session it holds when the call's bound passes, or the bundle's
|
||||
channel closes, whichever comes first.
|
||||
- **The bound.** The call's bound counts once for the whole session, from its first chunk, never per chunk.
|
||||
|
||||
The headers `Mesh-Put-Seq` and `Mesh-Put-Last` of §457 are these fields `seq` and `last`. Nothing of a session is
|
||||
on the bus, so §489's grants are not made and the grants part grants nothing for it. A module's process, which
|
||||
holds a bus account of its own, writes and reads its objects on the bus through the object store package directly,
|
||||
with the store's own chunking, and runs no session. The capability word `put-sessions` (§488) names these two
|
||||
calls. This amends §345, §457, §489 and §490; in the get the bundle asks each chunk, since on that channel every
|
||||
`mesh/` call is the bundle's. Why: the operator's answer to develop question D-13, chunks in order, each
|
||||
acknowledged before the next, is kept whole on the one channel a bundle has (develop questions T-5 and T-7). How it
|
||||
is checked: whole (mesh-sdk, tool runner), a value of a hundred times the limit, into a fixture state whose
|
||||
`objects-max-mib` holds it, is put and got back whole by a bundle, its digest checked, a put naming another
|
||||
module's object is refused, and a chunk out of order fails the put naming both sequences; the grants part's table
|
||||
test grants no session subject.
|
||||
- §519 **A bundle's fingerprint is in the environment the node-engine composes.** The node-engine writes
|
||||
`MESH_FINGERPRINT`, the fingerprint of the want it applies for the bundle's module, into each tools bundle's
|
||||
composed environment, as it hands it to each process (§205); the tool runner starts each bundle with its composed
|
||||
environment whole, and reads no catalog entry and no want for it. A bundle started with no value says `own build
|
||||
unknown` (§424). This completes §424. Why: the want the node-engine applies is the one fact of which build a node
|
||||
runs (§205; develop question T-12). How it is checked: whole (node-engine, tool runner), a bundle reads the
|
||||
fingerprint of its module's want.
|
||||
|
||||
## The node-engine and the want
|
||||
|
||||
- §520 **`running` says a build's health, and the assigner reads health from it alone.** The node-engine seat's
|
||||
`running.<node>.<module>` gains `healthy` (true or false), the health of the build that runs as the node-engine's
|
||||
have holds it from the module's declared check (ADR 0240), and the node-engine says `running` again on the same
|
||||
subject each time `healthy` changes, and for every module its have holds at its own start, so the stream, kept last per subject, holds each build's newest health.
|
||||
`stopped` (§365, §404) is said only when the have no longer holds the module, never for an unhealthy build. A `running` with no
|
||||
`healthy`, said by a node-engine of before G, reads as healthy while it stands, as `running` meant on main. The
|
||||
assigner reads a provider's health for rule 5, the canary's for rules 3 and 4, and a put's end from these events
|
||||
alone, read as §556 has it, and reads no have: a
|
||||
provider of which nothing was heard counts as not healthy, so its consumers' new wants
|
||||
are held as rule 5 holds any, and nothing falls back to the have. `SeatsToPassOn` reads no `healthy` (§459): an
|
||||
unhealthy holder still holds its seat. The assigner's `reads` of the node-engine's have go. This amends §309 and
|
||||
§404. Why: the assigner reads no other module's state (ADR 0596 §2), and a stopped build and an unhealthy one are
|
||||
told apart (develop questions AS15 and AS16). How it is checked: unit (the node-engine seat's fixtures), `running`
|
||||
with `healthy` read; whole (assigner, node-engine), a provider turning unhealthy holds a consumer's new want and its
|
||||
recovery lets the want go, with the assigner's account holding no read of the have; whole (assigner, a
|
||||
node-engine of before G), its provider's `running` with no `healthy` holds no consumer's want; a restarted assigner
|
||||
holds nothing it did not hold before.
|
||||
- §524 **The node-engine checks a want's parts by their digests.** A composition's archive, process and container
|
||||
resources name a source and a digest, not an artifact, so the node-engine matches no resource to a `parts` key. A want
|
||||
with no `parts` (from an assigner of before G, or for a node whose record does not state `want-parts`, §525) is
|
||||
applied as today, its resources fetched by their sources and checked by their own digests. A want with `parts` is
|
||||
applied only when the digest of every resource it fetched is among the values of the want's `parts`, and
|
||||
every value of `parts` is the digest of a resource it fetched; otherwise it applies nothing of that module and its
|
||||
have says the phase `parts-differ`, naming the digest. `parts` stays keyed by `<module>:<artifact>` for people and
|
||||
the delivery record. This completes §379. Why: the digest is what is fetched and checked (develop question H-8). How
|
||||
it is checked: unit (node-engine), a want whose parts and fetched digests agree applies, and one with a fetched
|
||||
digest outside `parts` or a part not fetched applies nothing, naming it; whole (node-engine of G), a want written by
|
||||
an assigner of before G is applied.
|
||||
- §525 **A node-engine says it reads the want's new fields.** A node-engine of G states the capability `want-parts` in
|
||||
its node record's capabilities (ADR 0614 §4, ADR 0618 §2), and the assigner writes `version`, `parts` and `kept-on`
|
||||
(§526) into a node's want only while that node's record states it; that is §379's "once that node runs G's
|
||||
node-engine". Why: ADR 0614 §4 has each node-engine state what it reads (develop question H-7). How it is checked:
|
||||
unit (node-engine), the word stated; whole (assigner), a node whose record lacks it gets a want without the fields.
|
||||
- §526 **A want names the node that keeps a kept build.** For a kept build (§271) the assigner writes `kept-on`, the
|
||||
build node the builder's `build.ended` names as keeping it (§379), into the want beside `parts`; the node-engine
|
||||
fetches that build through the seat verb `kept-artifact` of that node, and fetches a want with no `kept-on` from the
|
||||
store. Nothing else names the keeping node, the builder's `builds` going (§421). This amends §271's "the builder's
|
||||
done key names it so with its digest". Why: ADR 0596 §2 (develop question H-9). How it is checked: whole (assigner,
|
||||
node-engine), a kept build's want names its node and is fetched from it.
|
||||
- §527 **The node-engine's own module is read from the catalog half.** The seat list answers seat definitions alone
|
||||
(ADR 0636), never who holds a seat. The node-engine's apply guard and its compose read their own module's name from
|
||||
the catalog half of their view: the module whose entry claims the seat `node-engine`, which §508 makes one per
|
||||
revision; the manifest validator, beside §508's refusal of a second claim, refuses a revision in which no module
|
||||
claims it, naming the seat. §364's, §365's and §508's "from the seat list" read so, the condition keeper's too. With
|
||||
no entry claiming the seat, which only a revision from before G shows, as at a revert of G, the node-engine's own
|
||||
module is the module of the catalog graph entry its own build's fingerprint names (§443, §205), so a revert of the
|
||||
node-engine applies. Why: §364 and §508 have the node-engine claim its seat
|
||||
as one module, so the claim names it (develop question H-15). How it is checked: unit (manifest validator), a
|
||||
revision with no claim of `node-engine` refused; whole (node-engine), its guard protects the module its catalog
|
||||
half names, and with a revision of before G the module its own fingerprint's entry names, and the code review finds no fixed name (§428).
|
||||
|
||||
## Findings and the condition keeper
|
||||
|
||||
- §529 **A part's finding state and stream are declared in its kept data's form.** A part's state `findings` and its
|
||||
finding stream (§383) are declared as ADR 0666 §4 has a part declare its kept data:
|
||||
- **A foundation part** (the manifest validator's list: ADR 0619 §1's parts as ADR 0666 §4 changes them, the runner
|
||||
from G's delivery and the checker until its removal) declares `findings` in its old `state` section and the
|
||||
stream `<module>-findings` in its old `streams` section, with the events `finding-written.*`, `finding-cleared.*`
|
||||
and `findings-stated.*`, 7 days and 16 MiB, its oldest dropped (§383), published on
|
||||
`mesh.stream.<module>.event.<event>.<node>` (ADR 0363 §2).
|
||||
- **Every other part** asks both in its `requires`: the state `findings` by the template `state`, keeping its local
|
||||
name and carrying its settings as options (ADR 0595 §11), and the stream by the template `events` under the local
|
||||
name `finding-events`, with `max-age-days` 7 and `max-mib` 16, which the template drops oldest when full (ADR 0595
|
||||
§3), its entry listing the three finding events in its field `events`, which the catalog graph entry carries
|
||||
(§365), published on its binding's subject, `mesh.bus.<module>.finding-events.<event>.<node>`.
|
||||
- **`mesh-healers`**, whose old `streams` declares `mesh-healers-findings` on main, moves it so in G's change, as
|
||||
ADR 0595 §11 moves a module G touches. Its old stream stays on the bus as an orphan that `orphans` lists, removed
|
||||
only by the operator's `drop` (ADR 0595 §4, §5); the grants part deletes the keeper's consumer on it once the
|
||||
healers' entry no longer declares it (§386), and the healers say `findings-stated` at their start on the new
|
||||
stream (§384), so the keeper loses no finding.
|
||||
|
||||
The manifest validator applies ADR 0595 §11's count of old sections to no part of its foundation list (ADR 0619
|
||||
§2), so the tool runner's and the checker's manifests are not refused for it, and accepts in a foundation part's
|
||||
old `streams` the finding stream in the one form above, as it accepts a stream on its list of streams kept until
|
||||
moved; every other old `streams` entry is judged as today. A part whose list entry is missing is a fault of the
|
||||
list, fixed in the validator (ADR 0619 §3). The validator refuses a manifest whose state `findings` has no finding
|
||||
stream in its part's form, or no `consumes` of `mesh-conditions.findings-asked` (§387). The writer (§461) is handed
|
||||
the subjects from the part's binding or its old stream, as it is handed every subject. The catalog graph entry
|
||||
carries the finding stream in either form (§365); the grants part makes the keeper's consumer of §386 on an
|
||||
old stream at the revision that declares it, and on a template stream when it hears the bus module's `created` for
|
||||
`finding-events` and grants each part publish on its own finding stream's subjects of its own node only, in either form; the
|
||||
keeper takes the observer and the node from either subject. This amends §383, §386 and §387, whose "into the
|
||||
manifest's `streams`" holds for a foundation part alone. Why: ADR 0666 §4 and ADR 0595 §11 put a part's kept data
|
||||
in the templates unless it is a foundation part, and ADR 0619 §2 keeps the foundation's old sections whole; the
|
||||
local name `finding-events` is the design's choice, since `findings` names the state and ADR 0595 §8 takes one
|
||||
name per module (develop questions on §387, both validator refusals). How it is checked: unit (manifest validator),
|
||||
a foundation part's old `findings` and finding stream accepted, a non-foundation part's old sections refused and its
|
||||
template form accepted; the catalog's validation at G's heads refuses none of §387's manifests; whole (keeper, a
|
||||
template observer and the tool runner), both forms' events raise a condition; whole (keeper, healers), a healers'
|
||||
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
|
||||
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:<account>`, 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
|
||||
its new author's with two hours of its own. The keeper's tool `conditions_owner` sets a condition's `owner` now, of
|
||||
class `act` with §391's default callers, written in the hand-act log. The keeper times the two hours on its own conditions from `since`, so after its restart it times them from
|
||||
`since` again. Why: §33 has the keeper raise it as the author's, then the operator's (ADR 0505 §5, §6; develop
|
||||
question COND7). How it is checked: whole (keeper), a `pipeline-failed` is the operator's two hours after its
|
||||
`since`, and so after a restart of the keeper; unit (mesh-conditions' contract), `forge:<account>` read.
|
||||
- §541 **The keeper hears what a node runs and the healers' attempts as events.** The keeper's `reads` of
|
||||
`node-engine.have` and `mesh-healers.attempts` go (§434).
|
||||
- **What a node runs.** The keeper consumes the node-engine seat's `composed`, `running` (with `healthy`, §520, and
|
||||
`stopped`) and `wait-held` and `wait-ended` (§499), read as §556 has it, and compares them with the wants it hears
|
||||
from the assigner, to hold a module's findings while it is delivered (ADR 0564 §13), as it did from the haves.
|
||||
The node-engine says `wait-held` on `mesh.seat.node-engine.event.wait-held.<node>.<module>`, with `step: compose`
|
||||
and the reason, for each hold its have writes (§300's `restore point missing`, §421's `entry-missing`, §524's
|
||||
`parts-differ`, §499's kept build), and `wait-ended` on `.wait-ended.<node>.<module>` when the hold ends. The
|
||||
keeper raises no condition of its own from them: the watchman writes `delivery-waits` for a `wait-held` of the
|
||||
node-engine standing past composing's 30 minutes (§266), naming the node, the module and the reason, and it clears
|
||||
on `wait-ended`; a `composed` whose fingerprint is not the want's is covered by that same wait or by the put's
|
||||
wait (§498).
|
||||
- **The healers' attempts.** The seat `mesh-healers` says `attempt-changed` on
|
||||
`mesh.seat.mesh-healers.event.attempt-changed.<condition>`, the condition's key escaped as a key's name is (§73),
|
||||
carrying the attempt's value whole as its key in `attempts` holds it and `until`, the end of that key's
|
||||
lifetime, or `removed: true` when the healer ends the attempt; the seat's definition, in its contracts module,
|
||||
keeps it last per subject, 7 days and 16 MiB (§396). The healers say it again for every open attempt at their start. The
|
||||
keeper reads it as §556 has it, and drops an attempt at its `until` on its own clock.
|
||||
|
||||
Why: the keeper reads no other module's state (ADR 0596 §2; develop question COND8). How it is checked: whole
|
||||
(keeper, healers, node-engine), an attempt said is shown on its condition and dropped at its `until` or its
|
||||
removal, a node-engine's hold is heard from `wait-held` and past 30 minutes raises `delivery-waits`, a restarted keeper
|
||||
holds the attempts it held, and the keeper's manifest declares no `reads`.
|
||||
|
||||
## Views of the catalog half, per watched branch
|
||||
|
||||
- §521 **An owner's view event names its state, and the key names the branch.** An event an owner says for a per-branch
|
||||
state (`catalog-revision` for `catalog-revisions`) names the state as the owner's manifest names it,
|
||||
`catalog-revisions`, and the key, `<branch>.<revision>` (§343); mesh-sdk's `go/views` reader and process reader
|
||||
route it to the view `<owner>.<state>.<branch>` (§479) by the key's first token, the branch escaped as a key's name
|
||||
is (§73), which the subject's last token repeats. No event names a state `<state>.<branch>`; mesh-sdk's code at
|
||||
eed96854, which names it so, follows this line. Why: a state is named once, as its owner declares it, and the key
|
||||
already carries the branch (develop question on §479 and §495). How it is checked: unit (`go/views`), one
|
||||
subscription of a per-branch event routes two branches' events to their two views.
|
||||
- §530 **`revision` says `none yet` in a field.** The seat `mesh-catalog`'s `revision` for a watched branch with no
|
||||
revision yet answers `{none-yet: true}`, with no revision and no `error`; mesh-sdk's client reads `none-yet` as a
|
||||
ready, empty view (§495) and never reads an error's text for it; `views.NoneYet` is the client's name for that
|
||||
answer. Why: an answer is told by its fields, never its words (develop question on §495). How it is checked: unit
|
||||
(mesh-catalog's contract), the answer read; unit (client), `none-yet` gives a ready, empty view.
|
||||
- §532 **Every reader of the catalog half follows every watched branch, and adopts a branch registered while it runs.**
|
||||
Every part that reads the catalog half per watched branch (among them the bus module, the status view, the
|
||||
condition keeper, the tool runner, the assigner, the grants part and the runner) follows one view per watched
|
||||
branch: the branches the registrations name, read by `registrations` at its start and followed by
|
||||
`registration-changed`, and before the first registrations the branches the gate's `source` answers (§507); no part
|
||||
names a branch in its code, the view's `main` included.
|
||||
- **Adopted after the start.** mesh-sdk's views reader adopts a view after its start and drops one: on
|
||||
`registration-changed` adding a watched branch the part adopts `<owner>.<state>.<branch>`, which takes its first
|
||||
view at once and then follows; on one removing a branch the part drops the view and its row of
|
||||
`<module>_first_views`.
|
||||
- **One subscription per event.** The reader subscribes once per event, `<event>.>`
|
||||
(`mesh.seat.mesh-catalog.event.catalog-revision.>`), and routes each event to its branch's view by §521, so two
|
||||
branches never overwrite each other's handler; `meshcatalogclient` wires its views on that one reader, and the
|
||||
runner's own wiring of `catalog-revision.>` goes for it.
|
||||
- **The bus module across branches.** The bus module plans a module's kept data from the newest revision of each
|
||||
watched branch that lists the module: each local name once, from the first of the module's watched branches, in
|
||||
its registration's order, whose revision lists it. A registration's watched branches are a list in that order: the
|
||||
branch `register` names first (the repository's default branch, a placement's default, ADR 0666 §6), then each
|
||||
branch in the order `watch` added it; `unwatch` removes one and keeps the others' order; another branch asking that local name with other settings is
|
||||
said as the bus module's `drifted`, naming the branch (ADR 0595 §6), and plans nothing.
|
||||
|
||||
This amends §358, §365, §421, §433 and §507. Why: no part fixes a branch (§7, ADR 0666 §5), and a registration may
|
||||
add a watched branch while a part runs (develop questions NATS3, VW1 and COND6, and the client's lost per-branch
|
||||
events). How it is checked: unit (`go/views`), a view adopted after the start takes its first view and follows,
|
||||
and two branches' events reach their own views; whole (keeper, bus module), a branch registered while they run is
|
||||
followed with no restart; whole (bus module), a feature branch asking a local name with other settings than the
|
||||
default branch's is said `drifted` while the default branch's are planned; the code review finds no branch's name
|
||||
in any part.
|
||||
|
||||
## The bus module's plans
|
||||
|
||||
- §533 **A module of the new form.** "A module of the new form" (§59, §344) is a module that is no foundation part.
|
||||
The bus module tells it by its catalog graph entry declaring no old `objects` section `sent-objects`: a foundation
|
||||
part whose entry claims a seat whose definition has a verb or an event, or declares an event of its own, declares
|
||||
it (§59), and the manifest validator refuses such a foundation part's manifest without it, naming it. Why: the bus
|
||||
module reads no list of foundation parts, which is the validator's alone (ADR 0619 §3; develop question on §59 and
|
||||
§344). How it is checked: unit (manifest validator), a foundation part saying an event without `sent-objects`
|
||||
refused; whole (bus module), a module of the new form gets a sent store and a foundation part none.
|
||||
- §537 **A definition's included parts are resolved before they are counted.** The bus module counts a seat
|
||||
definition's verbs and events after resolving the parts it includes: it reads each definition that includes parts
|
||||
by the seat list's answer for that one seat, which resolves them (ADR 0636), and plans a sent store (§344) for the
|
||||
seat's holders when the resolved definition has a verb or an event. Including parts alone counts for nothing.
|
||||
Why: an included part may hold only shared bodies (develop question on §344). How it is checked: whole (bus module),
|
||||
a seat whose verbs come only from an included part gives its holder a sent store, and one including only bodies
|
||||
gives none.
|
||||
- §538 **The bus module plans again when the bus-state entries change.** The bus module compares, for each module,
|
||||
the bus-state entries the catalog graph entry carries with those it last planned for that module, kept in its old
|
||||
`state` section `plans` (the bus module is a foundation part), one key `<module>` holding the entries as planned
|
||||
and their digest, written after each plan and deleted when the module is in no watched branch's newest revision, its
|
||||
entries then orphans that `orphans` lists; its tool `nats_plans` reads it. It plans again only when they differ; it never compares the manifest's digest (§506), which changes with
|
||||
any field. Why: what it plans is those entries alone (develop question on §433 with §506). How it is checked: whole
|
||||
(bus module), a manifest changed outside `requires` plans nothing, and a changed option plans the difference.
|
||||
|
||||
## The runner, the checker and mesh-sdk's helpers
|
||||
|
||||
- §528 **The checker built from G's heads asks no group build.** From G's delivery the pipeline is the check and the
|
||||
run on request the try (§66), so the checker built from G's heads makes no group check: its group build through
|
||||
tagged versions (its check's group path, `judge.go`'s, and `tagwanted.go`) goes with `tag-wanted` (§373), nothing replaces it in
|
||||
the checker, and a group's builds against its package members' digests are the runner's (§373, §465). Until G's
|
||||
delivery the running checker makes G's own check with main's code (ADR 0667 §2). Why: §66 and §373 (develop
|
||||
question CK10). How it is checked: the code review finds no group build in the checker of G's heads.
|
||||
- §534 **The wait's `step` in the runner's body.** The runner's wait body keeps `step` as the pipeline step a wait inside
|
||||
a pipeline is in (`lint`, `unit`, `integration`, `composition`, `review`, `approval`), and gains the value
|
||||
`pipeline`, the acting step of §203, for a wait of the entries the runner holds for its new version (§266,
|
||||
`runner_waits`); `clock-from` stands beside it (§498). The watchman tells them apart by the value: `pipeline` and
|
||||
every value §498 lists are acting or delivery waits, timed by their bound (§269); a pipeline step's value is a
|
||||
step's wait on a person, a build node or the revision view (§73), timed as §75 has it, a wait on a person owing no
|
||||
progress (ADR 0666 §24). This completes §498 for the runner. Why: one field, told apart by its value (develop
|
||||
question on §498). How it is checked: unit (runner's contract), both kinds read; whole (watchman), a runner's
|
||||
`pipeline` wait raises `acting-part-late` past its 30 minutes and an `approval` wait raises no `pipeline-stands`.
|
||||
- §535 **A missing build seat and a seat with no holder, each read where it shows.** The runner reads that no build
|
||||
seat serves an artifact's language from the catalog half of its revision view: no entry whose `acts`, the acting
|
||||
rules of the seats it claims, hold a rule `build` with `on` naming that language (§323); the pipeline then ends
|
||||
failed at once, naming the language and the missing build seat. It reads that a seat has no holder from the step
|
||||
itself: an ask on that seat's work queue whose `step-started` is not heard within five minutes ends the pipeline
|
||||
failed, naming the seat (§32). It reads neither from the seat list, which answers definitions alone (§527), nor
|
||||
from any holding. Why: §32 already ends a pipeline whose step nothing starts, and the catalog half is the runner's
|
||||
one view (develop question Q-RN7). How it is checked: whole (runner), a fixture language with no build seat ends at
|
||||
once, naming it; a seat whose holder is stopped ends within five minutes, naming the seat.
|
||||
- §539 **The runner's tools are named `runner_`.** The runner's module, `mesh-delivery-pipeline`, names its tools with
|
||||
the prefix `runner_`, so the design's `runner_catch_up`, `runner_waits`, `runner_release` and `runner_health`
|
||||
stand, and its first-view tool is `runner_first_views`; `<module>_first_views` (§205) carries the prefix the
|
||||
module's tools carry. Why: the design names the runner's tools so throughout (develop question RN1). How it is
|
||||
checked: the runner's manifest, and `mesh_search` with "runner first views" finds `runner_first_views`.
|
||||
- §531 **The kept-call form in Go.** §460's form is mesh-sdk's `busretry.DoKept`, which takes the ask's key, `open` (of
|
||||
the type `busretry.Open`), an optional `replaced` and the function that writes the journal, and a process's call
|
||||
through it is `process.Conn.CallKeptWhileOpen`, as mesh-sdk 19fb1dce has them. Why: a helper's API is the design's
|
||||
(develop question R-5). How it is checked: §460's.
|
||||
- §536 **`SeatsToPassOn`'s types.** §459's function in mesh-sdk's `catalogue` takes `holdings`, `assignments` (a list
|
||||
of `Assignment` with `Node`, `Module` and `Branch`), `heard` (a function of a node and a module answering a `Heard`
|
||||
with `Fingerprint` and `Stopped`, and whether anything was heard) and `entries` (an `EntryReader` with
|
||||
`ByFingerprint` and `OnBranch`), as mesh-sdk e0f9356b has them. Why: a helper's API is the design's (develop
|
||||
question R-4). How it is checked: §459's.
|
||||
|
||||
## The operator's words
|
||||
|
||||
- §522 **The words the teller says.** The teller says, through `notify` on every channel (§514), in the operator's
|
||||
words:
|
||||
- `widens`, one line per entry of the pipeline's end (§335): "Widening: `<module>` `<commit7>` on `<branch>` widens
|
||||
`<kind>` `<name>`.", `<kind>` and `<name>` the entry's.
|
||||
- `recovery-merged` (§81): "Recovery merged: `<module>` `<commit7>` on `<branch>`, named by `<caller>`: `<why>`."
|
||||
- a `forge-made` record (§170): "Merged at the forge, not through the mesh: `<repository>` pull request #`<n>` at
|
||||
`<commit7>` on `<branch>`; delivered like any merge."
|
||||
|
||||
`<commit7>` is the commit's first seven hexadecimal characters. This completes §514. Why: the operator, 2026-11-11
|
||||
12:11 CET at lead-47's terminal, approved the words as the design writer proposed them. How it is checked: unit
|
||||
(teller), each of the three said in these words with its fields filled; whole (teller, router), as §514.
|
||||
|
||||
- §542 **An Approve given before G is that pull request's approval step.** The operator, 2026-11-11 12:33 CET at
|
||||
lead-47's terminal: approval is a step whose status each module's registration sets, never a gate of its own, so
|
||||
an Approve given before G counts, once G is delivered, as that pull request's `approval` step and nothing else is
|
||||
special. At G's switch the gate says, for each `merges` key the old bridge had not performed, `approval-carried` on
|
||||
`mesh.seat.mesh-delivery.event.approval-carried.<repository>.<pull>` (`repository`, `pull`, `commit` the head the
|
||||
Approve named, `approver` the operator, `at`), declared in the seat's definition with `keep` 90 days (§396). The gate
|
||||
keeps its `merges` keys, read no more, until §97's removal, so a revert's gate of before G finds them. The runner
|
||||
hears the event through a durable consumer made to start from the stream's first message, so a runner started
|
||||
after the switch hears every one, and keeps each in its old `state` section `pipelines` as
|
||||
`carried-approval.<repository>.<pull>`, holding the commit. It takes it as the result `passed`, caller the
|
||||
operator, only of the `approval` step of the delivering pipeline whose source revision takes in that pull
|
||||
request's merge, as `take-in.taken`'s entries name it (each entry carrying the repository and the pull request of a
|
||||
`merged` message, §493, §509), and only when the pull request's head merged is that commit; never in a run on
|
||||
request and never in another pipeline at the same commit; then it deletes the key, and deletes it unused when the
|
||||
seat `git` says the pull request `pull-closed`. Where the module's policy makes `approval` `required`, a pull request whose head
|
||||
moved after the Approve asks a new approval, as any step whose input changed does (an `approval` step is never
|
||||
carried, ADR 0666 §8); where it is `optional` or `bypass`, the carried Approve holds nothing. The merge itself is
|
||||
any merge (`merge-pull`, ADR 0666 §11): the bridge performs no carried act, the gate says no `wait-held` with
|
||||
`step: merge`, and the watchman writes no `merge-waits`. Every `wait-held` the runner says for an `approval` step
|
||||
has its `wait-ended`, said when the step ends in any of §24's outcomes (`passed`, `declined`, `superseded`,
|
||||
`cancelled`, `not asked`) or its pipeline is superseded or cancelled, so no approval wait stands without an end.
|
||||
This replaces §510 and §608, and `merge` leaves §498's list. Why: the operator's answer ("you're mixing in step and
|
||||
approval gates, this should be configurable"); the event, the key and the deletion are the design's (round 3,
|
||||
health and events' R7). How it is checked: whole (gate, runner), a carried Approve of a head passes the `approval` step
|
||||
of the pipeline taking in that pull request's merge, with the operator as caller, and no run on request at that
|
||||
commit; a runner started after the switch takes it all the same; with `approval` `required`, a head moved after the Approve asks a new
|
||||
approval; a pull request closed deletes its carried key; every `approval` wait-held in the whole test has its
|
||||
`wait-ended`; the code review finds no `merge-waits`.
|
||||
|
||||
## Round 3 of the review of §480 to §515
|
||||
|
||||
- §543 **A build seat's holder refuses a kind its asker may not ask.** Callers stay per accepted kind (§338), and the
|
||||
builder joins them as the one caller, beside the checker until §483's removal, of the kind `build`, as §601 has it
|
||||
ask under its name. The grants part grants each asker publish on `mesh.seat.<seat>.accept.<queue>.<asker>` (§600)
|
||||
for every queue of the seat on which a kind it is a caller of is taken, and the holder, which takes the asker from
|
||||
the subject (§481), refuses an ask whose body names a kind that asker is not a caller of, answering `error` naming
|
||||
the kind and the asker, and ends it with `step-ended` `failed`. On main's subject `accept.<queue>`, which names no asker and is granted to
|
||||
the checker and the builder alone (§600), the holder takes only the kinds `build` and `run` and refuses any other,
|
||||
`step` among them, as above; the builder's `run` there is taken until the checker's removal (§97), after which
|
||||
main's subject goes (§483). This amends §338 and §600. Why: §600 puts the queue
|
||||
in the subject and the kind in the body, so a subject's grant alone cannot hold a caller to its kinds (round 3,
|
||||
security and upgrade, seams and tools: R1). How it is checked: unit (Go build module), a `step` published from the
|
||||
indexer's account is answered `error` naming `step` and `indexer`; unit (grants part), each asker's grants are the
|
||||
queues of its kinds; unit (Go, Node and image build modules), a `step` on main's subject is answered `error`.
|
||||
- §544 **Named asks have a worker of their own.** For each queue the grants part makes, beside main's worker
|
||||
`SEAT_<SEAT>_<QUEUE>_worker` filtered to main's `mesh.seat.<seat>.accept.<queue>` alone, a second worker
|
||||
`SEAT_<SEAT>_<QUEUE>_named_worker` filtered to `mesh.seat.<seat>.accept.<queue>.*`; the two filters do not overlap,
|
||||
so the work-queue stream takes both. Only a holder of G pulls the named worker, and a holder of before G knows only
|
||||
main's, so no filter is ever switched and a holder of before G that comes back from away (a laptop) after the grants
|
||||
part runs takes no named ask. This replaces §601's "until every node's holder of a build seat is of G the grants
|
||||
part's worker keeps main's one filter", and with it the edge from the seats' holders to the grants part, which no
|
||||
manifest fact gives: the order is the asker's `invokes` of `<seat>.accept.<queue>` (kind 6, from the seat's holders
|
||||
to the asker, §601), and the grants part comes before every asker as the acting part of the step `grant` on
|
||||
`every` (§203): each entry of a revision waits for the grants part's new version to act for it (§266), so no asker
|
||||
of G runs before a grants part of G has made its named worker and its grant. A holder of G pulls main's worker
|
||||
alone until its membership names the named worker, which the grants part writes as it binds every consumer
|
||||
(§386), and says meanwhile, in its journal and its read tool, `named worker not bound`. A named ask waits on its worker while no holder of G
|
||||
runs, said by `build-capacity-waits` after 60 minutes, which corrects §483's "waits on the work queue, whose
|
||||
consumer of before G takes only main's subject". At a revert, the grants part of G takes its view of the revert's catalog revision before
|
||||
it is itself reverted, since it acts for every entry of it (§203); at the first revision in which no entry `invokes`
|
||||
any `<seat>.accept.<queue>`, it purges the subjects `accept.<queue>.*` of the stream and deletes the named workers,
|
||||
within its granting bound of 10 minutes (§266), saying each in its journal. Where that did not run (the grants part
|
||||
stopped first), its tool `grants_named_purge`, of class `act` with §391's default callers and written in the
|
||||
hand-act log, does it by hand; an ask is transport,
|
||||
not kept data (as §59 has a sent object). Why: one consumer per filter, and a filter that never moves cannot be
|
||||
pulled by a holder that does not read it (round 3, R2, the security reviewer's form). How it is checked: whole
|
||||
(grants part, Go build module), a holder of before G started after the grants part of G takes main's asks and no
|
||||
named one; a revert leaves no named worker and no named ask; a holder of G before its binding pulls main's worker
|
||||
and says `named worker not bound`.
|
||||
- §545 **The tool runner's artifact declares the words it states.** The artifact entry of the tool runner's manifest
|
||||
takes `states`, the capability words (§488) it states; the manifest validator refuses a package artifact's `calls`
|
||||
word (§605) that no artifact of the revision `states`, naming the word, and the delivery plan's edge of §605 runs to
|
||||
the module whose artifact `states` that word, so no manifest names the tool runner's module. A bundle is started by
|
||||
the tool runner on its channel and ends with it, so a restart of the tool runner restarts its bundles, and each
|
||||
reads the stated words at its own start; no event is heard and nothing polls. This amends §605's "each time the
|
||||
tool runner of its node starts". Why: the words are stated only at run time, and the plan needs them in a manifest
|
||||
(round 3, seams and tools: R3). How it is checked: unit (manifest validator), a `calls` word nothing `states`
|
||||
refused; unit (tool runner), the words it states are exactly its manifest's `states`; unit (delivery plan), the edge to the module stating the word.
|
||||
- §546 **When the builder forgets a node's toolchain.** The builder deletes its `toolchains-heard` key
|
||||
`<node>.<language>` (§604) when the node-engine seat's `running.<node>.<module>` says `stopped` (§365) for the
|
||||
module whose catalog graph entry claims the build seat of that language (its `acts` rule `build` with `on` naming
|
||||
it, §535), heard through its consumer of that seat's `running`, read as §556 has it; never on a placement, which
|
||||
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,
|
||||
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.
|
||||
- §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
|
||||
server's own limit does not. So each `<state>-objects` is planned with 16 MiB (about 2.4 GiB for 150 states), a
|
||||
state needing more naming `objects-max-mib`, and no later measure is waited for. The bus module reads the account's
|
||||
and the server's storage limits at its start and at each plan, sums the cap of every entry it plans (states, objects
|
||||
stores, sent stores, streams, logs) and of every old section the catalog graph's entries declare, and shows the sum and
|
||||
both limits in its `list` and its read tool. A plan whose sum would pass the account's limit is refused, naming the
|
||||
sum and the limit, said as its `refused` (ADR 0595 §6): the plan refused is the one that adds or raises a cap, and
|
||||
the caps already made stay as they are. With no account limit (unlimited) nothing is refused and the sum is shown
|
||||
against the server's limit. This amends §607's 64 MiB and its measure in G's check. Why: the limit is a
|
||||
fact of the server, read rather than written in the design, and a sum over it fails loudly (round 3, running and
|
||||
testing: R5). How it is checked: whole (bus module), a fixture bus with a small account limit refuses the plan
|
||||
that would pass it, naming the sum, and keeps the caps made; with no account limit nothing is refused; the sum and
|
||||
the limits are in `list`.
|
||||
- §548 **The forge module writes `seen` only from a pipeline's steps.** §487's `seen.<commit>.<module>` is written only
|
||||
from a `step-ended` that carries a pipeline's `commit` and `fingerprint`, which a pipeline's step carries; the
|
||||
`step-ended` of any other ask (§602) carries `asker`, `ask`, `node`, `outcome` and `at` and neither, so the forge
|
||||
module writes nothing from it and names no asker. This amends §487.
|
||||
Why: since §602 every ask says `step-ended`, and a builder's build is no run of a commit (round 3, health and
|
||||
events: R6). How it is checked: unit (forge module), a builder's failed build writes no `seen`; whole (watchman), a
|
||||
`stuck` raised for an ask clears on its late `step-ended`.
|
||||
- §549 **Smaller corrections from round 3.** At its start the runner appends an `unlogged` entry (§606) only after
|
||||
reading back its `step-log`'s last entry of that pipeline and step, and skips it when that entry is already
|
||||
logged, so a stop between the append and the clear appends nothing twice. `step-progress` and `ask-taken` (§603)
|
||||
name no `keep` and go on EVENTS, kept 7 days (§396). `runner_unlogged_append` is of class `act` and takes §391's
|
||||
default callers. §58 is planned with the cap §607 and §547 give. How it is checked: whole (runner), a runner
|
||||
stopped between the append and the clear logs the entry once; the rest as the lines they correct.
|
||||
- §550 **A publication's pipeline keeps the version.** The runner's pipeline value gains `version`, the version
|
||||
`package-published` names, for a pipeline the runner started from a publication or from `outdated` (§334), and
|
||||
none for any other; `show` answers it. This completes §334's "the version in the pipeline's state". Why: the
|
||||
runner's contract had no field for it (develop's note on §334). How it is checked: unit (runner's contract), the
|
||||
field read; whole (runner), a publish's pipeline shows its version.
|
||||
|
||||
## The operator's answers of 12:41 CET
|
||||
|
||||
- §551 **A restore point is removed after 90 days, never the newest.** The operator, 2026-11-11 12:41 CET at lead-47's
|
||||
terminal. The recovery module removes a restore point's directory (§516) 90 days after its `at`, as long as delivery
|
||||
records are kept, unless it is the newest point of its module and kept data, which it never removes; it checks at
|
||||
its start, once a day and at each `snapshot-kept`, on its own clock and its own directory, as one of its acts, never
|
||||
beside a `restore-kept` (§554). Each removal is written in the hand-act log of the seat `mesh-hand-acts` and said as
|
||||
`mesh-recovery`'s event `point-removed` on `mesh.seat.mesh-recovery.event.point-removed.<module>.<kept>` (`module`,
|
||||
`kept`, `form`, `fingerprint`, `snapshot`, `at`), kept 90 days (§396). The backup holder's copies go by its
|
||||
repository's own rotation (ADR 0235 §4). Data set aside is removed only by `recovery_discard_aside` (§554). This completes
|
||||
§516 and answers issue 1921's note on the retention of restore points. Why: the operator's answer; the event, the
|
||||
checks and their order are the design's. How it is checked: whole (recovery module), a point older than 90 days is
|
||||
removed and said, the newest point of a kept data older than 90 days stays, and a removal due during a restore runs
|
||||
after it.
|
||||
- §552 **The checker may drop its own asks until its removal.** The operator, 2026-11-11 12:41 CET at lead-47's
|
||||
terminal: the build seats' verb `drop` (§338) gains the checker as a caller until its entry is removed with its
|
||||
buckets and bus account (ADR 0667 §12), as `run` has it, so the validator accepts the checker's manifest's
|
||||
`invokes` of `seat:node-build-go.drop` and `seat:node-build-node.drop`. This amends §338. How it is checked: unit
|
||||
(manifest validator), the checker's manifest accepted; whole (grants part), the checker's drop granted and another
|
||||
module's refused.
|
||||
- §553 **A step status left empty is `optional`.** The operator, 2026-11-11 12:41 CET at lead-47's terminal: a step
|
||||
whose status a registration's policy (module-level `policy.steps`, or an artifact's) leaves empty is read as
|
||||
`optional`: it runs, and a failure is shown and holds nothing (§23); `register` and `policy` accept such a policy
|
||||
and refuse nothing for it, and the runner, `registrations` and `show` say the step `optional`. This completes §23.
|
||||
How it is checked: unit (runner), a step with no status runs and its failure holds no want; unit (mesh-catalog's
|
||||
contract), a registration with an empty status accepted.
|
||||
|
||||
## Questions an earlier line answers
|
||||
|
||||
These write nothing new; develop reads the line named.
|
||||
|
||||
- The tool runner's fallback of local commit 1015b38 for a foundation part's bundle goes: §407 binds that bundle to
|
||||
its old `objects` section, and a binding that is missing fails loudly (ADR 0595 §1) (Q-T5, T-11).
|
||||
- The re-read tool's callers of `seatlist.Part` are §204's for every part, the assigner's own list going (AS19).
|
||||
- The bus module's cap of a state's objects store is §513's as §607 and §547 amend it, and the binding's `objects`
|
||||
and `sent-objects` are §513's (NATS1, §399).
|
||||
- The contracts' `Hold` is §194's view, the newest assignment half and the catalog half it names; the candidate's
|
||||
whole-half reader is §195's and §441's, read by a run on request's steps, `grants-for` and the indexer's candidate
|
||||
pass (contracts).
|
||||
- The view's module value carries the entry's `manifest-digest` (§506) and computes none (VW1).
|
||||
- `store-filling` is raised past 80 % and cleared below 70 % (§181).
|
||||
@@ -28,7 +28,7 @@ takes §600 on, since §516 on are those of batch 4's file G-12.
|
||||
*These lines answer what the four reviewers by architectural domain found in round 2 of
|
||||
[G-11](G-11-develop-answers-review.md) (§480 to §515), the last round. Each is the design's choice with its reason.*
|
||||
|
||||
- §600 **A build seat's asks: subjects, workers and grants.** A build seat (`node-build-go`, `node-build-node`,
|
||||
- §600 **A build seat's asks: subjects, workers and grants.** (§543, §544) A build seat (`node-build-go`, `node-build-node`,
|
||||
`node-build-image`) keeps its three queues of main, `delivery`, `check` and `recheck` (ADR 0525 §4, ADR 0536 §4), on
|
||||
its one work-queue stream. An ask is published on `mesh.seat.<seat>.accept.<queue>.<asker>`, `<queue>` one of the
|
||||
three, `<asker>` the asker's name; the ask's kind (`step`, `run`, a build) stays in its body, as on main. The
|
||||
@@ -43,7 +43,7 @@ takes §600 on, since §516 on are those of batch 4's file G-12.
|
||||
checked: unit (grants part), each queue's worker filters both subjects and each asker's grant is its own name;
|
||||
whole (grants part, Go build module), an ask under `runner` is taken and answered, and the runner's account
|
||||
publishing on main's `accept.check` is refused.
|
||||
- §601 **The order of G's rollout for the build seats.** The holders of the three build seats are delivered first,
|
||||
- §601 **The order of G's rollout for the build seats.** (§544) The holders of the three build seats are delivered first,
|
||||
then the grants part, whose workers then filter both forms (§600), then every asker of G (the runner, the indexer,
|
||||
the assigner, the builder) and the watchman. Until every node's holder of a build seat is of G the grants part's
|
||||
worker keeps main's one filter, so a holder of before G never takes a named ask, whose key it would write in main's
|
||||
@@ -68,20 +68,20 @@ takes §600 on, since §516 on are those of batch 4's file G-12.
|
||||
`stuck`, naming the seat, the asker, the ask and the node, as main's mirror does. This completes §496. Why: only the
|
||||
runner says `step-started` (review round 2, health and events 1). How it is checked: whole (watchman, Go build
|
||||
module), a builder's build whose holder stops raises `stuck` within five minutes and one that ends raises nothing.
|
||||
- §603 **Where `step-progress` and `ask-taken` go.** Both are seat events and go on the stream that carries the seat's
|
||||
- §603 **Where `step-progress` and `ask-taken` go.** (§549) Both are seat events and go on the stream that carries the seat's
|
||||
events, at that stream's own age; no stream is added and no event's age changes. `step-progress` and `ask-taken`
|
||||
are declared in the three build seats' definitions in `mesh-delivery-contracts`, and `step-progress` in
|
||||
`mesh-wants`' definition for a composition step. This amends §496's "kept on the seat's stream for a day". Why:
|
||||
a build seat's own stream is its asks' work queue (review round 2, running and testing 4, seams and tools' note).
|
||||
How it is checked: unit (definitions), each event declared.
|
||||
- §604 **The builder keeps the toolchains it heard.** The builder writes each `toolchain-reported` (§492) in a state of
|
||||
- §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 `<node>.<language>` 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
|
||||
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.
|
||||
- §605 **The order after G's tool runner is derived from the package a build resolved.** A package's artifact in a
|
||||
- §605 **The order after G's tool runner is derived from the package a build resolved.** (§545) A package's artifact in a
|
||||
manifest takes `calls`, the capability words (§488) its code calls of the tool runner; mesh-sdk's Go and npm
|
||||
packages name `ledger-upkeep-calls`, `sent-objects-calls` and `put-sessions` from G. For each module whose build
|
||||
resolved a version of such a package (§466's `resolved`), the delivery plan derives a served-word edge (kind 6) to
|
||||
@@ -90,7 +90,7 @@ takes §600 on, since §516 on are those of batch 4's file G-12.
|
||||
This amends §488's `needs`. Why: the bundle makes a session whenever a value is large, so only the package knows
|
||||
(review round 2, seams and tools 3, running and testing's note). How it is checked: unit (delivery plan), a module
|
||||
built on G's mesh-sdk is ordered after the tool runner on each node; unit (manifest validator), `calls` read.
|
||||
- §606 **A step's end and its unlogged entry are one write.** The runner writes a step's end in `pipelines` with the
|
||||
- §606 **A step's end and its unlogged entry are one write.** (§549) The runner writes a step's end in `pipelines` with the
|
||||
entry as `unlogged` in the same compare-and-set, appends it to `step-log`, then clears it; at its start it appends
|
||||
every `unlogged` entry of its pipelines, in order. It reads the log's fill again at each step's end, at its start,
|
||||
and once a minute while the log is `full`, so the entries the bus ages out say `room` with no step ending. Its tool
|
||||
@@ -99,7 +99,7 @@ takes §600 on, since §516 on are those of batch 4's file G-12.
|
||||
full log (review round 2, running and testing 2, health and events 3, seams and tools' note). How it is checked:
|
||||
whole (runner), a runner stopped after a step's end appends its entry at start; a full log whose oldest entries age
|
||||
out says `room` with no step ending.
|
||||
- §607 **A state's objects store has the state's size.** Each `<state>-objects` (§58) is planned with the state
|
||||
- §607 **A state's objects store has the state's size.** (§547) Each `<state>-objects` (§58) is planned with the state
|
||||
template's size, 64 MiB, unless the state's `requires` names `objects-max-mib`; the sent stores keep §477's 256
|
||||
MiB. An estimated 150 states across about 120 modules give about 9.4 GiB of caps. Whether the bus counts a cap
|
||||
against its storage limit before anything is written is measured in G's check (the bus module's whole test reads
|
||||
@@ -108,7 +108,7 @@ takes §600 on, since §516 on are those of batch 4's file G-12.
|
||||
its owner. This amends §513 and leaves §58's "reserves nothing" to that measurement. Why: §58 names the template's
|
||||
size (review round 2, running and testing 3). How it is checked: unit (bus module's plan), each objects store's cap;
|
||||
whole (bus module), the reserved storage read after the plan.
|
||||
- §608 **A carried merge that waits is a timed wait.** A merge act carried by the switch (§510) waiting for the first
|
||||
- §608 **A carried merge that waits is a timed wait.** (§542) A merge act carried by the switch (§510) waiting for the first
|
||||
registrations is said by the gate as `wait-held` with `step: merge` (added to §498's list), naming the pull request
|
||||
and the head the Approve named, bounded at 60 minutes; past it the watchman writes `merge-waits`, which the
|
||||
condition keeper raises and `wait-ended` clears. It merges only the head the Approve named: a pull request moved
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
design: 47
|
||||
milestone: G
|
||||
updated: 2026-11-11
|
||||
decisions:
|
||||
- "ADR 0672"
|
||||
- "ADR 0436"
|
||||
- "ADR 0667"
|
||||
- "ADR 0666"
|
||||
- "ADR 0660"
|
||||
- "ADR 0656"
|
||||
- "ADR 0636"
|
||||
- "ADR 0626"
|
||||
- "ADR 0619"
|
||||
- "ADR 0618"
|
||||
- "ADR 0614"
|
||||
- "ADR 0596"
|
||||
- "ADR 0595"
|
||||
- "ADR 0564"
|
||||
- "ADR 0505"
|
||||
- "ADR 0404"
|
||||
- "ADR 0363"
|
||||
- "ADR 0240"
|
||||
- "ADR 0235"
|
||||
---
|
||||
|
||||
# 47, milestone G: the recovery module, and the review of §516 to §553
|
||||
|
||||
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".
|
||||
|
||||
*§554 and §555 are the operator's answer of 2026-11-11 at 12:55 CET at lead-47's terminal. §556 to §558 answer the
|
||||
four reviewers' round 1 of [G-12](G-12-develop-answers-fourth.md) (§516 to §553); the rest of that round's findings
|
||||
are written into the lines of G-12 they name.*
|
||||
|
||||
## The recovery module
|
||||
|
||||
- §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
|
||||
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`, callers `holder:mesh-recovery@same-node` alone).
|
||||
- **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
|
||||
`mesh-module-assigner`'s placements, never a fixed name: G's seed writes its placement there, and the
|
||||
placement verb refuses to move it while `kept-points` lists a point younger than 90 days, naming them, so its
|
||||
points and their copies in that node's repository stay together. Its data directory, its manifest's `data` item
|
||||
`points`, is capped at 10 GiB and measured by the disk readings (ADR 0571 §5): past 80 % it writes the finding
|
||||
`points-filling`, and a `snapshot-kept` that would pass the cap ends `failed`, naming it, which holds the move as a
|
||||
failed backup does (§296). Its `findings` state and finding stream are declared as §529's other parts declare
|
||||
them, so it waits on the bus module for them and is no foundation part (ADR 0619 §1).
|
||||
- **Its verbs answer at once; the result is the event.** `snapshot-kept` and `restore-kept` answer `accepted` with
|
||||
the act's `act` id, `busy` with the act that runs (it runs one act at a time and keeps no queue), or `error`, and
|
||||
nothing more; the point comes on `ended`, the restore on `restored`. A caller told `busy` asks again when it hears
|
||||
that act's event. The module writes each accepted act in its directory before it answers; at its start an act
|
||||
accepted and not ended is ended `failed` with `stopped`, so its caller asks again.
|
||||
- **Its events.** On `mesh.seat.mesh-recovery.event.` and kept last per subject, 90 days (§396): `ended.<module>.<kept>`
|
||||
and `restored.<module>.<kept>`, each carrying `act`, `module`, `kept`, `form`, `fingerprint`, `snapshot` and
|
||||
`outcome` (`done` or `failed`, with `error`), `ended` also the point whole; `restore-started.<module>.<kept>` when a
|
||||
restore begins; `set-aside.<module>.<kept>` and `aside-discarded.<module>.<kept>` with the aside's `id` and
|
||||
`size`; and `point-removed.<module>.<kept>` (§551). The node agent wakes only on the event whose `form` and
|
||||
`fingerprint` are its ask's. Its wait for `ended` or `restored` is bounded at 90 minutes (§405), past which its have
|
||||
says the wait and the watchman's `delivery-waits` raises it.
|
||||
- **Who calls it.** `snapshot-kept` and `restore-kept` are called by a node-engine holder (`seat:node-engine`): the
|
||||
recovery module takes a call only from an account the bus proves to be a node-engine's, and the identity of who
|
||||
asked is the check (the operator, 13:06 CET), every act logged; no want is read for it, since the operator,
|
||||
2026-11-11 13:10 CET: "if something asks for a restore, you should do it; he'll have his reasons".
|
||||
`kept-points` takes the default of a read (§391). The operator, 2026-11-11 13:06 CET at lead-47's terminal: setting
|
||||
aside is a move, not a removal, so deleting the live objects once their aside is whole and checked (§516) needs
|
||||
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`, callers `operator` and `sessions`, written in the hand-act log first; `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
|
||||
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
|
||||
`act`, callers `operator` and `sessions` (§391), written in the hand-act log; they are checked by identity, as above.
|
||||
- **Its account.** Composed by the grants part from the seat's definition and the manifest: 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`, each with the ordered
|
||||
consumer §556 needs; 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
|
||||
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`; no stream of the mesh's own (`CONTROL`, `NODES`, `EVENTS`, `DEAD_LETTER_NOTICES`, `DEAD_LETTERS`,
|
||||
`PROV_APPLIED`, `CHECKS_READY`, `CHECKS_OTHER`, every `SEAT_` stream and every `KV_` bucket of a seat) is ever
|
||||
granted. Restricted streams (ADR 0436) are among the names, as ADR 0672 records.
|
||||
- **Bus names.** The recovery module turns a module and a kept data into bus names from the catalog graph entry of
|
||||
the fingerprint it acts at, read by `mesh-catalog`'s `entry` (§443) in its `invokes` (an edge of kind 6): a
|
||||
template entry's name is `<module>_<local>` (ADR 0595 §1), an old section's its declared name; a point records the
|
||||
names it took, and a restore uses those.
|
||||
- **Never beside the nightly dump.** A `snapshot-kept` may run while the dump runs, both paced as ADR 0235 §10 has
|
||||
it, so the server has at most two snapshots at once. No `restore-kept` starts while the dump runs, and no dump of
|
||||
the bus starts while a restore runs: the holder of `node-backup` of G says `item-started.<node>.<module>.<item>`
|
||||
and `item-ended.<node>.<module>.<item>` for every item, kept last per subject, 7 days, and puts off the bus's item
|
||||
while a `restore-started` of the recovery module has no `restored`; the recovery module learns the bus module and
|
||||
its node from the seat list's definition of `mesh-broker` and the catalog half's claim of it, never a fixed name.
|
||||
Both read these streams as §556 has it, so a restart mid-dump or mid-restore misses neither. A blocked act waits,
|
||||
neither refused nor failing a want: past 60 minutes the recovery module writes `recovery-waits` and the backup
|
||||
holder `backup-waits`, each naming the item or the act it waits on, and `kept-points` lists the act that runs
|
||||
with since when and what it waits on. The recovery module consumes the item events that G's backup holder adds,
|
||||
an edge of kind 6 from that holder to it, so a backup holder of before G, which says none, is never relied on.
|
||||
- **Its health.** Its declared health check calls `kept-points`, and fails while any aside's record ends at
|
||||
`removed` (§516), when it also writes the finding `aside-unrestored` naming the module, the kept data and the
|
||||
aside's `id`.
|
||||
- **Its order.** The node-engine's `invokes` of its verbs gives the edge of kind 6 from the recovery module to the
|
||||
node-engine, so §298's first edge reads "the new version of the recovery module" (§555). At a revert of G the
|
||||
edge runs backward (ADR 0656 §4): the node-engine goes back only after every module it restores there said
|
||||
`restored` and runs (§298), and the recovery module, new in G, goes only after the node-engine, so it stays while
|
||||
any restore runs; its data item stays on its node, with its copies.
|
||||
- **Its tools** are named `recovery_`.
|
||||
|
||||
Why: the operator's answers; the node, cap, events, answer on acceptance, dump order, health and edges are the
|
||||
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
|
||||
`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`
|
||||
refused, and the operator's `recovery_discard_aside` removing the aside and writing the log.
|
||||
- §555 **What moves to the recovery module.** §296 asks `mesh-recovery`'s `snapshot-kept` and waits for its `ended`,
|
||||
never the seat `node-backup`; §297 asks its `restore-kept` and waits for its `restored`; §302's `backed-up` lists
|
||||
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
|
||||
`discard-aside`, the arguments `kept`, `form` and `fingerprint` of its `now` and `restore`, and its events
|
||||
`ended.<node>.<module>.<kept>` and `restored.<node>.<module>.<kept>` go from its definition in mesh-contracts, and
|
||||
it gains only `item-started` and `item-ended` with their `<item>` 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;
|
||||
§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.
|
||||
|
||||
## The review of §516 to §553, round 1
|
||||
|
||||
- §556 **A part that follows a stream kept last per subject reads it whole at each start.** A durable consumer goes on
|
||||
from its acknowledged position after a restart, so a part that acts on what it heard from a stream kept last per
|
||||
subject, and keeps no state of it, reads at each of its starts every subject's last message through an ordered
|
||||
consumer it makes for that one read, then follows its durable consumer from its acknowledged position, an event
|
||||
older by `at` than what that read gave changing nothing. Until the read ends the part acts on none of those events
|
||||
and its `<module>_first_views` names the stream `waiting`. So read: the node-engine seat's `running`, `composed`,
|
||||
`wait-held` and `wait-ended` (the last two kept on the stream `running` is kept on, last per subject, a node's
|
||||
module's newer one by `at` standing), by the assigner (§520), the condition keeper (§541), the builder (§546), the
|
||||
node-engine and the grants part (§199), and the watchman for `delivery-waits` (§541); `mesh-healers'`
|
||||
`attempt-changed` by the keeper (§541); `node-backup`'s `item-started` and `item-ended` by the recovery module, and the recovery module's `restore-started` and `restored` by the backup holder (§554). The
|
||||
grants part grants each such reader, beside its durable consumer, the creation of an ordered consumer on that
|
||||
stream with no durable name (the bus's consumer-create subject for that stream), from the reader's `consumes`. This amends
|
||||
§199's "each part's durable consumer starts from the last message per subject". Why: what a part heard must not
|
||||
depend on when it last restarted (review round 1, health and events 2, with running and testing 3). How it is
|
||||
checked: whole (assigner, keeper), a restarted assigner holds no want it did not hold before, and a restarted
|
||||
keeper holds the healers' attempts it held.
|
||||
- §557 **A whole test's bounds are settings.** Every bound a whole test waits on (§535's five minutes, §534's 30
|
||||
minutes, §544's 60 minutes, §540's two hours, §551's 90 days, §554's 90 minutes) is a setting of the part that
|
||||
times it, read at its start, its default the design's value, so a whole test sets it in seconds and never waits on
|
||||
real time. The bus module's and the recovery module's whole cases in these lines are cases of each module's one
|
||||
whole test against the real bus, within the test budget. Why: a whole test that waits hours runs never (review
|
||||
round 1, running and testing's notes). How it is checked: the code review; each whole test of these lines runs in
|
||||
under a minute.
|
||||
- §558 **A field of a served verb's answer is an edge of kind 6.** Kind 6 (§374) orders a module after a version that
|
||||
serves a verb or a word it uses, and a verb's presence alone says nothing of a field its answer gained, so a
|
||||
consumer relying on a new field of a served answer could run before the provider's new version and fall back in
|
||||
silence (the grants part's first view relies on `binding` in `mesh-broker`'s `list`). An `invokes` entry therefore
|
||||
takes a long form, `{verb, fields}`: `verb` as today (`seat:<seat>.<verb>`), `fields` the names of its answer's
|
||||
fields the consumer relies on. The manifest validator refuses a field the seat's definition does not give that
|
||||
verb's answer, naming it. The delivery plan derives the edge of kind 6 from the holders of that seat to the
|
||||
consumer, held until the holder runs a build whose catalog graph entry's seat definition (§194) gives the verb's
|
||||
answer every named field; §374's entry of kind 6 records the verb and its fields, and `outdated` (§375) says it
|
||||
behind when the delivered version no longer gives them. Both forms stay: the short string where no field is relied on, the long form
|
||||
where one is. On main mesh-sdk's manifest reader reads `invokes` as a list of strings, so the long form is read
|
||||
first by §494's second reader release, merged and delivered before G's merge: its manifest reader takes either
|
||||
form, and the running checker, the indexer and the grants part, which read manifests through it, are rebuilt with
|
||||
it by the release's publish (kind 1), as for `max-mib`. That publish rebuilds every module importing mesh-sdk's
|
||||
`catalogue`, the set the release rebuilds already, so the form adds no rebuild. The consumers of G that name fields:
|
||||
the grants part, `mesh-broker`'s `list` with `binding`; every reader of `mesh-catalog`'s `revision` through
|
||||
mesh-sdk's client (the bus module, the status view, the condition keeper, the tool runner, the assigner, the grants
|
||||
part and the runner), with `none-yet` (§530); the status view, `mesh-catalog`'s `entry` with `manifest-digest`
|
||||
(§506). The recovery module reads the manifest whole the entry carries (§443), a field of before G. Any other part of G relying on a field G adds to a served answer names it so in G's change, which the
|
||||
code review checks. Why: the module graph orders a consumer after what it relies on, and a field is part of the contract
|
||||
(lead-47's question from the operator's "the module graph is for this", 2026-11-11). How it is checked: unit
|
||||
(manifest validator), a field the definition lacks refused; unit (delivery plan), the grants part ordered after
|
||||
a bus module whose definition gives `binding`, and not before; unit (the release's reader), both forms read.
|
||||
- §559 **A bundle's finding writer publishes and hears through two runtime calls.** A bundle, in Go or TypeScript,
|
||||
holds no bus connection, so mesh-sdk's finding writer (§461, §503) in a bundle uses the runtime channel's existing
|
||||
calls, each gaining one argument: `mesh/publish` takes `ack: true`, and the tool runner then publishes the event on
|
||||
the subject the module's membership names for it (its old stream's `mesh.stream.<module>.event.<event>.<node>` or
|
||||
its template binding's, §529; ADR 0363 §8) and answers only once the bus acknowledged it, with its sequence, or
|
||||
`{error}`; `mesh/subscribe` takes `deliver: new`, and the tool runner makes an ordered consumer on the stream that
|
||||
carries the pattern, starting at the next message, and delivers each message to the bundle as a subscription
|
||||
delivers today. The writer says each finding event with `ack: true` (§383's one minute of resending counting from
|
||||
an unanswered or `{error}` publish) and makes its consumer of `findings-asked` with `deliver: new` before its start
|
||||
statement (§485). The tool runner states the capability word `finding-calls` (§488, §545) once it answers both,
|
||||
and the bundle's writer fails at once, naming the word and the node, where it is not stated. Why: one writer in both
|
||||
languages over the one channel a bundle has, as §518 (develop question of 13:08 CET on §461). How it is checked:
|
||||
unit (tool runner), a publish with `ack` answered with its sequence and a refused one with `{error}`, a `deliver:
|
||||
new` subscription given no message older than it; whole (mesh-sdk, TypeScript and Go bundles), a finding written
|
||||
and an ask answered through a tool runner of G.
|
||||
@@ -41,13 +41,13 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli
|
||||
compare-and-set; the object it replaced stays, as one whose key was deleted does, listed as `key gone` since no key
|
||||
names it, and only the drop tool removes either, on a person's word: the mesh removes kept data only through `drop`
|
||||
and `recreate`, each on a person's word (ADR 0595 §4; ADR 0666 §16).
|
||||
- §58 **One object store per state, granted to its owner.** (§513) Each state asked by the template `state` gets its object store
|
||||
- §58 **One object store per state, granted to its owner.** (§513, §549) Each state asked by the template `state` gets its object store
|
||||
beside it, `<state>-objects`, a template form of ADR 0595 that the bus module provides and the grants part grants to
|
||||
the state's owner alone (ADR 0666 §16); a foundation part's large values go in an old `objects` section of its own.
|
||||
Its size is the template's (ADR 0595 §3). An object store holds no space until a value is written to it, so the many
|
||||
it adds reserve nothing; the few values over the limit (a delivery record, a catalog graph revision list, a test's
|
||||
output) are estimated, as a guess, at under 1 GiB across the mesh.
|
||||
- §59 **An object sent is readable by the modules it is for.** A reply's or an event's object is written to the sender's
|
||||
- §59 **An object sent is readable by the modules it is for.** (§533) A reply's or an event's object is written to the sender's
|
||||
**sent store**, `<module>_sent-objects`: the bus module plans it, with no manifest field, for every module of the new
|
||||
form that serves a verb or emits an event, and a foundation part declares it as an old `objects` section
|
||||
`sent-objects` (ADR 0619 §2). Its cap is the objects template's (ADR 0595 §3), 256 MiB (§477), and it keeps an object 7 days, after
|
||||
|
||||
@@ -105,7 +105,7 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli
|
||||
asked it (1921's note of 2026-11-07: "the indexer reads its seat definitions at start"). How it is checked: in the
|
||||
indexer's whole-module test, started with a definition on a contracts trunk that no event announced, the first
|
||||
manifest claiming that seat is judged with it.
|
||||
- §199 **Who holds a seat is applied by one rule, from what each node runs.** The node-engine and the grants part decide a
|
||||
- §199 **Who holds a seat is applied by one rule, from what each node runs.** (§556) The node-engine and the grants part decide a
|
||||
seat's pass by mesh-sdk's `SeatsToPassOn` (ADR 0660 §3), reading the catalog graph's entry of the build each assignment
|
||||
runs, never a manifest (ADR 0660 §2; §442). What each node runs is heard, never asked: each part keeps it from the node-engine seat's events
|
||||
`running.<node>.<module>` (*What each step says*), through a durable consumer of its own declared in its `consumes`,
|
||||
|
||||
@@ -97,7 +97,7 @@ names go, since every new acting part needed code changes elsewhere (research 08
|
||||
what its new version is built from or needs (a base, a package, a provider) is acted on by its running version,
|
||||
never waited for: the running build module builds the shared contracts and the registry holder, then the new build
|
||||
module builds the rest, so ADR 0614 §6's cycle through them stays allowed, now for that reason.
|
||||
- §271 **The artifact store's holder takes its own new build even when its seat is the one broken.** (§499) A build module
|
||||
- §271 **The artifact store's holder takes its own new build even when its seat is the one broken.** (§499, §526) A build module
|
||||
stores the artifacts it builds through the seat `oci-artifact-registry`, so the
|
||||
holder of that seat is in its own build's path: its new build needs the store it replaces. As every holder's own
|
||||
inputs are (above), that store is acted on by the running holder: the running holder stores its new build, and only
|
||||
@@ -329,7 +329,7 @@ later change of a kept data's form, not as a case of this milestone.
|
||||
changes how it writes that data, or stops declaring it; a declaration naming none reads as form 0. The declaration
|
||||
alone cannot tell a changed layout of the same bucket, so the holder says it. Only kept data whose `form` changes is
|
||||
backed up and restored, so a part's other kept data, and every decision it holds, is never set back.
|
||||
- §296 **It is backed up before the module moves.** When a want moves a module whose new manifest declares a kept data at
|
||||
- §296 **It is backed up before the module moves.** (§555) When a want moves a module whose new manifest declares a kept data at
|
||||
another `form` than the running one, or no longer declares it, the node agent applying it first asks the seat
|
||||
`node-backup` of the node holding `mesh-broker` for a restore point of that kept data, and waits for its event
|
||||
`ended`, as for any backup before the apply. The bus module's account takes it, as it takes the bus's snapshots
|
||||
@@ -337,14 +337,14 @@ later change of a kept data's form, not as a case of this milestone.
|
||||
before, and it holds the kept data whole, the position of each durable consumer the module reads with, and the
|
||||
catch-up tool the newer manifest declares beside that kept data. A failed
|
||||
backup holds that module as any failed backup does.
|
||||
- §297 **A revert restores it before the reverted build starts.** When a want takes a module back across a change of a
|
||||
- §297 **A revert restores it before the reverted build starts.** (§555) When a want takes a module back across a change of a
|
||||
kept data's `form`, the node agent applying it stops the newer build, then asks that seat's verb `restore` (§405) for the restore point of that module,
|
||||
kept data and form, waits for the seat's event `restored`, and only then starts the reverted build. The node agent
|
||||
that restores is the one running when the revert starts. As every restore is, it is brought back beside the live data
|
||||
and never over it: the live kept data of the newer form is set aside under a name of its own, and only the operator
|
||||
removes it, so nothing written since is destroyed. The consumer's position is set back with it, so the reverted
|
||||
build hears everything since as after any restart.
|
||||
- §298 **The order of a delivery that crosses a form change** is the module graph's (*Order without a person*), with three
|
||||
- §298 **The order of a delivery that crosses a form change** (§554) is the module graph's (*Order without a person*), with three
|
||||
edges the assigner, which writes every want, keeps:
|
||||
- the new versions of the `node-backup` holder and of the bus module run before any module whose kept data's form
|
||||
changes is moved, since the restore point needs both;
|
||||
@@ -381,7 +381,7 @@ later change of a kept data's form, not as a case of this milestone.
|
||||
ask the gate of milestone G raised after the restore point is not among the pending ones, so its answer is not read
|
||||
and the operator is asked again. Whether the first look clears a merge kept in the restored `merges` that the forge
|
||||
merged since was not read in the code; the catch-up test below proves it with the real builds.
|
||||
- §300 **A missing restore point holds the revert, naming it.** When the restore point a revert needs does not exist, or
|
||||
- §300 **A missing restore point holds the revert, naming it.** (§541) When the restore point a revert needs does not exist, or
|
||||
`restored` does not come, the node agent applies nothing of that module, keeps what runs, and writes the have phase
|
||||
`held` with the reason `restore point missing` and the module, kept data and form it names; the assigner asks the
|
||||
operator (hold, or start the reverted build on the live data as it is), raises the condition naming them, and on
|
||||
@@ -391,12 +391,12 @@ later change of a kept data's form, not as a case of this milestone.
|
||||
(for milestone G, its delivery records and its graph revisions) is set aside and not read again; an Approve asked
|
||||
and answered since is asked again, and one the gate asked before still reads its answer. The revert's Approve ask
|
||||
says this in those words, naming each kept data restored.
|
||||
- §302 **Its tools.** The seat `node-backup`'s `backed-up` lists each module's restore points of its bus data, with the
|
||||
- §302 **Its tools.** (§517, §555) The seat `node-backup`'s `backed-up` lists each module's restore points of its bus data, with the
|
||||
kept data, the form and the fingerprint each was taken before, and the data set aside at each restore, with its
|
||||
size; `restore` restores one; `discard-aside` removes data set aside by a restore, only on the operator's call, and
|
||||
writes the act, who and why in the hand-act log of the seat `mesh-hand-acts`. `backed-up` and `restore` exist on
|
||||
the seat today and gain the module's kept data on the bus as an item; `discard-aside` is new.
|
||||
- §303 **How it is checked.** Whole (node-engine, backup holder, bus module): a want moving a module across a `form`
|
||||
- §303 **How it is checked.** (§555) Whole (node-engine, backup holder, bus module): a want moving a module across a `form`
|
||||
change, and one moving a module whose kept data declares no `form` to one that does, each take a restore point
|
||||
first, keyed by module, kept data, form and fingerprint; a want taking it back restores it beside the live data and
|
||||
the consumer's position before the reverted build starts, and the data set aside is listed with its size and
|
||||
|
||||
@@ -75,7 +75,7 @@ the seat `git` the verb `tag` (§349, §372, §375, §376, §370).
|
||||
of the revision view, ADR 0656), and `entry` and `difference` on `mesh-wants` (ADR 0656), with the events of *What
|
||||
each step says*.
|
||||
|
||||
§309 **The seat `node-engine`**'s event `running.<node>.<module>` carries, from research 085's milestone, the module, its
|
||||
§309 **The seat `node-engine`**'s (§520) event `running.<node>.<module>` carries, from research 085's milestone, the module, its
|
||||
fingerprint and the digest of its build's manifest, so the node-engine of another node and the grants part decide a
|
||||
seat's pass from the catalog graph's entry of that build (ADR 0660 §2; *Who holds a seat is applied by one rule*). No verb is added.
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ record it follows from, and replaces the builder's own choice where one was made
|
||||
|
||||
### The runner and its steps
|
||||
|
||||
- §323 **A step's build seat is read from the artifact's language.** The catalog graph entry names each artifact's
|
||||
- §323 **A step's build seat is read from the artifact's language.** (§535) The catalog graph entry names each artifact's
|
||||
`language`, as its manifest's artifact entry says it and as the indexer's language map matches today; the runner
|
||||
reads it from the catalog half of its revision view and asks lint and the test steps of the build seat whose
|
||||
definition's acting rule `build` has `on` naming that language. With no such seat, or no holder of it, the pipeline
|
||||
@@ -124,7 +124,7 @@ record it follows from, and replaces the builder's own choice where one was made
|
||||
`take-in.taken` (ADR 0666 §13), which ADR 0596 §1 lets any module subscribe to; the indexer's name stands in that
|
||||
manifest only, never in the runner's code. Why: ADR 0666 §13, in force, names that event. How it is checked: the code review
|
||||
reads that no module name stands in the runner's code (§7).
|
||||
- §334 **A publication's pipelines and their key.** `package-published` carries the package's artifact reference
|
||||
- §334 **A publication's pipelines and their key.** (§550) `package-published` carries the package's artifact reference
|
||||
(`<module>:<artifact>`, from the catalog entry), its version and digest, the watched branch and the source revision
|
||||
its build was made from. The runner asks `outdated` for that package on that branch and starts a pipeline for each
|
||||
dependent `outdated` names behind (§53), keyed by that branch, that source revision and the dependent module, the version in the pipeline's state; a `take-in.taken` of the same revision and module is the
|
||||
@@ -161,11 +161,11 @@ record it follows from, and replaces the builder's own choice where one was made
|
||||
definitions in `mesh-connectivity-contracts` names `invokers`, `persons` and `sessions` in this milestone, since
|
||||
sessions and persons call them today through the mesh MCP server. How it is checked: unit (definition reader), each
|
||||
form accepted and any other entry refused; the grants part's table test grants each form.
|
||||
- §337 **The bus module's restore points.** The verbs the holder of `node-backup` on the bus module's node calls to take
|
||||
- §337 **The bus module's restore points.** (§555) The verbs the holder of `node-backup` on the bus module's node calls to take
|
||||
and restore a module's kept data on the bus name `holder:node-backup@same-node`. Why: only that holder takes them
|
||||
(*A backup before the apply: kept data on the bus*). How it is checked: a call from another node's `node-backup`
|
||||
holder is refused by the bus.
|
||||
- §338 **Callers on accepted kinds.** (§480, §481) An accepted kind of a work queue carries `callers` as a verb does, and the grants part
|
||||
- §338 **Callers on accepted kinds.** (§480, §481, §543, §552) An accepted kind of a work queue carries `callers` as a verb does, and the grants part
|
||||
grants publish on its subject to them alone: the build seats' `step` the runner; `run` the runner, the indexer and
|
||||
the assigner, and the checker until its entry is removed with its buckets and bus account (ADR 0667 §12); `mesh-wants`'s
|
||||
`step` the runner. Verbs: `steps` the runner and the indexer (its seed); `drop` the runner and the builder; both
|
||||
@@ -198,14 +198,14 @@ record it follows from, and replaces the builder's own choice where one was made
|
||||
- §343 **Branch names the indexer's keys use.** `register` and `watch` refuse a watched branch named `candidate` or
|
||||
`entry`, naming why, since the catalog keeps its revisions under `<branch>.<revision>` beside those two key forms.
|
||||
How it is checked: whole (indexer), each is refused.
|
||||
- §344 **The bus module plans a sent store from what the catalog already says.** It plans `<module>_sent-objects` for a
|
||||
- §344 **The bus module plans a sent store from what the catalog already says.** (§533, §537) It plans `<module>_sent-objects` for a
|
||||
module of the new form whose catalog graph entry claims a seat whose definition has a verb or an event, or declares
|
||||
an event of its own, read from the catalog half of its revision view and the seat list; the indexer's event carries
|
||||
no field `sends`. When a seat's definition gains its first verb or event later, the bus module plans the store for
|
||||
its holders on the seat list's change. Why: no manifest field (*Any size*), and the catalog half is every part's view
|
||||
(ADR 0656 §6). How it is checked: whole (bus module), a module claiming a seat with a verb gets a sent store, one with
|
||||
neither gets none, and a definition gaining a verb gives its holder one.
|
||||
- §345 **A large value reaches the tool runner in chunks.** A bundle's put of a value over the bus's per-message limit is
|
||||
- §345 **A large value reaches the tool runner in chunks.** (§518) A bundle's put of a value over the bus's per-message limit is
|
||||
sent to the tool runner as a put session on the bundle's call subject, named by the call's id, in chunks under that
|
||||
limit, in order, each answered by the tool runner before the next is sent, and written as one object through the
|
||||
object store's own chunking, its wire form §457's; a put not sealed within the call's bound is dropped by the tool runner and its call
|
||||
@@ -279,7 +279,7 @@ record it follows from, and replaces the builder's own choice where one was made
|
||||
candidates, and nothing is guessed. A contribution edge runs from a consumer's entry to the provider its requirement
|
||||
resolves to, wherever that requirement carries values the consumer contributes. How it is checked: unit
|
||||
(assignment graph), each step of the order and a hold.
|
||||
- §358 **The catalog's shared view takes a branch.** The client's view of the catalog half is per watched branch, named by
|
||||
- §358 **The catalog's shared view takes a branch.** (§532) The client's view of the catalog half is per watched branch, named by
|
||||
its caller (§479). How it is checked: unit (client), two branches give two views.
|
||||
- §359 **`difference` names its revisions.** `difference` with none of `from`, `to` and `group` is refused, naming the
|
||||
missing argument. How it is checked: a unit row.
|
||||
@@ -299,10 +299,10 @@ record it follows from, and replaces the builder's own choice where one was made
|
||||
|
||||
### The condition keeper and the node-engine
|
||||
|
||||
- §364 **The node-engine claims its seat.** (§508) The node-engine's manifest claims the node seat `node-engine` (ADR 0563), and
|
||||
- §364 **The node-engine claims its seat.** (§508, §527) The node-engine's manifest claims the node seat `node-engine` (ADR 0563), and
|
||||
the indexer and the node-engine's own guard read its holder from the seat list, keeping no module name. How it is
|
||||
checked: the code review reads that neither fixes a module name (§7).
|
||||
- §365 **The condition keeper finds its sources in the catalog.** The catalog graph entry carries the events each
|
||||
- §365 **The condition keeper finds its sources in the catalog.** (§527, §532) The catalog graph entry carries the events each
|
||||
manifest declares in its `streams`; the keeper takes a first view of the catalog half, and its sources are the
|
||||
modules whose entry declares the finding events of §383, the node-engine among them, its holder read from the seat
|
||||
list. It joins the readers of *Every other reader of which modules exist*, reading every watched branch's newest
|
||||
@@ -406,7 +406,7 @@ record it follows from, and replaces the builder's own choice where one was made
|
||||
at G's delivery (design 51, *Tagged versions*). Why: the operator, 2026-11-10 about 21:40 CET, no custom versions for
|
||||
now, a tagged version being one; a run delivers nothing (ADR 0666 §18), so it needs no version; the digest's source
|
||||
and the wait are the design's choice, round 2 of the review by architectural domain, 2026-11-10. How it is checked: test 103.
|
||||
- §374 **A release records, per edge, the part it was built against or delivered after.** One version per module
|
||||
- §374 **A release records, per edge, the part it was built against or delivered after.** (§558) One version per module
|
||||
stays (§52), and an edge is judged by the digest of the part it points to. The catalog records on each released
|
||||
version (§349), in its key of `versions`, one entry per catalog-graph edge of the module's artifacts (the six kinds
|
||||
of *Dependencies between artifacts*), a lockfile per released version. An entry names the kind, whether the edge
|
||||
@@ -486,7 +486,7 @@ record it follows from, and replaces the builder's own choice where one was made
|
||||
dependency builds it (its build toolchain part). Every other kind (2, 4, 5 and 6) only orders. A change to a build
|
||||
module's own code, which is no toolchain part, rebuilds nothing. Why: the operator, 2026-11-10 about 22:30 to 23:00 CET. How it is checked: unit (indexer's
|
||||
graph), each kind's stale-or-order, and a build module's code change rebuilds no module.
|
||||
- §379 **A want names the released version and each part's digest.** From G's delivery a want `want.<node>.<module>`
|
||||
- §379 **A want names the released version and each part's digest.** (§524, §525, §526) From G's delivery a want `want.<node>.<module>`
|
||||
names, beside its fingerprint and source revision, the module's released version, for people (none for a build of
|
||||
another watched branch), and the digest of each of its parts; the node-engine fetches and checks each part by its
|
||||
digest, never by the version. The assigner takes the digests from `version-released` for a released version, and from
|
||||
|
||||
@@ -32,7 +32,7 @@ each module's findings as events; a module states its findings from its own trut
|
||||
tool-runner account stays as it is in G; no record is written for these answers, so each line that departs from a
|
||||
record says so in its Why. Round 3 of the review by architectural domain (2026-11-11) completed these lines.*
|
||||
|
||||
- §383 **An observer says its findings as events on a stream of its own; the keeper reads no observer's state.** Every
|
||||
- §383 **An observer says its findings as events on a stream of its own; the keeper reads no observer's state.** (§529) Every
|
||||
module that writes findings is an observer (§387 names them) and says each change of a finding on its own stream
|
||||
`<module>-findings` (ADR 0363 §1: under its name in capitals on the bus, its `events` `finding-written.*`,
|
||||
`finding-cleared.*` and `findings-stated.*`, kept 7 days and 16 MiB, its oldest message dropped when full, since the
|
||||
@@ -97,7 +97,7 @@ record says so in its Why. Round 3 of the review by architectural domain (2026-1
|
||||
account publishes for; G changes neither that account nor its grants, a known limit. Why: the operator, 2026-11-11;
|
||||
modules running as the machine's account are issue 1966's (note 193), whose fix carries its check. How it is checked:
|
||||
none in G; the limit is named on issue 1966.
|
||||
- §386 **A `*` emitter in `consumes` hears one event from every module that declares it.** A `consumes` entry
|
||||
- §386 **A `*` emitter in `consumes` hears one event from every module that declares it.** (§529) A `consumes` entry
|
||||
`*.<event>` takes the event `<event>` from every module whose manifest declares it, and is the one generic form for
|
||||
hearing an event that many modules say; the keeper's `*.finding-written`, `*.finding-cleared` and
|
||||
`*.findings-stated` are the first. The manifest validator takes `*` only as the whole emitter, and only before an
|
||||
@@ -114,7 +114,7 @@ record says so in its Why. Round 3 of the review by architectural domain (2026-1
|
||||
`*.finding-written` consumer one durable consumer on each declaring module's stream and none on a restricted
|
||||
stream; whole (keeper, grants part), a fixture module that declares the events after the keeper started is heard,
|
||||
and a keeper stopped while findings change catches up from its durable consumers at its start.
|
||||
- §387 **G's change writes the finding stream into every observer's manifest.** In the same change G writes the stream
|
||||
- §387 **G's change writes the finding stream into every observer's manifest.** (§529) In the same change G writes the stream
|
||||
`<module>-findings` of §383 into the manifest's `streams`, and `mesh-conditions.findings-asked` into its `consumes`,
|
||||
for every module that declares a state `findings` on main: `artifact-store-tools`, `claude-code`, `distribution`, `gitea`,
|
||||
`mesh-build-go`, `mesh-config`, `mesh-healers`, `mesh-knowledge`, `mesh-provisioner`, `mesh-self-check`, `mesh-vault`, `mesh-watcher`,
|
||||
|
||||
@@ -108,7 +108,7 @@ line says so.*
|
||||
(Q13). How it is checked: whole (indexer), `unwatch` of a placed branch refused.
|
||||
- §403 **A held-back ask.** A held-back ask (§83, design 46 §6) is answered in `asks` with the state `held-back` and the
|
||||
field `held-since`, and no field `behind`. Why: the design's choice (Q14). How it is checked: the seat's fixtures.
|
||||
- §404 **The node-engine's events' bodies.** `capabilities-changed` carries the node record's stated capabilities whole
|
||||
- §404 **The node-engine's events' bodies.** (§520) `capabilities-changed` carries the node record's stated capabilities whole
|
||||
and `at`; `composed` the module, the fingerprint and the composition's digest; `running` with `stopped` carries
|
||||
`stopped: true` and no fingerprint (§365), and mesh-sdk's `SeatsToPassOn` counts such a module as not running on that
|
||||
node, its input being §459's. Why: the design's choice (Q17). How it is checked: the seat's fixtures; unit (`SeatsToPassOn`), a row where a
|
||||
@@ -116,7 +116,7 @@ line says so.*
|
||||
|
||||
### Kept data on the bus, restore points and the reader release
|
||||
|
||||
- §405 **The bus module's restore points and node-backup's verbs.** The seat `mesh-broker` gains `snapshot-kept` and
|
||||
- §405 **The bus module's restore points and node-backup's verbs.** (§516, §517, §554, §555) The seat `mesh-broker` gains `snapshot-kept` and
|
||||
`restore-kept`, of class `act`, their callers `holder:node-backup@same-node` alone (§337): the bus module's account is
|
||||
the one that moves bus data, so `restore-kept` sets the live kept data aside under a name of its own and then
|
||||
restores the restore point beside it, with the argument `aside-only` it sets the live data aside and restores
|
||||
@@ -132,7 +132,7 @@ line says so.*
|
||||
choice, one answer to three preparers (Q8, S9, Q-H6, C19; lead-47's ruling, 2026-11-11). How it is checked: test 36;
|
||||
a call of `snapshot-kept` from another node's `node-backup` holder, and a `discard-aside` from any caller but the
|
||||
operator, are refused by the bus; a failed restore says `restored` with `failed` and its error.
|
||||
- §406 **A catch-up names its tool and arguments.** A restore point records the catch-up tool and its arguments whole
|
||||
- §406 **A catch-up names its tool and arguments.** (§516, §555) A restore point records the catch-up tool and its arguments whole
|
||||
(§299), and the fingerprint of the newer build it was taken before; the grants part derives the grant of that tool to
|
||||
`holder:node-engine@same-node` from the catalog graph's entry of that recorded fingerprint (§443). Why: the design's
|
||||
choice (Q-H7). How it is checked: whole (node-engine), a restore runs its recorded catch-up, granted from the
|
||||
@@ -208,7 +208,7 @@ line says so.*
|
||||
|
||||
### Readers, branches and the node-engine
|
||||
|
||||
- §421 **The node-engine reads the entry its want names.** The node-engine joins §196's readers: it reads, from the
|
||||
- §421 **The node-engine reads the entry its want names.** (§526, §532) The node-engine joins §196's readers: it reads, from the
|
||||
catalog half, the catalog graph's entry of the fingerprint its want names (§443), never a manifest and never by
|
||||
branch, so a want needs no field `branch`, and the parts by digest from its want (§379); its reads of the indexer's
|
||||
and builder's states go. When the catalog half no longer holds that entry, the node-engine holds the want and its
|
||||
@@ -223,7 +223,7 @@ line says so.*
|
||||
fixtures; whole (node-engine), a call from another caller is refused by the bus.
|
||||
- §423 **A kept-build wait says the existing words.** A have waiting for a kept build (§271) says the existing phase and
|
||||
words, with no new field. Why: the design's choice (Q-H10). How it is checked: whole (node-engine).
|
||||
- §424 **Each process's own build, and each bundle's.** A process says `own build unknown` in its
|
||||
- §424 **Each process's own build, and each bundle's.** (§519) A process says `own build unknown` in its
|
||||
`<module>_first_views` (§205); each tools bundle's composed environment carries its module's fingerprint. Why: the
|
||||
design's choice (S12, Q-T7). How it is checked: whole (tool runner), a bundle reads its fingerprint.
|
||||
- §425 **A kept call asks again what its asker names.** An asker passes the kept-call form the ask's key and the event
|
||||
@@ -268,9 +268,9 @@ line says so.*
|
||||
named; whole (knowledge base), the overview shows a group's end from `group-ended`.
|
||||
- §432 **The edges a `needs` names.** An artifact's `needs` names artifact references `<module>:<artifact>` of the
|
||||
catalog graph's edges (§95, §121). Why: the design's choice (C21). How it is checked: unit (manifest validator).
|
||||
- §433 **The bus module reads the catalog half.** The bus module's `consumes` and its call of `indexer_bus_state` are
|
||||
- §433 **The bus module reads the catalog half.** (§532, §538) The bus module's `consumes` and its call of `indexer_bus_state` are
|
||||
replaced by its view of the catalog half (§344). Why: ADR 0596 §2 (C22). How it is checked: its manifest.
|
||||
- §434 **Findings name their owner and whom they wait on, and the keeper reads by events.** A finding of §33, §8 and
|
||||
- §434 **Findings name their owner and whom they wait on, and the keeper reads by events.** (§541) A finding of §33, §8 and
|
||||
§75 carries `owner` and `waiting-on`; the keeper's other reads are by events or verbs, and no homes rows are added.
|
||||
Hand-written finding code in Go moves to the generated writer (§439). Why: the design's choice (C16, C17, C15's Go
|
||||
half). How it is checked: the code review; the keeper's manifest reads nothing.
|
||||
@@ -380,10 +380,10 @@ line says so.*
|
||||
- §449 **The grants part's fill events say what `mesh-wants`' say.** The seat `mesh-grants`' events `filling` and `room`
|
||||
carry the same body as `mesh-wants`' fill events: `store`, `bytes`, `cap` and `at` (§181, §331). Why: develop
|
||||
question D-4, 2026-11-11. How it is checked: the seat's fixtures, against `mesh-wants`'.
|
||||
- §450 **`ask-again` and `aside` answer.** `operator-channel`'s `ask-again` (§394) takes `key`, the ask's, and answers
|
||||
- §450 **`ask-again` and `aside` answer.** (§555) `operator-channel`'s `ask-again` (§394) takes `key`, the ask's, and answers
|
||||
`state`, the ask's state after it, or `error`; `node-backup`'s `aside` (§405) answers `aside`, the name the data was
|
||||
set aside under, or `error`. Why: develop question D-5, 2026-11-11. How it is checked: the seats' fixtures.
|
||||
- §451 **The forms of `owner`, `waiting-on` and a catch-up.** A finding's `owner` and `waiting-on` (§434, §439) are each
|
||||
- §451 **The forms of `owner`, `waiting-on` and a catch-up.** (§540) A finding's `owner` and `waiting-on` (§434, §439) are each
|
||||
a string: a person or a session as who@node, or a seat's name. A restore point's catch-up (§406) is `{tool,
|
||||
arguments}`: `tool` an address as the mesh MCP server names one, `arguments` an object. Why: develop question D-6,
|
||||
2026-11-11. How it is checked: unit (mesh-conditions' contract, node-backup's contract), each form read and another
|
||||
|
||||
@@ -5,6 +5,8 @@ design: 47
|
||||
milestone: G
|
||||
updated: 2026-11-11
|
||||
decisions:
|
||||
- "ADR 0672"
|
||||
- "ADR 0436"
|
||||
- "ADR 0670"
|
||||
- "ADR 0668"
|
||||
- "ADR 0667"
|
||||
@@ -23,6 +25,7 @@ decisions:
|
||||
- "ADR 0641"
|
||||
- "ADR 0639"
|
||||
- "ADR 0636"
|
||||
- "ADR 0626"
|
||||
- "ADR 0635"
|
||||
- "ADR 0633"
|
||||
- "ADR 0625"
|
||||
@@ -76,7 +79,7 @@ file on 2026-11-10, and is cited as "design 47 G §n". A sentence that holds a d
|
||||
stayed in the main file, and G builds what it says from G's delivery. A section named in italics is in this part, or,
|
||||
when it is not here, in the main file.
|
||||
|
||||
The part is ten files, each read whole, its design lines numbered across them:
|
||||
The part is fourteen files, each read whole, its design lines numbered across them:
|
||||
|
||||
- [G-1-pipelines-registration-and-steps](G-1-pipelines-registration-and-steps.md): pipelines per module: registration, watched branches, steps and policy, what holds a delivery, approval, groups, dependencies, a publish.
|
||||
- [G-2-pipelines-sizes-checks-and-tools](G-2-pipelines-sizes-checks-and-tools.md): pipelines per module: any size, the pipeline makes the check, who may say what, health, recovery, tools, kept data, how G itself is delivered, the choices under ADR 0666 and ADR 0667.
|
||||
@@ -89,4 +92,6 @@ The part is ten files, each read whole, its design lines numbered across them:
|
||||
- [G-9-prepare-answers](G-9-prepare-answers.md): the answers to the questions of G's final prepare and develop's first questions (§391 to §455).
|
||||
- [G-10-develop-answers](G-10-develop-answers.md): the answers to develop's second batch of questions, the operator's and those of internal form only (§456 to §479).
|
||||
- [G-11-develop-answers-review](G-11-develop-answers-review.md): the operator's answers of 2026-11-11 noon, the review of §456 to §479, and develop's next questions (§480 to §515).
|
||||
- [G-12-develop-answers-fourth](G-12-develop-answers-fourth.md): the operator's answers of 2026-11-11 noon, round 3's leftovers and develop's fourth batch of questions (§516 to §553).
|
||||
- [G-13-review-round-3](G-13-review-round-3.md): the review of §480 to §515, rounds 2 and 3 (§600 on).
|
||||
- [G-14-recovery-module-and-review](G-14-recovery-module-and-review.md): the recovery module, the operator's answer of 2026-11-11 12:55 CET, and the review of §516 to §553 (§554 to §559).
|
||||
|
||||
Reference in New Issue
Block a user