Issue 201: what was established about the race while closing the outage half

This commit is contained in:
2026-10-02 18:19:12 +02:00
parent 329a24fdae
commit 131a5e4714
@@ -65,10 +65,24 @@ which it cannot, and answers the reason when one of those is called. The same ra
the verbs the newer build added, for as long as the older binary is in place, and the ordinary
"this machine is behind" machinery would put the newer one back without a hand.
**The race itself is still open**, and this report stays open for it. A push sends the declaration
it composed; two waves overlapping on one machine can leave the later send carrying the earlier
content, and the declaration's sequence orders the sends rather than what is in them
(the numbering of [issue 107](../107-a-declaration-carries-no-order/00-report.md) orders arrival, not freshness). The
smaller of the two fixes the report first suggested — a push never sending a control plane a digest
older than the one it is running — is still the one to build, and is now a correctness nicety rather
than the difference between a working mesh and a dead one.
**The race itself is still open**, and this report stays open for it. What was established while
closing the other half, so the next reader does not redo it:
- Composing and sending are serialised per machine by a session advisory lock in the store, so two
control planes cannot compose one machine's declaration at the same time. The stale content did
not come from two concurrent composes.
- A container's image is resolved into the module's manifest when it is *built*, and a push composes
from the catalogue as it is at that moment, under the hold. So a compose that ran after the build
was taken in could not have named the older image.
- The declaration's sequence orders arrival and nothing else (the numbering of
[issue 107](../107-a-declaration-carries-no-order/00-report.md)); it cannot tell a later send
carrying earlier content from a later send carrying later content. The host refuses a declaration
numbered below the last it applied, and both of these were above it.
- The machine's own journal shows the two applies ten seconds apart and which replaced what; it does
not record which image each declaration named, which is the one fact that would settle it. A host
that recorded the digest it was told, per apply, would have answered this in a minute.
So the trigger is not yet pinned, and guessing at the push path is the most expensive place in the
mesh to guess. The fix the report first suggested — a push never sending a control plane a digest
older than the one that machine reports running — closes the class without needing the trigger, and
is now a correctness nicety rather than the difference between a working mesh and a dead one.