The grants part follows the assignment half, reads each node's reading and the runner its node-engine says running, and where the runner does not state approval-mark/1 or the reading is not the running runner's, composes the subscribe deny of every marked tool and verb the runtime carries, named in grants_user_list's withheld and answered by the seat's verb withheld. Builds: design 46 7 §6 (the deny's subjects, its cases, withheld in grants_user_list and the verb withheld), design 47 G §195, §309, lead answer A-203 (the assignment half followed by revision and assignment-revision; withheld's forms, keyed by node in the user list's state as the lead confirmed) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
86 lines
3.6 KiB
Go
86 lines
3.6 KiB
Go
package buscompose
|
|
|
|
import (
|
|
"slices"
|
|
"sort"
|
|
)
|
|
|
|
// **A machine whose tool runner does not honour the mark serves no marked tool or verb** (design 46 approval mark §6): on
|
|
// the account of a node's runtime whose readings lack approval-mark/1, or are not the running runner's, every marked
|
|
// subject of every module it carries is denied to subscribe, which outranks its allow of `mesh.mod.<module>.tool.>`, and
|
|
// each is named with why.
|
|
|
|
// ApprovalMark is the capability a tool runner that honours the mark states among its call capabilities (design 46
|
|
// approval mark §6).
|
|
const ApprovalMark = "approval-mark/1"
|
|
|
|
// WithheldWhy is why a marked subject is withheld (design 46 approval mark §6).
|
|
const WithheldWhy = "its tool runner does not state " + ApprovalMark
|
|
|
|
// WithheldSubject is one marked subject withheld from a runtime's account: the module it is of, the subject and why
|
|
// (lead answer A-203).
|
|
type WithheldSubject struct {
|
|
Module string `json:"module"`
|
|
Subject string `json:"subject"`
|
|
Why string `json:"why"`
|
|
}
|
|
|
|
// RunnerReading is a node's capability reading as the assignment half carries it: what its tool runner states of the
|
|
// calls it answers, and the fingerprint of the runner that announced it (design 46 approval mark §6).
|
|
type RunnerReading struct {
|
|
Capabilities []string
|
|
Fingerprint string
|
|
}
|
|
|
|
// Withholds says whether a node's runtime withholds the marked subjects: where the node has no reading, the reading
|
|
// lacks ApprovalMark, or its fingerprint is absent or differs from the one the node-engine last said running (no time is
|
|
// compared, failing closed).
|
|
func Withholds(reading RunnerReading, read bool, running string) bool {
|
|
return !read || !slices.Contains(reading.Capabilities, ApprovalMark) || reading.Fingerprint == "" ||
|
|
reading.Fingerprint != running
|
|
}
|
|
|
|
// MarkedSubjects are the subjects of a module's marked tools and of the marked verbs of the seats it holds, on node: a
|
|
// tool's `mesh.mod.<module>.tool.<tool>`, the same followed by `.*`, and the caller-named `mesh.mod.<module>.call.<tool>.>`;
|
|
// a verb of a seat held per node `mesh.seat.<seat>.tool.<verb>`, its `.<node>` form and `mesh.seat.<seat>.call.<verb>.<node>.>`;
|
|
// a verb of a seat held once for the mesh `mesh.seat.<seat>.tool.<verb>` and `mesh.seat.<seat>.call.<verb>.>`.
|
|
func MarkedSubjects(node string, d Declared) []string {
|
|
var out []string
|
|
for _, t := range d.Marked {
|
|
out = append(out, "mesh.mod."+d.Module+".tool."+t, "mesh.mod."+d.Module+".tool."+t+".*",
|
|
"mesh.mod."+d.Module+"."+CallKind+"."+t+".>")
|
|
}
|
|
for _, s := range d.Holds {
|
|
for _, v := range s.Marked {
|
|
if s.Scope == "node" {
|
|
out = append(out, "mesh.seat."+s.Name+".tool."+v, "mesh.seat."+s.Name+".tool."+v+"."+node,
|
|
"mesh.seat."+s.Name+"."+CallKind+"."+v+"."+node+".>")
|
|
} else {
|
|
out = append(out, "mesh.seat."+s.Name+".tool."+v, "mesh.seat."+s.Name+"."+CallKind+"."+v+".>")
|
|
}
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// MarksWithheld are the subjects withheld from a principal's account, each with its module and why: for a node's runtime that
|
|
// withholds, every marked subject of every module it carries; none for any other.
|
|
func MarksWithheld(p Principal) []WithheldSubject {
|
|
if p.Kind != KindNodeTools || !p.Withholds {
|
|
return nil
|
|
}
|
|
var out []WithheldSubject
|
|
for _, d := range p.Carries {
|
|
for _, s := range MarkedSubjects(p.Node, d) {
|
|
out = append(out, WithheldSubject{Module: d.Module, Subject: s, Why: WithheldWhy})
|
|
}
|
|
}
|
|
sort.Slice(out, func(i, j int) bool {
|
|
if out[i].Module != out[j].Module {
|
|
return out[i].Module < out[j].Module
|
|
}
|
|
return out[i].Subject < out[j].Subject
|
|
})
|
|
return slices.CompactFunc(out, func(a, b WithheldSubject) bool { return a == b })
|
|
}
|