From 68a193d6f0a0bee13d26de3cb8a46ca615322cd9 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 28 Sep 2026 02:21:56 +0200 Subject: [PATCH] A host adopts a delivered membership at start, not only after a declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rescue path: an operator writes the membership file by hand on a machine no bus can reach — rotated while it still held the old password — and restarts the host. Same file, same check as the declaration path. --- cmd/mesh-host/main.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/mesh-host/main.go b/cmd/mesh-host/main.go index 6435317..0afbc03 100644 --- a/cmd/mesh-host/main.go +++ b/cmd/mesh-host/main.go @@ -962,9 +962,14 @@ func runLink(ctx context.Context, opts options) error { return nil // asked to stop while waiting } - fmt.Printf("node %s, linking to %s\n", mine.Node, mine.Membership.Broker) - + // **A membership delivered while this host was not running is adopted before the first dial.** + // The ordinary path is a declaration, read after it applies; the rescue path is an operator + // writing the file by hand on a machine no bus can reach — rotated while it held the old + // password, say — and restarting the host (design 28, task 5.2). Same file, same check. say := func(line string) { fmt.Println(line) } + adoptDeliveredMembership(identity.Path(opts.state), &mine, say) + + fmt.Printf("node %s, linking to %s\n", mine.Node, mine.Membership.Broker) // One scheduler for the life of the process, re-established from each applied declaration // (novox/hq ADR 0053). It fires scheduled steps on their cadence, surviving across applies and -- 2.54.0