diff --git a/00-META/glossary.md b/00-META/glossary.md index 04bd1286..cf622668 100644 --- a/00-META/glossary.md +++ b/00-META/glossary.md @@ -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). diff --git a/03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md b/03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md index e762ae39..87d005b5 100644 --- a/03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md +++ b/03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md @@ -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 diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index c741eda0..0b2ece77 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -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