diff --git a/02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md b/02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md index dabf0b04..c513a75e 100644 --- a/02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md +++ b/02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md @@ -164,6 +164,18 @@ either, because **delivery group** already names deliveries that share a head br repository exist and that none names its merge, or that the controller holds none) and listed by `stalled` at once, so probe D14 raises it for the operator. +> **Decided during the build, 2026-10-10** (on the operator's delegation). Decision 2 batches every merge of the +> window together, and decision 4 starts a walk on the controller's own path without mesh-delivery's word. A +> batch holding both a merge on that path and a catalogue merge would therefore start the catalogue's deliveries +> without their word: their turn in a delivery group, their holds, and the order of decision 5 would be skipped. +> So **a merge on the controller's own path never shares a batch with a merge that waits for the delivery's +> word.** Such a merge goes into a batch of its own, with its own window; the open catalogue batch closes and is +> cut by the normal rules, and queues behind the own-path walk like any other. Catalogue merges heard during the +> own-path batch's window join the next catalogue batch. An own-path walk being cut folds no catalogue walk that +> waits for its word: that walk's merges are batched again behind it, and the walk names that batch as the one +> that took it over, so no catalogue delivery ever skips its turn. Checked by the controller's test +> `TestAMergeOnTheControllersPathNeverSharesABatch`. + ## Consequences - **A merge waits up to 90 seconds before it is planned**, and up to 10 minutes in a busy period. A walk @@ -181,6 +193,11 @@ either, because **delivery group** already names deliveries that share a head br restart-safe; the walk's record names several repositories and commits instead of one, and every reader of it (`plans`, S3, S16, `plan-moved`, mesh-delivery) changes with it. The store gains the batch and the merges a walk answers, as a numbered migration and in the consolidated schema. + +> **Progressive insight — 2026-10-10.** The controller has no consolidated schema file: a fresh install runs its +> numbered migrations from the first, embedded in the build, so the numbered migration (0089) is the whole of +> the schema change. The bullet above said "as a numbered migration and in the consolidated schema"; that second +> half describes mesh-delivery's kind of store, not the controller's. The decision stands. - **The replay of issue 362** in the lab raises a mesh, merges two commits of one repository 18 seconds apart, and passes when one walk delivers both without a person; it fails on the commit before the change. 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 16dcac84..8f59bb0a 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-10 decisions: + - 02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md - 02-DECISIONS/0271-a-send-held-for-the-buss-planned-step-is-told-to-the-operator-at-once-and-a-change-that-needs-it-says-so-before-it-merges.md - 02-DECISIONS/0265-a-verb-that-reads-is-answered-on-the-serving-controllers-own-connection-and-every-connection-says-what-it-is.md - 02-DECISIONS/0264-a-message-a-consumer-gives-up-on-is-kept-until-a-person-delivers-it-again-or-drops-it.md @@ -238,6 +239,8 @@ signal and asserts its condition. `doctor signals` shows, for every row, the age | S15 | a hand act with a cause already recorded | hand-act log | each act | the second within 14 days; clears when fewer than two remain within 14 days | `healer-wanted` (names the cause, and the healer that was not enough where one answers it) | warning | — | | S16 | a walk waiting for its delivery's word is let go | mesh-delivery, through `deliver` (ADR 0239) | each merge whose walk waits | 30 min; urgent after 4 h | `waiting` (names the walk and `plans go`) | warning | — | | S17 | a send held for the bus's planned step is told to a person (ADR 0271) | controller's plan | each send refused because it would replace the bus outside its step | none: the first refusal; cleared once the bus's machine has been sent the build the mesh holds | `bus-step-waiting`, for the operator (names the machines, what waits, the bus build from and to, since when and the `mesh-controller.bus` call); S3 leaves such a walk out | warning | — | +| S18 | a batch of merges is cut into its walk (ADR 0276) | controller's merge window | each batch | a minute past `merge-window-at-most` while no walk is open: the controller failed to cut it | `batch-not-cut` (names the batch and what it holds) | warning | — | +| S19 | a batch waiting behind an open walk is cut when it ends (ADR 0276) | controller's merge window | each batch closed while a walk is open | that walk's bound, a tier's bound for each of its tiers, from when the batch closed | `batch-behind-walk` (names the walk) | warning | — | The bus advisories (S9) cost one read-only subscription: the server already publishes them. The controller translates each into a condition naming the thing in the mesh's words, as the refused reply 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 2949244b..eead5824 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 @@ -130,6 +130,11 @@ controller's `plan-moved` event, never inferred from time. - **One walk at a time.** Merges that arrive while a walk is open join the next batch. A walk that started is never superseded. A walk still waiting for its word when the next batch is cut is folded into the new walk, which answers every merge the folded one answered. +- **The controller's own path.** A merge that moves a module whose walk waits for nobody's word (the controller, + the node-engine, the tool runner, the bus, mesh-delivery) never shares a batch with one that waits for + mesh-delivery's: it has a batch of its own, with its own window, and the catalogue's batch queues behind its + walk like any other. An own-path walk folds no waiting catalogue walk; that walk's merges are batched again + behind it, so no catalogue delivery skips its turn (ADR 0276, decided during the build, 2026-10-10). - **A late merge.** A merge heard after a later merge of its repository and branch was put in a walk is answered by that walk: the assembling batch, the open walk, or, when that walk was delivered, it ends `covered` at once. diff --git a/04-ISSUES/362-two-merges-seconds-apart-left-their-delivery-waiting-for-a-person/00-report.md b/04-ISSUES/362-two-merges-seconds-apart-left-their-delivery-waiting-for-a-person/00-report.md index c1752d85..5b5a2e3c 100644 --- a/04-ISSUES/362-two-merges-seconds-apart-left-their-delivery-waiting-for-a-person/00-report.md +++ b/04-ISSUES/362-two-merges-seconds-apart-left-their-delivery-waiting-for-a-person/00-report.md @@ -1,8 +1,9 @@ --- -status: located +status: resolved opened: 2026-10-10 located-in: [mesh-catalog modules/mesh-delivery (holder.go deliveryWalking), mesh-controller cmd/mesh-controller (upgrades.go SourceMoved, release_plan.go laterOnTheBranch)] -fixed-by: +fixed-by: mesh-catalog#171, mesh-controller#197 +replay: R362 amended-design: 03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md --- @@ -65,3 +66,14 @@ The operator decided the model that removes this shape, not only its bookkeeping commit per repository, one walk at a time. The bookkeeping that tied a walk to an ended delivery is repaired as well, and every wait of this shape has a bound and a condition. It is designed in to-be 47, *The merge window and the batch*. + +## Resolved + +2026-10-10. mesh-delivery's side is mesh-catalog#171 (merged): a walk is tied to every live delivery whose +merge it answers, never to one that has ended, and a waiting walk no live delivery holds is listed by `stalled` +at once. The controller's side is mesh-controller#197: the merge window and the batch, one walk per batch with +one commit per repository, the walk naming every merge it answers, and the bounds of decision 9. The replay +R362 is registered in mesh-lab's replays register (mesh-lab#75), proved to fail on the commit before the +mesh-delivery fix and pass on it. The build raised one rule the record had not settled, decided during the +build and written into ADR 0276: a merge on the controller's own path never shares a batch with a catalogue +merge.