diff --git a/cmd/mesh-controller/desk_secret.go b/cmd/mesh-controller/desk_secret.go index 96524993..930a29da 100644 --- a/cmd/mesh-controller/desk_secret.go +++ b/cmd/mesh-controller/desk_secret.go @@ -381,7 +381,8 @@ var askOperatorChannel = func(ctx context.Context, args map[string]any) (json.Ra func announceSecretGiven(ctx context.Context, node, module, name, how, askedBy string) error { at := time.Now() body := map[string]any{ - "headline": fmt.Sprintf("A password was entered for %s's %s", module, secretNameWords(name)), + "headline": fmt.Sprintf("A password was entered for %s's %s on %s", module, secretNameWords(name), node), + "subject": node, "lines": []string{ fmt.Sprintf("%s at %s, asked by %s.", how, at.Local().Format("15:04"), askedByName(askedBy)), "If that was not you, give it again yourself at the controller's terminal.", diff --git a/cmd/mesh-controller/desk_secret_test.go b/cmd/mesh-controller/desk_secret_test.go index 00e41f81..85bbb40e 100644 --- a/cmd/mesh-controller/desk_secret_test.go +++ b/cmd/mesh-controller/desk_secret_test.go @@ -594,9 +594,12 @@ func TestASecretGivenAtTheDeskIsToldOnceAndOpensNoCondition(t *testing.T) { t.Fatalf("told the operator %d times, want exactly 1: %v", len(*calls), *calls) } call := (*calls)[0] - if call["headline"] != "A password was entered for telegram's telegram token" { + if call["headline"] != "A password was entered for telegram's telegram token on anchor" { t.Errorf("headline %v", call["headline"]) } + if call["subject"] != "anchor" { + t.Errorf("subject %v", call["subject"]) + } lines, _ := call["lines"].([]string) if len(lines) != 2 || !strings.Contains(lines[0], "at the desk on laptop at") || !strings.Contains(lines[0], "asked by mail-seats-835@novox") || @@ -678,3 +681,47 @@ func TestATrustedPartysSecretAtTheTerminalIsNotKeptWhenTellAndTheConditionBothFa t.Error("the value was kept despite the failure") } } + +// Review round 2 of mesh-controller (feat/mail-seats, head 5f24a47d): ADR 0380 §9's fallback — raising the +// secret-given condition — answers only link.ErrNothingServes and link.ErrGrantRefused. Any other failure of +// the operator channel's `tell` (the holder itself refusing, or answering something unreadable) is the +// announcement's own failure, surfaced to the caller, and opens no condition. +func TestAnOperatorChannelFailureOtherThanNothingServesOrGrantRefusedSurfacesAndRaisesNoCondition(t *testing.T) { + ctx := context.Background() + k, _ := withConditionsInMemory(t) + refused := errors.New("operator-channel.tell refused: too many lines") + askOperatorChannelFake(t, func(map[string]any) (json.RawMessage, error) { return nil, refused }) + if err := announceSecretGiven(ctx, "anchor", "telegram", "telegram-token", "at the desk on laptop", "me"); err != refused { + t.Fatalf("announceSecretGiven = %v, want the refusal itself surfaced", err) + } + open, err := k.Open(ctx) + if err != nil { + t.Fatal(err) + } + if len(open) != 0 { + t.Errorf("a condition was raised though the failure was neither ErrNothingServes nor ErrGrantRefused: %+v", open) + } +} + +// Review round 2 of mesh-controller: a secret accepted at the controller's terminal writes a hand act naming +// who asked, where and when it was given — and never the value (novox/hq ADR 0380 §6). +func TestASecretAcceptedAtTheTerminalWritesAHandActNamingWhoWhereAndNeverTheValue(t *testing.T) { + act := terminalGiveHandAct("anchor", "telegram", "telegram-token", "mail-seats-835@novox") + if act.Verb != "secret accept" || act.Cause != "given-at-the-terminal" { + t.Fatalf("act %+v", act) + } + if !strings.Contains(act.Why, "at the controller's terminal") { + t.Errorf("the act does not name where: %q", act.Why) + } + if !strings.Contains(act.Why, "asked by mail-seats-835@novox") { + t.Errorf("the act does not name who: %q", act.Why) + } + if strings.Contains(act.Why, typed) { + t.Error("the act carries the value") + } + // When is RecordHandAct's own job (it stamps At with time.Now when the act leaves none, and By with the + // caller when the act leaves that empty too): this act leaves both for it to fill. + if act.By != "" || !act.At.IsZero() { + t.Errorf("the act sets its own who/when instead of leaving them to RecordHandAct: %+v", act) + } +} diff --git a/cmd/mesh-controller/secret.go b/cmd/mesh-controller/secret.go index 09e69c12..85b7b20b 100644 --- a/cmd/mesh-controller/secret.go +++ b/cmd/mesh-controller/secret.go @@ -172,9 +172,7 @@ func secretCommand(ctx context.Context, args []string) error { } // The giving is recorded, never the value (novox/hq ADR 0380 §6): the desk already logs its own act; the // terminal's own secret accept did not until now. - act := link.HandAct{Verb: "secret accept", Args: []string{node, module, name}, - Why: fmt.Sprintf("the operator gave %s for %s on %s at the controller's terminal", name, module, node), - Cause: "given-at-the-terminal"} + act := terminalGiveHandAct(node, module, name, askedBy) if err := onTheBus(func(conn *nats.Conn) error { _, err := link.RecordHandAct(ctx, conn, act) return err @@ -558,6 +556,16 @@ func whoAsked() string { return "the mesh" } +// terminalGiveHandAct is the hand-act log's entry for a secret accepted at the controller's terminal +// (novox/hq ADR 0380 §6): who asked, where and that it happened — never the value, which the act never +// carries a field for. +func terminalGiveHandAct(node, module, name, askedBy string) link.HandAct { + return link.HandAct{Verb: "secret accept", Args: []string{node, module, name}, + Why: fmt.Sprintf("the operator gave %s for %s on %s at the controller's terminal, asked by %s", name, module, + node, askedByName(askedBy)), + Cause: "given-at-the-terminal"} +} + // keepGiven keeps a value given at the controller's terminal, and announces it on the operator's channels // (the confirmation review of 2026-10-09, N1-give). **A trusted party's — a module running as an account of its // own: the router, a verified channel — is announced before it is kept, and not kept when the announcement