|
|
|
@@ -41,26 +41,33 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
|
|
|
|
|
## The operator's answers
|
|
|
|
|
|
|
|
|
|
- §610 **Every class's default admits the modules that invoke it, and sessions call `warrant` and `accept`.** (§391,
|
|
|
|
|
§394, §405, §555; ADR 0666 §20, ADR 0286) The operator, 2026-11-11 about 15:40 CET at lead-47's terminal: "the
|
|
|
|
|
operator and agents may do everything, we might make it more strict and start asking for additional checks for
|
|
|
|
|
agent stuff, modules can get as many permissions as they want". §391's defaults become:
|
|
|
|
|
- `read`: `invokers`, `persons` and `sessions`, as before;
|
|
|
|
|
- `act`: `operator`, `sessions` and `invokers`;
|
|
|
|
|
- `warrant`: `operator`, `sessions` and `invokers`, and it still carries the approval mark, so each call runs only on
|
|
|
|
|
the operator's Approve of that one call, whoever made it (ADR 0286, which this line does not change);
|
|
|
|
|
- `accept`: `operator`, `sessions` and `invokers`. The runner's `accept` (§30, §394) is no longer the operator's
|
|
|
|
|
alone.
|
|
|
|
|
- §610 **No verb keeps a list of named callers: every verb takes its class's default.** (§391, §392, §394; ADR 0286;
|
|
|
|
|
the records this ends are named below) The operator, 2026-11-11 about 15:40 CET at lead-47's terminal: "the operator
|
|
|
|
|
and agents may do everything, we might make it more strict and start asking for additional checks for agent stuff,
|
|
|
|
|
modules can get as many permissions as they want"; and about 16:10 CET: "we can always lock it down later, but we
|
|
|
|
|
most definitely don't want stupid things like 'named lists'".
|
|
|
|
|
- **The defaults.** A verb's definition names its class, and its callers are its class's default, which the
|
|
|
|
|
seat-definition reader applies: `read` takes `invokers`, `persons` and `sessions`; `act`, `warrant` and `accept`
|
|
|
|
|
take `operator`, `sessions` and `invokers`. `invokers` is every module whose manifest names the verb in `invokes`
|
|
|
|
|
(§391). A module tool's callers are its class's default alike.
|
|
|
|
|
- **No list.** A seat definition and a manifest name no `callers`: the seat-definition reader and the manifest
|
|
|
|
|
validator refuse the field, naming the verb or tool, and every `callers` G's heads carry goes in G's change. So
|
|
|
|
|
`git`'s `tag` (§370), the build seats' `run` (§229), `node-backup`'s `now`, `restore`, `aside` and `discard-aside`
|
|
|
|
|
(§405, §555), `restore` taking any module's item (no own-item limit), `mesh-recovery`'s `snapshot-kept` and
|
|
|
|
|
`restore-kept` (§554, §659), the bus module's `nats_snapshot_get` (§554, §666), the node-engine's eleven verbs
|
|
|
|
|
(§393), `operator-channel`'s `ask-again` (§394), the indexer's `indexer_unpin` (§579) and every hand tool of G
|
|
|
|
|
take their class's default. §392's prefixed forms and `holder:<seat>@same-node` (§336) are no longer written in
|
|
|
|
|
a definition; a part that must tell callers apart reads the account the bus proved (`by-caller`, ADR 0259 §3).
|
|
|
|
|
- **What stays.** Who may publish an event or a step's result stays its owner's alone (ADR 0363 §2, ADR 0666
|
|
|
|
|
§21), and a verb's own judgement of its input stays (`restore-kept` refusing `aside-only`, §516; `merge-pull`
|
|
|
|
|
counting a rerun only by the operator or the healers, ADR 0666 §11, §585).
|
|
|
|
|
- **The approval mark stays** (ADR 0286), so a `warrant` verb, or any verb a manifest marks, runs only on the
|
|
|
|
|
operator's Approve of that one call, whoever calls (§677).
|
|
|
|
|
|
|
|
|
|
`invokers` is every module whose manifest names the verb in `invokes` (§391). A verb whose definition names its own
|
|
|
|
|
`callers` keeps them (§391); §394's verbs, which take their class's default, take the new one. So `node-backup`'s
|
|
|
|
|
`now` and `restore` (§405, §555), which take `act`'s default, are called by the operator, sessions and every
|
|
|
|
|
module that invokes them: the assigner, the node agent, the bus step's grant and the recovery module, today's
|
|
|
|
|
callers among them [mesh-contracts DQ-6]. This amends §391 and §394. Why: the operator's answer; no accepted record
|
|
|
|
|
makes a `warrant` or `accept` verb the operator's alone (ADR 0286 has the operator approve each marked call and
|
|
|
|
|
alone answer its ask). How it is checked: unit (seat-definition reader), the table's rows for `act`, `warrant`
|
|
|
|
|
and `accept` give their new callers, and a verb with `callers` of its own keeps them; whole (backup holder), a
|
|
|
|
|
`now` from the assigner's account and a `restore` from the recovery module's are taken.
|
|
|
|
|
This amends §391, §392, §393 and §394, and every line naming `callers`. Why: the operator's answers. How it is
|
|
|
|
|
checked: unit (seat-definition reader, manifest validator), a definition or manifest naming `callers` refused, and
|
|
|
|
|
a table row per class giving its default; whole (backup holder, recovery module), a `restore` from a session and
|
|
|
|
|
from the recovery module for another module's item taken, and a `snapshot-kept` from a session taken.
|
|
|
|
|
- §611 **Five parts move only their findings to templates in G.** (§529, §577) The operator, 2026-11-11 between 15:14
|
|
|
|
|
and 15:42 CET at lead-47's terminal: in G only the state `findings` and the finding stream of the teller, the
|
|
|
|
|
status view, the watchman, enrolment and the forge bridge move to `requires` templates (§529). Their other old
|
|
|
|
@@ -86,16 +93,23 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
`orphans` lists, removed only by the operator's `drop` (ADR 0595 §4).
|
|
|
|
|
- `merges` and `source` stay in the old `state` section (§542, §15).
|
|
|
|
|
- `deliveries`, `groups`, `owed` and `conditions` move to `requires` entries of the template `state`, under the same
|
|
|
|
|
names. At its first start, before it serves anything, the gate of G copies every key of the old section of each
|
|
|
|
|
into its template entry, from its own data alone, says in its journal and in `gate_records` how many keys it
|
|
|
|
|
copied of each, and leaves a key already in the template as it is (as §584 copies the image registry's). The old
|
|
|
|
|
sections' keys stay, read no more, so a revert's gate of before G finds them, until the operator's `drop`.
|
|
|
|
|
names. The old sections' keys stay, read no more, so a revert's gate of before G finds them, until the operator's
|
|
|
|
|
`drop`.
|
|
|
|
|
- **Copied at every start that finds the old section changed.** The gate of G keeps, in a template state of its
|
|
|
|
|
own `copies`, one key per state with the old section's last revision it copied and when. At each start, before it
|
|
|
|
|
serves anything, for each of the four whose old section's last revision is newer than that key, it copies every
|
|
|
|
|
key changed since: a key whose write in the old section is newer than its template key's replaces it, a key
|
|
|
|
|
deleted in the old section after its template key's write is deleted in the template, and an older one is left.
|
|
|
|
|
It then writes the mark, and says in its journal and in `gate_records` how many keys it copied and deleted of
|
|
|
|
|
each. So forward, a revert (whose gate of before G writes the old sections), and forward again carry every change
|
|
|
|
|
made while reverted, and nothing older overwrites a newer write.
|
|
|
|
|
|
|
|
|
|
[mesh-catalog Q-G1.] This corrects §15's "the gate's other kept data stay in ADR 0595's templates". Why: the
|
|
|
|
|
operator's answer. How it is checked: unit (manifest validator), the gate's manifest of G's heads declares `merges`
|
|
|
|
|
and `source` old and the four templates; whole (gate), a first start with keys in the four old sections copies
|
|
|
|
|
them, says how many, and serves them.
|
|
|
|
|
|
|
|
|
|
operator's answer; the copy at every start is the design's (review: security and upgrade 5, running and testing 2).
|
|
|
|
|
How it is checked: unit (manifest validator), the gate's manifest of G's heads declares `merges` and `source` old
|
|
|
|
|
and the five templates; whole (gate), forward, then a revert's write and deletion in the old sections, then
|
|
|
|
|
forward: the template holds the reverted gate's write, the key it deleted is gone, and a key written in the
|
|
|
|
|
template after the revert is kept.
|
|
|
|
|
## Reading the catalog half, every part alike
|
|
|
|
|
|
|
|
|
|
- §614 **How a part reads the catalog half per watched branch, once for every part.** (§196, §199, §443, §459, §479,
|
|
|
|
@@ -110,7 +124,11 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
reader of the seat: the registrations' watched branches, read by `registrations` at the start and followed by
|
|
|
|
|
`registration-changed` (§532); before the first registrations, the branches the gate's `source` answers, read at
|
|
|
|
|
the start and followed by the gate's `source-moved` (§507), which it stops following at the first
|
|
|
|
|
`registration-changed`. mesh-sdk's `go/views` adopts and drops the views (§532) and holds no seat's verb.
|
|
|
|
|
`registration-changed`. The gate's `source` given no branch answers `{branches}`, the branch of each
|
|
|
|
|
`source.<branch>` key it keeps, and given a branch that branch's source revision. mesh-sdk's `go/views` adopts and
|
|
|
|
|
drops the views (§532) and holds no seat's verb. The forge module, in TypeScript, follows the branches the same
|
|
|
|
|
way through the TypeScript form of `meshcatalogclient`, beside the seat's generated TypeScript contract in
|
|
|
|
|
mesh-delivery's contracts, on mesh-sdk's TypeScript view follower (§196).
|
|
|
|
|
- **The manifest entries every such part declares.** In `consumes`: `mesh-catalog.catalog-revision`,
|
|
|
|
|
`mesh-catalog.registration-changed` and `mesh-delivery.source-moved`. In `invokes`:
|
|
|
|
|
`seat:mesh-catalog.revision` (with the field `none-yet`, §617), `seat:mesh-catalog.registrations`,
|
|
|
|
@@ -120,13 +138,26 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
`running` or a `wanted` naming a fingerprint that no branch's newest revision lists and it does not hold, it asks
|
|
|
|
|
`entry` once, as a kept call (ADR 0668 §1), and keeps the answer; it removes one when no `running` or `wanted` it
|
|
|
|
|
holds names that fingerprint any more. The reader it passes to a pure function (§459) answers from the views and
|
|
|
|
|
those entries alone, and reads no bus; an entry not yet answered is answered as none, which §459 says.
|
|
|
|
|
those entries alone, and reads no bus. Each kept entry is `asked`, `answered` or `not-found`:
|
|
|
|
|
- **asked**: the reader answers it as pending, a state apart from none; the part's health says it waits on that
|
|
|
|
|
fingerprint, and the node-engine's have says the phase `held` with its detail opening `entry-asked:` (§421's
|
|
|
|
|
`entry-missing` is said only once `entry` answered not found);
|
|
|
|
|
- **answered**: the answer starts a new pass at once;
|
|
|
|
|
- **not-found**: the part writes the finding `entry-not-found` (scope the part, id the fingerprint), cleared when
|
|
|
|
|
nothing it holds names that fingerprint or a later ask answers it.
|
|
|
|
|
|
|
|
|
|
`<module>_first_views` lists these entries with their state and since when, and the part's tool
|
|
|
|
|
`<module>_entry_again` (`fingerprint`; class `act`) asks one again now.
|
|
|
|
|
- **A branch at `none yet`.** A view whose `revision` answered `none-yet` (§530) is ready and empty: the reader's
|
|
|
|
|
answer for that branch lists no entry.
|
|
|
|
|
- **The first pass.** A part acts on nothing until every branch it follows has its first view, `none-yet`
|
|
|
|
|
counting as one; until then `<module>_first_views` says each branch `waiting` and its health says it waits (§200,
|
|
|
|
|
§556). After its first views it acts on what it holds, and a view behind is read again by §196.
|
|
|
|
|
- **A dropped branch.** When `go/views` drops a branch's view (§532), it clears, through the part's writer (§639),
|
|
|
|
|
- **The node-engine follows no branch.** It reads the catalog half only by the fingerprints its wants name
|
|
|
|
|
(§421), through the entries above, and declares none of the branch entries; it never waits on a branch's view, the
|
|
|
|
|
registrations or the gate's `source`, so it composes the gate (and every part) before any of them answers, and no
|
|
|
|
|
cycle runs through it at G's delivery.
|
|
|
|
|
- **A dropped branch.** When `go/views` drops a branch's view (§532), it clears, through the part's mesh-sdk writer (§639: a views reader writes its findings through the part's writer, never a writer of its own),
|
|
|
|
|
every finding that view raised (`first-view-unanswered`, `view-waits`, `view-unsaid`, `view-too-large`), says the
|
|
|
|
|
drop and each cleared finding in the part's log, and removes the view's row of `<module>_first_views` [D-12].
|
|
|
|
|
|
|
|
|
@@ -136,8 +167,10 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
§532. Why: the same question came from five build maps, each about to build its own form (develop's D-5). How it
|
|
|
|
|
is checked: unit (`meshcatalogclient`), a branch added by `registration-changed` and one by `source-moved` before
|
|
|
|
|
the first registrations are followed, an entry asked once on a `running` of an unlisted fingerprint and dropped
|
|
|
|
|
when nothing names it, a `none-yet` branch read as empty; whole (grants part, tool runner), a part started with one
|
|
|
|
|
branch at `none-yet` acts once every first view is in; a dropped branch's findings are cleared.
|
|
|
|
|
when nothing names it, a pending entry read apart from none and a not-found one raising `entry-not-found`, a
|
|
|
|
|
`none-yet` branch read as empty; unit (gate), `source` with no branch lists the branches; whole (grants part, tool
|
|
|
|
|
runner), a part started with one branch at `none-yet` acts once every first view is in; a dropped branch's findings
|
|
|
|
|
are cleared; whole (node-engine), a want composed with no branch view and no `source` answered.
|
|
|
|
|
- §615 **The tool runner's and the Go build module's manifests come from the entry too.** (§594, §614, §443, §445,
|
|
|
|
|
test 61) The mesh MCP server of the tool runner takes each module's manifest from its catalog graph entry, through §614's
|
|
|
|
|
reader; its first view of the indexer's `manifests` and its `consumes` of `mesh-delivery-indexer.views.manifests`
|
|
|
|
@@ -145,14 +178,17 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
names, by `seat:mesh-catalog.entry` (§506's `manifest-digest` naming the entry's), and its `invokes` of
|
|
|
|
|
`mesh-delivery-indexer.indexer_read_manifests` goes [mesh-catalog Q-B1]. Both join §594's readers. Why: test 61, and
|
|
|
|
|
`manifests` is kept only for node-engines of before G (§445). How it is checked: test 61, a row each.
|
|
|
|
|
- §616 **The owner of the assigner's views is read from the catalog half.** (§428, §7) The tool runner's code reads the
|
|
|
|
|
module that holds `mesh-module-assigner` from the catalog half's claims of that seat (§614), and names the views
|
|
|
|
|
`<that module>.assignments` and `<that module>.seat-holders` from it, never by a name fixed in code. Its manifest's
|
|
|
|
|
`consumes` keeps `mesh-delivery-assigner.views.assignments` and `views.seat-holders`, the module's own declaration of
|
|
|
|
|
what it hears, as a manifest may name a module. Design 46 7-approval-mark §19's holder of `operator-channel` is read
|
|
|
|
|
from that view so found. [mesh-tools Q-R3, Q-R17.] Why: §428 removes the name from code, and the catalog half
|
|
|
|
|
says who claims a seat. How it is checked: unit (tool runner), a fixture catalog half naming another holder of the
|
|
|
|
|
seat gives views of that name; the code review finds no assigner name in the tool runner's code.
|
|
|
|
|
- §616 **The assigner's views are named by the seat, in the code and in the manifest.** (§428, §7) The tool runner's
|
|
|
|
|
code reads the module that holds `mesh-module-assigner` from the catalog half's claims of that seat (§614) and
|
|
|
|
|
names the views `<that module>.assignments` and `<that module>.seat-holders` from it, never by a name fixed in code.
|
|
|
|
|
Its manifest's `consumes` names them by the seat, `mesh-module-assigner.views.assignments` and
|
|
|
|
|
`mesh-module-assigner.views.seat-holders`, which the grants part resolves to the seat's holder from the catalog
|
|
|
|
|
half as it resolves a seat's events, so a new holder is granted with no change of the manifest. Design 46
|
|
|
|
|
7-approval-mark §19's holder of `operator-channel` is read from that view so found. [mesh-tools Q-R3, Q-R17.] Why:
|
|
|
|
|
§428 removes the name from code, and the catalog half says who claims a seat (review: seams and tools' note). How
|
|
|
|
|
it is checked: unit (tool runner), a fixture catalog half naming another holder of the seat gives views of that
|
|
|
|
|
name; unit (grants part), a seat-named view granted for the seat's new holder; the code review finds no assigner
|
|
|
|
|
name in the tool runner's code or manifest.
|
|
|
|
|
- §617 **The long form of an `invokes` entry stands beside `*`.** (§558, §545) A manifest's `invokes` may hold `*`
|
|
|
|
|
and long-form entries together: the tool runner's is `*`, then `{verb: "seat:mesh-catalog.revision", fields:
|
|
|
|
|
["none-yet"]}` and `seat:mesh-catalog.entry` with no fields named [mesh-tools Q-R4, Q-R18]. The manifest validator
|
|
|
|
@@ -214,13 +250,14 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
its start (§205), the fingerprint the node-engine's `running` says of it; the tool runner consumes nothing more for
|
|
|
|
|
it. Design 34 every-event §35 is corrected so. [mesh-tools Q-R14.] Why: the node-engine hands each process its own
|
|
|
|
|
build (§205). How it is checked: unit (tool runner), the act carries the fingerprint of its environment.
|
|
|
|
|
- §626 **A module ends G with no more tests than it starts with.** (§419, test budget) §419 holds for the tool runner's
|
|
|
|
|
- §626 **A module ends G with no more tests than it starts with.** (§419, test budget) §419's count starts, for each
|
|
|
|
|
module, at the commit of its repository's main from which G's branch of that repository starts (its merge base with
|
|
|
|
|
that branch), and the check compares the module's count at G's heads against it. This holds for the tool runner's
|
|
|
|
|
work of design 34 every-event and design 46 7-approval-mark: the new tables and the whole test of design 46
|
|
|
|
|
7-approval-mark §22 and design 34 every-event §19 replace existing tests, and every test they delete counts.
|
|
|
|
|
Their "New test functions are allowed within each module's budget" is corrected to say so. [mesh-tools Q-R16.] Why:
|
|
|
|
|
§419 is milestone G's rule and both parts ship in G's release. How it is checked: the check counts the tool runner's
|
|
|
|
|
tests against its count at G's start.
|
|
|
|
|
|
|
|
|
|
7-approval-mark §22 and design 34 every-event §19 replace existing tests, and every test they delete counts. A test
|
|
|
|
|
moved with its code (§655) counts in the module it moves to, as no new test there, and as deleted in the module it
|
|
|
|
|
left. [mesh-tools Q-R16.] Why: §419 is milestone G's rule and both parts ship in G's release. How it is checked: the
|
|
|
|
|
check counts each module's tests against its count at that commit.
|
|
|
|
|
## The node-engine and the node agent
|
|
|
|
|
|
|
|
|
|
- §627 **The node-engine is a foundation part.** (§6, §529, §577; ADR 0619 §1 to §3) The node-engine composes every
|
|
|
|
@@ -291,10 +328,13 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
(`view-waits`, `first-view-unanswered`, `view-unsaid`, `view-too-large`) are written through the part's mesh-sdk
|
|
|
|
|
writer as kinds of their own (§580), and the writer's statement covers them beside `observe`'s. [mesh-sdk 7.] How it
|
|
|
|
|
is checked: unit (writer), a statement keeps the reader's open findings.
|
|
|
|
|
- §640 **The writer keeps its copy of the finding layout, held equal to the generated types.** (§439, §452) mesh-sdk's
|
|
|
|
|
writer keeps its own `FindingBody`, `FindingCleared`, `FindingsStated` and `FindingsAsked`, in Go and TypeScript, and
|
|
|
|
|
a test in mesh-contracts holds them field for field equal to the types the seat generator emits. [mesh-sdk 8.] Why:
|
|
|
|
|
one layout, checked, without changing which package imports which. How it is checked: that test.
|
|
|
|
|
- §640 **The finding writer reads the generated types; it keeps no copy of the layout.** (§439, §452) mesh-sdk's
|
|
|
|
|
writer, in Go and TypeScript, defines the small interface it needs of a finding's body (its key's parts, its
|
|
|
|
|
`since`, its kind) and takes the types the seat generator emits for `findings` through it; it holds no
|
|
|
|
|
`FindingBody`, `FindingCleared`, `FindingsStated` or `FindingsAsked` of its own, so there is one layout and nothing
|
|
|
|
|
to keep equal. [mesh-sdk 8.] Why: a copy held equal by a test in another repository is not checked on a change of
|
|
|
|
|
mesh-sdk alone, and the TypeScript copy by none (review: running and testing 6). How it is checked: unit (writer,
|
|
|
|
|
both languages), a generated body written and stated; the code review finds no copy.
|
|
|
|
|
- §641 **A stream kept last per subject: where it is read and how it is told.** (§396, §556) mesh-sdk's
|
|
|
|
|
`HearSeatEvents` makes §556's read at the start with an ordered consumer, then follows the durable, and names the
|
|
|
|
|
stream `waiting` in `<module>_first_views` until the read ends [mesh-sdk 9]. The grants part tells such a stream by
|
|
|
|
@@ -341,79 +381,134 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
|
|
|
|
|
## mesh-catalog's parts
|
|
|
|
|
|
|
|
|
|
- §654 **The readers of the forge module's old events and tools move to the seat `git`.** (§310, §311, §313, §431)
|
|
|
|
|
mesh-config consumes `git`'s `pull-merged` and `pull-closed` in place of `gitea.pull.merged`, `gitea.pull.closed`
|
|
|
|
|
and `gitea.forge.pull-request.closed`, and invokes `seat:git.pull` in place of `gitea.gitea_get_pull_request`; the
|
|
|
|
|
records module consumes `git.pull-merged`; mesh-issues invokes `seat:git.pull` and `seat:git.contains`, and reads a
|
|
|
|
|
pull request's checks and reviews from the delivery record's `show` (its steps' results, the review step's among
|
|
|
|
|
them), in place of `seat:mesh-delivery.checks` and `gitea_pull_reviews`. [mesh-catalog Q-F1.] How it is checked:
|
|
|
|
|
unit (manifest validator), each manifest of G's heads names none of the old events or tools.
|
|
|
|
|
- §654 **The readers of the forge module's old events and tools move to the seat `git`.** (§310, §311, §313, §431;
|
|
|
|
|
ADR 0659 §1) [mesh-catalog Q-F1.]
|
|
|
|
|
- **mesh-config** consumes `git`'s `pull-merged` and `pull-closed` in place of `gitea.pull.merged`,
|
|
|
|
|
`gitea.pull.closed` and `gitea.forge.pull-request.closed`, and invokes `seat:git.pull` in place of
|
|
|
|
|
`gitea.gitea_get_pull_request`; **the records module** consumes `git.pull-merged`.
|
|
|
|
|
- **The order.** Main's forge module says its own `pull.merged`, not the seat's events, so each consumer of
|
|
|
|
|
`git.pull-merged` or `pull-closed` is ordered after the forge module's version that says them, by the edge of kind
|
|
|
|
|
6 its `consumes` gives (§558); its durable consumer is made from the stream's first message, so no merge said
|
|
|
|
|
before it began is missed, and no catch-up through `git.pull` is needed.
|
|
|
|
|
- **mesh-issues** invokes `seat:git.pull` and `seat:git.contains`, and reads a pull request's steps from the
|
|
|
|
|
runner's `show` given the repository and the pull request's head commit (`seat:mesh-pipeline-runner.show` in its
|
|
|
|
|
`invokes`), which answers that commit's pipelines with each step's result, the review step's among them (ADR
|
|
|
|
|
0666 §22); a commit with no pipeline is answered `none`, which mesh-issues shows as "no run". The forge's own
|
|
|
|
|
reviews are read nowhere: G keeps no review record (ADR 0659 §1). Its read of `seat:mesh-delivery.checks` and
|
|
|
|
|
`gitea_pull_reviews` go.
|
|
|
|
|
|
|
|
|
|
How it is checked: unit (manifest validator), each manifest of G's heads names none of the old events or tools;
|
|
|
|
|
unit (mesh-config, records), each acts on a `git.pull-merged` fixture; unit (mesh-issues), a commit with no
|
|
|
|
|
pipeline shown as "no run".
|
|
|
|
|
- §655 **The take and restore of one stream is shared code in mesh-sdk.** (§554, §464; ADR 0672 §1) The code that
|
|
|
|
|
takes and restores one stream's snapshot moves whole from the bus module's `bussnap` into mesh-sdk's `go/bussnap`,
|
|
|
|
|
imported by the bus module (its snapshot before `recreate` and `drop`) and by the recovery module (its points and
|
|
|
|
|
restores); no module imports another module's package. [mesh-catalog Q-R1.] Why: code two modules share lives in
|
|
|
|
|
imported by the bus module (its snapshot before `recreate` and `drop`), by the recovery module (its points and
|
|
|
|
|
restores), and by any part that takes the nightly dump's stream snapshots; no module imports another module's
|
|
|
|
|
package, and no third copy is kept. The edge of kind 1 from mesh-sdk's package (§47) orders its publication before
|
|
|
|
|
the bus module's and the recovery module's builds. [mesh-catalog Q-R1.] Why: code two modules share lives in
|
|
|
|
|
mesh-sdk (§464's reason). How it is checked: the code review finds one copy.
|
|
|
|
|
- §656 **The hand tools are the recovery module's own tools, answered by its process.** (§554, §566; ADR 0672 §3, §7)
|
|
|
|
|
Each hand tool is a module tool on the process's own `by-caller` subject, the bundle passing the call through, so
|
|
|
|
|
the bus proves the tool runner's account; the seat `mesh-recovery` gains no verb. [mesh-catalog Q-R2.] How it is
|
|
|
|
|
checked: whole (recovery module), a hand tool from another account is refused by the bus.
|
|
|
|
|
- §657 **The recovery module's health check is a tool.** (§554, §468) The recovery module serves the read tool
|
|
|
|
|
`recovery_kept_points`, answering what `kept-points` answers, and its declared health check names it.
|
|
|
|
|
[mesh-catalog Q-R3.] How it is checked: unit (manifest validator), the check names a served tool.
|
|
|
|
|
- §656 **The hand tools' acts are verbs of the seat `mesh-recovery`.** (§554, §566; ADR 0672 §7) Each hand tool's act
|
|
|
|
|
is a verb of the seat `mesh-recovery`, `by-caller`, answered by the process: `take`, `restore`, `retry`, `aside`,
|
|
|
|
|
`discard-aside`, `restore-aside`, `cancel` and `expire-points`, each of class `act` (§610), beside `snapshot-kept`,
|
|
|
|
|
`restore-kept` and `kept-points`, all defined in mesh-contracts. The tools bundle's `recovery_*` tools call them,
|
|
|
|
|
named in its `invokes`, and hold no grant of their own; the bus proves the tool runner's account, as ADR 0672 §7
|
|
|
|
|
has the bundle call the seat's verbs. [mesh-catalog Q-R2.] Why: ADR 0672 §7 (review: seams and tools 2). How it is
|
|
|
|
|
checked: unit (mesh-recovery's contract), each verb read; whole (recovery module), each hand tool acts through its
|
|
|
|
|
verb.
|
|
|
|
|
- §657 **The recovery module's health check is a tool.** (§554, §468, §561) The recovery module serves the read tool
|
|
|
|
|
`recovery_kept_points`, answering what `kept-points` answers, its bundle naming `seat:mesh-recovery.kept-points` in
|
|
|
|
|
`invokes`, and its declared health check names it. The check fails while an aside's record ends at `removed` and no
|
|
|
|
|
running act holds it, as §554 has it, which `recovery_kept_points` answers. §554's "calls `kept-points`" is
|
|
|
|
|
corrected so. [mesh-catalog Q-R3.] How it is checked: unit (manifest validator), the check names a served tool;
|
|
|
|
|
whole (recovery module), an unrestored aside fails the check.
|
|
|
|
|
- §658 **A module new in G starts with the tests its lines name.** (§419) A module new in G counts from none: its
|
|
|
|
|
tests are the checks its design lines name (for the recovery module, its one whole test and the unit rows of its
|
|
|
|
|
lines), within the per-module budget. [mesh-catalog Q-R4.]
|
|
|
|
|
|
|
|
|
|
## mesh-contracts' seat contracts
|
|
|
|
|
|
|
|
|
|
- §659 **`snapshot-kept` and `restore-kept` are of class `act`.** (§554; ADR 0672 §3) Class `act`, their callers
|
|
|
|
|
`seat:node-engine` alone, as §554 names them. [mesh-contracts DQ-5.]
|
|
|
|
|
- §659 **`snapshot-kept` and `restore-kept` are of class `act`.** (§554, §610) Class `act`, taking its default, as
|
|
|
|
|
every verb does (§610). [mesh-contracts DQ-5.]
|
|
|
|
|
- §660 **A finding's key and value.** (§461, §437, §439) The state `findings` keeps the key `<scope>.<id>.<kind>` and the
|
|
|
|
|
value `#/bodies/Finding`. [mesh-contracts DQ-7.]
|
|
|
|
|
- §661 **`list` shows the caps.** (§547) The seat `mesh-broker`'s `list` answer gains `caps {sum-mib,
|
|
|
|
|
account-limit-mib, server-limit-mib}`, an absent limit meaning unlimited. [mesh-contracts DQ-10.]
|
|
|
|
|
- §662 **A subject function with parts can fail.** (§523) A generated subject function with `<part>` tokens answers
|
|
|
|
|
`(string, error)` in Go and throws in TypeScript for an empty part, `.` or `..`. [mesh-contracts DQ-11.]
|
|
|
|
|
- §663 **The condition keeper's sources are the bus module's `created` events.** (§515, §529) The keeper takes a
|
|
|
|
|
source when it hears the seat `mesh-broker`'s `created` of a part's `finding-events` entry, and a foundation part's
|
|
|
|
|
old finding stream from the catalog half (§614); at its start it reads both by `list` and the catalog half. §515 is
|
|
|
|
|
corrected so. [mesh-contracts DQ-12; D-7's COND9.] Why: the grants part makes the consumers (§386), and no binding
|
|
|
|
|
names one. How it is checked: whole (keeper, bus module), a part declaring finding events is asked once its entry
|
|
|
|
|
is `created`.
|
|
|
|
|
- §663 **The condition keeper's sources are the bus module's `created` events, and it follows a moved stream.** (§515,
|
|
|
|
|
§529, §611, §612) The keeper takes a source when it hears the seat `mesh-broker`'s `created` of a part's
|
|
|
|
|
`finding-events` entry, named in its `consumes`, and a foundation part's old finding stream from the catalog half
|
|
|
|
|
(§614); at its start it reads both by `list` and the catalog half. When a part's catalog graph entry no longer
|
|
|
|
|
declares the stream the keeper follows for it (its findings moved to a template, §611, or to an old section, §612),
|
|
|
|
|
the keeper drops that source and its consumer, keeps the part's open conditions, and asks `findings-asked` on the
|
|
|
|
|
new stream once it is a source; the part's statement there settles them (§384). §515 is corrected so.
|
|
|
|
|
[mesh-contracts DQ-12; D-7's COND9.] Why: the grants part makes the consumers (§386), and no binding names one; a
|
|
|
|
|
moved stream must neither raise twice nor leave a condition open (review: health and events 1). How it is
|
|
|
|
|
checked: whole (keeper, bus module), a part declaring finding events is asked once its entry is `created`; a part
|
|
|
|
|
whose findings move keeps its condition raised once and clears it from the new stream.
|
|
|
|
|
- §664 **`backed-up` needs no contract change.** (§563) The backup holder's answer carries a put-off item's `act` and
|
|
|
|
|
since when in its own fields. [mesh-contracts DQ-14.]
|
|
|
|
|
- §665 **`attempt-changed` is keyed by condition and attempt.** (§541) The subject is
|
|
|
|
|
`mesh.seat.mesh-healers.event.attempt-changed.<condition>.<attempt>`, kept last per subject, so two attempts on one
|
|
|
|
|
condition both stay. [mesh-contracts DQ-15.] How it is checked: unit (healers' contract).
|
|
|
|
|
|
|
|
|
|
- §665 **`attempt-changed` is keyed by condition and attempt.** (§541, §73) The subject is
|
|
|
|
|
`mesh.seat.mesh-healers.event.attempt-changed.<condition>.<attempt>`, each token escaped as a key's name is (§73),
|
|
|
|
|
kept last per subject, 7 days and 16 MiB (§541), so two attempts on one condition both stay. At about 0.5 KiB a
|
|
|
|
|
message, 16 MiB holds about 30,000 attempts, far more than seven days have seen (an estimate). The stream discards
|
|
|
|
|
nothing new: a publish past its cap fails, and the healers say it in their health and write the finding
|
|
|
|
|
`attempt-unsaid` (scope the healers, id the condition), cleared by that subject's next publish taken. §541's
|
|
|
|
|
subject is corrected so. [mesh-contracts DQ-15.] How it is checked: unit (healers' contract), two attempts of one
|
|
|
|
|
condition kept; whole (healers), a full stream raises `attempt-unsaid`.
|
|
|
|
|
## Met in develop
|
|
|
|
|
|
|
|
|
|
- §666 **`nats_snapshot_get`'s arguments and answer.** (§554, §567; ADR 0672 §1, §8; ADR 0666 §16) It takes `request`,
|
|
|
|
|
the id of the bus module's `drop` or `recreate` request whose snapshot is asked, as the keeper's requests record it.
|
|
|
|
|
It answers `{request, module, local, stream, size, digest, at, object}`: `digest` the `sha256:` digest of the
|
|
|
|
|
snapshot's bytes, and `object` the name of the snapshot in the bus module's sent store (§59), which the recovery
|
|
|
|
|
module reads by the standing grant of that answer; a snapshot larger than the sent store's cap (§591) answers
|
|
|
|
|
`error`, naming its size and the cap. `recovery_restore` names it by `request`, and the recovery module checks the
|
|
|
|
|
bytes against `digest` before it takes any aside, as §567. [D-1.] Why: the snapshot crosses the bus as every large
|
|
|
|
|
answer does, never as a shared file. How it is checked: whole (bus module, recovery module), a `drop`'s snapshot
|
|
|
|
|
restored by `recovery_restore` with its `request`, and one with altered bytes refused.
|
|
|
|
|
- §667 **Where a trusted change and the seed wait for their warrant.** (§3, §8; ADR 0666 §2, §12; ADR 0259) [D-2, D-3.]
|
|
|
|
|
- §666 **`nats_snapshot_get`: the snapshot recorded with its digest, and sent on the call's own session.** (§554,
|
|
|
|
|
§567, §518, §620; ADR 0672 §1, §8; ADR 0667 §12) [D-1.]
|
|
|
|
|
- **When it is taken.** The bus module's keeper, taking the snapshot before a `drop` or `recreate` (ADR 0595 §5),
|
|
|
|
|
writes into that request's record in its state `requests` the snapshot's `path` (under its snapshots directory),
|
|
|
|
|
`size` and `digest` (`sha256:` of its bytes) before it touches the live data. A snapshot it cannot write whole and
|
|
|
|
|
record so makes the `drop` or `recreate` refuse, naming why, before anything is removed.
|
|
|
|
|
- **Who deletes it.** The keeper alone: the snapshot file and its record are kept 90 days (ADR 0667 §12, as the
|
|
|
|
|
delivery records), its setting `snapshot-keep-days`, and removed at the keeper's start and at each new request
|
|
|
|
|
once older, each removal written in its journal.
|
|
|
|
|
- **The call.** It takes `request`, the request's id. It reads the file, computes its digest, and answers `error`
|
|
|
|
|
`snapshot damaged`, naming the request, when it differs from the recorded one, or `snapshot missing` when no file
|
|
|
|
|
is there. Otherwise it answers `{request, module, local, stream, size, digest, at, chunked: true}` and sends the
|
|
|
|
|
file on the call's own get session, `<the tool's call subject>.get.<call id>`, in chunks under the bus's
|
|
|
|
|
per-message limit, each acknowledged by the caller before the next, as §518 and §620 have a get session; only the
|
|
|
|
|
bus module's account publishes the chunks and only the caller's account answers them, granted so (§489). No size
|
|
|
|
|
limit applies and nothing goes through the sent store.
|
|
|
|
|
- **Its use.** `recovery_restore` names it by `request`, and the recovery module checks the bytes it received
|
|
|
|
|
against `digest` before it takes any aside (§567).
|
|
|
|
|
|
|
|
|
|
Why: a snapshot larger than the sent store's cap, or asked after its 7 days, could never be restored, and the
|
|
|
|
|
sent store's read grant is wider than this one caller (review: all four domains). How it is checked: whole (bus
|
|
|
|
|
module, recovery module, with small settings), a snapshot larger than 256 MiB restored whole; one asked eight days
|
|
|
|
|
after its `drop` with `snapshot-keep-days` 90 restored; a file altered on disk after the `drop` refused `snapshot
|
|
|
|
|
damaged`; a `drop` whose snapshot cannot be written refuses before it removes anything.
|
|
|
|
|
- §667 **Where a trusted change and the seed wait for their warrant.** (§3, §8; ADR 0666 §2, §12; ADR 0259 §6; ADR
|
|
|
|
|
0286 §10) [D-2, D-3.]
|
|
|
|
|
- **Kept.** The indexer keeps each change of `register`, `policy`, `watch` and `unwatch` awaiting its warrant in its
|
|
|
|
|
old `state` section `proposals`, one key `<verb>.<module>` (`<verb>.<module>.<branch>` for `watch` and
|
|
|
|
|
`unwatch`, each token escaped as a key's name is, §73), holding the change whole, the ask's id, its caller and
|
|
|
|
|
when it was asked; the seed's key is `seed`. Capped at 4 MiB.
|
|
|
|
|
`unwatch`, each token escaped as a key's name is, §73), holding the change whole, its `digest` (`sha256:` of the
|
|
|
|
|
change in RFC 8785's canonical form), the current ask's id, its caller and when it was asked; the seed's key is
|
|
|
|
|
`seed`. Capped at 4 MiB.
|
|
|
|
|
- **Asked.** Through `operatorchannelclient`, kind `ask`, level `approve`, its `about` the key, so a newer change of
|
|
|
|
|
the same key replaces the open ask (ADR 0666 §12).
|
|
|
|
|
- **Heard.** By the indexer's durable consumer of `mesh.seat.operator-channel.event.decided.<the indexer's module>`.
|
|
|
|
|
A warrant writes the version by compare-and-set and deletes the key; a Decline, an expiry or a refusal deletes it
|
|
|
|
|
and writes nothing, said in its journal and its answer to the caller; the seed's keeps `seed-waits` (§8).
|
|
|
|
|
- **A restart.** At its start the indexer reads each key and the seat `operator-channel`'s `asks` for its ask:
|
|
|
|
|
a decided one is applied as above, an open one waited on, and one the router no longer holds deleted, said.
|
|
|
|
|
- **Its tools.** `indexer_proposals` (class `read`) lists the keys with their asks; `indexer_seed_again` raises
|
|
|
|
|
the seed's ask again from its key (§8).
|
|
|
|
|
the same key replaces the open ask (ADR 0666 §12); the ask names every value the change moves (§3) and carries the
|
|
|
|
|
change's `digest`, so the warrant approves those exact values (ADR 0286 §10).
|
|
|
|
|
- **Heard.** The indexer's manifest `consumes` `operator-channel.decided`, on
|
|
|
|
|
`mesh.seat.operator-channel.event.decided.<the indexer's module>`, through a durable consumer. A warrant is
|
|
|
|
|
applied only when its ask's id is the key's current ask and its digest the key's: it writes the version by
|
|
|
|
|
compare-and-set and ends the key `applied`. A warrant of a replaced ask writes nothing, said in its journal. A
|
|
|
|
|
Decline, an expiry or a refusal ends the key with that outcome; the seed's keeps `seed-waits` (§8).
|
|
|
|
|
- **Ended keys stay readable.** An ended key keeps its outcome, its ask and when, until the next change of the same
|
|
|
|
|
key replaces it.
|
|
|
|
|
- **A restart.** At its start the indexer reads each open key and the seat `operator-channel`'s `asks` for its
|
|
|
|
|
ask: a decided one is applied or ended as above, an open one waited on, and one the router no longer holds ended
|
|
|
|
|
`lost`, said.
|
|
|
|
|
- **Its tools.** `indexer_proposals` (class `read`) lists the open and ended keys with their asks and outcomes;
|
|
|
|
|
`indexer_proposal_drop` (`key`, `why`; class `act`, in the hand-act log) cancels the key's open ask and ends it
|
|
|
|
|
`dropped`; `indexer_seed_again` raises the seed's ask again from its key (§8).
|
|
|
|
|
|
|
|
|
|
How it is checked: whole (indexer), a `policy` applied on its warrant after a restart while open, a decline
|
|
|
|
|
writes nothing, and two `policy` changes of one module leave one ask.
|
|
|
|
|
How it is checked: whole (indexer), a `policy` applied on its warrant after a restart while open; a decline ends
|
|
|
|
|
the key `declined`, read by `indexer_proposals`; two `policy` changes of one module leave one ask, and the first
|
|
|
|
|
ask's late warrant writes nothing; a dropped key's ask is cancelled.
|
|
|
|
|
- §668 **`manifest-accepted`'s `problems`.** (§500; ADR 0579 §1) The event gains `problems`, a list of `{rule,
|
|
|
|
|
words}`: each problem the indexer's re-judgement finds in a manifest it keeps accepted because its digest is
|
|
|
|
|
unchanged (ADR 0579 §1), the same items its verdict writes as warnings; an empty list when none. It is defined in
|
|
|
|
@@ -438,16 +533,25 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
§526 gives the want's field; every artifact of the build is kept on that node, and each artifact in `made` keeps its
|
|
|
|
|
digest as now. A build not kept carries no `kept-on`. [D-9.] How it is checked: unit (builder), a kept build's
|
|
|
|
|
`build.ended` names its node, and the assigner writes it into the want (§526).
|
|
|
|
|
- §672 **The builder's toolchain wait.** (§267, §276, §472, §629) The builder holds an entry while its fingerprint
|
|
|
|
|
names a toolchain version of its language other than the one the builder's newest `toolchain-agreed` of that
|
|
|
|
|
language names (§267). It keeps each wait in its old `state` section `waits`, one key `<module>.<fingerprint>`
|
|
|
|
|
(escaped as a key's name is, §73), capped at 4 MiB, deleted when the wait ends. It says `wait-held` and
|
|
|
|
|
`wait-ended` on its own stream, on `mesh.stream.mesh-delivery-builder.event.wait-held` and `.wait-ended` (G-4's
|
|
|
|
|
table), the body the fields of §629's wait with `step` `building`, `on` `toolchain:<language>@<version>`, `module`
|
|
|
|
|
and `fingerprint`, and `wait-ended` its `how` (`ran` when a `toolchain-agreed` names that version, `released` by
|
|
|
|
|
`builder_release`). `builder_waits` reads the state, and `builder_release` builds the entry with the running build
|
|
|
|
|
module, written in the hand-act log (§276). [D-10.] How it is checked: whole (builder), an entry held until
|
|
|
|
|
`toolchain-agreed` names its version, then built, the wait ended `ran`; one released by hand ended `released`.
|
|
|
|
|
- §672 **The builder's toolchain wait.** (§267, §276, §472, §557, §629, §633) The builder holds an entry while its
|
|
|
|
|
fingerprint names a toolchain version of its language other than the one the builder's newest `toolchain-agreed`
|
|
|
|
|
of that language names (§267).
|
|
|
|
|
- **Its state.** Each wait is kept in the builder's old `state` section `waits`, one key `<module>.<fingerprint>`
|
|
|
|
|
(each token escaped as a key's name is, §73), capped at 4 MiB, deleted when the wait ends.
|
|
|
|
|
- **Its events.** It says `wait-held` and `wait-ended` on its own old `streams` section `waits`, on
|
|
|
|
|
`mesh.stream.mesh-delivery-builder.event.wait-held.<module>.<fingerprint>` and `.wait-ended.<module>.<fingerprint>`,
|
|
|
|
|
kept last per subject, 7 days, 16 MiB; the body the fields of §629's wait with `step` `building`, `on`
|
|
|
|
|
`toolchain:<language>@<version>`, `module` and `fingerprint`, and `wait-ended` its `how` (`ran` when a
|
|
|
|
|
`toolchain-agreed` names that version, `released` by `builder_release`). At its start it says `wait-held` again
|
|
|
|
|
for every key of `waits`. G-4's table reads so.
|
|
|
|
|
- **Its bound.** 60 minutes, its setting `toolchain-wait-minutes`; past it the builder writes the finding
|
|
|
|
|
`toolchain-waits` (scope the builder, id `<module>.<fingerprint>`), cleared when the wait ends.
|
|
|
|
|
- **Its tools.** `builder_waits` reads the state, and `builder_release` builds the entry with the running build
|
|
|
|
|
module, written in the hand-act log (§276).
|
|
|
|
|
|
|
|
|
|
[D-10.] How it is checked: whole (builder, with small settings), an entry held until `toolchain-agreed` names its
|
|
|
|
|
version, then built and ended `ran`; one released by hand ended `released`; one past its bound raises
|
|
|
|
|
`toolchain-waits`; a restart says the open wait again.
|
|
|
|
|
- §673 **`package-published`'s one `dependencies` list holds both kinds.** (§374, §466) The contract's `dependencies`
|
|
|
|
|
in each artifact of `package-published` is §466's `resolved` and `toolchain` in one list: each item `{kind,
|
|
|
|
|
part, version, digest}`, kind 1 for each `resolved` package (its part the package's artifact reference, §504) and
|
|
|
|
@@ -476,10 +580,15 @@ for several build maps is answered once, and the maps' names for it are given in
|
|
|
|
|
`<node>.<module>` whose want or running build names it, written by compare-and-set, capped at 4 MiB. An entry
|
|
|
|
|
object is removed only at the first revision after no kept revision lists it and its `named` set is empty; a
|
|
|
|
|
`wanted` or `running` that moves on removes its `<node>.<module>` from the old fingerprint's set.
|
|
|
|
|
- **Its tool.** `indexer_entries` (class `read`) reads a fingerprint's key, its object's digest and its `named` set.
|
|
|
|
|
- **A node that leaves.** A `running` stays on its stream for ever, so a member a `running` put in the set leaves it
|
|
|
|
|
also when the want of that node and module is removed (`wanted` saying it removed: the node left or the module was
|
|
|
|
|
unplaced), whatever that node last said running.
|
|
|
|
|
- **Its tools.** `indexer_entries` (class `read`) reads a fingerprint's key, its object's digest and its `named` set;
|
|
|
|
|
`indexer_named_drop` (`fingerprint`, `member`, `why`; class `act`, in the hand-act log) removes one member.
|
|
|
|
|
|
|
|
|
|
How it is checked: unit (indexer), an entry no revision lists is answered by `entry` while a want names it and
|
|
|
|
|
removed after the want moves on; a restart reads `named` whole before it removes anything.
|
|
|
|
|
removed after the want moves on; a member whose want is removed leaves the set; `indexer_named_drop` removes one;
|
|
|
|
|
a restart reads `named` whole before it removes anything.
|
|
|
|
|
- §676 **Each entry carries its artifacts' package names.** (§491, §478, §504, §412) At take-in the indexer reads each
|
|
|
|
|
artifact's package name from the revision's own files at the artifact's path (the `module` of its `go.mod` for a Go
|
|
|
|
|
package, the `name` of its `package.json` for an npm package, the manifest's image name for an image) and writes it
|
|
|
|
|