From b7f7b97d8ae4e250aeb7b4e0c37979c253da50e5 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 30 Sep 2026 09:00:18 +0200 Subject: [PATCH] Group 1: 145's report states its scope, and 107 waits for delivery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 145, partly resolved. The sentence that was true for eleven hours of a mesh in which no module could reach another now says what it is not a claim about: that is the mesh and the machines agreeing, and nothing here dials a provision. It checks nothing and does not pretend to — ADR 0146 decides the check and is deliberately not built. What changed is that the report no longer implies otherwise. Stays open for that reason. Carried forward: 0146's check needs an internal name fetched over TLS with the certificate verified, and until today no machine trusted the mesh's authority. Three of four do now, so whoever builds it does not have to solve that first. 107, diagnosed and deliberately not built. The premise is confirmed in the host's own words — unknown fields are refused because "a field the host does not know is a thing the control plane believes it asked for" — so the fix is a flag day, not an addition. 087 now makes the cost measurable, and the measurement is why it waits: one machine of four runs an older host, it is parked, and nothing delivers a host at all (142). Shipping the field means hand-placing binaries and unparking a machine, and one missed in that sequence is unreachable, not degraded. The fault it prevents has never been observed. 142 gains the note that it is 107's gate, and that it is what makes a declaration field cost a rollout instead of an expedition. A judgement about order, not a refusal, and cheap to overrule. --- .../01-diagnosis.md | 68 +++++++++++++++++++ .../00-report.md | 15 ++++ .../00-report.md | 2 +- .../01-resolution.md | 64 +++++++++++++++++ 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 04-ISSUES/107-a-declaration-carries-no-order/01-diagnosis.md create mode 100644 04-ISSUES/145-a-machine-reads-healthy-while-its-modules-cannot-reach-each-other/01-resolution.md diff --git a/04-ISSUES/107-a-declaration-carries-no-order/01-diagnosis.md b/04-ISSUES/107-a-declaration-carries-no-order/01-diagnosis.md new file mode 100644 index 0000000..de7e24e --- /dev/null +++ b/04-ISSUES/107-a-declaration-carries-no-order/01-diagnosis.md @@ -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. diff --git a/04-ISSUES/142-the-host-is-the-one-thing-the-mesh-does-not-deliver/00-report.md b/04-ISSUES/142-the-host-is-the-one-thing-the-mesh-does-not-deliver/00-report.md index b147e04..30b4e1d 100644 --- a/04-ISSUES/142-the-host-is-the-one-thing-the-mesh-does-not-deliver/00-report.md +++ b/04-ISSUES/142-the-host-is-the-one-thing-the-mesh-does-not-deliver/00-report.md @@ -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. diff --git a/04-ISSUES/145-a-machine-reads-healthy-while-its-modules-cannot-reach-each-other/00-report.md b/04-ISSUES/145-a-machine-reads-healthy-while-its-modules-cannot-reach-each-other/00-report.md index ee8ac6b..6931708 100644 --- a/04-ISSUES/145-a-machine-reads-healthy-while-its-modules-cannot-reach-each-other/00-report.md +++ b/04-ISSUES/145-a-machine-reads-healthy-while-its-modules-cannot-reach-each-other/00-report.md @@ -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 --- diff --git a/04-ISSUES/145-a-machine-reads-healthy-while-its-modules-cannot-reach-each-other/01-resolution.md b/04-ISSUES/145-a-machine-reads-healthy-while-its-modules-cannot-reach-each-other/01-resolution.md new file mode 100644 index 0000000..8ec7ab5 --- /dev/null +++ b/04-ISSUES/145-a-machine-reads-healthy-while-its-modules-cannot-reach-each-other/01-resolution.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. -- 2.54.0