Bind node-tools' consumers by mesh-provisioner's plans and provisions alone, dropping the read of the controller's assignments the sdk's helper no longer makes (issue 1954 L6-T1)

Pins mesh-sdk 692dbf9 (L6-P3).
This commit is contained in:
2026-10-29 22:43:58 +01:00
parent e9009b7f04
commit 9d67b0995f
5 changed files with 37 additions and 14 deletions
+1 -4
View File
@@ -40,8 +40,7 @@ func Offers() map[string]provider.Offer {
// busOf is the helper's bus over the runtime's own state: the provider's bucket is its state `bound`, and the
// provisions and plans of the seat mesh-provisioner are the states it reads, by mesh-sdk's names (novox/hq ADR 0570,
// issue 1954 L6-T1). The controller's assignments stay readable while the sdk's helper still reads its plans there
// (until L6-P3 moves it); the constant's removal from the sdk then fails this build, so the read goes with it.
// issue 1954 L6-T1). The controller's assignments are read no more (mesh-sdk 692dbf9, L6-P3).
type busOf struct{ conn *bus.Conn }
func (b busOf) state(bucket string) (string, error) {
@@ -52,8 +51,6 @@ func (b busOf) state(bucket string) (string, error) {
return provisions.ProvisionsRead, nil
case provisions.PlansBucket:
return provisions.PlansRead, nil
case provider.AssignmentsBucket:
return "mesh-controller.assignments", nil
}
return "", fmt.Errorf("%s is not a bucket this provider keeps or reads", bucket)
}
+33 -8
View File
@@ -7,6 +7,7 @@ import (
"testing"
"time"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/provider"
"git.novox.be/novox/mesh-sdk/go/provisions"
@@ -44,19 +45,39 @@ func fill(t *testing.T, template string, entry map[string]any) string {
func TestTheRuntimeAnswersAHandedConsumersMcpEndpointThroughTheHelper(t *testing.T) {
mesh := mt.New(t)
bound := mesh.Bucket(t, "node-tools_bound")
assignments := mesh.Bucket(t, "mesh-controller_assignments")
plans := mesh.Bucket(t, provisions.PlansBucket)
provs := mesh.Bucket(t, provisions.ProvisionsBucket)
mem := mt.MembershipOf("node-tools", "anchor", false, nil)
mem.State = []bus.StateIssued{
{Name: "bound", Bucket: "node-tools_bound", Writes: true},
{Name: "mesh-controller.assignments", Bucket: "mesh-controller_assignments"},
{Name: provisions.PlansRead, Bucket: provisions.PlansBucket},
{Name: provisions.ProvisionsRead, Bucket: provisions.ProvisionsBucket},
}
mesh.Issue(t, mem)
// claude-code, handed on this machine, is bound to node-tools here for mcp-endpoint (issue 788's plan entry).
plan := `{"node":"anchor","module":"claude-code","provisioning":{"provisions":[{"provision":"mcp-endpoint",` +
`"provider":"anchor","provider-module":"node-tools","at":"127.0.0.1","from":"anchor","as":"mesh_anchor_claude_code"}]}}`
if _, err := assignments.Put("anchor.claude-code", []byte(plan)); err != nil {
// claude-code, handed on this machine, is bound to node-tools here for mcp-endpoint: its plan and its provision
// key, written as mesh-provisioner writes them, with mesh-sdk's encoders (ADR 0570 clauses 1-3, issue 1954).
plan, err := provisions.EncodePlan(provisions.Plan{Node: "anchor", Module: "claude-code", Plan: catalogue.Plan{
Provisions: []catalogue.PlanProvision{{Provision: "mcp-endpoint", Provider: "anchor", ProviderModule: "node-tools",
At: "127.0.0.1", From: "anchor", As: "mesh_anchor_claude_code"}}}})
if err != nil {
t.Fatal(err)
}
if _, err := plans.Put("anchor.claude-code", plan); err != nil {
t.Fatal(err)
}
key, err := provisions.Key("anchor", "claude-code", "mcp-endpoint", "")
if err != nil {
t.Fatal(err)
}
asked, err := provisions.Encode(provisions.Provision{Provision: "mcp-endpoint", State: provisions.Asked,
Consumer: provisions.End{Node: "anchor", Module: "claude-code"}, Provider: provisions.End{Node: "anchor", Module: "node-tools"},
At: time.Now()})
if err != nil {
t.Fatal(err)
}
if _, err := provs.Put(key, asked); err != nil {
t.Fatal(err)
}
@@ -138,13 +159,18 @@ func TestTheOfferServesThePortTheManifestServes(t *testing.T) {
t.Error("the manifest still carries a consumers file the helper does not need")
}
}
for _, r := range m.Reads {
if r == "mesh-controller.assignments" {
t.Error("the manifest still reads mesh-controller.assignments, which the sdk's helper no longer reads (issue 1954)")
}
}
for _, a := range m.Build.Artifacts {
if a.Name == "files" || len(a.Env) > 0 {
t.Errorf("the build still carries %+v, which only a moved module needs", a)
}
}
// Every bucket the sdk's helper reaches is a state the manifest keeps or reads, by the sdk's names: the provider's
// own, the seat mesh-provisioner's provisions and plans (issue 1954 L6-T1), and the assignments the helper still reads.
// own and the seat mesh-provisioner's provisions and plans (issue 1954 L6-T1); the controller's assignments no more.
declared := map[string]bool{}
for _, n := range append(m.State, m.Reads...) {
declared[n] = true
@@ -153,7 +179,6 @@ func TestTheOfferServesThePortTheManifestServes(t *testing.T) {
provider.BucketOf(Module): "bound",
provisions.ProvisionsBucket: "mesh-provisioner.provisions",
provisions.PlansBucket: "mesh-provisioner.plans",
provider.AssignmentsBucket: "mesh-controller.assignments",
} {
got, err := (busOf{}).state(bucket)
if err != nil || got != want || !declared[got] {