package console import ( "encoding/json" "os" "reflect" "strings" "testing" ) // novox/hq ADR 0367 §5: the tool runner's manifest names the families a session waits on today, one by one, // and the asker's `decided` for the claude-code module alone. Adding one is a reviewed change to this file // (§6), so this list changes with it. The delivery's transitions are waited on under the gate's name alone (ADR 0450 §8, issues 1350 // and 1406): today's module is forgotten. func TestTheManifestNamesTheFirstFamiliesOneByOne(t *testing.T) { raw, err := os.ReadFile("../../module.json") if err != nil { t.Fatal(err) } var m struct { Module string `json:"module"` Waits []string `json:"waits"` Consumes []string `json:"consumes"` } if err := json.Unmarshal(raw, &m); err != nil { t.Fatal(err) } want := []string{"mesh-knowledge.reviewed", "mesh-delivery-gate.transition", "gitea.forge.status", "mesh-self-check.checked", "operator-channel.decided.claude-code"} if m.Module != "node-tools" || !reflect.DeepEqual(m.Waits, want) { t.Errorf("%s waits on %v, want %v", m.Module, m.Waits, want) } for _, w := range m.Waits { if strings.ContainsAny(w, "*>") { t.Errorf("a family named by a wildcard: %s", w) } } // A wait is no consumer (ADR 0367 §2): what it consumes is the four views families of its first views (ADR 0615 §5, issue // 1966 TLS-5) and the two events of the seat that serves the seat list (ADR 0636 §4), and nothing else. wantConsumes := []string{"mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-delivery-assigner.views.assignments", "mesh-delivery-assigner.views.seat-holders", "mesh-delivery-indexer.views.manifests", "mesh-delivery-indexer.views.modules"} if !reflect.DeepEqual(m.Consumes, wantConsumes) { t.Errorf("the tool runner consumes %v, want %v", m.Consumes, wantConsumes) } } // issue 1966 TLS-1: the tool runner declares its own secret `ledgers`, each module's ledger credential, in the directory it // keeps its broker credential in, which is where the runner reads it (runtime.LedgersFileOf). func TestTheManifestDeclaresTheRunnersOwnSecretLedgers(t *testing.T) { raw, err := os.ReadFile("../../module.json") if err != nil { t.Fatal(err) } var m struct { OwnSecrets map[string]string `json:"own-secrets"` } if err := json.Unmarshal(raw, &m); err != nil { t.Fatal(err) } want := map[string]string{"broker": "${dir:mesh-state}/broker", "ledgers": "${dir:mesh-state}/ledgers"} if !reflect.DeepEqual(m.OwnSecrets, want) { t.Errorf("own secrets %v, want %v", m.OwnSecrets, want) } }