Promise the vault's intake verbs and let the controller ask them in its own name (issue 675)

The vault takes a value only from the controller, which it knows from the
subject that names its caller. The grant is composed from the records, as
the issued tools' is, so the installer's first user list is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 19:07:04 +00:00
co-authored by Claude Opus 5.5
parent 8a428e3e86
commit 234dea9d29
6 changed files with 187 additions and 5 deletions
+17 -1
View File
@@ -609,13 +609,29 @@ func PausedSaid(js *broker.JetStream, seat string, nodes []string) (map[string]H
// (design 33 §4: a mesh seat's verb carries no machine), and reads its answer (novox/hq ADR 0239: the
// delivery's owner's `stalled` and `close`).
func AskMeshSeatTool(ctx context.Context, conn *nats.Conn, seat, verb string, args any, timeout time.Duration) (Answer, error) {
return askMeshSeatToolAt(ctx, conn, SeatToolSubject(seat, verb), seat, verb, args, timeout)
}
// AskMeshSeatToolAs is AskMeshSeatTool in the caller's own name: on the subject that names its caller (novox/hq
// issue 365), which the bus lets only that user publish, so the holder knows who asks from the subject alone —
// how the vault takes a value from the controller and nobody else (design 57's V2, issue 675).
func AskMeshSeatToolAs(ctx context.Context, conn *nats.Conn, caller, seat, verb string, args any,
timeout time.Duration) (Answer, error) {
subject := broker.CalledSubject(SeatToolSubject(seat, verb), caller)
if subject == "" {
return Answer{}, fmt.Errorf("%q cannot ask %s.%s in its own name: it is not a bus user's name", caller, seat, verb)
}
return askMeshSeatToolAt(ctx, conn, subject, seat, verb, args, timeout)
}
func askMeshSeatToolAt(ctx context.Context, conn *nats.Conn, subject, seat, verb string, args any,
timeout time.Duration) (Answer, error) {
body, err := json.Marshal(args)
if err != nil {
return Answer{}, err
}
asking, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
subject := SeatToolSubject(seat, verb)
refused, stop := refusalsOf(conn, subject)
defer stop()
type replied struct {