A named push's cascade sent every machine a build held back by `record` or by a plan waiting on its first machine, so a change meant to be walked through the mesh one machine at a time reached all of them at once (issue 259). Records the decision, narrows ADR 0083's flush with a dated pointer, amends to-be 30, and locates issue 259 in the controller.
67 lines
3.8 KiB
Markdown
67 lines
3.8 KiB
Markdown
---
|
|
topic: the mesh
|
|
status: accepted
|
|
date: 2026-09-18
|
|
deciders: jochen
|
|
reconstructed: false
|
|
extends: 0010-delivery.md
|
|
---
|
|
|
|
# 83. One push leaves the mesh consistent
|
|
|
|
## Context
|
|
|
|
A provision is minted while composing the *consumer's* node; the provider's grant list is a pure
|
|
read of secrets already issued from it. So assigning a cross-node consumer and pushing its node
|
|
produced a consumer that retried forever against a provider that had never heard of it, until the
|
|
provider's node was pushed a second time — an action with no signal to take, documented nowhere,
|
|
and invisible whenever consumer and provider share a machine
|
|
([issue 057](../04-ISSUES/057-a-cross-node-consumer-is-provisioned-only-when-the-provider-is-pushed-again/00-report.md)).
|
|
|
|
Two remedies were on the table: **cascade** — a push also delivers to the machines its compose
|
|
changed — or **report** — a push says "now push the provider" and leaves the act to the operator.
|
|
|
|
## Decision
|
|
|
|
A push finishes what it starts: after composing and sending the named node, the controller flushes
|
|
every *other* machine that is now behind — whose declaration differs from what it was last sent —
|
|
by name, in the push's own output, converging over a bounded number of rounds (a flushed send may
|
|
itself mint).
|
|
|
|
Behind is measured against what a machine was last *sent*, not against a before/after snapshot of
|
|
this push. The mint that makes a provider behind happens when the consumer is assigned or its
|
|
account issued — before `push` runs at all — so by push time the provider already differs from
|
|
what it holds, with no in-command delta to detect. The only durable signal is "what it should be"
|
|
versus "what it last received", which is the same comparison `push --behind` already makes.
|
|
|
|
A machine behind for an unrelated reason is flushed by this too, and that is correct rather than a
|
|
cost: a named push that knew a machine was behind and left it so would be the very silence this
|
|
decision removes. The narrower reading — flush only what this push provably changed — was
|
|
rejected because it cannot see a mint that a prior command performed, which is precisely the 057
|
|
case.
|
|
|
|
Reporting alone was rejected because it converts a derived fact the controller already holds into
|
|
an operator obligation, and an obligation enforced by nothing is issue 057 restated. The
|
|
declaration is computed from the whole mesh; delivering a mesh that is knowingly inconsistent and
|
|
merely saying so would make "push succeeded" mean less than it says.
|
|
|
|
> **The mechanism changed — 2026-10-05, by [ADR 0221](0221-a-push-sends-no-build-a-policy-or-a-plan-holds-back-except-to-the-machine-it-names.md).**
|
|
> A named push still flushes every other machine that is behind, compared against what each was last
|
|
> sent. A machine whose modules would move to a build their upgrade policy records, or that an open plan
|
|
> has not sent it yet, is no longer flushed: the push names it and leaves it for `push <node>`. "Behind
|
|
> for an unrelated reason" no longer covers a held upgrade
|
|
> ([issue 259](../04-ISSUES/259-a-named-push-sent-every-machine/00-report.md)).
|
|
|
|
## Consequences
|
|
|
|
- One push is sufficient for a cross-node consumer: the provider's grants arrive from the same
|
|
act that minted the provision. The undocumented rule "push the provider node too" ceases to
|
|
exist rather than becoming documentation.
|
|
- A named push delivers to every machine that is behind, not only the one named — each named in
|
|
the output, never silent. `push --behind` remains the way to reconcile the mesh without naming
|
|
a node; a named push now carries the same guarantee for the machines its work touched and any
|
|
others already waiting.
|
|
- How this is checked: the built-store-cross-node bed registers a cross-node consumer, pushes
|
|
only the consumer's node, and asserts the provider minted its vhost — the workaround push is
|
|
removed, so a regression fails the bed.
|