From 131a5e4714072de869abe07fa638a708f7a84b42 Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 2 Oct 2026 18:19:12 +0200 Subject: [PATCH] Issue 201: what was established about the race while closing the outage half --- .../00-report.md | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/04-ISSUES/201-a-push-recreated-the-controller-behind-the-row-its-successor-wrote/00-report.md b/04-ISSUES/201-a-push-recreated-the-controller-behind-the-row-its-successor-wrote/00-report.md index 417d803..53469f7 100644 --- a/04-ISSUES/201-a-push-recreated-the-controller-behind-the-row-its-successor-wrote/00-report.md +++ b/04-ISSUES/201-a-push-recreated-the-controller-behind-the-row-its-successor-wrote/00-report.md @@ -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.