Join 10: the validator takes a seat's accepted kind on a stream in invokes at parse, as its seat rule does

The per-manifest invokes rule refused seat:<seat>.<stream>.<kind> (the pipeline's seat:node-build-go.check.step) before
the seat rule that accepts it was reached; the test now runs both rules on each row.

Builds: design 47 G A-102

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 02:49:04 +01:00
parent 6563094d20
commit 9b3cc53db9
2 changed files with 16 additions and 3 deletions
+14 -2
View File
@@ -3991,12 +3991,24 @@ func filepathDir(p string) string {
}
// invokeNameValid says a module or process's invoked entry names a tool: <module>.<tool>, a role's
// seat:<seat>.<verb>, or * for every tool on the mesh (novox/hq ADR 0152, ADR 0436 §1).
// seat:<seat>.<verb> or a kind the seat accepts (seat:<seat>.<kind>, seat:<seat>.<stream>.<kind>, design 47 G A-102),
// or * for every tool on the mesh (novox/hq ADR 0152, ADR 0436 §1).
func invokeNameValid(t string) bool {
if t == "*" {
return true
}
t = strings.TrimPrefix(t, "seat:")
if rest, isSeat := strings.CutPrefix(t, "seat:"); isSeat {
// A seat's verb, or a kind the seat accepts: `<kind>`, or `<stream>.<kind>` for one that rides a stream (design 47 G
// A-102); seatInvokeProblems judges it against the seat.
seat, after, named := strings.Cut(rest, ".")
if !named || !name.MatchString(seat) {
return false
}
if stream, kind, onStream := strings.Cut(after, "."); onStream {
return toolName.MatchString(stream) && toolName.MatchString(kind)
}
return toolName.MatchString(after)
}
first, second, named := strings.Cut(t, ".")
return named && name.MatchString(first) && toolName.MatchString(second)
}
@@ -6457,7 +6457,8 @@ func TestASeatNamedReadIsJudgedAgainstTheSeatsStates(t *testing.T) {
{"seat:mesh-provisioner.check.other", `serves no verb "check.other"`},
} {
shelf["caller"] = catalogue.Manifest{Module: "caller", Invokes: []string{row.invoke}}
problems := strings.Join(seatInvokeProblems(shelf, nil), "\n")
// The manifest's own invokes rule (at parse) takes the dotted kind as well; the seat's rule then judges it.
problems := strings.Join(append(invokeProblems(shelf["caller"]), seatInvokeProblems(shelf, nil)...), "\n")
if row.says == "" && problems != "" || row.says != "" && !strings.Contains(problems, row.says) {
t.Errorf("%s: problems %q, want %q", row.invoke, problems, row.says)
}