It reported "N machines run an older host than another" by comparing versions as strings. A host reports its version as a commit, and commits have no order. On the live mesh it named the three machines running the NEWER host as the ones behind — ced54d4 sorts above 04a27ca and that is all it means. The code even carried a caveat saying versions compare as strings and that this "is enough for the timestamps and commits this mesh uses". That was the error, written down and not noticed: enough for timestamps, meaningless for commits, and the mesh reports commits. It now reports the split and claims no ordering, which is more useful as well as more honest — the reader sees who is on which side, and that is what decides whether a field can be sent. Ordering is left with the host, which would have to report something ordered for anybody to have it. This is issue 145 arriving by my own door an hour after I closed it: a report that confidently says the opposite of the truth is worse than one that says less.
2.1 KiB
status, opened, located-in, fixed-by, amended-design
| status | opened | located-in | fixed-by | amended-design | |||
|---|---|---|---|---|---|---|---|
| resolved | 2026-09-22 |
|
mesh-controller 7683ba8, corrected by 1d9c102 |
087 — The controller cannot tell that a node's host is too old for what it sends
What was observed
Found in review of the adoption-mode build, 2026-09-22, by reading the code.
A host parses a declaration strictly: a field it does not know makes it refuse the whole declaration, and nothing is applied. That is deliberate, and it is what keeps a half-understood declaration off a machine. It also means every new field in a declaration is a flag day: hosts must be upgraded before the controller sends it.
The controller has no record of which version of the host a node runs. It is not in what a node reports, and it is not in the node's profile. So when a node refuses a declaration for that reason, the mesh shows the node failing and relays the host's refusal. Nothing says the host on this machine is older than what the mesh now sends, and nothing could have said so beforehand.
Adoption mode adds four such fields, one of them on the declaration of every node, and its merge order exists for this reason alone: the host merges first, every machine is upgraded, then the controller.
Why it matters beyond this instance
Every future field in a declaration has the same flag day, and the mesh upgrades itself. A mesh that cannot say which machines are ready for what it is about to send has to be upgraded by someone remembering the order. The rule that a host refuses what it does not understand is right; the missing half is that the controller should know before it sends.
Open questions
- Should a node report the version of its host, so the controller can refuse to send a declaration a node cannot parse, and say which machines are behind?
- Should the mesh refuse to send a field no node understands yet, or refuse per node and say so?
- Is there a general shape here — a declaration saying which version of the host it needs — or is a reported version enough?