Files
mesh-controller/internal/catalogue/licence_test.go
T
jschoubben faf5ecd70f One machine's unanswerable requirement does not remove it from the mesh
The pass that answers *what does this node offer* takes a failed resolution to
mean it learned nothing about that node. So refusing an unanswerable
requirement there made the machine disappear — and every other machine was then
told, wrongly, that the two of them shared no private network.

A wrong answer about a machine nobody asked about, caused by a fault on a
third. The lab found it: one module needing a licence that had not been added
yet made two unrelated machines look disconnected.

The second pass still refuses it, where the question is actually being asked.
2026-08-31 03:06:33 +02:00

188 lines
7.1 KiB
Go

package catalogue
import (
"strings"
"testing"
)
func aModelUser() Manifest {
return Manifest{Module: "assistant", Requires: []string{"model-access"},
Binds: map[string]string{"model-access": "/etc/assistant/model.json"},
Secrets: map[string]string{"model-access": "/etc/assistant/key"}}
}
// A provision answered by a record rather than a node.
//
// novox/hq ADR 0024: a hosted model is on nobody's machine and is reached over the public
// internet, so the rule that refuses two ends sharing no private network must not apply. This
// node is deliberately not on the private network at all — under the old rule that alone would
// refuse it.
func TestAProvisionAnsweredByARecordDoesNotNeedAPrivateNetwork(t *testing.T) {
got, err := Resolve(
map[string]Manifest{"assistant": aModelUser()},
[]string{"assistant"},
Node{Name: "workstation"},
World{
Licences: map[string][]Record{"model-access": {{Name: "personal",
Serves: map[string]any{"model": "a-model"}}}},
Using: map[string]map[string]Record{"assistant": {"model-access": {Name: "personal",
Serves: map[string]any{"model": "a-model"}}}},
})
if err != nil {
t.Fatalf("a machine off the private network could not be given model access: %v", err)
}
if len(got.Needs) != 1 {
t.Fatalf("the licence was not recorded as something this node takes: %+v", got.Needs)
}
if !got.Needs[0].ByRecord {
t.Fatal("the licence was treated as a machine, so the reachability rule would apply to it")
}
if got.Needs[0].From != "personal" {
t.Fatalf("the licence is not named by what a person calls it: %+v", got.Needs[0])
}
}
// Refused when the consumer has not said which — and the refusal names the candidates and the
// command, because ADR 0024 warns this will be felt: a mesh holding three ways to reach a model
// refuses every consumer that has not chosen.
func TestAConsumerThatHasNotSaidWhichLicenceIsRefusedWithTheCandidates(t *testing.T) {
_, err := Resolve(
map[string]Manifest{"assistant": aModelUser()},
[]string{"assistant"},
Node{Name: "workstation"},
World{Licences: map[string][]Record{"model-access": {
{Name: "personal"}, {Name: "the-organisation"},
}}})
if err == nil {
t.Fatal("a consumer was given model access without anybody saying which")
}
said := err.Error()
for _, want := range []string{"personal", "the-organisation", "licence use"} {
if !strings.Contains(said, want) {
t.Fatalf("the refusal does not name %q, so it is correct and unusable:\n%s", want, said)
}
}
}
// A model the mesh runs itself answers it locally, and a record is not consulted.
func TestAModelInTheMeshsOwnSetAnswersItWithoutALicence(t *testing.T) {
got, err := Resolve(
map[string]Manifest{
"assistant": aModelUser(),
"ollama": {Module: "ollama",
Provides: []Offer{{Name: "model-access", Scope: ScopeNode}}},
},
[]string{"assistant", "ollama"},
Node{Name: "workstation"},
World{Licences: map[string][]Record{"model-access": {{Name: "personal"}}}})
if err != nil {
t.Fatalf("a machine running its own model was asked to choose a licence: %v", err)
}
for _, n := range got.Needs {
if n.ByRecord {
t.Fatal("a record was used although the answer was on this machine")
}
}
}
// A key that was never supplied is refused by name rather than silently not written.
//
// The mesh discarded the plaintext when the key was accepted and cannot seal another, so a
// machine that resolved cleanly would receive no file and fail at whatever read it.
func TestAModuleOnALicenceWithNoKeyIsRefusedRatherThanLeftEmpty(t *testing.T) {
r := Resolution{
Node: "workstation",
Modules: []Manifest{aModelUser()},
Needs: []Needed{{Name: "model-access", From: "personal", ByRecord: true, For: "assistant"}},
}
_, err := r.Declaration(Rendering{})
if err == nil {
t.Fatal("a module was given a licence with no key, so it receives nothing and fails later")
}
if !strings.Contains(err.Error(), "licence key personal") {
t.Fatalf("the refusal does not say how to fix it: %v", err)
}
}
// And with a key, both files arrive: what is public, and what is not.
func TestALicenceDeliversWhatIsPublicAndWhatIsSealed(t *testing.T) {
r := Resolution{
Node: "workstation",
Modules: []Manifest{aModelUser()},
Needs: []Needed{{Name: "model-access", From: "personal", ByRecord: true, For: "assistant",
Serves: map[string]any{"model": "a-model"}, Sealed: "sealed-blob"}},
}
out, err := r.Declaration(Rendering{})
if err != nil {
t.Fatal(err)
}
files := map[string]map[string]any{}
for _, res := range out {
if path, ok := res["path"].(string); ok {
files[path] = res
}
}
bound, given := files["/etc/assistant/model.json"]
if !given {
t.Fatal("the consumer was not told what it needs to know that is not secret")
}
content, _ := bound["content"].(string)
if !strings.Contains(content, "a-model") {
t.Fatalf("the binding does not carry what the licence serves:\n%s", content)
}
// The binding says it is a record rather than leaving an empty address, which a reader would
// take for something the mesh failed to fill in.
if !strings.Contains(content, "not a machine") {
t.Fatalf("the binding leaves an empty address with no explanation:\n%s", content)
}
key, delivered := files["/etc/assistant/key"]
if !delivered {
t.Fatal("the key was not delivered")
}
if key["sealed"] != "sealed-blob" {
t.Fatalf("the key is not the sealed one: %+v", key)
}
// And never in the open. The whole arrangement is that what travels is unreadable by
// everything between here and the machine.
if strings.Contains(content, "sealed-blob") {
t.Fatal("the key was written into the public file as well")
}
}
// One machine's unresolvable module must not remove it from the private network.
//
// The pass that answers *what does this node offer* takes a failed resolution to mean it learned
// nothing — so refusing an unanswerable requirement there makes the machine disappear, and every
// other machine is then told, wrongly, that the two of them share no network. A wrong answer about
// a machine nobody asked about, caused by a fault on a third.
func TestAnUnanswerableRequirementDoesNotRemoveAMachineFromTheMesh(t *testing.T) {
shelf := map[string]Manifest{
"assistant": aModelUser(),
"networking": {Module: "networking",
Provides: []Offer{{Name: "mesh-network", Scope: ScopeNode}}},
}
// The first pass: what does this machine offer? It is assigned something nothing answers.
got, err := Resolve(shelf, []string{"assistant", "networking"},
Node{Name: "laptop"}, World{Unchecked: true})
if err != nil {
t.Fatalf("a machine with one unanswerable requirement was lost entirely: %v", err)
}
var offers bool
for _, m := range got.Modules {
for _, o := range m.Offers() {
if o == "mesh-network" {
offers = true
}
}
}
if !offers {
t.Fatal("the machine's own network module was not seen, so it looks off the network")
}
// And the second pass, where the question is actually being asked, still refuses it.
if _, err := Resolve(shelf, []string{"assistant", "networking"},
Node{Name: "laptop"}, World{}); err == nil {
t.Fatal("the requirement nothing answers was accepted when it was actually asked")
}
}