From f8e4c1b0ae06b0acfe7ea484934b6fd652fc8231 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 2 Nov 2026 11:49:55 +0100 Subject: [PATCH] Stop serving the vault's move-asks, which only the controller called move-asks copied the controller's record of asks into the vault's once; the controller is not placed (ADR 0590) and nothing else calls it. move-in stays: the node-engine calls it. The drift test names the node's own composition now that the controller composes for none (issue 1126). Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL --- modules/mesh-vault/cmd/mesh-vault/move.go | 91 ------------------- .../mesh-vault/cmd/mesh-vault/move_test.go | 62 +------------ modules/mesh-vault/cmd/mesh-vault/tools.go | 22 ----- modules/mesh-vault/module.json | 1 - 4 files changed, 2 insertions(+), 174 deletions(-) diff --git a/modules/mesh-vault/cmd/mesh-vault/move.go b/modules/mesh-vault/cmd/mesh-vault/move.go index be9dab1b..3950af49 100644 --- a/modules/mesh-vault/cmd/mesh-vault/move.go +++ b/modules/mesh-vault/cmd/mesh-vault/move.go @@ -33,7 +33,6 @@ import ( "errors" "fmt" "slices" - "strconv" "strings" "time" @@ -259,96 +258,6 @@ func (v *Vault) MoveTake(caller, call, sealed, readBackTo string) (MovedIn, erro // ---- move-asks ---------------------------------------------------------------------------------------------- -// MovedAsk is one row of the controller's record of asks at a desk (its secret_ask table): no value. -type MovedAsk struct { - ID int64 `json:"id"` - Node string `json:"node"` - Module string `json:"module"` - Name string `json:"name"` - Desk string `json:"desk"` - AskedBy string `json:"asked_by"` - OpenedAt time.Time `json:"opened_at"` - EndedAt *time.Time `json:"ended_at,omitempty"` - Outcome string `json:"outcome,omitempty"` -} - -// AsksMoved is what a copy of the record of asks did. -type AsksMoved struct { - Copied int `json:"copied"` - Already int `json:"already"` -} - -// MovedAsksAtOnce bounds one call: the controller sends its record in parts. -const MovedAsksAtOnce = 500 - -// movedAskID is the vault's id of a row of the controller's record. -func movedAskID(id int64) string { return "controller-" + strconv.FormatInt(id, 10) } - -// MoveAsks copies rows of the controller's record of asks into the vault's, as they are: each ask's opening and, -// when it ended, its end — once, so a copy run again adds nothing. From the controller alone, whose record it is. -// Every row is judged before any is written. -func (v *Vault) MoveAsks(caller string, asks []MovedAsk) (AsksMoved, error) { - if err := fromTheController(caller, "move-asks"); err != nil { - return AsksMoved{}, err - } - if len(asks) > MovedAsksAtOnce { - return AsksMoved{}, fmt.Errorf("%d asks at once is more than %d; send them in parts", len(asks), MovedAsksAtOnce) - } - type lines struct{ opened, ended AskRecord } - var all []lines - for _, a := range asks { - secret, err := OwnSecret(a.Node, a.Module, a.Name) - if err != nil { - return AsksMoved{}, fmt.Errorf("ask %d: %w; nothing was copied", a.ID, err) - } - if !namePart.MatchString(a.Desk) || a.OpenedAt.IsZero() || a.ID <= 0 { - return AsksMoved{}, fmt.Errorf("ask %d names no desk, no time it opened or no id; nothing was copied", a.ID) - } - l := lines{opened: AskRecord{ID: movedAskID(a.ID), At: a.OpenedAt.UTC(), Event: AskOpened, Secret: secret, - Node: a.Node, Module: a.Module, Name: a.Name, Desk: a.Desk, AskedBy: askedByName(a.AskedBy), - Caller: ControllerCaller}} - if a.EndedAt != nil { - if a.Outcome != "given" && !askOutcomes[a.Outcome] { - return AsksMoved{}, fmt.Errorf("ask %d ended %q, which is no outcome the record knows; nothing was "+ - "copied", a.ID, a.Outcome) - } - l.ended = AskRecord{ID: movedAskID(a.ID), At: a.EndedAt.UTC(), Event: AskEnded, Secret: secret, - Outcome: a.Outcome} - } - all = append(all, l) - } - v.Store.asksMu.Lock() - defer v.Store.asksMu.Unlock() - held, err := v.Store.asks() - if err != nil { - return AsksMoved{}, fmt.Errorf("the record of asks cannot be read: %w; nothing was copied", err) - } - seen := map[string]bool{} - for _, r := range held { - if r.Event == AskOpened { - seen[r.ID] = true - } - } - out := AsksMoved{} - for _, l := range all { - if seen[l.opened.ID] { - out.Already++ - continue - } - if err := v.recordAsk(l.opened); err != nil { - return out, fmt.Errorf("ask %s could not be copied, after %d: %w", l.opened.ID, out.Copied, err) - } - if l.ended.ID != "" { - if err := v.recordAsk(l.ended); err != nil { - return out, fmt.Errorf("the end of ask %s could not be copied, after %d: %w", l.opened.ID, out.Copied, err) - } - } - seen[l.opened.ID] = true - out.Copied++ - } - return out, nil -} - // StateNodeKey records the sealing key the node-engine of caller's machine states in its own name (novox/hq ADR 0372, // issue 786), at its start and whenever the key changes, whether or not it ever moved a secret in. The machine is the // caller's, as the bus proved it (`node.`), never an argument. A first key is handled like a changed one: the diff --git a/modules/mesh-vault/cmd/mesh-vault/move_test.go b/modules/mesh-vault/cmd/mesh-vault/move_test.go index b6270be4..c4002845 100644 --- a/modules/mesh-vault/cmd/mesh-vault/move_test.go +++ b/modules/mesh-vault/cmd/mesh-vault/move_test.go @@ -239,57 +239,6 @@ func TestAMoveTakesNothingItCannotOpenOrReadBack(t *testing.T) { } } -// The controller's record of asks is copied as it is, once: each ask's opening and its end, who asked and at which -// desk, and the bounds then count them. From the controller alone. -func TestTheRecordOfAsksIsCopiedAsItIsOnce(t *testing.T) { - v := newVault(t, nil) - now := v.Now() - ended := now.Add(-30 * time.Second) - asks := []MovedAsk{ - {ID: 41, Node: "anchor", Module: "telegram", Name: "telegram-token", Desk: "laptop", AskedBy: "g14/claude-code", - OpenedAt: now.Add(-50 * time.Minute), EndedAt: &ended, Outcome: "given"}, - {ID: 42, Node: "anchor", Module: "telegram", Name: "telegram-token", Desk: "laptop", AskedBy: "g14/claude-code", - OpenedAt: now.Add(-40 * time.Minute), EndedAt: &ended, Outcome: "dismissed"}, - {ID: 43, Node: "anchor", Module: "telegram", Name: "telegram-token", Desk: "laptop", AskedBy: "ace/agent", - OpenedAt: now.Add(-20 * time.Minute)}, - } - if _, err := v.MoveAsks("node.anchor", asks); err == nil { - t.Error("a node-engine copied the record of asks") - } - copied, err := v.MoveAsks(ControllerCaller, asks) - if err != nil || copied.Copied != 3 || copied.Already != 0 { - t.Fatalf("copied %+v, %v", copied, err) - } - again, err := v.MoveAsks(ControllerCaller, asks) - if err != nil || again.Copied != 0 || again.Already != 3 { - t.Fatalf("copied again %+v, %v", again, err) - } - all, _ := v.Store.Asks(100) - if len(all) != 5 { - t.Fatalf("%d lines: %+v", len(all), all) - } - opened := map[string]AskRecord{} - for _, r := range all { - if r.Event == AskOpened { - opened[r.ID] = r - } - } - if r := opened["controller-41"]; r.Secret != "own/anchor/telegram/telegram-token" || r.AskedBy != "g14/claude-code" || - r.Desk != "laptop" || !r.At.Equal(asks[0].OpenedAt) || r.Caller != ControllerCaller { - t.Errorf("ask 41: %+v", r) - } - // Three asks in the hour, from the controller's record: the vault's bound holds them. - if _, err := v.AskOpen(ControllerCaller, telegramAsk("g14/claude-code")); err == nil || - !strings.Contains(err.Error(), "in the last hour") { - t.Errorf("an ask after three copied in the hour: %v", err) - } - bad := []MovedAsk{{ID: 44, Node: "anchor", Module: "telegram", Name: "x", Desk: "laptop", AskedBy: "a", - OpenedAt: now, EndedAt: &ended, Outcome: "whatever"}} - if _, err := v.MoveAsks(ControllerCaller, bad); err == nil { - t.Error("an ask that ended in no outcome the record knows was copied") - } -} - // The two steps as the runtime calls the tool: the caller is the one it proved, never an argument. func TestMoveInThroughTheTool(t *testing.T) { v := newVault(t, nil) @@ -317,13 +266,6 @@ func TestMoveInThroughTheTool(t *testing.T) { if rec.MadeAt.Year() != 2025 || rec.MovedFrom == nil || rec.MovedFrom.Generation != "g-1" { t.Errorf("kept %+v", rec) } - asks := toolNamed(t, definitions(&Env{Vault: v.Vault}), Seat+".move-asks") - moved, err := asks.runAs("controller", map[string]any{"asks": []any{map[string]any{"id": 7, "node": "anchor", - "module": "telegram", "name": "telegram-token", "desk": "laptop", "asked_by": "g14/claude-code", - "opened_at": "2026-10-01T10:00:00Z", "ended_at": "2026-10-01T10:00:20Z", "outcome": "given"}}}) - if err != nil || moved.(AsksMoved).Copied != 1 { - t.Fatalf("asks through the tool: %+v, %v", moved, err) - } } // Issue 1126, cause C4: a machine's node-engine hands the vault what runs of its own machine's own secret, where the @@ -445,7 +387,7 @@ func TestANodeEngineHandsTheVaultWhatRunsOnItsOwnMachine(t *testing.T) { Module: "postgres", Why: "the resource differs", Bodies: []delivery.ResourceBodies{{ID: "postgres.needs-superuser-password", Composed: `{"sealed":"` + delivery.MaskedAnotherValue + `"}`, Running: `{"sealed":"` + delivery.MaskedAnotherValue + `"}`}}}}} have, err := delivery.EncodeHaveNode(delivery.HaveNode{Candidates: map[string]delivery.CandidateAnswer{"pro": answer}, - Composes: delivery.ComposesController}) + Composes: delivery.ComposesOwn}) if err != nil { t.Fatal(err) } @@ -457,7 +399,7 @@ func TestANodeEngineHandsTheVaultWhatRunsOnItsOwnMachine(t *testing.T) { } if len(drift.Secrets) != 1 || drift.Secrets[0].Secret != "own/anchor/postgres/superuser-password" || drift.Secrets[0].Generation != 2 || drift.Secrets[0].Previous != 1 || drift.Secrets[0].Takeable || - len(drift.Nodes) != 1 || drift.Nodes[0].ValuesDiffer["pro"] != 1 || drift.Nodes[0].Composes != delivery.ComposesController { + len(drift.Nodes) != 1 || drift.Nodes[0].ValuesDiffer["pro"] != 1 || drift.Nodes[0].Composes != delivery.ComposesOwn { t.Errorf("own_drift: %+v", drift) } } diff --git a/modules/mesh-vault/cmd/mesh-vault/tools.go b/modules/mesh-vault/cmd/mesh-vault/tools.go index f384f15d..ad9bb635 100644 --- a/modules/mesh-vault/cmd/mesh-vault/tools.go +++ b/modules/mesh-vault/cmd/mesh-vault/tools.go @@ -350,28 +350,6 @@ func definitions(env *Env) []toolDef { } return v.OwnOfNode(caller, asked...) }}, - {Name: Seat + ".move-asks", - Description: "Copy rows of the controller's record of asks at a desk into the vault's, as they are and once " + - "(design 57's V3): from the controller alone, at most 500 at a time. No value is in any of them.", - Input: map[string]any{"type": "object", "properties": map[string]any{ - "asks": map[string]any{"type": "array", "description": "the controller's rows: id, node, module, name, " + - "desk, asked_by, opened_at, and ended_at and outcome when the ask ended", - "items": map[string]any{"type": "object"}}}}, - run: func(caller string, a map[string]any) (any, error) { - v, err := env.ready() - if err != nil { - return nil, err - } - raw, err := json.Marshal(a["asks"]) - if err != nil { - return nil, err - } - var asks []MovedAsk - if err := json.Unmarshal(raw, &asks); err != nil { - return nil, fmt.Errorf("asks is not the controller's rows: %w", err) - } - return v.MoveAsks(caller, asks) - }}, {Name: "secret_asks", Description: "The record of asks for a module's own secret at a desk, newest first: who asked as the bus named " + "them, for what, at which desk, when, and how each ended. Never a value.", diff --git a/modules/mesh-vault/module.json b/modules/mesh-vault/module.json index dcfa8eb1..964ecdbd 100644 --- a/modules/mesh-vault/module.json +++ b/modules/mesh-vault/module.json @@ -204,7 +204,6 @@ "rotate", "move-in", "node-key", - "move-asks", "own", "issue-account", "sign",