RD-2: the validator accepts one module claiming the seat node-engine
G's node-engine claims its seat as one module; the trunk refused every claim of a seat the engine holds. One claim is accepted, a second refused naming both. Builds: design 47 G §508, §494, §621 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -167,6 +167,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)
|
||||
}
|
||||
|
||||
@@ -4651,13 +4651,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
|
||||
@@ -7918,3 +7911,22 @@ func ObjectsCatalogueProblems(shelf catalogue.Shelf) []string {
|
||||
}
|
||||
return problems
|
||||
}
|
||||
|
||||
// NodeEngineSeat is the seat the node-engine's module claims as one module (design 47 G §508).
|
||||
const NodeEngineSeat = "node-engine"
|
||||
|
||||
// nodeEngineClaimProblems refuses a revision in which more than one module claims the seat node-engine, naming them: one
|
||||
// module claims it, the node-engine's own (design 47 G §508), in place of refusing every claim.
|
||||
func nodeEngineClaimProblems(shelf catalogue.Shelf) []string {
|
||||
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)
|
||||
}
|
||||
}
|
||||
if len(holders) < 2 {
|
||||
return nil
|
||||
}
|
||||
slices.Sort(holders)
|
||||
return []string{fmt.Sprintf("%s claim the seat %s, which one module claims (design 47 G §508)", strings.Join(holders, " and "), NodeEngineSeat)}
|
||||
}
|
||||
|
||||
@@ -6380,6 +6380,7 @@ func TestRulesOther(t *testing.T) {
|
||||
t.Run("TakesSettingsIsRefusedWhereItCannotMeanAnything", caseTakesSettingsIsRefusedWhereItCannotMeanAnything)
|
||||
t.Run("TheInstallationCheckReadsADefault", caseTheInstallationCheckReadsADefault)
|
||||
t.Run("ASeatNamedViewIsJudgedAgainstTheSeatsViews", caseASeatNamedViewIsJudgedAgainstTheSeatsViews)
|
||||
t.Run("OneModuleClaimsTheNodeEnginesSeat", caseOneModuleClaimsTheNodeEnginesSeat)
|
||||
}
|
||||
|
||||
// A consumed view, `seat:<seat>.views.<state>`, is accepted where the seat offers the state as a view and refused, by name,
|
||||
@@ -6401,3 +6402,35 @@ func caseASeatNamedViewIsJudgedAgainstTheSeatsViews(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// One module of a revision claims the seat node-engine and is accepted; a second is refused naming both (design 47 G §508).
|
||||
func caseOneModuleClaimsTheNodeEnginesSeat(t *testing.T) {
|
||||
was := catalogue.Seats()
|
||||
t.Cleanup(func() { catalogue.UseSeats(was) })
|
||||
catalogue.UseSeats([]catalogue.Seat{{Name: NodeEngineSeat, Scope: catalogue.ScopeNode, Decision: "test", HeldByTheEngine: true}})
|
||||
engine := func(module string) []byte {
|
||||
return []byte(`{"module":"` + module + `","version":"1","claims":[{"name":"node-engine","scope":"node"}]}`)
|
||||
}
|
||||
for _, row := range []struct {
|
||||
name string
|
||||
raws map[string][]byte
|
||||
wants string
|
||||
}{
|
||||
{"one claim", map[string][]byte{"mesh-host": engine("mesh-host")}, ""},
|
||||
{"two claims", map[string][]byte{"mesh-host": engine("mesh-host"), "other": engine("other")},
|
||||
"mesh-host and other claim the seat node-engine, which one module claims"},
|
||||
} {
|
||||
shelf := catalogue.Shelf{}
|
||||
for name, raw := range row.raws {
|
||||
m, problems := Manifest(raw, nil)
|
||||
if len(problems) > 0 {
|
||||
t.Fatalf("%s: %s refused alone: %v", row.name, name, problems)
|
||||
}
|
||||
shelf[name] = m
|
||||
}
|
||||
got := strings.Join(Between(shelf, 0, nil), "\n")
|
||||
if row.wants == "" && strings.Contains(got, "node-engine") || row.wants != "" && !strings.Contains(got, row.wants) {
|
||||
t.Errorf("%s: %s", row.name, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user