IX30 (part 2): a revision's one claim of the seat node-engine is accepted, a second and none are refused
Builds: design 47 G §508, §527 (IX30) Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -160,7 +160,7 @@ func judgedByRequest(t *testing.T, shelf catalogue.Shelf, known KnownPackages) s
|
||||
if known != nil {
|
||||
names = append([]string{}, slices.Sorted(maps.Keys(known))...)
|
||||
}
|
||||
c := composer.Case{Name: "change", Manifests: map[string]composer.Manifest{}}
|
||||
c := composer.Case{Name: "change", Manifests: map[string]composer.Manifest{"node-engine": {Raw: []byte(engineManifest("node-engine"))}}}
|
||||
for name, m := range shelf {
|
||||
raw, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
|
||||
@@ -108,3 +108,31 @@ func findingEventsProblems(module string, e catalogue.BusStateEntry) []string {
|
||||
slices.Sort(problems)
|
||||
return problems
|
||||
}
|
||||
|
||||
// NodeEngineSeat is the seat the node-engine claims as one module (design 47 G §508).
|
||||
const NodeEngineSeat = "node-engine"
|
||||
|
||||
// nodeEngineClaimProblems are the refusals of a revision's claims of the seat `node-engine`: one module claims it, a second
|
||||
// is refused naming both (§508), and a revision in which none does is refused naming the seat (§527), since the
|
||||
// node-engine's own module is read from the module whose entry claims it. A revision whose seat list lacks the seat is
|
||||
// not judged.
|
||||
func nodeEngineClaimProblems(shelf catalogue.Shelf) []string {
|
||||
if _, known := catalogue.SeatNamed(NodeEngineSeat); !known {
|
||||
return nil
|
||||
}
|
||||
var holders []string
|
||||
for module, m := range shelf {
|
||||
if slices.ContainsFunc(m.Claims, func(c catalogue.Claim) bool { return c.Name == NodeEngineSeat }) {
|
||||
holders = append(holders, module)
|
||||
}
|
||||
}
|
||||
slices.Sort(holders)
|
||||
switch {
|
||||
case len(holders) == 0:
|
||||
return []string{fmt.Sprintf("no module of the revision claims the seat %s; the node-engine's own module is the one that does "+
|
||||
"(design 47 G §527)", NodeEngineSeat)}
|
||||
case len(holders) > 1:
|
||||
return []string{fmt.Sprintf("%s claim the seat %s, which one module claims (design 47 G §508)", strings.Join(holders, " and "), NodeEngineSeat)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -170,6 +170,7 @@ func Between(shelf catalogue.Shelf, longestMachine int, known KnownPackages) []s
|
||||
between = append(between, PackagesCatalogueProblems(shelf, known)...)
|
||||
between = append(between, IdentityProblems(shelf, longestMachine)...)
|
||||
between = append(between, DataProblems(shelf)...)
|
||||
between = append(between, nodeEngineClaimProblems(shelf)...)
|
||||
sort.Strings(between)
|
||||
return slices.Compact(between)
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ package judge
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/composer"
|
||||
"git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go/overlay"
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
)
|
||||
|
||||
// The judge (novox/hq ADR 0578 §1): a manifest alone is accepted, or refused with each problem; an unknown field is
|
||||
@@ -46,7 +46,7 @@ func TestTheJudge(t *testing.T) {
|
||||
"enrolment": `{"module":"enrolment","version":"1.0","claims":[{"name":"enrolment","scope":"mesh","serves":["issue","again"]}],` +
|
||||
`"tools":["enrolment_first_views","enrolment_first_view_again"]}`}},
|
||||
} {
|
||||
raws := map[string][]byte{}
|
||||
raws := map[string][]byte{"node-engine": []byte(engineManifest("node-engine"))} // a revision has one claim of the seat node-engine (§527)
|
||||
for k, v := range row.raws {
|
||||
raws[k] = []byte(v)
|
||||
}
|
||||
@@ -153,3 +153,47 @@ func versioned(t *testing.T, raw []byte) []byte {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// engineManifest is the manifest of a module that claims the seat node-engine, serving every verb the seat promises
|
||||
// (design 47 G §508, §527).
|
||||
func engineManifest(module string) string {
|
||||
seat, _ := catalogue.SeatNamed(NodeEngineSeat)
|
||||
var verbs []string
|
||||
for _, v := range seat.Serves {
|
||||
verbs = append(verbs, `"`+v.Name+`"`)
|
||||
}
|
||||
return `{"module":"` + module + `","version":"1.0","claims":[{"name":"node-engine","scope":"node","serves":[` + strings.Join(verbs, ",") + `]}]}`
|
||||
}
|
||||
|
||||
// Design 47 G §508, §527: one module of a revision claims the seat node-engine; a second is refused naming both, and none
|
||||
// refuses the revision naming the seat.
|
||||
func TestTheRevisionHasOneClaimOfTheNodeEngine(t *testing.T) {
|
||||
for _, row := range []struct {
|
||||
name string
|
||||
raws map[string]string
|
||||
want string // empty: accepted
|
||||
}{
|
||||
{"one claim", map[string]string{"engine": engineManifest("engine")}, ""},
|
||||
{"two claims", map[string]string{"engine": engineManifest("engine"), "other": engineManifest("other")},
|
||||
"claim the seat node-engine"},
|
||||
{"none", map[string]string{"ok": `{"module":"ok","version":"1.0"}`}, "claims the seat node-engine"},
|
||||
} {
|
||||
raws := map[string][]byte{}
|
||||
for k, v := range row.raws {
|
||||
raws[k] = []byte(v)
|
||||
}
|
||||
refused, unnamed := Shelf(raws, nil, 0)
|
||||
got := strings.Join(append(unnamed, flat(refused)...), "\n")
|
||||
if (row.want == "") != (got == "") || !strings.Contains(got, row.want) {
|
||||
t.Errorf("%s: refused %q, want %q", row.name, got, row.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func flat(refused map[string][]string) []string {
|
||||
var out []string
|
||||
for _, p := range refused {
|
||||
out = append(out, p...)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -4638,13 +4638,6 @@ func claimProblems(m catalogue.Manifest) []string {
|
||||
}
|
||||
|
||||
for _, c := range m.Claims {
|
||||
if s, known := catalogue.SeatNamed(c.Name); known && s.HeldByTheEngine {
|
||||
// The node's engine holds it on every node, and no module may (novox/hq ADR 0563 §1): a module answering
|
||||
// root-free or a hand-over would be an agent answering it.
|
||||
problems = append(problems, fmt.Sprintf("%s claims %s, which every node's engine holds itself and no "+
|
||||
"module may (novox/hq ADR 0563 §1)", m.Module, c.Name))
|
||||
continue
|
||||
}
|
||||
if _, known := catalogue.SeatNamed(c.Name); known {
|
||||
// **A seat's scope and what it delivers are not judged here** (novox/hq ADR 0122).
|
||||
// This function runs wherever a manifest is parsed, and one of those places is the
|
||||
|
||||
Reference in New Issue
Block a user