Amend design 47 with milestone 47/G's joint findings as its own choices
mesh/delivery merged: source.main moved to novox/hq@3d97fe016c2d
mesh/check being carried to b33ac325c0ec on 3d97fe016c2d | from d0d71b554876

The prepare found where ADR 0666, ADR 0667 and design 47 disagreed. The
ADR 0666 insight was dropped, so its five points are written here as the
design's choices with their reasons: the foundation from the registrations
(departing from ADR 0619 §3 for ADR 0666 §5), the want's compare-and-set per
module and watched branch, every pipeline started on catalog-revision, the
cost of a refused new indexer, and each check at its row's level. ADR 0667's
clause numbers follow the record as accepted, so the merge token goes only at
§12's moment and on the operator's word. The approval is the operator-channel's
accepted kind, a replace removes its object, the sent store's age is
transport, and what the milestone creates has its retention. The glossary
gains "held back" and "sent store"; design 51 starts a publication's
pipelines on catalog-revision.

Claude-Session: https://claude.ai/code/session_01JG73KK8HD1gufnqyFxMFdW
This commit is contained in:
2026-11-10 16:13:45 +01:00
parent d0d71b5548
commit b33ac325c0
3 changed files with 203 additions and 83 deletions
+13 -2
View File
@@ -561,8 +561,8 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
passes), `optional` (runs, a failure shown and holding nothing) or `bypass` (nothing runs), kept in its registration
and never in a manifest (ADR 0666 §7). Not the **upgrade policy** (Module), how a module's builds reach its nodes (see
[Homonyms](#homonyms)).
- **registration** — a module's entry in the catalog: its git origin, the path of its manifest, its watched branches and
its policy, kept by the seat `mesh-catalog`, every version with who changed it and on whose Approve;
- **registration** — a module's entry in the catalog: its git origin, the path of its manifest, its watched branches,
its policy and whether it is a foundation part (`foundation`), kept by the seat `mesh-catalog`, every version with who changed it and on whose Approve;
registering and changing one are trusted acts (ADR 0666 §2). The mesh knows modules, and a repository only as a
module's git origin.
- **watched branch** — a branch a module's registration names, whose commits start that module's pipeline and which a
@@ -983,6 +983,11 @@ becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283, 0564, 0668.
its size: one over the bus's per-value limit is kept in the object store beside its state, `<state>-objects`, granted
to its owner alone, its name in the key, and a reply or an event over the per-message limit carries the object's
name (ADR 0666 §16).
- **sent store** — a sender's object store of the objects its large replies and events carry, `<module>_sent-objects`
(a foundation part's old `objects` section `sent-objects`), planned by the bus module with no manifest field and
readable by a standing grant to the callers and consumers its manifests declare (ADR 0666 §16). It is transport, not
kept data: the bus expires an object after 7 days (design 47, *Any size*).
*Not:* ~~outbox~~
- **`bus-state`** — the provision of the bus module that every bus-state entry of a manifest requires, so the module
graph orders the bus module's build before a module asking bus state (ADR 0614 §5). Provided by the holder of the
seat `mesh-broker`.
@@ -1094,6 +1099,12 @@ asking, never the act. **Decided by** ADR 0152, 0175, 0234, 0259, 0272, 0383, 03
same `about` replaces its open one, and a fourth is offered while the oldest waits, never the newest (ADR 0666 §12;
design 46 §6). From the delivery of design 47's milestone G the operator's approval of a delivery is the pipeline
step `approval`, asked as an ask like any other, and no merge is asked (ADR 0666 §10).
- **held back** — said of an ask kept open behind newer asks of the same asker: when an asker's fourth ask is offered,
its oldest offered ask is held back, its answer tickets withdrawn and its message edited to say it waits, and it is
offered again with new tickets as soon as one of the asker's three offered asks ends, or by the router's tool
`ask-again`; `asks` lists the held-back asks with since when. The newest ask is never held back, and a held-back
ask is never refused or hidden (ADR 0666 §12; design 46 §6). From the delivery of design 47's milestone G.
*Not:* ~~held ask~~, ~~queued ask~~
- **warrant** — the router's record that a person chose one option of one ask: the ask, the option,
who chose (the operator, as a channel kind's identity), through which channel, the proofs and when,
published for that asker alone. The only thing an asker acts on (ADR 0259).
@@ -439,12 +439,12 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
│ registrations; a catalog graph
│ per watched branch; the revision
│ validated before take-in
▼ take-in.taken
▼ catalog-revision (seat mesh-catalog)
pipeline runner (mesh-pipeline-runner) ── asks each pipeline step on the serving seat's work queue, hears step-ended:
│ lint, unit tests, integration tests ──► the build seats (node-build-go, node-build-node, node-build-image)
│ composition ──────────────────────────► the assigner (mesh-wants)
│ code review ──────────────────────────► the runner's own verb `review`, from the reviewer's bus account
│ approval ─────────────────────────────► operator-channel: ask, then decided
│ approval ─────────────────────────────► operator-channel: accepted kind ask, then decided
▼ pipeline-ended (every step's result), keyed by source revision
assigner ──► wants from a revision whose required steps passed, on the watched branch a placement chose
gate ──► the delivery record keeps the step and pipeline events
@@ -453,7 +453,8 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
### A module's registration
- **What it holds.** The seat `mesh-catalog` keeps each module's **registration**: its git origin, the path of its
manifest, its watched branches and its policy, on the bus, every version with who changed it and the warrant of the
manifest, its watched branches, its policy and whether it is a foundation part (its value `foundation`, absent read
as no), on the bus, every version with who changed it and the warrant of the
operator's Approve (ADR 0666 §2). The indexer is a foundation part, so the registrations are kept in its old sections
(ADR 0619 §1 to §3, ADR 0666 §4): one key per module in its old `state` section `registrations`, and every version on
its old `streams` section's stream `registration-history`, kept with no age limit.
@@ -462,7 +463,8 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
- **Changing one is a trusted act.** The seat's verbs `register` (a module whole), `policy` (one module's step
statuses, per artifact), `watch` and `unwatch` (add or remove a watched branch) each raise an authorising ask of tier
approve through the seat `operator-channel` (design 46 §10), naming every value the change moves, one line each
("`mesh-grants:program` unit tests: `required` → `bypass`"), and write the version only on its warrant; a Decline or
("`mesh-grants:program` unit tests: `required` → `bypass`", "`nats` foundation: no → yes"), and write the version
only on its warrant; a Decline or
an expiry writes nothing (ADR 0666 §2). Until a record binds each forge account to its bus identity, `register` and
`policy` refuse code review as a `required` step, naming why, so no review gates while its author cannot be told
(ADR 0666 §22; issue 1966, note 157). A manifest moved to another path is the one manifest change that changes the
@@ -474,6 +476,16 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
- **An unprotected branch is refused.** `register` and `watch` read a branch's protection through the seat `git`'s read
verb `branch` (its head, and whether a rule refuses a direct push and admits only merges), and refuse a watched branch
the forge does not protect, naming it (ADR 0666 §3).
- **The foundation parts are written once, in the registrations.** Which modules are foundation parts (ADR 0619 §1 as
ADR 0666 §4 changes it) is each registration's value `foundation`, changed only as every registration value is, on
the operator's Approve; the manifest validator holds no list of them in its code and takes them from its input, the
validation ask the indexer makes before every take-in carrying the foundation modules from the registrations, and
the running indexer's own judging reading them from the registrations it keeps. This departs from ADR 0619 §3,
which makes the validator's list in code the one place the foundation is written: a list of module names in code is
what ADR 0666 §5 refuses, so the one place becomes the registrations (the design's choice under ADR 0666 §5). The
indexer's finding `foundation-differs`, raised and cleared by the condition keeper (ADR 0564 §2), names a module
the registrations and a watched branch's catalog graph disagree on: one marked `foundation` that the graph does not
hold, or one whose manifest keeps old sections (ADR 0619 §2) that no registration marks.
- **No part fixes a name.** Every branch, repository and module name a part needs is read from the registrations and the
catalog graph; the lint step refuses such a name in a string, a constant or a table of code logic, a Go import path
not being code logic (ADR 0666 §5). About 39 such names in 9 parts were found on 2026-11-09 (research 086, Findings);
@@ -482,7 +494,9 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
proposes one registration for every module its trunk revision holds, from what it took in (the origin and path of
each), its watched branch the repository's default branch read through the seat `git`, and the statuses the check
judged until then: lint, unit tests, integration tests and composition `required`, code review `optional`, approval
`bypass`; it raises them as one ask naming every registration, as the seat `mesh-module-assigner`'s `adopt` proposes
`bypass`; `foundation` marked for exactly the parts ADR 0619 §1 names at that start and the runner (ADR 0666 §4),
read once from the validator's list, which the same change then deletes; it raises them as one ask naming every
registration, as the seat `mesh-module-assigner`'s `adopt` proposes
placement whole (ADR 0567). Until that Approve the runner starts no delivering pipeline and says why, so the
operator is told of this one ask before G's delivery starts. A Decline or an expiry leaves the seed unwritten and
says so; the indexer's tool `indexer_seed_again` raises the ask again, recorded in the hand-act log.
@@ -494,8 +508,11 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
the warrant writes nothing, and a declined one writes nothing; a change from `required` to `bypass` asks, showing
that line; `registration-changed` is said and `registrations` answers the history; the first start proposes the seed
as one ask, and `indexer_seed_again` asks it again after a Decline and after an expiry; a policy making code review
`required` is refused. Unit (the Go build module's lint step): a module name in a string, a constant and a table is refused, an
import path is not. Tests 75, 68 and 83.
`required` is refused; a change of `foundation` without the warrant writes nothing. Unit and whole (indexer): given
registrations marking `nats` foundation and not `node-tools`, the validator refuses `nats`'s manifest asking a
template and judges `node-tools`'s as any part's, and no module name is left in the validator's code; a module
marked `foundation` that the graph does not hold raises `foundation-differs`. Unit (the Go build module's lint step):
a module name in a string, a constant and a table is refused, an import path is not. Tests 75, 68, 83 and 101.
### Watched branches and the catalog graph per branch
@@ -539,6 +556,13 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
clears once the protection is back (ADR 0666 §6).
- **A pending revision holds its own branch only.** A merge waits behind a pending revision only on the same watched
branch; other branches move on (ADR 0666 §6, which changes ADR 0633 §3).
- **A refused new indexer holds its branch until a revert lands.** A merge of a new indexer whose own validator refuses
its revision has already landed when it is refused, since the validation runs before take-in and after the merge
(ADR 0666 §6). It stays pending, and every later merge on that watched branch waits behind it, said by
`take-in-waits` at the 60-minute bound, until a revert, an ordinary merge through its pipeline (ADR 0666 §26), lands
and is taken in; nothing takes a later merge in past it. This is the cost of validating every revision with the
validator built from its own heads, the design's reading of ADR 0666 §6, and the operator is told it with the
condition, which names the pending revision and the revert as the way on.
- **How it is checked.** Whole (forge bridge): a commit of a branch no registration names starts nothing; a commit on a
watched branch is taken from the seat's `branch` read, not the event; a head missed while the bridge was stopped is
read at its start. Whole (indexer, assigner): a commit on `beta` gives a revision of the `beta` graph only and moves
@@ -552,14 +576,16 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
- **The runner.** The seat `mesh-pipeline-runner`, held once for the mesh by the module `mesh-delivery-pipeline`,
runs each pipeline (ADR 0666 §7). It is a foundation part, since the bus module's own delivery waits on its pipeline
(ADR 0666 §4): its kept data are in old sections (ADR 0619 §2), it waits on no bus module process to start, and it
joins the manifest validator's list of foundation parts, which refuses its manifest asking a template. It reads the policy from the registrations, asks each step that is not `bypass` of
is registered `foundation` from the first registrations on (*A module's registration*), so the manifest validator
refuses its manifest asking a template. It reads the policy from the registrations, asks each step that is not `bypass` of
the seat that serves it, and says each step's start and end and the pipeline's end (*Health and going back*, below).
- **The steps and who serves them.** Lint, unit tests and integration tests are the build seats' (`node-build-go`,
`node-build-node`, `node-build-image`): each gains the verb `steps`, which answers which pipeline steps an artifact
can run by its language's convention (as *The check from release 4* says the tests are found), and the accepted kind
`step` on its stream `check`, which runs one. Composition is the assigner's, an accepted kind `step` of the seat
`mesh-wants`. Code review comes in through the runner's own verb `review`. Approval is asked through the seat
`operator-channel`'s ask and heard on its event `decided` (ADR 0666 §7, §10). A step with nothing to do ends at once as
`mesh-wants`. Code review comes in through the runner's own verb `review`. Approval is asked as the seat
`operator-channel`'s accepted kind `ask`, on its work queue by the runner's name (design 46 §10, *Asks, warrants and answers on the bus*;
the seat has no verb `ask`), and heard on its event `decided` (ADR 0666 §7, §10). A step with nothing to do ends at once as
`nothing to run`, never as passed.
- **The policy.** Each step's status, per module and per artifact, is `required` (runs; holds the delivery until it
passes), `optional` (runs; a failure is shown and may be accepted) or `bypass` (nothing runs; said as bypassed),
@@ -604,7 +630,10 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
(the record's `pipeline ended`), keyed by source revision, with every step's result. The assigner consumes it, and
writes a want only from a source revision whose every `required` step passed for the modules it moves, on the watched
branch a placement chose, by compare-and-set on a newer revision, so an older revision ending after a newer one
writes nothing (ADR 0666 §9). This is one more rule beside the assigner's others (ADR 0429 §6), checked per module.
writes nothing (ADR 0666 §9). The compare-and-set is keyed per module and watched branch: it compares a revision only
with the last one written for the same module on the same watched branch, so a revision of `beta` ending after a
newer one of `main` writes its own want and refuses neither (the design's choice under ADR 0666 §9: source
revisions are kept per watched branch, `source.<branch>`, and two branches' revisions have no order between them). This is one more rule beside the assigner's others (ADR 0429 §6), checked per module.
From G's delivery it replaces the trunk-only want (ADR 0656 §2 as ADR 0666 §9 changes it). For a group's source
revision the runner says one `group-ended` once every member's modules have ended, and the assigner writes the
group's wants only on it: a member's own `pipeline-ended` writes nothing (ADR 0666 §9).
@@ -629,7 +658,8 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
- **The delivery record keeps every step.** The gate's delivery record consumes the step and pipeline events and keeps
them as long as the record (ADR 0666 §9; *The delivery record*).
- **How it is checked.** Whole (assigner): a failed `required` step writes no want; a failed `optional` step holds
nothing; an older revision's `pipeline-ended` after a newer one's writes nothing; a group with one member passed and
nothing; an older revision's `pipeline-ended` after a newer one's writes nothing, and a revision of one watched branch
ending after a newer one of another writes its own want; a group with one member passed and
another still running writes no want until `group-ended`. Whole (runner): a newer commit that changed a module's
fingerprint supersedes its older pipeline and drops its asks, and one that left it unchanged lets it finish; a step
with no holder ends the pipeline naming the seat within five minutes; a failed `required` step on a head raises
@@ -642,8 +672,8 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
no Approve is asked per merge, and the delivery gate's merge turns and its Approve per merge go (ADR 0666 §10, which
changes ADR 0661 §3 to §5). The operator is asked only where a module's policy says `approval`, and for registrations
and policy changes.
- **The approval is an ask of the runner's.** The runner raises an authorising ask of tier approve on the seat
`operator-channel` under its own name, its `about` the module and the watched branch only, so a newer commit's ask
- **The approval is an ask of the runner's.** The runner raises an authorising ask of tier approve as the seat
`operator-channel`'s accepted kind `ask`, under its own name, its `about` the module and the watched branch only, so a newer commit's ask
replaces the older one's (design 46 §10). The warrant ends the step passed; an ask that is declined, expires or is
refused ends it `declined`, and one that is replaced ends it `superseded`. Only a declined `approval` step is asked
again, by the runner's verb `ask-again` (ADR 0666 §10). While it waits the runner
@@ -657,7 +687,8 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
nothing; it never waits for a run and never asks an Approve (ADR 0666 §11). The forge keeps only its branch protection.
- **Judged from its own state, never by a call.** The holder of the seat `git` consumes the runner's `step-ended`
through a durable consumer of its own and keeps, in its own state `failed-steps`, each failed `required` step by
module and build-input fingerprint, with the commits it was seen at and the run that failed it, for 30 days; so a head
module and build-input fingerprint, with the commits it was seen at and the run that failed it, until none of those
commits is a watched branch's head or the head an open pull request names (*The runner's kept data*); so a head
merges while the runner is down, judged on what it already heard (ADR 0666 §11, ADR 0596). A head's fingerprints are
those its runs named for its commit; a step that failed at that fingerprint in any run, a group's or another commit's
of the same content included, refuses it, unless a later run of that same step at that fingerprint, asked again by
@@ -665,7 +696,8 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
§11). The runner's `step-ended` says that the step was a rerun and the caller the runtime proved, and the forge module
clears a failure only for a rerun whose caller is the operator or a healer; a plain pass, or a rerun asked by anyone
else, clears nothing. A run still running is judged by the steps it has ended, since the merge never waits. A refusal names the run, the module and the step, so the session knows what to fix. The gate merges nothing, and its forge merge token is
removed by G's delivery (ADR 0667 §6); the forge bridge hears the landed commit as it hears every commit of a watched
removed with the checker's buckets and bus account, after the first pipeline after G's delivery has delivered a change
end to end and on the operator's word (ADR 0667 §12; *How milestone G itself is checked and delivered*); the forge bridge hears the landed commit as it hears every commit of a watched
branch.
- **The operator-channel hides no ask.** It keeps design 46's three open asks per asker, never holds the newest back,
and replaces an open ask by the same asker's ask with the same `about` (ADR 0666 §12; design 46 §6).
@@ -686,8 +718,9 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
`mesh-delivery`'s verb `groups`, and publishes `forge.group.merged` when that verb says every member has (ADR 0666 §13,
which changes ADR 0633 §4).
- **One source revision, one pipeline per branch.** The indexer keeps landed members pending until the group's end and
takes them in together as one source revision of that watched branch, saying `take-in.taken`; the runner starts the
group's one pipeline per watched branch on that event, and a member of a gathered group starts no pipeline of its own.
takes them in together as one source revision of that watched branch, saying the catalog revision it makes as the seat
`mesh-catalog`'s event `catalog-revision`; the runner starts the group's one pipeline per watched branch on that
event, and a member of a gathered group starts no pipeline of its own (ADR 0666 §13).
When one member's `required` step fails, none of the group's modules is delivered (research 086, R5).
- **A group that never completes is said.** By ADR 0633 §5's 30-minute bound and its condition; `bridge_group_end_again`
says a group's end again from the gate's group verb, never the gate's `merges` state (ADR 0666 §13, which changes ADR
@@ -736,20 +769,31 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
51, *The versions*). The seat is new, held once for the mesh, defined in `mesh-delivery-contracts`; the builder held
none until now, and its waits stay on its own stream in this milestone.
- **Every dependent is rebuilt against it.** On `package-published` every artifact with a kind-1 edge to the package is
rebuilt against the new version, and the runner, which consumes the event, starts its pipeline; nothing else is
rebuilt, and a change to tests alone publishes nothing (ADR 0666 §15; research 086, R18).
rebuilt against the new version; nothing else is rebuilt, and a change to tests alone publishes nothing (ADR 0666
§15; research 086, R18). The indexer consumes `package-published` and says the catalog revision the publication
makes as `catalog-revision`; the runner starts those artifacts' pipelines on it, once each, and a publication's
pipeline is keyed by that catalog revision.
- **The runner starts on one event.** The runner starts every pipeline on the seat `mesh-catalog`'s `catalog-revision`,
a commit's, a group's and a publication's alike, and consumes neither `package-published` nor the indexer's own
`take-in.taken`. The design's choice under ADR 0666 §13 and §15: the seat's event is the mesh path (a module's own
event would have the runner name the indexer, ADR 0666 §5), and one start event makes one publication one pipeline per
dependent, never two.
- **Unread packages refuse.** A build that cannot read the published packages refuses and names the unread state
(ADR 0666 §15).
- **How it is checked.** Whole (builder, indexer): a mesh-sdk merge changing one package publishes one version, and only
the artifacts importing that package rebuild; a merge changing only tests rebuilds nothing; a build whose packages
cannot be read refuses naming the state. Tests 70 and 80.
cannot be read refuses naming the state. Whole (runner): the runner starts a pipeline only on `catalog-revision`, and
one publication starts one pipeline per dependent. Tests 70, 80 and 102.
### Any size
- **A value over the limit is an object.** mesh-sdk's own small object store package (ADR 0595 §9) puts a value over
the bus's per-value limit in the object store beside its state and keeps the object's name in the key; a verb's reply or an event over the
per-message limit carries the object's name (ADR 0666 §16). A value moved there is deleted with its key, and a
replaced value leaves one object.
per-message limit carries the object's name (ADR 0666 §16). A replace writes the new object, sets the key by
compare-and-set, and removes the object it replaced in the same act, so a replaced value leaves one object; a key
deleted leaves its object, listed as `key gone`, which only the drop tool removes on a person's word (ADR 0666 §16,
as ADR 0595 §4 removes kept data). The design's choice under ADR 0666 §16: the object a replace removes is no longer
named by any key, so nothing can read it, while a deleted key may be one a person wants back.
- **One object store per state, granted to its owner.** Each state asked by the template `state` gets its object store
beside it, `<state>-objects`, a template form of ADR 0595 that the bus module provides and the grants part grants to
the state's owner alone (ADR 0666 §16); a foundation part's large values go in an old `objects` section of its own.
@@ -757,21 +801,31 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
it adds reserve nothing; the few values over the limit (a delivery record, a catalog graph revision list, a test's
output) are estimated, as a guess, at under 1 GiB across the mesh.
- **An object sent is readable by the modules it is for.** A reply's or an event's object is written to the sender's
object store of sent objects, and the grants part derives from the manifests a standing grant to read them: the
**sent store**, `<module>_sent-objects`: the bus module plans it, with no manifest field, for every module of the new
form that serves a verb or emits an event, and a foundation part declares it as an old `objects` section
`sent-objects` (ADR 0619 §2). Its cap is the objects template's (ADR 0595 §3), and it keeps an object 7 days, after
which the bus expires it. That age is transport, not kept data: an object sent exists only to carry one reply or one
event, read within its call's bound or its consumer's lag, so its expiry is not a removal of kept data that ADR 0595
§4 holds to a person's word (the design's choice; 7 days is a guess at the longest a consumer lags, read from the
fill tools once G runs). A full sent store is the bus module's `full` and its condition (ADR 0595 §6), and the sender
then refuses the large reply or event loudly, naming the store. The grants part derives from the manifests a standing grant to read them: the
callers its seat definition names for the verbs it serves, and the consumers whose `consumes` declare its events;
no other module may read them (ADR 0666 §16). The grant follows the manifests, so it is written when they change,
never per object. A consumer's reader of
the form is delivered before its producer writes it, an edge of kind 4.
- **Its tools come with the package.** The package serves each module that imports it `<module>_state_objects` (the
objects of each state, with their size, the key that names each and the fill against its cap) and
objects of each state, with their size, the key that names each or `key gone`, and the fill against its cap),
`<module>_state_objects_drop` (drop the objects whose key is gone, on a person's word as ADR 0595 §4 removes kept
data, recorded in the hand-act log).
data), `<module>_sent_objects` (each sent object, its size, when it was sent and to which verb or event, its age
against the store's and the fill against its cap) and `<module>_sent_objects_drop` (drop sent objects older than an
age a person names); each drop names who asked and is recorded in the hand-act log.
- **Its cost.** Only the modules that import the package are built with it, so no other module is rebuilt for it: a
package published before its users build (ADR 0573 §2, ADR 0667 §3).
- **How it is checked.** Whole (mesh-sdk, against the real bus): values of one, ten and a hundred times the per-value
limit stored, sent as a reply and as an event, and read back whole by a caller and a consumer the manifests declare,
and refused to a module that declares neither; a replaced large value leaves one object; a key deleted takes its object.
Tests 69 and 90.
and refused to a module that declares neither; a replaced large value leaves one object; a key deleted leaves its
object listed `key gone`, which the drop tool removes and nothing else does; a sent object is readable within its 7
days and expired after; each drop without who asked is refused. Tests 69 and 90.
### The pipeline makes the check, and the checker goes
@@ -802,7 +856,7 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
| the kept verdicts and the carry | the runner's `kept`, taken from the checker's at the runner's first start, and its carry (ADR 0548 §5) |
| the checking program: the manifest validator at the heads, the cycle rule, the composer, the rule names | the indexer's validation before take-in; the indexer's cycle rule; the composition step; `widens` in the pipeline's end |
| the `run` ask, published by the checker's account | published by the runner's account and the indexer's (its validation), each with step keys under its own name |
| its buckets and bus account | removed after the first pipeline after G's delivery has delivered a change end to end, after a backup kept 90 days whose restore is tested, the operator told before (ADR 0667 §6) |
| its buckets and bus account | removed with the gate's forge merge token after the first pipeline after G's delivery has delivered a change end to end, on the operator's one word, the buckets through `drop` after its snapshot, whose restore is tested first (ADR 0667 §12) |
- **How it is checked.** Whole (runner, assigner): a run on request of `feature/1966-x` delivers nothing, and a call of
`run` from another account is refused; a composition step refuses two modules owning one path; a step whose part
@@ -860,8 +914,8 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l
its members, and a merge behind a pending revision, are governed by their own bounds (ADR 0666 §24). At its start the
watchman seeds its open waits from the runner's `stands`, as it seeds `take-in-waits` from `indexer_pending`.
- **The runner's own health.** Its manifest declares its health check, run outside its process (ADR 0240): the runner
answers `show`, and its durable consumers of `step-ended`, `take-in.taken`, `package-published` and `decided` are
each less than five minutes behind; a failed check names which.
answers `show`, and its durable consumers of `step-ended`, `catalog-revision` and `decided` are each less than five
minutes behind; a failed check names which.
- **The runner waits for its view.** With no revision view it says so in `<module>_first_views` and raises `view-waits`
after five minutes, as every part does (ADR 0656 §6).
- **Going back is one act.** A failing new version holds while the old keeps running (ADR 0656 §4); a return to an
@@ -901,7 +955,7 @@ four lines a module's tools answer; every read tool of a store also answers its
| the assigner (`mesh-wants`) | `assigner_why_not` (why a module is not on a machine yet: the pipeline it waits for, its hold, the placement, the node's last `running`) | — | `assigner_release` |
| the watchman | `watchman_views` (how far behind each part's view is, from each part's `view-waits` and first-view tools) | — | each part's `<module>_first_view_again` |
| the operator-channel | `asks` (with each asker's asks held back) | — | `ask-again` (offer a held-back ask now) |
| every module (mesh-sdk's runtime) | `<module>_state_objects` | — | `<module>_state_objects_drop` |
| every module that imports mesh-sdk's small object store package | `<module>_state_objects`, `<module>_sent_objects` | — | `<module>_state_objects_drop`, `<module>_sent_objects_drop` |
Every recover tool writes its act, who and why in the hand-act log of the seat `mesh-hand-acts`. How it is checked:
each tool answers its whole-module test's case, every store's read answers its fill, and `mesh_describe` reads each
@@ -917,15 +971,17 @@ and an estimated 2 mesh-sdk publishes a day, each rebuilding about 120 artifacts
| Part | Kept data | Section or template | Retention | Cap and growth |
|---|---|---|---|---|
| the runner | `pipelines`: one key per pipeline, keyed by watched branch, source revision and module, its steps, statuses, outcomes, fingerprints and test counts | old `state` section | 30 days, or while it is its branch's newest for its module; the delivery record keeps its own copy of the events for 90 | 128 MiB; about 300 pipelines a day of about 4 KiB is about 36 MiB at 30 days |
| the runner | `step-log`: one entry per step's start and end, its output by name | old `streams` section | 30 days | 64 MiB; about 3,600 entries a day of about 0.2 KiB is about 22 MiB at 30 days |
| the runner | `pipelines`: one key per pipeline, keyed by watched branch, source revision and module, its steps, statuses, outcomes, fingerprints and test counts | old `state` section | a pipeline a delivery record cites, deleted with that record (90 days); a superseded pipeline, a run on request's and one no record cites, 7 days after its end; always while it is its branch's newest for its module | 256 MiB; about 300 pipelines a day of about 4 KiB is at most about 105 MiB at 90 days, under half the cap |
| the runner | `step-log`: one entry per step's start and end, its output by name | old `streams` section | by its age, 90 days, as long as the delivery records that cite its steps | 128 MiB; about 3,600 entries a day of about 0.2 KiB is about 63 MiB at 90 days |
| the runner | `step-outputs`: a lint or test step's output | old `objects` section | 7 days | 1 GiB; about 1,200 steps run a day (the rest carried) of about 50 KiB is about 420 MiB at 7 days |
| the runner | `kept`: a package's passing result per level, by digest | old `state` section | 30 days unread | 128 MiB; a publish changes the digest of about 1,000 importing packages at two levels, so about 4,000 entries a day of about 0.3 KiB, about 36 MiB at 30 days |
| the indexer | `registrations` and its stream `registration-history` | old `state` and `streams` sections | the life of the mesh, never derived again | 64 MiB (*A module's registration*) |
| the indexer | catalog graph revisions, per watched branch | objects in the old form (ADR 0619 §2) | while a record pins it or it is its branch's current | 512 MiB, as *Two graphs, one source of truth*; a second watched branch on a few modules adds a few MiB |
| the gate | `source`: one key per watched branch | its old `state` section, as today | 64 revisions of each key | a few KiB |
| the forge module | `failed-steps`: failed `required` steps by module and fingerprint | state | 30 days | the template's 64 MiB; an estimated 50 failed steps a day of about 0.5 KiB is under 1 MiB at 30 days |
| every module | `<state>-objects` beside each state | objects | with its key | the template's; nothing reserved until written |
| the gate | `source`: one key per watched branch | its old `state` section, as today | 64 revisions of each key; a branch's key deleted when `registration-changed` says the last registration watching it unwatched it (`unwatch`) | a few KiB |
| the forge module | `failed-steps`: failed `required` steps by module and fingerprint, with the commits each was seen at | state | an entry deleted once none of its commits is a watched branch's head or the head an open pull request names, judged on each `branch-moved` and each pull request's close | the template's 64 MiB; an estimated 50 failed steps a day of about 0.5 KiB, most gone within days, is under 1 MiB |
| every module that imports the object store package | `<state>-objects` beside each state | objects | an object removed when a replace supersedes it; one whose key is gone, until `<module>_state_objects_drop` on a person's word (ADR 0666 §16) | the template's; nothing reserved until written |
| every sender of the new form, and a foundation part by its old `objects` section | `<module>_sent-objects` (`sent-objects`) | objects, planned by the bus module with no manifest field | 7 days, transport (*Any size*) | the objects template's cap; full is the bus module's `full` |
| the grants part, for each seat event a definition keeps | `SEAT_<seat>_<event>`, among them `SEAT_mesh-pipeline-runner_*`, `SEAT_<build seat>_step-ended`, `SEAT_git_branch-moved`, `SEAT_mesh-builds_package-published` and `SEAT_mesh-catalog_registration-changed` | a stream the grants part makes with its durable consumers | the seat definition's age (`keep`), 90 days unless the definition names less | the seat definition's cap (`keep`) |
**The build capacity.** A pipeline runs a module's steps once per commit on a watched branch, carrying what did not
change, where the check ran before the merge and carried after each trunk move; a group runs one pipeline per watched
@@ -948,33 +1004,44 @@ step keys and the builder's build log, against the checker's last week (test 99)
- **Its other parts as any module.** mesh-sdk's small object store package is a package published before the modules
that use it build; the manifest validator moves with the indexer; the runner is placed like any module and acts only
from the next change on; mesh-delivery's `contracts` and `sdk` move under its `modules/` folder (ADR 0667 §3).
- **Readers, the stream maker and the bus module first** (ADR 0667 §4): the edges the delivery plan derives, kind 4 each:
the indexer's manifest validator for the seat definitions' new fields (`callers`, `acts`, `subject`, `keep`) before
any definition using them; on each node the node-engine that reads `form` and `catch-up` before any manifest writing
them; the grants part, which makes each kept seat stream and its durable consumers, before the parts that hear a kept
stream; the bus module, with `<state>-objects` and its grant to the owner alone, before the modules requiring it, the
grants part writing that grant from the milestone's heads. A restart of the bus its new version needs is said to the
operator before it starts.
- **The new assigner before the new merge.** The new assigner, which writes a want only from a passed pipeline, is
delivered before the forge module's new `merge-pull`, which asks no Approve, and before the runner: an edge of kind 4
from `mesh-delivery-assigner` to each, declared in their manifests' `needs` since nothing else says it. Without it a
merge made with no Approve could reach the old assigner, which writes wants from the trunk with no pipeline. Both
switch on one fact, the first registrations written, said as `registration-changed`: until it the new assigner keeps
the trunk-only want and the new `merge-pull` refuses every merge, naming the missing registrations (ADR 0667 §5).
Meanwhile a fix, an indexer fix included, is merged by the operator on the forge, whose protection admits the operator
(ADR 0398 §2), and delivered under the trunk-only want still in force, and `indexer_seed_again` asks the first
registrations again.
- **A gap is built, not worked around.** An order the delivery plan cannot derive from the edges is built in the
delivery system within G; a node-engine of the version before applies every want whose manifests use no field it does
not read, and a want that uses one waits for the new node-engine on that node (ADR 0667 §5).
- **What is removed, and when.** The checker's buckets and bus account and the gate's forge merge token are removed only
after the first pipeline after G's delivery has delivered a change end to end (test 63), after a backup of the buckets
kept 90 days, as the delivery records are, whose restore is tested, and the operator is told before it (ADR 0667 §6).
The checker leaves the manifest validator's list of foundation parts (ADR 0619 §1) when it is removed; the runner is
on that list from G's delivery.
- **Told to the operator before it starts**: one more Approve per merge under ADR 0661 for G's own group, then none; the
one ask of the seed registrations; the bus's restart; and later the
checker's removal.
- **Readers first** (ADR 0667 §4): an edge of kind 4 each, which the delivery plan derives: the indexer's manifest
validator for the seat definitions' new fields (`callers`, `acts`, `subject`, `keep`) before any definition using
them; on each node the node-engine that reads `form` and `catch-up` before any manifest writing them.
- **The stream maker first** (ADR 0667 §5): the grants part, which makes each kept seat stream and its durable
consumers, before the parts that hear a kept stream.
- **The bus module first** (ADR 0667 §6): the bus module, with `<state>-objects`, the sent store and the grant of each
state's object store to its owner alone, before the modules requiring them, the grants part writing that grant from
the milestone's heads.
- **A bus restart is said first** (ADR 0667 §7): a restart of the bus its new version needs is said to the operator
before it starts.
- **A gap is built, not worked around** (ADR 0667 §8): an order the delivery plan cannot derive from the edges is
built in the delivery system within G, never a step done by hand.
- **A node-engine of the version before applies what it can read** (ADR 0667 §9): it applies every want whose
manifests use no field it does not read, and a want that uses one waits, by the reader edge above, for the new
node-engine on that node.
- **The new assigner and the new merge switch on the first registrations** (ADR 0667 §10). The new assigner, which
writes a want only from a passed pipeline, is delivered before the forge module's new `merge-pull`, which asks no
Approve, and before the runner: an edge of kind 4 from `mesh-delivery-assigner` to each, declared in their manifests'
`needs` since nothing else says it (the design's choice: without it a merge made with no Approve could reach the old
assigner, which writes wants from the trunk with no pipeline). Both switch on one fact, the first registrations
written, said as `registration-changed`: until it the new assigner keeps the trunk-only want and the new
`merge-pull` refuses every merge, naming the missing registrations.
- **Until then, the operator merges a fix at the forge** (ADR 0667 §11). Until that fact an ordinary change waits for
it, and a fix, an indexer fix included, is merged by the operator's own hand at the forge (ADR 0661 §3) and
delivered under the trunk-only want still in force; `indexer_seed_again` asks the first registrations again. Before
the milestone's delivery every merge goes as ADR 0661 has it.
- **What is removed, and when** (ADR 0667 §12). The checker's buckets and bus account and the gate's forge merge token
are removed only after the first pipeline after G's delivery has delivered a change end to end (test 63), the runner
then making every check in the checker's place (ADR 0666 §19), and only on the operator's word, asked once for all
three. That one ask also names the checker's registration leaving the foundation (`foundation`: yes → no), the design's
choice so that one warrant covers every value it moves (*A module's registration*).
The checker then leaves the foundation and is no longer placed, so no running module declares its buckets and they
are orphans `orphans` lists; they go through ADR 0595's `drop` on that word, after the stream snapshot `drop` takes
(ADR 0595 §4, §5, §10), kept 90 days as the delivery records are; a restore from that snapshot is tested before the
word is asked. The runner is registered `foundation` from the first registrations on.
- **Told to the operator before it starts**: G's own merges are asked as ADR 0661 has them (ADR 0667 §2, §11); the one
ask of the seed registrations; the bus's restart (ADR 0667 §7); and later the one word for the checker's removal
(ADR 0667 §12).
- **How it is checked.** Tests 94 to 97, and 100 for the assigner's edge.
### Choices this design makes under ADR 0666 and ADR 0667
@@ -982,7 +1049,13 @@ step keys and the builder's build log, against the checker's last week (test 99)
| Choice | Why |
|---|---|
| The registrations in the indexer's old `state` section with their history on an old stream, capped at 64 MiB, kept for the life of the mesh | the indexer is a foundation part (ADR 0619 §1 to §3, ADR 0666 §4); a registration keeps every version with who and on whose Approve, and nothing derives it again |
| The runner a foundation part, its kept data in old sections, on the manifest validator's list | the bus module's own delivery waits on its pipeline (ADR 0666 §4) |
| The runner a foundation part, its kept data in old sections, registered `foundation` | the bus module's own delivery waits on its pipeline (ADR 0666 §4) |
| The foundation parts written once, as the registration value `foundation` on the operator's Approve, read by the manifest validator from its validation ask; its list in code gone; `foundation-differs` when a catalog graph disagrees | a list of module names in code is what ADR 0666 §5 refuses, so the one place ADR 0619 §3 asks for becomes the registrations, changed as every registration is (ADR 0666 §2); a disagreement is said, never guessed |
| The want's compare-and-set keyed per module and watched branch | source revisions are kept per watched branch, so two branches' revisions have no order; comparing across them would let `main` refuse `beta`'s want (ADR 0666 §9) |
| The runner starts every pipeline on `catalog-revision`, a publication's included, and consumes no `package-published` and no `take-in.taken` | the seat's event is the mesh path and names no module (ADR 0666 §5); one start event gives one pipeline per dependent of a publication (ADR 0666 §13, §15) |
| A refused new indexer revision holds later merges on its branch until a revert lands | the validation runs after the merge and before take-in (ADR 0666 §6), so the refused revision has landed; taking later merges in past it would deliver them on a graph its own validator refused |
| Each check at its row's level, every requirement R1 to R18 keeping its named test | the record's rows name the levels; the test budget and one check per release bound what runs |
| The approval asked as the operator-channel's accepted kind `ask` on its work queue | the seat has no verb `ask`: an ask is its accepted kind, by the asker's own name (design 46 §10) |
| The gate no foundation part, its `source` in the old section it already has | the bus module's delivery waits on no act of the gate's; only the key's layout changes |
| The verbs `register`, `policy`, `watch`, `unwatch`, `registrations` and the event `registration-changed` on `mesh-catalog` | one verb per trusted act, each its own ask naming what moves; readers follow the event (ADR 0596) |
| The seed of the first registrations proposed as one ask, with the statuses the check judged until then and approval `bypass`, raised again by `indexer_seed_again` | registering is a trusted act (ADR 0666 §3), and one ask for the whole seed is how placement was adopted (ADR 0567); a declined or expired seed must not leave the pipelines stopped with no way on |
@@ -1006,12 +1079,16 @@ step keys and the builder's build log, against the checker's last week (test 99)
| The field `callers` in a seat definition replaces the holders' trusted `callers`, a missing field admitting the holder roles and the operator only | the record makes the definition the grants part's one source (ADR 0666 §20); a field left out must open nothing |
| `widens` in `pipeline-ended`, computed by the running runner over every part serving a step, passed on by the teller | a widening is said and nothing refuses it (ADR 0666 §23, §26); a change must not compute its own |
| `merge-pull` judged from the forge module's own `failed-steps`, heard from `step-ended`, any run at the head's fingerprint counting unless a later rerun of that step passed, the protection read again on every `branch-moved` | the record has it judge from the events it consumes, never by a call, so a head merges while the runner is down (ADR 0666 §11, ADR 0596) |
| The new assigner before the new `merge-pull` and the runner, by `needs`, both switching on the first `registration-changed` | a merge with no Approve must never reach an assigner that writes wants without a pipeline (ADR 0667 §5) |
| The new assigner before the new `merge-pull` and the runner, by `needs`, both switching on the first `registration-changed` | a merge with no Approve must never reach an assigner that writes wants without a pipeline (ADR 0667 §10) |
| The forge bridge's finding `branch-unprotected` | a move of a branch whose protection was removed starts no delivering pipeline and is said (ADR 0666 §6) |
| The verb `recovery` of `mesh-delivery` | a recovery is named by its author as a fact the bus keeps with who said it, never read from text (ADR 0666 §26, research 086 R10) |
| No forge status for a pipeline | the step results live on the bus (research 086 R10), shown by the runner and the delivery record; a status would be a second copy outside it |
| The runner's `pipelines` kept 30 days, its outputs 7, keyed by source revision | the delivery record keeps its own copy of the events for 90 days; about 300 pipelines a day must fit its caps |
| The checker's removal after the first end-to-end pipeline and a tested restore, its backup kept 90 days | ADR 0667 §6; 90 days is the delivery records' retention, the longest a trace reads back |
| The runner's `pipelines` kept as long as the delivery record that cites each (90 days), a superseded, run-on-request or uncited one 7 days, its step log 90 days by age, its outputs 7, keyed by source revision | a pipeline is read back as long as the record that delivered it; one nothing delivered has no trace to serve after a week; about 300 pipelines a day must fit its caps, so they are 256 MiB and 128 MiB |
| The forge module's `failed-steps` kept until no head it was seen at is a watched branch's head or an open pull request's | an entry judges only a head that can still be merged; once neither names it, nothing can be refused by it |
| The gate's `source.<branch>` deleted when the branch's last watch goes | a branch no registration watches makes no revision, so its key would name nothing |
| The sent store kept 7 days by age, with no person's word | an object sent carries one reply or event and is transport, not kept data (ADR 0595 §4); its readers fetch it within a call's bound or a consumer's lag |
| A replace removes the object it replaced; a gone key's object waits for the drop tool | no key names a replaced object, so nothing reads it; a deleted key may be wanted back, and ADR 0666 §16 drops it on a person's word |
| The checker's removal after the first end-to-end pipeline, on one word naming its `foundation` too, its buckets through `drop`, the snapshot kept 90 days | ADR 0667 §12 asks one word for all three; a registration change needs a warrant naming its value (ADR 0666 §2), so the one ask names it; 90 days is the delivery records' retention, the longest a trace reads back |
| The pipeline steps on the `check` stream after `delivery` | a delivery's build is never held by a pipeline, as a check never held one (ADR 0525 §4) |
## A delivery
@@ -1642,13 +1719,13 @@ the parts follow it through a seat (ADR 0656); a holder's own event stays under
manifest's `streams` and published on `mesh.stream.<module>.event.<event>` (ADR 0363 §1, §2). A seat's event is
declared in its definition and its holder's manifest claims the seat; a seat event's name has no dot, since it is read
as a subject's token, and it is kept on the stream `SEAT_<seat>_<event>`, which the grants part makes with its durable
consumers. **An event a node publishes carries the node in
consumers, keeping it by the age and cap the definition's `keep` names, 90 days unless it names less. **An event a node publishes carries the node in
its subject**, and the grants part grants each node-engine's account only its own node's subjects, so one node cannot
say another runs a build (ADR 0363 §2); the gate's events are granted to the gate's account alone.
| Step | Event | Owner: the seat, then the module | Subject | Declared in |
|---|---|---|---|---|
| a catalog graph revision kept, saying whether it is a trunk revision or a candidate's | `catalog-revision` | `mesh-catalog`, the indexer | `mesh.seat.mesh-catalog.event.catalog-revision` | the seat's definition in `mesh-delivery-contracts` |
| a catalog graph revision kept, saying whether it is a trunk revision or a candidate's and its watched branch; the one event every pipeline starts on, from G's delivery | `catalog-revision` | `mesh-catalog`, the indexer | `mesh.seat.mesh-catalog.event.catalog-revision`, the watched branch in the subject from G's delivery | the seat's definition in `mesh-delivery-contracts` |
| an assignment graph revision kept | `assignment-revision` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.assignment-revision` | the seat's definition in `mesh-delivery-contracts` (ADR 0641 §2) |
| a difference worked out | `difference` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.difference` | the same |
| an entry taken in | `take-in.taken`, which gains the entries | the indexer's own | `mesh.stream.mesh-delivery-indexer.event.take-in.taken` | the indexer's manifest |
@@ -3006,7 +3083,9 @@ of each verb (ADR 0666 §7, §20, §25):
| `rerun`, `accept`, `cancel`, `ask-again` | one step again; a failed `optional` step accepted with why; a pipeline ended, its asks dropped; a declined `approval` asked again | the operator, the healers (`accept` and `ask-again` the operator) |
**The seat `mesh-catalog`** gains, from milestone G's delivery, `register`, `policy`, `watch`, `unwatch` and
`registrations`, and the event `registration-changed` (*A module's registration*). **The build seats** gain the verb
`registrations`, and the event `registration-changed` (*A module's registration*); a registration carries `foundation`,
and `catalog-revision` names its watched branch in its subject and is the one event the runner starts a pipeline on,
a publication's included (*A publish rebuilds*). **The build seats** gain the verb
`steps` and the accepted kind `step`, and **the seat `mesh-wants`** the kind `step`, each saying `step-ended`. **The
seat `mesh-builds`**, new and held once for the mesh, says `package-published` (*A publish rebuilds*).
@@ -3473,8 +3552,11 @@ What milestone G's prepare found, and its test:
`assigner_puts` after milestone G's put of its own indexer).
From research 086 (ADR 0666 and ADR 0667), its acceptance tests by level and repository (research 086, choice 29): one
end-to-end test against the real bus per requirement, R1 to R18, each as the requirement's check states it, then the
failure paths and ADR 0667's checks. Each whole-module test below is a case of its module's one whole-module
test per requirement, R1 to R18, each as the requirement's check states it and at the level its entry names (unit,
whole-module against the real bus and store, or live), then the failure paths and ADR 0667's checks. Each clause of
ADR 0666 is checked at the level its row of the record's *How it is checked* names; the design's choice is that a
level is never raised to an end-to-end run for its own sake, since the test budget and the one check per release
bound what runs, and every requirement keeps its named test here. Each whole-module test below is a case of its module's one whole-module
integration test, which starts the module whole against the real bus and store; the runner,
`modules/mesh-delivery-pipeline` in mesh-delivery, has one of its own. The checker's tests go with it at G's delivery,
its whole-module test, its try test and the examiner's table among them, and so do the indexer's try-candidate rows and
@@ -3540,7 +3622,8 @@ The failure paths:
81. **A group that never completes** raises `take-in-waits` at 30 minutes, and none of its members is delivered (whole,
indexer and watchman).
82. **An indexer whose manifest its validator refuses** leaves its revision pending, holds only its own watched branch,
raises `take-in-waits` at 60 minutes, and a revert taken in moves the branch on (whole, indexer).
raises `take-in-waits` at 60 minutes, a later merge on that branch waits behind it and is not taken in past it, and
a revert taken in moves the branch on (whole, indexer).
83. **A declined registration change, and an unprotected branch,** each write nothing: the first after its Decline, the
second refused naming the branch; a watched branch whose protection is removed later starts no delivering pipeline
on its next move and raises `branch-unprotected` naming it (whole, indexer and forge bridge).
@@ -3555,9 +3638,11 @@ The failure paths:
and its successor never both write one pipeline key (compare-and-set), and a new runner's failing build leaves the
old one running pipelines; a build module restarted mid-step finishes the step from its work queue (whole, runner
and Go build module).
89. **An older revision ending after a newer one** writes no want; a newer commit supersedes a module's pipeline only
89. **An older revision ending after a newer one** writes no want, and a revision of one watched branch ending after a
newer one of another writes its own want and refuses neither; a newer commit supersedes a module's pipeline only
when it changed that module's build-input fingerprint (whole, assigner and runner).
90. **A replaced oversized value** leaves one object, and a deleted key takes its object (whole, mesh-sdk).
90. **A replaced oversized value** leaves one object; a deleted key leaves its object listed `key gone` until
`<module>_state_objects_drop` removes it on a person's word; a sent object expires after its 7 days (whole, mesh-sdk).
91. **A session's merge** through `merge-pull` at its head merges with no run yet and with a passed run, and asks no
Approve; with the runner stopped it still merges, judged on the `step-ended` it kept; a head at whose fingerprint any
run failed a `required` step, a head that moved, and a branch whose protection was removed since its last
@@ -3582,8 +3667,9 @@ ADR 0667's checks, of milestone G itself:
96. **No order by hand.** The delivery plan names every ordering edge it derived, and the hand-act log of the seat
`mesh-hand-acts` names none for the milestone (live).
97. **What G removes, and when.** The checker's buckets and bus account and the gate's forge merge token are removed
only after test 63 has passed on the mesh, after a backup of the buckets whose restore was tested, and after the
operator was told; then they are gone, and the backup is kept 90 days (live).
only after test 63 has passed on the mesh and on the operator's one word for all three, asked after a restore from
the stream snapshot was tested; the buckets are listed by `orphans` once the checker is unplaced and no longer
`foundation`, and go through `drop`; then they are gone, and the snapshot is kept 90 days (live).
98. **A failed head is said.** A `required` step that failed, or could not run, on a watched branch's head raises
`pipeline-failed`, the commit's author's for two hours and then the operator's, cleared when a newer revision of
that branch passes it (whole, runner and condition keeper).
@@ -3595,6 +3681,14 @@ ADR 0667's checks, of milestone G itself:
`merge-pull` reaches an old assigner; until the first registrations' `registration-changed` the new assigner writes
wants from the trunk alone and `merge-pull` refuses every merge, and after it both switch (live, read from the
delivery plan and the forge module's and the assigner's `running`; whole, assigner and forge module).
101. **The foundation from the registrations.** Given registrations marking `nats` foundation and not `node-tools`, the
manifest validator refuses `nats`'s manifest asking a template and judges `node-tools`'s as any part's; a change of
`foundation` without the warrant writes nothing; a module marked `foundation` that a watched branch's catalog graph
does not hold raises `foundation-differs`; no module name is left in the validator's code (unit, manifest
validator; whole, indexer, mesh-delivery; live, a search of the indexer's code).
102. **One start event.** The runner starts a pipeline only on `catalog-revision`, a commit's, a group's and a
publication's, and one publication of a package starts one pipeline per dependent artifact, never one more on
`package-published` (whole, runner and indexer, mesh-delivery).
## What retires
@@ -3653,8 +3747,8 @@ ADR 0667's checks, of milestone G itself:
- At milestone G's delivery, from research 086 (ADR 0666, ADR 0667): the checker (`mesh-delivery-checker`), its seat,
its try with `tryevent` and the indexer's try candidates, its kept verdicts and carries (the runner's from then), the
checking program and `mesh/check`, and its buckets and bus account, removed with the gate's forge merge token only
after the first pipeline after G's delivery has delivered a change end to end, after a backup kept 90 days whose
restore is tested, the operator told before (ADR 0667 §6); the bundle of steps run before a merge; the Approve per
after the first pipeline after G's delivery has delivered a change end to end and on the operator's one word, its
buckets through `drop` after a snapshot whose restore is tested (ADR 0667 §12); the bundle of steps run before a merge; the Approve per
merge, the milestone ask and its three events, and the gate's merges; the gate's merge states, one key per pull request and its verbs `table`, `recheck` and
`close`; the trunk-only want; `source.main`, for one source revision per watched branch; every fixed branch,
repository and module name in code logic; the recovery merge verb this design sketched, never built; and the holders'
@@ -3960,3 +4054,17 @@ Left as notes on issue 1921, not in this amendment: a conformance check that a c
size and retention of restore points and set-aside data; who may call `restore` for bus data and which manifest grants
the catch-up call; the hold's bound while a large backup is taken; the granting and placing bound read from the first
live run; a builder seat.
The joint amendment for milestone 47/G (2026-11-10) writes what the milestone's prepare found where ADR 0666, ADR 0667
and this design disagreed, each as this design's own choice with its reason: the foundation parts written once, as the
registration value `foundation` on the operator's Approve, the validator's list in code gone (ADR 0666 §5, where it
departs from ADR 0619 §3) and `foundation-differs` when a catalog graph disagrees; the want's compare-and-set per module
and watched branch; every pipeline started on `catalog-revision`, a publication's included, and the runner's health
read on that consumer; the cost of a refused new indexer revision, which holds its branch until a revert lands; each
check at its row's level, tests 101 and 102 added; ADR 0667's clause numbers as accepted, the gate's forge merge token
removed only at ADR 0667 §12's moment and on the operator's one word, and a fix before the first registrations merged
by the operator's own hand (ADR 0661 §3); the approval asked as the operator-channel's accepted kind `ask`; a replace
removing its object and a gone key's object left to the drop tool; the sent store, its 7-day age as transport, and its
two tools; and the retentions of what the milestone creates (the runner's pipelines and step log, the forge module's
`failed-steps`, the gate's `source.<branch>`, the kept seat streams). Its review by architectural domain is still to
come.
@@ -275,7 +275,8 @@ the verb.
names older content than the one below it. When the holder says `published`, the builder says the publication as the
event `package-published` of its seat `mesh-builds` (the name, the version, the fingerprint, the commit, the watched
branch). On it every artifact with a "published before it builds" edge to the package is rebuilt against the new
version, and the pipeline runner, which consumes the event, starts its pipeline (design 47, *A publish rebuilds*);
version; the indexer, which consumes the event, says the catalog revision the publication makes, and the pipeline
runner starts each such artifact's pipeline on that `catalog-revision`, once each (design 47, *A publish rebuilds*);
nothing else is rebuilt, and a change to a package's tests alone publishes nothing. This removes the claim's wait
for earlier merges' numbers below, which held a group on 2026-11-09 (research 086, Findings). Why at publication: a
number given at the claim must wait for every earlier merge's number, and a build that never publishes keeps a