diff --git a/04-ISSUES/107-a-declaration-carries-no-order/00-report.md b/04-ISSUES/107-a-declaration-carries-no-order/00-report.md index 79a530a..a54dde1 100644 --- a/04-ISSUES/107-a-declaration-carries-no-order/00-report.md +++ b/04-ISSUES/107-a-declaration-carries-no-order/00-report.md @@ -1,8 +1,8 @@ --- -status: located +status: resolved opened: 2026-09-23 located-in: [mesh-controller internal/link, mesh-host internal/link] -fixed-by: +fixed-by: mesh-host PR 59 (the host refuses an older sequence and drains by it), mesh-controller PR 160 (each send is numbered under the node's hold) — measured 2026-09-30, 02-resolution.md amended-design: --- diff --git a/04-ISSUES/107-a-declaration-carries-no-order/02-resolution.md b/04-ISSUES/107-a-declaration-carries-no-order/02-resolution.md new file mode 100644 index 0000000..15a9b3a --- /dev/null +++ b/04-ISSUES/107-a-declaration-carries-no-order/02-resolution.md @@ -0,0 +1,60 @@ +# 107 — resolved: a declaration carries its order + +*2026-09-30. Measured on the mesh.* + +## What was done + +**Hosts first, then the controller** — the order [issue 087](../087-the-controller-cannot-tell-a-host-is-too-old/00-report.md) +says a new declaration field needs, and now a build and a push rather than an expedition +([issue 142](../142-the-host-is-the-one-thing-the-mesh-does-not-deliver/01-progress.md)). + +The host understands a `sequence` on a declaration and tolerates its absence: absent reads as "no +order claimed", not "first", so a controller that sends none is still understood and a host that kept +a declaration before it understood the field compares nothing. It refuses a declaration with a lower +sequence than the one it kept, whole, and says why; and the drain that picks one declaration from a +batch keeps the highest sequence rather than the last to arrive — which is the case the report +constructed, a backlog drained out of order. + +The controller numbers each send: the next number for that node, taken under the node's hold, before +the body exists, so the number is inside what the mesh signs and a replayed older declaration cannot +borrow a newer one's. + +## Measured + +``` +push shanks; push shanks +sequence in kept declaration: 2 +node sequence +novox 2 +shanks 2 +ace (none — not sent since numbering) +g14 (none) +status: nobody "not running what the mesh would send them" +``` + +Both applies went through; neither was refused; the machine holding the earlier one accepted the later. + +## The subtlety, which would have read every machine as behind for ever + +The mesh decides a machine is behind by comparing the digest of what it **would** send against what it +**did** send. A number changes the bytes. So the read-only comparison composes with the number the +machine was *last* sent — not a fresh one — and is byte for byte what was sent when nothing else +changed. Without that, numbering would have made `status` name all four machines as out of date on +every reading, permanently. + +## The open questions + +- *A per-node `sequence` under the controller's node hold?* Yes, as described. **`supersedes` — the + previous digest — is not added.** A strictly-greater sequence gives the ordering; a chain of digests + would give continuity, which nothing here needs yet and which every re-composition would break. +- *Genesis signing its bundle as sequence zero?* Zero is "no order claimed", which is what the bundle + carries by carrying nothing. Same rule, no genesis branch. +- *A marker for a mode change?* Not needed for the incident it guards: a replayed converged declaration + reaching a node returned to adopted is already refused **by mode**, before this check runs. + +## How it is checked + +Host: an older sequence is refused, a newer or equal one is not, and no order claimed on either side +compares nothing; the drain keeps the highest sequence, and falls back to arrival when none is claimed. +Controller: a send carries its number inside the signed bytes, an unnumbered send is byte for byte what +it was before, and each node's counter is one higher per send and readable for the comparison.