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..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..tool.`, the same followed by `.*`, and the caller-named `mesh.mod..call..>`; // a verb of a seat held per node `mesh.seat..tool.`, its `.` form and `mesh.seat..call...>`; // a verb of a seat held once for the mesh `mesh.seat..tool.` and `mesh.seat..call..>`. 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 }) }