From e4382d016e1b2759fb9db9c06bc9daae147cb17f Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 2 Nov 2026 00:51:55 +0100 Subject: [PATCH] mesh-conditions answers hand-back as gone and writes nothing: nothing reads the take-over key any more (ADR 0564 clause 9) After the group the messenger and the watcher hear the condition keeper alone; a hand-back written to the take-over key answered follow: controller and changed nothing. It is now answered as gone, naming its record, as placement's adopt and hand-back are; the verb stays on the seat so a caller is told rather than not found. Tests: none added; the hand-back lines of TestCompareCountsOnlyWhatBothSidesRaise become a row per lease state, each answered as gone with the take-over key unwritten. (issue 774, review g1 round 1) Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL --- .../cmd/mesh-conditions/compare.go | 21 +++++++------------ .../cmd/mesh-conditions/keeper_test.go | 17 ++++++++------- .../cmd/mesh-conditions/tools.go | 4 ++-- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/modules/mesh-conditions/cmd/mesh-conditions/compare.go b/modules/mesh-conditions/cmd/mesh-conditions/compare.go index e04e805a..b73e0a85 100644 --- a/modules/mesh-conditions/cmd/mesh-conditions/compare.go +++ b/modules/mesh-conditions/cmd/mesh-conditions/compare.go @@ -4,8 +4,8 @@ package main // lists the open keys of the keeper and of the controller, each difference with its reason; the kinds that end with the // controller, the kinds only the keeper raises and the keys held while their module is delivered are listed apart and // not counted. `take-over` raises an approve ask under the keeper's own name (ADR 0259), refused while compare shows a -// difference, and on the warrant writes the take-over key naming the keeper. `hand-back` writes it back to the -// controller until the lease write, and is refused after it. +// difference, and on the warrant writes the take-over key naming the keeper. `hand-back` is gone (issue 774): nothing +// reads the take-over key any more, so it is answered as gone and changes nothing. import ( "encoding/json" @@ -179,19 +179,12 @@ func (k *Keeper) Warranted(o asks.Option, w asks.Warrant) error { return k.writeTakeover(health.Takeover{Follow: health.FollowKeeper, At: k.Now().UTC(), By: w.Says(), Ask: w.Ask}) } -// HandBack switches the readers back to the controller, until the lease write. +// HandBack is gone (issue 774): the readers of conditions hear the keeper alone and nothing reads the take-over key, so +// a hand-back written there would answer success and do nothing (ADR 0564 clause 9). It is answered as gone, naming the +// record, and changes nothing. func (k *Keeper) HandBack(by, why string) (map[string]any, error) { - if strings.TrimSpace(why) == "" { - return nil, errors.New("a hand-back says why") - } - if k.LeaseAway() { - return nil, errors.New("refused: the controller's lease is handed away, so there is no controller to hand back to") - } - t := health.Takeover{Follow: health.FollowController, At: k.Now().UTC(), By: by, Why: why} - if err := k.writeTakeover(t); err != nil { - return nil, err - } - return map[string]any{"follow": t.Follow, "at": t.At}, nil + return nil, errors.New("hand-back is gone: the readers of conditions hear the condition keeper alone, and nothing " + + "reads the take-over key, so there is no controller to hand them back to (ADR 0564 clause 9)") } // writeTakeover writes the take-over key, and keeps it in history as the record of the switch. diff --git a/modules/mesh-conditions/cmd/mesh-conditions/keeper_test.go b/modules/mesh-conditions/cmd/mesh-conditions/keeper_test.go index 6d2b16f3..21a28ee4 100644 --- a/modules/mesh-conditions/cmd/mesh-conditions/keeper_test.go +++ b/modules/mesh-conditions/cmd/mesh-conditions/keeper_test.go @@ -265,7 +265,7 @@ func TestTheKeeperRaisesChangesAndClearsFromFindings(t *testing.T) { // ADR 0564 clause 9 (issue 1952 C5, C8; the lead 2026-10-29): compare counts only what both sides can raise. A key held // while its module is delivered, a kind that ends with the controller and a kind the controller never raises are listed // apart; a kind with no home decided is a difference naming the gap; take-over is refused while compare differs, and -// hand-back after the lease write. +// hand-back is gone (issue 774, review g1): answered as gone, naming its record, and writing nothing. func TestCompareCountsOnlyWhatBothSidesRaise(t *testing.T) { r := newRig() put := func(key, kind string) []byte { @@ -335,11 +335,14 @@ func TestCompareCountsOnlyWhatBothSidesRaise(t *testing.T) { if _, err := r.k.TakeOver(nil, "jochen", "now"); err == nil || !strings.Contains(err.Error(), "2 difference") { t.Errorf("take-over while compare differs: %v", err) } - if _, err := r.k.HandBack("jochen", "back"); err != nil { - t.Errorf("hand-back before the lease write: %v", err) - } - _ = r.k.Lease(true) - if _, err := r.k.HandBack("jochen", "back"); err == nil { - t.Error("hand-back after the lease write was taken") + for _, away := range []bool{false, true} { + _ = r.k.Lease(away) + if _, err := r.k.HandBack("jochen", "back"); err == nil || !strings.Contains(err.Error(), "hand-back is gone") || + !strings.Contains(err.Error(), "ADR 0564 clause 9") { + t.Errorf("hand-back with the lease away %v: %v, want it answered as gone naming its record", away, err) + } + if _, _, found, _ := r.k.Store.Get(TakeoverState, health.TakeoverKey); found { + t.Errorf("hand-back with the lease away %v wrote the take-over key", away) + } } } diff --git a/modules/mesh-conditions/cmd/mesh-conditions/tools.go b/modules/mesh-conditions/cmd/mesh-conditions/tools.go index 330e153e..4ff0ee80 100644 --- a/modules/mesh-conditions/cmd/mesh-conditions/tools.go +++ b/modules/mesh-conditions/cmd/mesh-conditions/tools.go @@ -79,8 +79,8 @@ func Tools(k *Keeper, a Asks) []stdio.Tool { Run: func(args map[string]any) (any, error) { return k.TakeOver(a, stdio.CallerOf(args), strArg(args, "why")) }}, - {Name: Seat + ".hand-back", Description: "Switch the readers of conditions back to the controller, until its lease " + - "is handed away.", + {Name: Seat + ".hand-back", Description: "Gone: the readers of conditions hear the keeper alone, so there is nothing " + + "to hand back; answered as gone and changes nothing (ADR 0564 clause 9).", Input: obj(map[string]any{"why": str("why")}, "why"), Run: func(args map[string]any) (any, error) { return k.HandBack(stdio.CallerOf(args), strArg(args, "why")) }}, {Name: Seat + ".resync", Description: "Read every finding again and raise and clear what differs.",