Give ADR 0323 its place in to-be 47, to-be 45 §9 and the glossary (issue 341)
mesh/delivery-group group feat/341-a-merge-check-judges-the-merge checking: 0 of 3 member(s) ready
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request

A merge check now judges the head merged into a named trunk commit and its
verdict goes out of date when the trunk moves; the designs and the glossary say
so, with the tests that hold it.
This commit is contained in:
2026-10-12 17:29:59 +02:00
parent 285ead0043
commit e373474db7
3 changed files with 41 additions and 8 deletions
+6 -2
View File
@@ -305,13 +305,17 @@ and the operator act. **Recorded by** the controller's `identity` and `licences`
**Purpose.** To take one commit from its pull request to every node that should run it, and to put it
back when it fails. **Recorded by** the `mesh-delivery` module (deliveries) and the controller (the
planner, the walk). **Downstream of** Module, Core, Health and repair and Data.
**Decided by** ADR 0162, 0218, 0236, 0237, 0238, 0239, 0250, 0267, 0270, 0276.
**Decided by** ADR 0162, 0218, 0236, 0237, 0238, 0239, 0250, 0267, 0270, 0276, 0323.
**Uses:** module, node, declaration and send (Placement), health (Health and repair), person.
- **merge check** — the two statuses a pull request carries before it may merge: the **merge gate**
(`mesh/merge-gate`, the build seat's composed check of the modules the change touches) and the
**repository check** (`mesh/repo-check`, the repository's own `merge-check.sh`)
(ADR 0238).
(ADR 0238). Both judge the merge of the pull request's head into a named **trunk commit**, made in the
build seat's own clone and never pushed (ADR 0323).
- **trunk commit** — the commit of the trunk a merge check's verdict was judged against: the trunk's head when
the build seat cloned it. The verdict holds for that commit only, and goes out of date when the trunk moves
(ADR 0323).
- **build seat** — the seat whose holder builds modules, `node-build-agent`; its holder on a node is the
**builder**. Any node may hold the seat, so there is no build node by nature
(ADR 0237).
@@ -4,6 +4,7 @@ status: in-progress
code: [mesh-controller, mesh-host, mesh-tools, mesh-catalog, mesh-sdk, mesh-lab]
updated: 2026-10-12
decisions:
- "ADR 0323"
- "ADR 0314"
- "ADR 0293"
- "ADR 0289"
@@ -671,7 +672,19 @@ R310). A repository with none has "no repository
check defined", a success where the branch does not require `mesh/repo-check` and a failure for a person
where it does. **A note is never a warning on a required status**: the forge combines `warning` as a
failure, so a note — a wide rebuild, a problem already so on the base — is a success that says it, and only
what a person must decide fails (issue 293; checked by the forge module's status tests). The
what a person must decide fails (issue 293; checked by the forge module's status tests).
Revision, ADR 0323 (2026-10-12). **The gate judges what merging makes, not the head.** The build seat takes
the trunk the pull request merges into, its head at that moment as the check's **trunk commit**, and makes in
its own clone the merge of the head into it, as the forge's default merge would; both layers judge that
merge, and a head that does not merge cleanly fails, naming the files in conflict. The merge is only checked:
never pushed, never registered. The verdict names the head and the trunk commit in both statuses' words
("head … merged into trunk …"), in mesh-delivery's `checks` and `show` and in the kept delivery plan, and
names the commits of the other repositories the check read; their move is issue 568's question. When the
trunk moves, the forge's holder puts both statuses of every open pull request into it back to pending with
the reason and runs nothing; the merge tool refuses a verdict whose trunk commit is not the trunk's head,
asks that head's check once, says how long the last check of the repository took, and never merges by
itself (checked by the builder's `TestReplay341`, replayed as R341, and the forge module's `trunk` and
`guard` tests). The
check's result is the commit's **delivery plan** — the build plan, the deploy plan machine by machine with
what is not an ordinary send, and the verdict — posted on the pull request. The plan is one object with
a state machine, kept, followed by the release and written to the commit as a note; which parts are built
@@ -4,6 +4,7 @@ status: in-progress
code: [mesh-controller, mesh-catalog modules/mesh-delivery]
updated: 2026-10-12
decisions:
- "ADR 0323"
- "ADR 0313"
- "ADR 0306"
- "ADR 0299"
@@ -81,7 +82,7 @@ allows.
| State | Means | Bound | H2 after the bound |
|---|---|---|---|
| proposed | a head was announced and is being checked | 1 hour | nothing: the check's own watchdog (S6) speaks |
| proposed | a head was announced and is being checked | 1 hour from when its check is asked; none while its verdict is out of date and no check is asked | nothing: the check's own watchdog (S6) speaks |
| checked | a verdict arrived | 1 minute | nothing: it is decided at once |
| ready | it passed; it waits to be merged | none | — |
| rejected | it failed its check | none | — |
@@ -90,7 +91,16 @@ allows.
| delivering | its walk runs; its builds are asked and registered tier by tier | 2 hours | `delivered`, `failed` or `superseded`, as the walk's record says |
| delivered, failed, superseded, stopped, retired, covered | final | — | — |
The transitions are those of ADR 0239 decision 2 and ADR 0270. A delivery that is
**A verdict holds for one trunk commit** (ADR 0323). The check judges the head merged into the trunk's head
at the moment the build seat clones it, the **trunk commit**, and the verdict names both. When another merge
moves the trunk, a `ready` delivery goes back to `proposed` on the observed event `trunk moved`, with both
commits in the transition's reason; a `rejected` one stays `rejected`, its statuses saying the verdict is out
of date. Nothing is asked for it: a recheck, a new head or the merge tool asks the check again. The row from
`proposed` to `checked` takes only a verdict that names the trunk's head as its trunk commit, so a verdict for
an older trunk is kept and shown and does not count, and the rows reach a fixed point. Checked by
mesh-delivery's `TestATrunkMoveSendsAReadyDeliveryBackToProposed` and the table's own walk.
The transitions are those of ADR 0239 decision 2, ADR 0270 and ADR 0323. A delivery that is
merged while not `ready` goes to `held`. Its check did not pass, and only a person decides that it goes on. A
delivery merged with no walk answering it within ten minutes is held too, with the true reason, and listed by
`stalled` at once. Nothing waits silently.
@@ -308,9 +318,15 @@ only once it is built.
first, then *built by* and *version skew*, then *engine before controller*. The pair shows the rule that
won and the rules it won over. Rules of one rank both ways are a contradiction. The group is `rejected`,
and the reason names both members, both rules and the `after:` line that would settle it.
- **Check**: the members' heads composed together, one gate over every machine with all their definitions. It
is asked by mesh-delivery through `delivery-check` when the group forms or a member's head moves, and
posted on every member's head as `mesh/delivery-group`.
- **Check**: the members' heads composed together, one gate over every machine with all their definitions,
each head merged into its own trunk's head first and named with that trunk commit (ADR 0323). It is asked
by mesh-delivery through `delivery-check` when the group forms or a member's head moves, and posted on
every member's head as `mesh/delivery-group`. A member rebased or pushed is a new head with its own check:
it takes its old head's place in the group, even once the group is delivering, and the composed check runs
again for the new heads instead of holding the group. A merge into a member's trunk that is not one of the
group's members puts the composed check out of date: the group reads `checking` with the reason, and the
composed check runs again once a member is judged again. Checked by mesh-delivery's
`TestAGroupsComposedCheckGoesOutOfDateOnAMergeThatIsNotItsMember` and `TestARebasedMemberIsComposedAgainNotHeld`.
- **Delivering**: in order. A member waits in `published` until the one before is `delivered` or `covered`.
A member published while its group's composed check is asked and not answered waits there for the answer;
one held because that check had not passed is *lifted* back to `published` once it passes or warns for the