diff --git a/03-DESIGN/01-to-be/47-milestones/G-20-lead-answers.md b/03-DESIGN/01-to-be/47-milestones/G-20-lead-answers.md index f3ebac4a..26864c96 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-20-lead-answers.md +++ b/03-DESIGN/01-to-be/47-milestones/G-20-lead-answers.md @@ -555,3 +555,136 @@ names the principle that settles it, and is cited as "design 47 G A-n". foundation part's kept old sections, and only that, since the trunk validator must accept the new indexer manifest. - **A-147** (A-123, A-132, A-137; principle 3) While a module runs at two fingerprints (a move under way), a recovery act on its kept data is refused, naming both; the caller asks again once the move has ended. +- **A-148** (A-145; principle 7, one release one check) A trunk fault that fails a release's own check rides that + release as its own commit, as fix 1975's distribution test did: the second reader release carries the builder's + by-hand answer fix (an ask is answered as put only after its put; issue 1126, ADR 0668 §1). +- **A-149** (§634, §527, A-120; principles 2 and 7) The node-engine knows its own name at start from its applied + store: the record of the module whose fingerprint is its own `MESH_FINGERPRINT`; the finding writer, discovery and + the vault login use it. Only on a first start with no such record do they wait for the first composing to name it. +- **A-150** (§563, A-107, A-115; principles 1 and 7) restic's `night` process, which dumps, gets a `bus` of its own + (its own broker account, as the recovery module's process has) and says item-started and item-ended and reads the + recovery module's events itself; no local request to the tools runtime, and the backup does not move into it. +- **A-151** (§465, ADR 0614 §2; principle 7) The three build modules `require` the provision `artifact-store` to read a + group member's build, with a `binds` file as go-package-registry's (`at`, `serves.port`), and read the blob by the + store's own path `:/v2///blobs/`; they never write into it, so ADR 0614 §2 + holds, and their manifest tests assert the read. +- **A-152** (§472, §492; principles 3 and 7) The toolchain's `digest` is the sha256 of the toolchain program the build + module runs (the `go` or `node` it finds), computed at its start and again when the toolchain's version changes; no + field is added to the provision. +- **A-153** (§559, E §1; principles 7 and 8) The tool runner resolves a `deliver: new` subscription's key + `.` to its subjects with mesh-sdk's `buscompose.EventSubjects`, the one rule from an event name to + its subjects (a seat's event subject or the module's); a pattern with a wildcard is refused with `{error}`. +- **A-154** (design 46 approval mark §4, §16, §19; principles 7 and 8) The approval mark's three findings take scope + `machine` and the id `.`, `.` or `.approvals`, escaped as a key's name, with the + subject of the tool runner on that machine, as the runner's first-view findings already do. +- **A-155** (§561, §563, §302, A-77; principles 1, 2 and 3) restic's put-off wait for a restore is a bound key in a + state of its own on the bus, bounded by the setting `put-off-bound`: the key is the put-off record `backed-up` reads, + its expiry raises `backup-waits` and ends the wait, so the night never holds its lock without a bound and no file + or timer keeps it. BKP7 is not built: §555 gives `restore` its class's default with no own-item limit. +- **A-156** (§610, A-82, design 51 *The move*; principle 7) Once distribution's `callers` list goes, the windows' + driver takes "every build module" as the modules that claim a build seat (`node-build-*`) in the catalog half it + follows, the one source A-82 gives; the holder's own per-verb `Allowed` checks go with the list, since §610's class + defaults are applied where the call is read, and the refusal of an unproven caller is that reader's. +- **A-157** (design 46 approval mark §16, §19, ADR 0668 §1, A-77; principles 1 and 3) Each try of `warranted` is a + `DoKept`; past its bound the call is made again when the hand-act seat's holder is heard again (the seat-holders + view the runner follows) and at each start; `call-unanswered` is raised on the expiry of a five-minute bound key per + ask, not a timer. A failed read or write of `approvals` is made again at the next marked call and at the next + membership change the runner hears. +- **A-158** (design 46 approval mark §16, §677; principle 8) A marked call's answer is `{answer, approval}`: the tool's + own answer and the line naming the approval, the form a process holder's `gated-ended` has, so a caller reads one + form from both gates. A-157's bound key lives in the runner's state `bound` as `.unanswered.`. +- **A-159** (§466, §472; principles 3 and 7) A build's `resolved{package, version, digest}` names what was used: its + `version` is the commit the ask names, and its `digest` the sha256 of what was laid (the Go module cache zip, the + npm tarball), or the member build's digest when it was laid from `builds`. +- **A-160** (§64, §190, §321, A-85, A-93; principle 7) A run's candidate is keyed by its run id `run-` from the + runner's `run-started`, beside `try-`; each member {module, commit, branch} maps to its repository by the + registrations and to the branch's revision view as its trunk; its manifests and fingerprints come from the same + branch take-in the indexer computes for any commit (its files read through the seat `git`), so no checker preview + is heard. +- **A-161** (§522, §81, §170; principle 1) An event carries what its hearers need to say it: `recovery-merged` gains + `module` and `branch`, and a forge-made record's `record-opened` gains `repository`, `pull`, `commit` and `branch`, + in their contracts and from their emitters; the teller makes no call per message. +- **A-162** (amends A-100; §575, A-94, ADR 0596; principle 1) The builder's `build.ended` is said for every end of a + build, carrying `outcome` (done or failed) and, when failed, `error`; the assigner's hold says "failed: " + from it and "is being built" while no `build.ended` of that fingerprint is heard. The assigner never reads the + builder's `builds` bucket; its read there (put.go:85, the manifest's `reads`) goes. +- **A-163** (§543, §544; principles 7 and 8) The asker in an ask's accept subject is the asking seat's own name + (`mesh-pipeline-runner`, `mesh-catalog`, `mesh-wants`, `mesh-builds`, `mesh-delivery-checker`), not a nickname, so + steprun checks it against the callers the build seat's definition lists, read from the seat list; no table of its + own and no name map. A body's kind is the word the seat definition gives; a queue keeps its own name. +- **A-164** (§468, §76, §495, A-115; principles 4 and 7) The runner's process writes each durable consumer's oldest + unacknowledged age into a state of the runner's own when it changes; the bundle's `runner_health` reads that state, + its own module's, and asks no seat verb of itself; tools stay the bundle's (A-115). +- **A-165** (§610, A-156; principles 3 and 7) The class defaults of §610 are applied where a seat's verb is answered: + mesh-sdk's seat server (`conn.AnswerSeat`) and the tool runner's `serveSeats` read `seatdef.EffectiveCallers` and + refuse a caller outside them, the unproven one included, before the holder runs; a holder keeps no caller check of + its own. +- **A-166** (A-164, §76, §495; principles 1 and 7) The runner keeps a state `consumers` (history 1, a key per + consumer) holding the time its oldest unacknowledged message was delivered, written when a message is delivered or + acknowledged; `runner_health` works the age out as now minus that time when it is read, so nothing is read on a + timer. +- **A-167** (§354, §63, §22, §64, §357, §298; principles 1, 2, 3 and 7) For the assigner's composition step (AS5): its + `run` builds the node-engine's composer (`mesh-compose`) at the fingerprint the node-engine runs; each machine's + input is asked of that node's engine by `compose-candidate`; the machines are the nodes the branch's revision places + the module on; a node is asleep when the watchman's `machine-away` is heard for it; `mesh-compose` reading + `MESH_RUN_INPUT` and answering the run's output is the node-engine's, a row of its own. An entry held for want of a + provider (AS14) carries a field `held` naming the candidates, never only a log line. A revert (AS17) is a want that + goes back to an earlier fingerprint, which the assigner computes itself; a kept data's `form` is read from the + catalog entry's kept declarations (`catalogue.KeptDeclarations`). AS14's named seat and contribution edge, and + AS17's ask of the operator, go to a design line. +- **A-168** (E §33, design 46 approval mark §5; principle 3) For a marked wait on a module the runner does not serve, + the marks are the union of the newest entry of every followed branch; where the runner serves the module, its + served entry is added to that union. A mark is never lost. +- **A-169** (§579; principles 2 and 7) A pins state keys a revision by the revision object's own name (the assigner's + `trunk.`, the indexer's `.`), value `{records, missing?}`, and holds two more keys in the same + form in every holder of pins: `made`, written once by create-only when the state is first used, and + `pins-stated`, the `at` of the applied event; pins count only once a `pins-stated` later than `made` is applied. +- **A-170** (§600, §481, §415, A-163; principles 7 and 8) Every ask to a build seat rides `accept..`; + its kind is in its body only, as §600 says. A build seat definition's `stream` names only the queue, and the + generated accept subjects follow; the kind in the subject goes. §543's main subject takes `build` and `run` as + written, the checker's asks riding it until it goes. +- **A-171** (§579, A-169; principles 2 and 8) The `pinned` event's `catalog` entries name their branch: each is + `{branch, revision}`, in the mesh-delivery seat's definition and from the gate that says it, so a holder keys the + pin `.` from what the event says. +- **A-172** (§653, §431, A-161; principles 1 and 7) With the Approve per merge gone, the teller's merge-ask path goes + whole (its reads of the gate's `asks`, its handlers and their tests); the teller keeps `answers` and `answered` for + the assigner's asks only. A view's answer reaches it by the view's event, as §431 says, never by reading the + view's state. The gate fills `recovery-merged`'s `branch` from the branch it merged into and its `module` from the + catalog half's registrations; while no path of the gate opens a forge-made record, the teller says none. +- **A-173** (§507, §512, §532, A-103; principle 7) The view derives each watched branch's source on its own: the + source row and `delivered` per branch, a repository's reach from the source of the first branch of its + registration (before the first registrations, the branches `source` answers), and `view_tiers` with no revision + answering per branch; no branch is named in its code. +- **A-174** (§64, §190, A-160, A-93; principles 2 and 7) The indexer keeps a state `runs` (key `run-`, value the + members and the modules whose pipeline ended), written on `run-started` and on each of the run's `pipeline-ended`, + removed with the candidate, so a restart loses nothing. A member on a branch its registration does not watch takes + the trunk's revision view as the base of its take-in; one on a watched branch takes that branch's. +- **A-175** (§512, §431, A-43, A-172; principles 1 and 7) The teller says its `answers` as a plain views family + `views.answers`, and the view says its own `answers` the same way; each follows the other's by mesh-sdk's + `ProcessReader.Follow` (first view through the owner's tool, then its views family). That is the "event" A-172 and + §431 mean; no own follower and no module-event adopt are added. +- **A-176** (A-166, §579, §76; principle 7; code shared between modules is in mesh-sdk) A process writes its durable + consumers' facts (stream, name, acknowledged sequence, pending, last event applied and its `at`, and when its oldest + unacknowledged message was delivered) into its module's own state `consumers` (history 1, a key per consumer) through + one mesh-sdk helper, after each message it applies; the runner and the indexer use it, and their tools read that + state. +- **A-177** (design 46 approval mark §4; principle 7) mesh-sdk's compiled `catalogue.Verb` gains `NeedsApproval`, + copied by `SeatsFromDefinitions` from the definition, so the validator and every reader of the seat list read a + verb's mark from one place. +- **A-178** (A-175, A-43; principles 7 and 8) The view says its `answers` as other owners say theirs: a read tool + `view_read_answers` (mesh-sdk `views.ReadTool`, in the view's tools bundle, the teller among its callers) and a + marks state `view-marks` (history 1), as the assigner and the indexer have; the teller's side is the same, with + `teller_read_answers` and `teller-marks`. +- **A-179** (refines A-165; §610, §336; principles 3 and 7) Where a seat's verb is answered, an unproven caller is + refused, and so is every caller when the verb's effective callers are empty; a proven caller is taken as among + them, since the grants part composes a verb's call subject only for the callers its effective list names, so the + bus holds the rest out. `seatdef.DefaultCallers` follows §610 (act, warrant and accept: operator, sessions and + invokers). +- **A-180** (§64, §420, A-160, A-174; principles 1 and 7) The runner places a run's pipelines when it hears the + catalog seat's `catalog-revision` for the candidate `run-` (a candidate's revision, its subject naming it), + reading the candidate's entries and fingerprints through the seat's `revision` verb with the candidate's group; + `` is a random 12-hex id the runner makes, so two runs of one commit are two pipelines. +- **A-181** (amends A-100 and A-162; §556; principles 1 and 2) The builder's `build.ended` stream keeps the last + message per subject (one per fingerprint), and the assigner reads it whole at its start as §556 reads a kept + stream, then hears it; so what was built, and a failed build's error, survive its restart and it reads no builder + bucket. `assigner_put`'s fingerprint-prefix form goes: a put names the whole fingerprint. diff --git a/03-DESIGN/01-to-be/47-milestones/G-22-lead-answers-2.md b/03-DESIGN/01-to-be/47-milestones/G-22-lead-answers-2.md new file mode 100644 index 00000000..2853dcf1 --- /dev/null +++ b/03-DESIGN/01-to-be/47-milestones/G-22-lead-answers-2.md @@ -0,0 +1,355 @@ +--- +layer: to-be +status: in-progress +design: 47 +milestone: G +updated: 2026-11-12 +decisions: + - "ADR 0667" +--- +# 47, milestone G — the lead's answers to develop's questions, continued + +The answers of [G-20](G-20-lead-answers.md) go on here, since that part reached its size bound: each one line, naming +the principle that settles it, cited as "design 47 G A-n". + +- **A-182** (§31, §350, §119; principles 2 and 7) A superseded step's ask is dropped where it stands: a taken step + keeps the node `ask-taken` named, and the drop is asked of that node's holder of the build seat; an untaken ask's drop + is asked of any holder, which records it in the seat's shared drop key, so no holder takes it. Steps on `mesh-builds` + and `mesh-wants`, whose seats serve no `drop`, are only ended superseded. +- **A-183** (design 46 approval mark §4, §23; principles 3 and 7) A manifest that marks a verb nothing enforces is + refused by the validator wherever it runs, as every rule's problem is; the indexer's "set aside to wait" is only its + reading of a field it does not yet know (the reader edge of §23), so no new waiting verdict is added. +- **A-184** (clarifies A-170; §543; principle 3) Until main's subject goes, it also takes the checker's `check` and + `recheck` asks, so no ask that runs today is refused by G; a queue is only `delivery`, `check` or `recheck`, and + steprun's `AskKinds` lists no `step` queue. +- **A-185** (A-180; principle 7) The catalog client (`meshcatalogclient`'s catalog follower), which already hears every + `catalog-revision`, hands a candidate's revision it does not keep to a hook its caller sets; the runner sets it to + place a run's pipelines. mesh-sdk's event hub keeps its one handler per pattern. +- **A-186** (A-179; principles 3 and 7) `conn.AnswerSeat` takes the seat's definition from its caller, which reads it + from the seat list it already follows; a verb the definition does not hold, or a definition not yet read, is + refused for every caller and said so, so a holder answers only once its seat list is read. +- **A-187** (A-176, §76; principle 3) The consumer ledger keeps a message's first delivery time: a message delivered + again (asked again, or after a restart) keeps the time it was first delivered, so a message that never settles + grows old and §76's check fires for it. +- **A-188** (A-172, §170, §151; principles 3 and 7) A take-in writes its entries (each with its module) into the + gate's record, so `recovery-merged`'s `module` is filled from the record; no forge-made open path is built, since + G ends the mark (§151). A record of the old milestone form, made before G, says no branch. +- **A-189** (§376, §374, A-181; principles 1, 2 and 7) At its start the assigner reads whole, as A-181 reads + `build.ended`, the streams of its own `version-delivered` and of the catalog seat's `version-released`, so it says + each version delivered once and knows the released ones. A dependent whose want changes fingerprint waits, by an + edge of kind 2, 4 or 6, for its dependency's newest released version on the dependent's branch not yet said + delivered; on a branch where no version is released there is no wait. +- **A-190** (ADR 0668 §1, §2; principles 3 and 7) A kept call is kept only while what it serves still stands; for the + indexer's four: `messageVia` while the commit's take-in is still pending, `stepsVia` while the candidate is held, + `sourceVia` while the branch is watched, `versionsVia` while the module is in that branch's newest view. Once + that ends, the call stops and is not said unanswered. `pin-missing` takes scope `module`, id + `mesh-delivery-indexer.pin.`. +- **A-191** (§33, §540; principle 3) A `pipeline-failed` finding whose commit no pull request merged, or whose `pull` + read fails, is written with no `owner` (so it reaches the operator at once) and says why in its explanation; a + failed read is said and the owner is written at the next step end of that commit. +- **A-192** (ADR 0596, ADR 0603 §8, §499, §541, §520; principles 1 and 7) The builder says `wait-held` and `wait-ended` + for a key queued behind a package, in the one wait form with its `part`, and the watchman times it from those; its + reads of the builder's `builds`, the node-engine's `have` and `mesh-host.health` go, replaced by the node-engine's + `running` (with `healthy`) and its wait events. +- **A-193** (§64, §73, §373, §420, A-180, A-185; principles 2, 3 and 7) For a run: `run` writes each member's + pipeline at once (key `..`, running, no steps, `Run` its id), and the candidate's + revision places its steps by compare-and-set; `pipeline-started` is said when the steps are placed, with the + fingerprint and the candidate's revision; `run-started`'s subject names one member's module, branch and commit, or + for several the first member's module and branch and `run-`; a member naming no branch is refused. The hook is + called once per candidate revision at the catalog follower's one subscription, whatever branches are followed, so + a runner following none still hears it. As §373 says, a run builds each member and its dependents: the dependents' + pipelines come from the candidate's entries whose fingerprints the members change. +- **A-194** (principle 4; §64) The indexer's state `runs` and its run candidates get tools as every kept thing does: + `indexer_runs` reads them and `indexer_run_drop` drops one by hand (its hand act written first); a run id is + `run-` and the runner's random 12-hex id, which the indexer's wider pattern accepts. +- **A-195** (§65, §266, §276, §534, §19, A-77, A-149; principles 2, 3 and 7) The runner's `pipeline` wait is a field on + each held pipeline's record (`held`: since, and the fingerprint awaited), no new state. A take-in changes the runner + when its own module's entry (its own name, A-149) gets a new fingerprint; every pipeline started after that take-in + is held. The pipelines' records are on the bus, so whichever runner holds the seat when the wait ends starts them: + the wait ends on the node-engine seat's `running` for the runner's module at the awaited fingerprint with `healthy` + true, on any node; its 30 minutes are a bound key, whose expiry starts the held pipelines and writes a finding. +- **A-196** (§553 with A-91; principle 7; the operator, 2026-11-09: merges need no approval) An empty status makes a + step `optional`, as §553 says, except the approval step: a policy that names no approval status asks the operator + nothing, as A-91 says; only a policy that names approval asks for it. +- **A-197** (ADR 0596, A-192, A-149; principles 1, 3 and 7) What only the node-engine knows of itself it raises as its + own findings through its finding writer: a have's failed or removed phase and its detail, its kept-data findings, + an unreachable tunnel, and every part of its health report (machine network, rewritten network, machine units, + relogin needed, directory used as found, node account fallback). The watchman stops reading `node-engine.have` and + `mesh-host.health` and raising those; it keeps only what it sees across parts. +- **A-198** (§677; principle 7; shared code is in mesh-sdk) The act's form, `ActDigest` and the ask's form move from + `operatorchannelclient` into mesh-sdk's `go/operatorask`, which the client re-exports, so the seat server in + `go/process` holds the gate with no import of mesh-contracts and no cycle between the two. +- **A-199** (A-185, A-193; principle 7) mesh-sdk's `ProcessReader` gains `AdoptEvent(seat, event, hear)`, a seat event + heard on the one subscription with no picture, made at once if no follower made it; meshcatalogclient's + `WireCandidatesProcess` adopts `catalog-revision` through it and hands each candidate revision to the hook. +- **A-200** (§502, A-188; principles 7 and 8) A taken-in delivery record's `milestone` is `.`, + so the watchman ties a `record-opened` to the `take-in.taken` of that branch and source revision by its milestone; + `record-opened` gains nothing, and a record is covered only by what is late for its own revision's entries. +- **A-201** (§189, §190, A-160, A-174; principle 7) The assigner keeps a candidate's assignment graph per run (key + `run-`), made when the candidate's revision is heard and dropped on that run's last `pipeline-ended`, as the + indexer keeps the candidate; the gate's `heads-replaced` drops nothing in the assigner. +- **A-202** (§31; principles 2 and 7) A pipeline's record and `pipeline-started` say their cause: an optional + `published` {artifact, version} set when a package's publish started it; a newer publish of the same artifact on + the same branch supersedes the running pipelines whose `published` names that artifact at an older version. +- **A-203** (design 46 approval mark §6, G §195, §424; principles 1, 7 and 8) The withheld path's forms: the tool + runner's announcement carries `fingerprint` (its own `MESH_FINGERPRINT`) beside `capabilities`; the node's record + gains `runner-capabilities` and `runner-fingerprint`, its merge into `capabilities` staying for placement; the + assignment half's per-node item gains `readings` and `fingerprint`, its digest over all of it, read from the node + record the assigner holds; the grants part follows the assignment half by `mesh-wants`' `revision` and its + `assignment-revision` event; its user list carries `withheld: [{module, subject, why}]`, and the seat `mesh-grants`' + verb `withheld` takes `{node}` and answers `{node, modules: [{module, subjects: [{subject, why}]}]}`. +- **A-204** (§498; principle 2) The assigner keeps which put waits it said in its own state on the bus, so a put + that ends while the assigner is stopped gets its `wait-ended` at the next start. +- **A-205** (§441, §195; principle 7) `grants-for` reads its candidate's catalog half through the catalog seat's + `revision`: for a run, with `group` `run-` (the candidate's newest); for a source revision, with `branch` and a + new optional argument `source`, answering the branch's revision taken in from that source revision. It answers the + permissions the composed memberships gain and lose with the candidate's entries in place of the branch's newest. +- **A-206** (A-195, §65, §534, A-181; principles 3, 4 and 8) The runner's held pipelines are released by hand through + a seat verb `release` of `mesh-pipeline-runner` (class act, its hand act written first), beside `start` and + `ask-again`, its tool `runner_release`; the bound's expiry writes the finding `pipeline-waits` (scope `module`, id + `..`); the wait's `on` gains the value `runner version`; its `clock-from` is the `build.ended` + of the awaited fingerprint, heard as A-181 says. +- **A-207** (§86, §81, §415, §71, §275, §335, §441; principles 1, 2 and 7) The runner keeps a state `recoveries` + (commit to why) written when it hears the mesh-delivery seat's `recovery-merged`, read at a pipeline's start and + resume; a recovery heard after its pipeline started asks nothing again. `widens` is computed from two reads: the + catalog seat's `revision` of the candidate against the branch's newest (the serving parts' entries and fingerprints, + found by holder from the seat list; the acting rules `step`, `on` and `bound` and the credentials the entries + declare), and the grants part's `grants-for` (the permissions); no other verb. +- **A-208** (ADR 0656, §558, §605, §16, §293, §600, §18, §104, §44-§46, A-93, A-190; principle 7) The indexer writes a + catalog entry's edges of kinds 1 to 6, as the catalog graph is its own; the long form of `invokes` is read by the + second reader release's `InvokeFields`, which G merges. Every watched branch's take-in uses the trunk's machinery, + per branch: its own pending revision (holding only that branch) and its own groups. `stepsVia` is open while the + entry's fingerprint is still in the branch's newest revision; `messageVia` while a pending entry names the merge or + a take-in of that commit runs. +- **A-209** (design 46 approval mark §13, §677, §73; principles 3 and 7) A digest in a key is escaped with mesh-sdk's + `keys.EscapeName`, the one escape form for every name in a key, in both gates: `.act.`. The + kind (a test's in-memory state accepting a key the bus refuses) is fixed where it lives: mesh-sdk's in-memory state + for tests refuses every key the bus would. +- **A-210** (§7, §428, A-126, A-131, ADR 0596; principles 3 and 7) A module that calls another module's tool or hears + its module events finds that module as the holder of the seat it holds, with `seatlist.HolderOf`, when it calls, + asking again after a failure and never stopping its start for it; a read of another module's bucket goes (each by + its own row). A tool's callers list names no module: it takes the holders of the seats `node-tool-runner` and + `mesh-healers` from the seat list when a call is checked, beside `operator`. +- **A-211** (A-204; principles 2 and 7) The assigner's said put waits live in a state of their own, `put-waits` + (history 1, key `.`, value the wait's id and the put), so no form is shared with §706's waits and the + record outlives a supersede. +- **A-212** (§47, §432, A-208; principle 8) An edge of kind 2 comes from a `needs` reference to another module's + artifact: that is what an artifact "fetches by reference at its start", so the referenced artifact is published + before the referring one delivers. Kind 5 goes to a design line (which acting steps give it, and between what). +- **A-213** (corrects A-86; §16, §354, §206) The indexer does ask node-build-go's `run` for its validation of a + revision before its take-in, as §16 says; A-86 holds only for `KeepInput`, which the indexer's `input` verb calls + for a run on request's asker. The run's input and job, what holds the pending revision meanwhile, and how a non-trunk + branch's pending revision and groups are made go to design lines. +- **A-214** (§366, §623; principle 7) `show` and `kept` read each store's fill through the bundle's state call + `mesh/state.info` (§623), as the forge module's read tool does; the runner's process writes nothing for it. + `pipeline-failed` takes scope `merge`, id the commit. +- **A-215** (§71, §275, §335, A-207; principles 3 and 7) For `widens`, the pipeline's own revision (the candidate) is + compared with the branch's newest revision: an acting rule widens when an entry's `Acts` gains a rule, or a rule's + `on` now names more, or its `bound` is longer; a credential widens when an entry's manifest names an own secret or + provision of a credential it did not name before; permissions come from `grants-for`. +- **A-216** (amends A-181; principles 2 and 7) The builder's `build.ended` stream, kept last per subject, has no age + bound, only a cap in bytes: one end per fingerprint is the record of what was built, so a module unchanged for any + time is still known built after a restart. +- **A-217** (§298, §300, A-167, A-132; principles 2 and 7) A want reverts when its fingerprint is one the module had + in an earlier assignment graph revision than the one it now runs from, by the revisions' own numbers; the running + manifest is the catalog entry of the fingerprint the node-engine seat's `running` names, read through the catalog + seat's `entry`, and `FormChanges` compares it with the want's entry. +- **A-218** (A-206, §696; principle 3) `pipeline-waits` is cleared when the node-engine seat's `running` says the + awaited runner fingerprint healthy; A-206's `runner version` holds over §696's wording. +- **A-219** (refines A-198; §677; principle 7, one form for each thing) Only `Act` and `ActDigest` move into mesh-sdk's + `go/operatorask`; the ask's types stay the generated seat contract's. The gate in `go/process` takes the operator + channel's calls (ask, read the warrant, record) as an interface its caller passes, which `operatorchannelclient` + implements over the generated types, so no form is copied and no import cycle arises. The seat client's + `wait: held` lives with `process.Conn`'s call, as there is no `go/seats`. +- **A-220** (§71, §441, A-167, A-207, A-215; principle 7) The serving parts `widens` compares are the holders of the + seats `mesh-pipeline-runner` (the runner), `mesh-catalog` (step detection), each step's own seat (the build seats + that run lint and tests) and `node-engine` (the composer, A-167), found by `seatlist.HolderOf`. +- **A-221** (§509, A-208; principle 8, one word per thing) On every forge message `branch` names the watched branch + the move changed, on `merged` as on `pushed`; a merged pull request's own branch is kept as `head` (a group is + known by its head branch); `pushed`'s head before is `before`. +- **A-222** (A-193, A-199, §350, A-77; principles 2 and 3) An adopted event whose handler fails is asked again by + the bus, not acknowledged; at its start the runner reads, for each run pipeline with no steps yet, its candidate's + revision through `revision`, so a placing lost while it was down is taken up. A run's rerun asks with the + candidate's catalog half. An unanswered drop is said `call-unanswered` on a five-minute bound key's expiry. +- **A-223** (corrects A-221; principle 8) A merged pull request's own branch is `head-branch`; `head` stays the head + commit, as everywhere in the forge messages. +- **A-224** (§677, A-219; principle 7; code shared between modules is in mesh-sdk) The approval gate is one package, + mesh-sdk `go/approval`: the tool runner's gate (`node-tools` `internal/approval`) moves there and both the tool + runner and `go/process`'s seat server use it, each passing the operator channel as an interface (A-219); no second + gate is written. +- **A-225** (A-173, §532; principles 2 and 7) The view keeps each repository's reach in its own state on the bus, so a + restart does not lose it; its history is the source revisions heard since its start, re-asked through `source` on + each `source-moved`, laid over the reach it kept. +- **A-226** (A-167, §354, §64, §63, A-174; principles 2 and 7) The composition step asks each node's + `compose-candidate` with the key the step's pipeline names: a run's candidate `run-`, or for a branch pipeline + the branch's revision `.`, which the node-engine reads as it reads a candidate. It runs + `mesh-compose` once per node-engine fingerprint among the machines (the change's build where the change alters the + node-engine, §63), the program read from that fingerprint's catalog entry through `entry`, each run's request + joining the inputs of the machines on that fingerprint. +- **A-227** (withdraws A-221 and A-223; §714, §715) As design line §714 says, a merged message gains `base`, the + watched branch it landed on; `branch` stays the pull request's branch and `head` its head commit, as today; + `pushed` keeps `branch` for the branch pushed and gains `before`. +- **A-228** (A-219, A-224; principle 7) Everything the gate reads beyond itself crosses into mesh-sdk `go/approval` as + an interface in the gate's own terms, its caller translating from the generated contracts: the catalog's entries + (module, fingerprint, serves, manifest), a finding writer (raise and clear by kind and id), the seat holders (a + holder function), and the operator channel (ask, record, and claim with the warrant and the act). The gate's own + kept form `Kept` moves into `go/approval`, which `operatorchannelclient` re-exports. +- **A-229** (§708, §709; principle 7) As §709 says, a catalog entry's `requires` names every requirement as + `catalogue.Manifest.Wants` lists them, optional ones included; a reader that means "required, not optionally" (the + module graph's `Requirers`, the assigner's halves) tells the optional ones apart by the entry's manifest + (`IsOptional`). +- **A-230** (§554, §565, A-124; principle 7) A restore point's `Point` gains `names`, the bus names it took, one per + bus object as `Aside`'s; the recovery module fills it when it takes a point, and the grants part reads + `points[].names` and `asides[].names` from `kept-points`. +- **A-231** (§544, §601, A-163, A-170; principles 3 and 7) An asker names the queue it asks in its manifest's `invokes` + as `seat:.accept.`, read by one mesh-sdk `catalogue` helper that the validator, the indexer's kind-6 + edge and the grants part share; every asker of a build seat gains that entry in G, so the named workers stand from + G's delivery and the purge finds nothing to remove. +- **A-232** (§712 with §600, A-163, A-170; principle 7) The validation run rides `accept.check.` with its kind + `run` in the body and the asker the indexer's seat name `mesh-catalog`, as every ask does; its id is the usual + form (`NewID`), and the revision's sequence and try number are kept in the pending value's `validation`. §712's + subject and id are read so. +- **A-233** (A-181, A-189; principle 7) mesh-sdk's `HearStream` gains a form that reads an age-kept stream whole from + its first message by an ordered consumer at every start, then follows the durable; the grants part grants that + ordered consumer on every heard seat kept stream, as it grants `STREAM.INFO`, with no manifest word. +- **A-234** (§711, ADR 0656 §6; principle 2) The indexer fills each catalog revision's `definitions` (the seat + definitions it was taken in with, by digest) when it keeps the revision, and the `acts` fill reads from them; until + then reading the trunk's from its `seat-definitions` state stands. +- **A-235** (A-201, A-174, §190, RN9; principles 1 and 7) The runner says `group-ended` with group `run-` once every + pipeline it placed for the run has ended, as it says a group's end; the assigner drops its candidate graph on it, and + the indexer drops the run's candidate on it in place of counting members itself. The kept object's key stays the + seat's form `candidate..` with group `run-`. +- **A-236** (§509, §714, §715, §11, A-227; principles 2 and 7) A `pushed` message's new head is `head`; the bridge + keeps each watched branch's last head written in its own state `heads` (key `branch...`), `before` read from it and its start read comparing with it; `pushed` carries the same take-in inputs as + `merged`. For §715 the mesh-delivery seat's `groups` member gains `base` in the contract, which the gate fills and + the bridge reads. +- **A-237** (§712, §354, ADR 0666 §16, A-139; principle 7) A run's input is any size: the indexer keeps it in its state + `inputs` with the state's `-objects` store holding a large value (mesh-sdk's `stateobjects`), and serves it through + its `input` verb answered in chunks (`buscalls.SeatChunks`, a verb marked `chunks`); `RunInputBound` goes, and the + holder takes the input by that verb. +- **A-238** (§712; principle 7) A run ask may name no head: `RunJob.check` takes an empty `Heads` when the program + is named, and the holder lays an empty `MESH_RUN_HEADS`; the validation's program is built from the indexer's + entry alone. +- **A-239** (design 46 approval mark §6, H-21; principles 3 and 7) The node-engine's `composition` answer gains + `withheld` [{subject, why}] (the module's entry of the grants part's `withheld` for this node) and + `withheld-unknown`, the words "withheld unknown: the grants part does not answer" when the verb fails; its + manifest's `uses` gains `mesh-grants` beside the `invokes` of `seat:mesh-grants.withheld` H-21 added. +- **A-240** (§354, ADR 0596; principle 1) The assigner waits on its composition run's answer by hearing the build + seat's `step-ended` for that ask, never by reading the seat's step state. +- **A-241** (§712, A-234; principle 3) The validation's `seats` are the branch's revision's seat definitions (A-234) + with the merges' changed definitions laid over them, so a revision that touches no definition is still judged + against the whole seat list. +- **A-242** (§512, §186, §376, §378; principles 1, 2 and 7) The assigner's `difference` fills `Tiers` and each + change's `after` (the kind of edge that orders it), computed in its compare; the view orders nothing itself. A + `view_tiers` call for a source revision compares the kept assignment revision whose catalog for that branch is that + source revision with the revision kept before it. The view keeps a state `waits` (key owner, step, node, module) + written by its process from every part's `wait-held` and `wait-ended` it consumes, read by its own read tool. +- **A-243** (corrects A-226's joining; A-237, A-238; principle 7) The composition step runs one request per machine, + each carrying that machine's input; no inputs are joined. A-237 holds for every run's input (the assigner's and + `mesh-wants`' `input` too): any size, kept with an `-objects` store, answered in chunks. The composition run names + no head (A-238); its program is the node-engine fingerprint's entry (repository, commit, directory) with the + composer's package. +- **A-244** (§677, A-186, A-219; principles 7 and 8) `wait: held` travels as a bus header on the request, never as an + argument, so no verb's input and no act's digest changes; the holder's held answer is a reply field `held` + {asked, call} beside result, error and node. `process.Conn`'s seat call sends the header on every seat call and + waits for `gated-ended` only when the reply says `held`. A process holder applies the seat definition's + `needs-approval` alone (the definition `AnswerSeat` is given); it reads no catalog entry. +- **A-245** (§298, §368; principle 7) §298's order edges are held under the assigner's rule 7, as its acting waits + are; a change of the assigner's state forms bumps its manifest's version once, in the commit that changes them. +- **A-246** (§376, §498, A-211; principles 2 and 4) A dependent's delivery wait is kept in a state of its own, + `delivery-waits` (key the module, value the `wait-held` said), read by `assigner_waits` beside the others; + `assigner_release` {module, step: delivery} writes the hand-act log first and ends the wait `released`. +- **A-247** (§713, A-232; principles 1, 2 and 7) The pending value's `validation` gains `accepted` (the seq it was + accepted at), so a revision held for another indexer is never asked again; `validation` sits on the newest pending + value of the revision alone. The answer is read from the `step-ended` event's own output and output object, never + through the build seat's `steps`; the ask is put through the delivery SDK's `buildrun.Asker`. +- **A-248** (A-163, A-232; principle 8) `buildrun.Asker` gains the asker its subject names (the caller's seat name, + A-163), empty meaning the builder until the asker rename at the join; the ask's own `Asker` field is left as it is. +- **A-249** (A-237; principles 7 and 8) A bundle takes a chunked seat answer through its ordinary seat call: the tool + runner receives the chunks with `buscalls.SeatChunks` and hands the bundle the whole answer, so no bundle receives + chunks itself. mesh-build-go's `inputOf` calls the mesh-catalog seat's `input` that way and decodes that verb's + own answer form. +- **A-250** (§376; principles 1, 2 and 4) `assigner_delivered_again` writes the hand-act log, then an ask in the + assigner's own state `delivered-again` (key the module, value {version, by, why}) and answers "asked". The + assigner's process hears that write on its own state at once, says `version-delivered` again when every present + placing machine runs the version healthy and deletes the ask, else keeps it with its reason, read by + `assigner_waits`. +- **A-251** (§17, §383, §437; principle 8) The finding `branch-unprotected` has scope `merge`, id the owner, + repository and branch escaped as one key name (`~~`), severity warning, and that scope + and id as its subject. +- **A-252** (§354, A-167, A-174, A-226, A-243; principles 1, 2 and 7) The composition step's machines are the nodes + whose placement of the module names the step's branch in the seat's assignments (no branch read as the trunk); a + run on request on an unwatched branch takes the nodes placing the module on the trunk. Each request's cases and seats + come from the step's catalog revision through mesh-catalog's `revision` (each entry's manifest digest and verdict, + its `definitions`), depth compose, the one machine, one case `change`. A machine's node-engine build is what the + assigner keeps from the node-engine seat's own events, never read from the node-engine's bucket; where the step's + revision's node-engine entry differs from the trunk's, that build serves every machine. One run ask per machine. +- **A-253** (A-249; principle 8) The tool runner hands a bundle a chunked answer as the verb's own answer with the + whole file added as the member `file` (base64). +- **A-254** (§712, §354, A-240, A-247, ADR 0596; principles 1, 2 and 7) A build seat's `step-ended` of a run carries + the run's answer (its standard output's last line): inline as `output` up to the event bound, else as + `output-object`, the name of an object the build seat keeps, read through the seat's verb `output` answered in + chunks. Every build seat (`node-build-go`, `node-build-image`, `node-build-node`) says it the same way, from the + shared step runner; no asker reads the seat's step state. +- **A-255** (§677, A-77, A-244; principles 1, 7 and 8) The header is `x-wait: held`. A process holder's + `gate-unanswered` is a bound key with its time to live in the `approvals` state, as the tool runner's `bound` is, + never a clock wait. A process holder's act names no node, so two instances of the holder raise one ask. +- **A-256** (corrects A-251's separator; principle 8) The finding's id is the owner, repository and branch joined by + `/` and escaped as one key name (`keys.EscapeName`); a key holds no `~`. +- **A-257** (A-249, A-253, A-254; principles 7 and 8) The tool runner sends a bundle's answer of a verb marked + `chunks` in chunks, from the whole file the bundle answers in its member `file`, the mirror of A-249: no bundle + sends chunks itself. +- **A-258** (§298, A-210; principles 1 and 8) §298's "bus module" is the holder of the seat `mesh-broker`, and its + "`node-backup` holder" the holder of the seat `node-backup`, each read from the seat list as every holder is: the + assigner names no module. +- **A-259** (§298, A-245, §266, §268; principle 7) §298's three order edges are acting waits of the assigner, kept + in its state `waits` under `order...` beside `acting.`, said as `wait-held` when the want is + held and `wait-ended` (ran, released, replaced) when it moves, with the step `placing`; `assigner_waits` reads + them and `assigner_release` releases them as it does the acting waits. No new mechanism. +- **A-260** (§298, ADR 0633 §1, A-181; principles 1 and 7) For §298's third edge the trunk's head is the highest + source revision (`Src`) among the trunk branch's module values the assigner holds; the wait ends when a + `take-in.taken` of the trunk branch with `source` at or above it is heard. The assigner consumes + `mesh-delivery-indexer.take-in.taken` (a `consumes` entry), heard as it hears `build.ended`; a wait still held + after a restart is said again as `wait-held` and ends at the next such take-in. +- **A-261** (A-252, A-234; principles 2 and 3) A composition request's `Seats` carry, for each (seat, digest) of the + step's catalog revision, the definition whose digest it is: from the revision's `definitions` once A-234 fills + them, until then from mesh-catalog's `seat-definitions` where the trunk's digest matches; a digest neither holds + ends the step `could not run`, naming the seat and the digest. +- **A-262** (§496; principles 1 and 7) The assigner says a running composition step's progress once a minute with a + ticker inside the running step, stopped at its end, as mesh-delivery-sdk's `steprun` says its own beat (pull.go); + no bound key and no new key form. +- **A-263** (§712, §676; principles 7 and 8) §676 writes `package` (the Go module its `go.mod` names) for every Go + artifact, a `bundle` too, since a bundle is built from that Go module; §712 reads it there. +- **A-264** (§677, §697, A-186; principle 7) The event `gated-ended`, the verb `approvals` and the by-caller form of + a marked verb are added in mesh-sdk's `seatdef.Resolve`, which the seat generator and every reader of a definition + (the seat list, the grants part, the validator, `AnswerSeat`) go through: one place, one definition for all; the + seat files stay as written. +- **A-265** (A-264, design 46 approval mark §20; principles 4 and 7) A-264 holds for every marked definition. Where a + tool bundle holds the seat (the login shell's `execute`), the tool runner, which already holds that bundle's gate, + answers the marked verb by caller and serves `approvals` for the seats its bundles hold, as `AnswerSeat` does for a + process; no holder changes and no mark moves. +- **A-266** (A-264, A-265, ADR 0132; principle 7) `approvals` is the gate's verb, served wherever a marked verb is: + `CanHold` and the validator's same rule ask no holder to name it in its claim's `serves` or its tools. +- **A-267** (§496, §481, §22, A-170; principle 7) The composition step's `step-progress` carries `asker` `runner`, the + one asker that sends the accepted kind `step` on `mesh-wants`; the asker rename after join 11 (A-163, A-170) reads + it from the accept subject's asker token instead. +- **A-268** (corrects A-263; §712, §676, §491; principle 7) §676's `package` stays for package artifacts only, since a + bundle's Go module named as a package collides under §491's package names when two modules share one `go.mod`. + §712's job names the indexer entry's repository, `path` and the revision's head, and the program's directory; + `mesh-build-go` reads the Go module from the `go.mod` it builds there, as it does for every build. +- **A-269** (§509, §714; principles 7 and 8) A `pushed` message's `head` stands where a `merged` message's `merge` + stands: pending refs, the newest load and the revision's head key on it alike. +- **A-270** (A-255, §677; principles 3 and 7) A holder's approvals state is declared with `key-ttl` beside §677's + 48 hours and 64 MiB, since its bound keys `unanswered.` need it; the validator refuses a holder of a marked + verb whose approvals state lacks it. +- **A-271** (A-265, §677; principle 7) The tool runner's `approvals` answer has the form of `AnswerSeat`'s, read from + the runner's own record of the calls its gate holds; it keeps no `call.` keys of its own for it. +- **A-272** (§677, ADR 0596; principle 1) The `GateChannel` over `process.Conn` asks and reads an ask only through + mesh-sdk's `operatorchannelclient` on the seat `operator-channel`, never through the router's bucket. +- **A-273** (corrects A-272; §700, A-74, A-89; principles 1 and 7) The `GateChannel` over `process.Conn` is §700's: + `operatorchannelclient.Client` given, as its `Record`, a get of the key under `.` in the seat + `operator-channel`'s state `asks` (the bucket formed from the seat's holder on the seat list and `StateAsks`, A-74) + on the process's own connection; the verb `asks` stays as it answers. The ask is published by a new `go/process` + method that publishes on a seat's accept subject (`mesh.seat..accept..`), on the a3g line, + as `Emit` publishes an event. diff --git a/03-DESIGN/01-to-be/47-milestones/G.md b/03-DESIGN/01-to-be/47-milestones/G.md index 19ede5c2..a71562b7 100644 --- a/03-DESIGN/01-to-be/47-milestones/G.md +++ b/03-DESIGN/01-to-be/47-milestones/G.md @@ -104,5 +104,6 @@ The part is eighteen files, each read whole, its design lines numbered across th - [G-18-fix-round-six-seven](G-18-fix-round-six-seven.md): the fix round of §587 to §676: the approval mark once no verb names its callers, the keeper's snapshots, the recovery module's verbs, the node-engine's kept entries, the gate before a marked verb's running, develop's D-16 to D-49, and a delivery's wait on another machine's network (§677 to §705). - [G-19-outside-wait-and-refusals](G-19-outside-wait-and-refusals.md): a delivery's wait on an outside cause, written whole once (§706, in place of §705), and the finding writer's own refusals in every bundle (§707, amending §580). - [G-20-lead-answers](G-20-lead-answers.md): the lead's one-line answers to develop's questions, each tested against the principles (A-1 on). +- [G-22-lead-answers-2](G-22-lead-answers-2.md): the lead's answers continued, from A-182. Design 34's milestone [every-event](../34-milestones/every-event.md) and design 46's milestone [7-approval-mark](../46-milestones/7-approval-mark.md) ship in milestone G's release, built in its repositories beside G's lines (lead-47, 2026-11-11 15:30 CET); where one of their lines and a line of G differ, G's later line holds and the other is corrected in place (§624 to §626).