Hosts first, then the controller — a build and a push each, now that the mesh delivers the host. The host refuses a lower sequence than it kept and drains a batch by sequence rather than arrival; the controller numbers each send under the node's hold, inside the signed bytes. Measured: two pushes, sequence 2 in the kept declaration, counters in the store agree, no machine reads as behind. That last one is the subtlety: the mesh compares the digest of what it would send against what it did, and a number changes the bytes, so the read-only comparison composes with the last number sent rather than a fresh one.
56 lines
3.2 KiB
Markdown
56 lines
3.2 KiB
Markdown
---
|
|
status: resolved
|
|
opened: 2026-09-23
|
|
located-in: [mesh-controller internal/link, mesh-host internal/link]
|
|
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:
|
|
---
|
|
|
|
# 107 — A declaration carries no order, so a host cannot tell an older one from a newer
|
|
|
|
## What was observed
|
|
|
|
Reviewing the fix for [issue 104](../104-reconcile-applies-a-stale-declaration-and-refuses-nothing/00-report.md),
|
|
2026-09-23. A signed declaration carries a vocabulary version, the node it is for, its mode and
|
|
its resources — and nothing that orders it against another. Its only identity is the digest of
|
|
its bytes. So a host asked to apply a file can say "this is not the one the mesh last sent"; it
|
|
cannot say "this is older".
|
|
|
|
The same absence reaches the link. The host drains a backlog of declarations and applies the
|
|
newest it received, but "newest" is decided by arrival within a batch of sixteen and a 750 ms
|
|
window: a backlog of more than sixteen pushes queued across a `converge`/`adopt` pair, or a slow
|
|
broker splitting one, applies a declaration the controller had already superseded. Not observed;
|
|
constructed from the code, and narrow — but a converged declaration applied to a node that has
|
|
since been returned to adopted is the incident of issue 104 by another door.
|
|
|
|
## Why it matters beyond this instance
|
|
|
|
Ordering is the one property a declaration needs that its signature does not give it. Every
|
|
refusal the host can make about staleness today is "not the last", which is both too strict (a
|
|
legitimately newer file is refused too) and too weak (a replay within a batch is not caught). The
|
|
controller already holds a per-node lock while it composes and records each send; the order
|
|
exists there and is thrown away at the wire.
|
|
|
|
## Open questions
|
|
|
|
- Should the signed declaration carry a per-node `sequence`, assigned under the controller's node
|
|
hold and persisted with the node, and `supersedes` — the digest of the previous send — so a host
|
|
refuses anything not strictly newer, on the link and from a file alike?
|
|
- Should genesis sign its rewritten bundle as sequence zero, so one rule covers the bundle and no
|
|
separate genesis-digest branch is needed on the host?
|
|
- Is a sequence enough, or does a mode change deserve its own marker, so a replayed converged
|
|
declaration is refused by mode as well as by order?
|
|
|
|
## What has since made this safer to do (2026-09-30)
|
|
|
|
Adding a `sequence` to a declaration is adding a field, and a host refuses a declaration carrying a
|
|
field it does not know — whole. That was
|
|
[issue 087](../087-the-controller-cannot-tell-a-host-is-too-old/00-report.md), and it is resolved: the
|
|
mesh now records which host each machine reports and `status` names every machine running an older one
|
|
than another does.
|
|
|
|
So the flag day is visible before it is walked into, which it was not when this was filed. It does not
|
|
make the field free: **the oldest host in the mesh is still what the mesh may send**, and one machine of
|
|
four is behind today. A sequence that an old host refuses takes that machine out of the mesh's reach
|
|
entirely — worse than the replay it prevents, which has never been observed.
|