A-165 callers: the tool runner refuses a seat verb's caller outside its effective callers before the bundle

Where serveSeats answers a seat's verb it reads the verb from the runner's seat list (seatdef's
EffectiveCallers): an unproven caller is refused, and every caller while the seat's definition is unread,
names no such verb or opens it to none; a proven caller is among them, since the grants part composes the
call subject only for the effective callers. A module's tool on the subject naming no caller is unchanged.

Builds: design 47 G §610; lead answers A-165, A-179

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 05:49:57 +01:00
parent afc327392e
commit e7e20e3d13
4 changed files with 86 additions and 9 deletions
+38
View File
@@ -1,6 +1,10 @@
package runtime
import (
"fmt"
"git.novox.be/novox/mesh-sdk/go/seatdef"
"github.com/novox/mesh-tools/node-tools/internal/approval"
"github.com/novox/mesh-tools/node-tools/internal/launch"
)
@@ -33,6 +37,40 @@ func WithGate(g Gate) Option { return func(c *consumers) { c.gate = g } }
var _ Gate = (*approval.Gate)(nil)
// WithSeatDefinitions refuses, where a seat's verb is answered, a caller outside the verb's effective callers, before the
// bundle runs (design 47 G §610; lead answers A-165, A-179): defs are the seat definitions the runner's seat list holds.
// Without it a verb is answered for every caller, as before.
func WithSeatDefinitions(defs func() map[string]seatdef.Definition) Option {
return func(c *consumers) { c.definitions = defs }
}
// admitted says why a seat's verb is refused to a caller, nil when it is answered: an unproven caller is refused, and so is
// every caller while the seat's definition is not read, names no such verb, or the verb's effective callers are empty; a
// proven caller is among them, since the grants part composes a verb's call subject only for its effective callers (A-179).
func (c *consumers) admitted(seat, verb, caller string) error {
if c.definitions == nil {
return nil
}
if caller == "" {
return fmt.Errorf("Not run: %s.%s takes no unproven caller: call it on its subject that names its caller, "+
"mesh.seat.%s.call.%s.<caller>", seat, verb, seat, verb)
}
def, ok := c.definitions()[seat]
if !ok {
return fmt.Errorf("Not run: the definition of the seat %s is not yet read by this tool runner's seat list, so no caller "+
"of %s.%s is admitted", seat, seat, verb)
}
for _, v := range def.Verbs {
if v.Name == verb {
if len(v.EffectiveCallers()) == 0 {
return fmt.Errorf("Not run: %s.%s is open to no caller", seat, verb)
}
return nil
}
}
return fmt.Errorf("Not run: the seat %s's definition names no verb %s, so no caller is admitted", seat, verb)
}
// unservedMarks is, of the module's marked tools, those its bundle's registrations under its own name do not register.
func (r *runner) unservedMarks(module string, regs []launch.Registration) []string {
if r.events.gate == nil {