The mesh's own verbs are the mesh-controller seat's tools

A seat's protocol lives in the store (migration 0047; seeded additively), a served verb carries its
description and schema, holding a mesh seat requires serving its verbs, a node-scoped seat's tool
carries the node, and the control plane serves status, nodes, node, modules, seats, builds, plan,
assign, unassign, push, build and tools on its seat by running the same commands (novox/hq ADR 0132,
ADR 0154, design 33). A grant of * reaches a role's tools; seat:<seat>.<verb> grants one.
This commit is contained in:
2026-09-30 17:39:38 +02:00
parent 990ef27cd2
commit e9df5dccab
18 changed files with 840 additions and 27 deletions
+6 -5
View File
@@ -38,8 +38,9 @@ type SeatDeclaration struct {
Accepts []string `json:"accepts,omitempty"`
// Emits are the verbs the holder publishes: 1:many, nobody obliged to act.
Emits []string `json:"emits,omitempty"`
// Serves are the verbs the holder answers: request and reply, awaited.
Serves []string `json:"serves,omitempty"`
// Serves are the verbs the holder answers: request and reply, awaited. A bare name, or the
// verb in full with its schema (novox/hq ADR 0132).
Serves []Verb `json:"serves,omitempty"`
// RetainSeconds is how long the inbound backlog survives with no holder, zero for the
// mesh's default. Retention belongs to whoever owns the namespace (design 29 §3) — a seat
@@ -62,7 +63,7 @@ func (s SeatDeclaration) At() string {
func (s SeatDeclaration) verbs() []string {
out := append([]string{}, s.Accepts...)
out = append(out, s.Emits...)
return append(out, s.Serves...)
return append(out, VerbNames(s.Serves)...)
}
// declaredSeatProblems is what one manifest can be judged on alone.
@@ -228,8 +229,8 @@ func unserved(m Manifest, s SeatDeclaration) []string {
}
var missing []string
for _, t := range s.Serves {
if !has[t] {
missing = append(missing, t)
if !has[t.Name] {
missing = append(missing, t.Name)
}
}
return missing