Issue 087 is resolved: the mesh knows which host runs a machine #203
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
status: open
|
status: resolved
|
||||||
opened: 2026-09-22
|
opened: 2026-09-22
|
||||||
located-in: []
|
located-in: [mesh-controller internal/link/protocol.go (the report field that was missing), internal/inventory, cmd/mesh-controller (node show and status)]
|
||||||
fixed-by:
|
fixed-by: mesh-controller 7683ba8
|
||||||
amended-design:
|
amended-design:
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# 087 — resolved: the mesh knows which host runs a machine
|
||||||
|
|
||||||
|
*2026-09-30.*
|
||||||
|
|
||||||
|
## The field existed and was thrown away on arrival
|
||||||
|
|
||||||
|
The machine has reported its host version since
|
||||||
|
[ADR 0141](../../02-DECISIONS/0141-the-host-delivers-its-own-successor.md) — `Host` on the report, with
|
||||||
|
a comment saying why it must be there: *"without it nothing can say a machine is behind."*
|
||||||
|
|
||||||
|
**The controller's own copy of the report did not have the field.** Two structs describe one message,
|
||||||
|
one on each side of the wire, and only the sending side had it — so it unmarshalled into nothing and the
|
||||||
|
mesh could not answer a question the machine had been answering for a week. That is the whole of this
|
||||||
|
issue's mechanism, and it is worth stating plainly because neither side was wrong on its own.
|
||||||
|
|
||||||
|
## What it says now
|
||||||
|
|
||||||
|
`node show` names it per machine:
|
||||||
|
|
||||||
|
```
|
||||||
|
last heard from here
|
||||||
|
host 2026-09-30-0214
|
||||||
|
```
|
||||||
|
|
||||||
|
`not reported — this machine has not said since the mesh began keeping it` where the mesh has not been
|
||||||
|
told, because a machine that has not said is a different thing from a machine running nothing.
|
||||||
|
|
||||||
|
`status` names the machines that are behind another:
|
||||||
|
|
||||||
|
```
|
||||||
|
1 machine(s) run an older host than another machine does:
|
||||||
|
ace 2026-09-29-0113
|
||||||
|
|
||||||
|
the newest any machine reports is 2026-09-30-0214. A host refuses a declaration carrying a
|
||||||
|
field it does not know, whole — so a new field reaches these machines last
|
||||||
|
```
|
||||||
|
|
||||||
|
## Disagreement, not staleness, and that is deliberate
|
||||||
|
|
||||||
|
The open questions asked whether the controller should refuse to send a declaration a node cannot
|
||||||
|
parse. It cannot yet, honestly: **nothing delivers a host version** (ADR 0141 is accepted and not
|
||||||
|
built, which is [issue 142](../142-the-host-is-the-one-thing-the-mesh-does-not-deliver/00-report.md)),
|
||||||
|
so the mesh holds no canonical current version and "behind" has no fixed point to be behind.
|
||||||
|
|
||||||
|
What it can say truthfully is that these machines do not all run the same host, and which is newest of
|
||||||
|
the ones it has been told about. That is the fact that matters before a declaration gains a field: **the
|
||||||
|
oldest host in the mesh is what the mesh may send.**
|
||||||
|
|
||||||
|
Two deliberate refusals to guess:
|
||||||
|
|
||||||
|
- **A machine that has reported nothing is not called behind.** It may be running anything. `node show`
|
||||||
|
says it has not said, per machine, which is the honest form.
|
||||||
|
- **Versions compare as strings.** That suits the timestamps and commits this mesh uses and is wrong
|
||||||
|
for a scheme where `10` sorts before `9`. Said in the code at the place that would have to learn,
|
||||||
|
rather than left as a surprise.
|
||||||
|
|
||||||
|
## The open questions, answered as far as they can be
|
||||||
|
|
||||||
|
- *Should a node report the version of its host?* It already did. The gap was the reading.
|
||||||
|
- *Should the mesh refuse to send a field no node understands yet, or refuse per node and say so?*
|
||||||
|
Neither, yet — refusing needs the mesh to know which fields need which version, which is the third
|
||||||
|
question below and is not answered here. What it does is make the disagreement visible before
|
||||||
|
somebody adds a field.
|
||||||
|
- *Is there a general shape — a declaration saying which version of the host it needs?* Still open, and
|
||||||
|
now cheaper to answer: the versions are recorded, so a minimum-version field on a declaration has
|
||||||
|
something to compare against. It belongs with
|
||||||
|
[issue 107](../107-a-declaration-carries-no-order/00-report.md), which wants to add a field and is the
|
||||||
|
first thing this makes safe.
|
||||||
@@ -40,3 +40,16 @@ exists there and is thrown away at the wire.
|
|||||||
separate genesis-digest branch is needed on the host?
|
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
|
- 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?
|
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.
|
||||||
|
|||||||
Reference in New Issue
Block a user