From e373474db74dd640c5b64d17e08fa3053cedd02e Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 12 Oct 2026 17:29:59 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Give=20ADR=200323=20its=20place=20in=20to-b?= =?UTF-8?q?e=2047,=20to-be=2045=20=C2=A79=20and=20the=20glossary=20(issue?= =?UTF-8?q?=20341)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- 00-META/glossary.md | 8 ++++-- .../45-a-core-that-cannot-fail-silently.md | 15 ++++++++++- .../47-delivery-from-commit-to-delivered.md | 26 +++++++++++++++---- 3 files changed, 41 insertions(+), 8 deletions(-) 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 From 09916e2bbc076a46d721588e9caee98230050923 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 12 Oct 2026 17:46:42 +0200 Subject: [PATCH 2/2] Say in to-be 47 what ADR 0323 leaves as it is, and give to-be 45's revision its own paragraph The review asked that the trunk-less verdicts, mesh-delivery's trunk head, the refuse-ask race and the lost check's recheck be said, and found the revision spliced mid-paragraph. --- .../45-a-core-that-cannot-fail-silently.md | 13 +++++++------ .../47-delivery-from-commit-to-delivered.md | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) 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 87d005b5..769c2c79 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 @@ -672,7 +672,12 @@ 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). +what a person must decide fails (issue 293; checked by the forge module's status 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 +is Phase 5's. + 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 @@ -684,11 +689,7 @@ trunk moves, the forge's holder puts both statuses of every open pull request in 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 -is Phase 5's. +`guard` tests). **The replays.** mesh-lab carries a scripted scenario for each core incident, asserting the rule's outcome, run on every merge to mesh-controller, `mesh-host` and mesh-tools: 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 0b2ece77..8e7be134 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 @@ -100,6 +100,22 @@ of date. Nothing is asked for it: a recheck, a new head or the merge tool asks t 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. +What this leaves as it is, said so nobody reads more into it: + +- **mesh-delivery's trunk head is the last merge it heard** into that trunk while the delivery was open. A push + to the trunk that is not a merge it hears does not move it; the forge's holder, which reads the branch, and + the merge tool, which compares commits when asked, still catch it. +- **A verdict that names no trunk commit**, from a build seat older than ADR 0323, counts in mesh-delivery as it + did: such a delivery stays `ready`. The forge reads the same verdict out of date once its trunk moves, and the + merge tool refuses it and asks the check. The two agree once the head is judged again. +- **A verdict no build judges** (a change that touches no module, in a repository with no `merge-check.sh` or + not the mesh's) names the base branch's head the forge announced with the head as its trunk commit. +- **In a busy repository the merge tool can refuse, ask, and refuse again**: another merge may move the trunk + while the asked check runs, and the new verdict is then out of date too. Each refusal asks once more; the + merge goes through once a check finishes before the next merge. +- **A check that was asked and never answers** is listed by `stalled` an hour after the ask, and is asked again + with `mesh-delivery.recheck`, which the merge tool's refusal names. + 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