Group 1: 145's report states its scope, and 107 waits for delivery #204

Merged
jschoubben merged 1 commits from issue/145-and-107-what-group-one-leaves into main 2026-09-30 07:00:32 +00:00
4 changed files with 148 additions and 1 deletions
Showing only changes of commit b7f7b97d8a - Show all commits
@@ -0,0 +1,68 @@
# 107 — diagnosis: the fix is a flag day, and it should wait for delivery
*2026-09-30. Read, measured, and not built — deliberately.*
## The premise is confirmed
A host parses a declaration with unknown fields refused, and the code says why rather than leaving it
to be inferred:
> `DisallowUnknownFields` is the whole point rather than strictness for its own sake: a field the host
> does not know is a thing the control plane believes it asked for.
So adding `sequence` and `supersedes` is not an additive change. **Any host that has not been upgraded
refuses the whole declaration and applies nothing** — which is exactly the behaviour that keeps a
half-understood declaration off a machine, and exactly what makes this expensive.
## What has changed since this was filed
[Issue 087](../087-the-controller-cannot-tell-a-host-is-too-old/00-report.md) is resolved: the mesh now
records the host version each machine reports and `status` names every machine running an older host
than another does. The flag day is visible before it is walked into, which it was not on 2026-09-23.
That makes the cost measurable rather than hypothetical, and the measurement is the reason this is not
being built today.
## Why it waits
**One machine of four runs an older host, and it cannot be upgraded.** `ace` is adopted, deliberately
parked until the network and module-assignment work is settled, and **nothing delivers a host version at
all** — [ADR 0141](../../02-DECISIONS/0141-the-host-delivers-its-own-successor.md) is accepted and not
built, which is [issue 142](../142-the-host-is-the-one-thing-the-mesh-does-not-deliver/00-report.md).
Every machine takes a hand-placed binary.
So shipping the field means, in order: place a host by hand on three machines, unpark the fourth, place
it there too, and only then turn the controller half on. A machine missed in that sequence is a machine
the mesh cannot send anything to at all — not degraded, unreachable.
**And the fault it prevents has never been observed.** The record says so itself: *"Not observed;
constructed from the code, and narrow."* It needs a backlog of more than sixteen declarations queued
across a `converge`/`adopt` pair, or a broker slow enough to split one, and the host already applies the
newest of a drained batch and refuses a declaration that is not the last by digest.
**Trading a machine's reachability for a replay nobody has seen is the wrong way round.** The right
order is [issue 142](../142-the-host-is-the-one-thing-the-mesh-does-not-deliver/00-report.md) first —
when the mesh can deliver a host, a declaration field costs a rollout instead of an expedition — and the
work order already puts that in its last group, as the proof that the mesh can make another of itself.
## What the open questions look like now
- *A per-node `sequence` under the controller's node hold, and `supersedes` as the previous digest?*
Still the right shape. The controller already holds the lock and already records each send, so the
order exists and is thrown away at the wire — unchanged since this was filed.
- *Genesis signing its bundle as sequence zero?* Yes, and it is the cheaper half: the bundle is written
by the host that will read it, so it has no flag day of its own.
- *Is a sequence enough, or does a mode change deserve its own marker?* A sequence alone does not stop
a replayed *converged* declaration reaching a node that has since been returned to adopted, which is
the incident of issue 104 by another door and is what this record names as its real risk. It wants
both, and the second is the one worth having first.
- **And one this record did not ask:** should a declaration say which host version it needs? 087 makes
that comparable for the first time, and it is the general form of the answer — a field that announces
its own requirement, rather than a flag day per field, for ever.
## Status
Left `located`. The owner is unchanged, the shape of the fix is agreed, and the gate is
[issue 142](../142-the-host-is-the-one-thing-the-mesh-does-not-deliver/00-report.md) rather than anything
in this record. **This is a judgement about order, not a refusal** — it is cheap to overrule, and the
code is a day's work once a host can be delivered.
@@ -74,3 +74,18 @@ every future change of this shape, and it was paid today.
argues for the former.
- Does the same gap apply to the launcher and the units beside the binary, which are also files no
declaration names?
## What now waits on this (2026-09-30)
[Issue 107](../107-a-declaration-carries-no-order/00-report.md) — a declaration carries no order, so a
host cannot tell an older one from a newer. Its fix adds a field to the declaration, and a host refuses a
declaration carrying a field it does not know, **whole**. So it is a flag day: every host upgraded, then
the controller.
With nothing delivering a host, that means placing a binary by hand on every machine and unparking the
adopted one, and a machine missed in the sequence is a machine the mesh cannot send anything to at all.
107 is held for that reason rather than for anything in its own diagnosis.
**This is what makes a declaration field cost a rollout instead of an expedition**, which is a use for
this record beyond keeping machines current: it is the thing standing between the mesh and its own
protocol evolving.
@@ -4,7 +4,7 @@ opened: 2026-09-29
located-in:
- mesh-controller internal/catalogue/filtering.go (fixed for this instance)
- mesh-controller (what status reports, and what it does not ask)
fixed-by:
fixed-by: partly — mesh-controller 1da96e8 makes the report state its own scope; nothing dials a provision yet, which is ADR 0146 and is not built
amended-design: 03-DESIGN/01-to-be/10-delivery.md
---
@@ -0,0 +1,64 @@
# 145 — partly resolved: the report says what it is not a claim about
*2026-09-30.*
## What was done
The sentence that was true for eleven hours now states its own scope, immediately below itself:
```
4 machine(s), all doing what they were told, all heard from, running what the mesh would send
them, and every module current with its source
That is the mesh and the machines agreeing. Nothing here dials a provision:
no grant the mesh composed has been tested, so a module unable to reach what it
requires would not appear above (04-ISSUES/145)
```
That is the whole of what this change does, and it is deliberately small. It does not check anything.
It closes the distance between *the machines are as the mesh described them* and *it works* by naming
it, and that distance is where the eleven hours went: the report was read as the second and only ever
meant the first.
Two other reports in this group now carry real information they did not
([issue 125](../125-a-hold-is-not-a-line-in-the-apply-report/00-report.md): a hold is a line in the
apply report and breaks the all-well sentence;
[issue 087](../087-the-controller-cannot-tell-a-host-is-too-old/00-report.md): the mesh knows which
host runs a machine). Neither would have caught this fault, and both were the same shape of blindness.
`printStatus` is now separated from the asking, so these words can be read by a test with no store, bus
or machine — they have been acted on and been misleading twice, which makes them worth holding still.
## What is NOT done, and why this record stays open
**Nothing dials a provision.** [ADR 0146](../../02-DECISIONS/0146-connectivity-is-checked-by-name-per-hosting-form.md)
decides how it should be done — a module on every machine serving an endpoint of its own and dialling
every other machine's, one name per hosting form, over TLS with the certificate verified. **Nothing is
built**, the module that existed was deleted, and the work was deferred deliberately by the operator.
It is not this record's to start.
So the measured fault of this issue — that the mesh can only report on itself — is unchanged. What
changed is that the report no longer implies otherwise.
## The open questions, where they stand
- *Should a grant be checked, and from where?* Answered by ADR 0146 and not built: from the position
the callers are in, by a module on every machine, per hosting form.
- *What would it cost to be wrong in the other direction?* Unanswered and important. A check that
reports a provision broken while it works trains a reader to ignore the report, which is the failure
this whole issue is about arriving by the other door.
- *What should `status` say about a machine whose modules cannot reach each other?* Answered in part:
until something checks, it says that it has not checked. What it says when a check exists is ADR
0146's to settle.
- *Is there a cheaper signal than a probe?* Still open. The affected module logged the failure 6,154
times; the mesh reads no module's logs and arguably should not, but something a module could *say*
about its own provisions would have surfaced this in minutes.
- *Does the same blindness apply to a provider that lost a consumer's grant?* Still open, and still
nothing checks it.
## One thing worth carrying forward
**The certificate half of ADR 0146 is now possible where it was not.** Its check requires an internal
name fetched over TLS with the certificate verified, and until 2026-09-30 no machine trusted the mesh's
authority at all ([issue 129](../129-nothing-makes-a-machine-trust-the-meshs-authority/02-resolution.md)).
Three of four do now. Whoever builds 0146 no longer has to solve that first.