The node-engine owns the composition it alone runs (H1, H2)

ADR 0593 §1 and §7: compose, its bus reader and runtime reader, takein,
validate, the overlay generator, the composer's run and mesh-compose, and
the judgement of a move leave mesh-sdk for the node-engine's internal
packages, so no other module composes and a change to them rebuilds only
the node-engine. The shapes others read (the composer's request and
verdict, the overlay's names, compositions and answers) stay in mesh-sdk.
The node's grant is now a golden file of what the grants part composes,
since the composer of the bus's user list leaves mesh-sdk too.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 18:24:05 +01:00
parent 98fbc490a4
commit 9a12f2851f
218 changed files with 33022 additions and 54 deletions
+48
View File
@@ -0,0 +1,48 @@
// Package nodegrant is the grant the grants part composes for a node's engine (its principal of kind node), as a golden
// file the node-engine's tests run under (novox/hq ADR 0593 §1): the composer of the bus's user list is the grants
// part's own, so this repository holds what it composes for a node rather than calling it. testdata/node.json is that
// grant for the node NODE, captured from mesh-sdk's buscompose.PermissionsFor at 3d87ddc, with what this release adds
// to it (ADR 0593 §6, §7): the node's writes of its own composition state, and its reads of the indexer's candidates.
// When the grants part changes a node's grant, this file changes with it in the same group.
package nodegrant
import (
_ "embed"
"encoding/json"
"strings"
)
//go:embed testdata/node.json
var golden []byte
// Permissions is a node's grant: the subjects it may publish to, those refused though an allow covers them, those it
// may subscribe to, and whether it may answer a request once on its reply subject.
type Permissions struct {
Publish []string
PublishDeny []string
Subscribe []string
AllowResponses bool
}
// For is the grant of node, with the served keys (`<node>.<module>.<key>` of mesh-config's resolved values) it may
// read of another node: each one read by its watch and by a direct get, as the grants part grants a served read.
func For(node string, servedReads ...string) Permissions {
var p Permissions
if err := json.Unmarshal(golden, &p); err != nil {
panic("nodegrant: the golden grant is not JSON: " + err.Error())
}
swap := func(in []string) []string {
out := make([]string, len(in))
for i, s := range in {
out[i] = strings.ReplaceAll(s, "NODE", node)
}
return out
}
p.Publish, p.PublishDeny, p.Subscribe = swap(p.Publish), swap(p.PublishDeny), swap(p.Subscribe)
for _, key := range servedReads {
p.Publish = append(p.Publish,
"$JS.API.CONSUMER.CREATE.KV_mesh-config_resolved.*.$KV.mesh-config_resolved."+key,
"$JS.API.DIRECT.GET.KV_mesh-config_resolved.$KV.mesh-config_resolved."+key)
}
return p
}