E-1: the tool runner's manifest names no waits and keeps its approvals (issue 1966)
module.json drops waits and its five families, uses operator-channel for the asks of marked waits, and keeps the per-machine state approvals (48 hours) in its old state section; the manifest test holds each change. Builds: design 34 every-event §11, §19 (the manifest test); design 46 7-approval-mark §7, §13 (manifest entry) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -8,19 +8,28 @@ import (
|
||||
"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) {
|
||||
// The tool runner's manifest names no events to wait on (novox/hq ADR 0670 §2): a session waits on any event by its
|
||||
// name. It holds each change of design 34 every-event §11 (E-1): no `waits`, `operator-channel` in `uses` for the asks of
|
||||
// marked waits, the per-machine state `approvals` in the old `state` section with its 48 hours and none in `requires`
|
||||
// (design 46 7-approval-mark §13), and the finding stream (design 47 G §387).
|
||||
func TestTheManifestNamesNoWaitsAndKeepsItsApprovals(t *testing.T) {
|
||||
raw, err := os.ReadFile("../../module.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var keys map[string]json.RawMessage
|
||||
if err := json.Unmarshal(raw, &keys); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := keys["waits"]; ok {
|
||||
t.Error("the manifest still carries waits (novox/hq ADR 0670 §2)")
|
||||
}
|
||||
var m struct {
|
||||
Module string `json:"module"`
|
||||
Waits []string `json:"waits"`
|
||||
Consumes []string `json:"consumes"`
|
||||
Module string `json:"module"`
|
||||
Uses []string `json:"uses"`
|
||||
State []json.RawMessage `json:"state"`
|
||||
Requires []json.RawMessage `json:"requires"`
|
||||
Consumes []string `json:"consumes"`
|
||||
Streams []struct {
|
||||
Name string `json:"name"`
|
||||
Events []string `json:"events"`
|
||||
@@ -29,20 +38,33 @@ func TestTheManifestNamesTheFirstFamiliesOneByOne(t *testing.T) {
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if m.Module != "node-tools" || !reflect.DeepEqual(m.Uses, []string{"operator-channel"}) {
|
||||
t.Errorf("%s uses %v, want operator-channel (design 46 7-approval-mark §7)", m.Module, m.Uses)
|
||||
}
|
||||
type state struct {
|
||||
Name string `json:"name"`
|
||||
PerMachine bool `json:"per-machine"`
|
||||
TTLSeconds int `json:"ttl-seconds"`
|
||||
}
|
||||
var approvals []state
|
||||
for _, r := range m.State {
|
||||
var s state
|
||||
if json.Unmarshal(r, &s) == nil && s.Name == "approvals" {
|
||||
approvals = append(approvals, s)
|
||||
}
|
||||
}
|
||||
if want := []state{{Name: "approvals", PerMachine: true, TTLSeconds: 172800}}; !reflect.DeepEqual(approvals, want) {
|
||||
t.Errorf("the old state section's approvals is %+v, want %+v (design 46 7-approval-mark §13)", approvals, want)
|
||||
}
|
||||
for _, r := range m.Requires {
|
||||
if strings.Contains(string(r), `"approvals"`) {
|
||||
t.Errorf("approvals is asked in requires too: %s", r)
|
||||
}
|
||||
}
|
||||
if len(m.Streams) != 1 || m.Streams[0].Name != "node-tools-findings" ||
|
||||
!reflect.DeepEqual(m.Streams[0].Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}) {
|
||||
t.Errorf("the finding stream is %+v, want node-tools-findings with the three finding events (design 47 G §387)", m.Streams)
|
||||
}
|
||||
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 assigner's two views families (ADR 0615 §5, issue 1966
|
||||
// TLS-5), the events of the catalog half's branch follower (design 47 G §196, §614: `catalog-revision`,
|
||||
// `registration-changed`, and the gate's `source-moved`; never the indexer's `views.modules` or `views.manifests`), the two
|
||||
|
||||
@@ -126,7 +126,7 @@ func TestTheOfferServesThePortTheManifestServes(t *testing.T) {
|
||||
var m struct {
|
||||
Serves map[string]map[string]any `json:"serves"`
|
||||
Moved bool `json:"moved"`
|
||||
State []string `json:"state"`
|
||||
State []json.RawMessage `json:"state"`
|
||||
Reads []string `json:"reads"`
|
||||
Provides []struct {
|
||||
Name string `json:"name"`
|
||||
@@ -172,9 +172,18 @@ func TestTheOfferServesThePortTheManifestServes(t *testing.T) {
|
||||
// Every bucket the sdk's helper reaches is a state the manifest keeps or reads, by the sdk's names: the provider's
|
||||
// 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...) {
|
||||
for _, n := range m.Reads {
|
||||
declared[n] = true
|
||||
}
|
||||
for _, r := range m.State { // an old state entry is its name, or an object naming it (approvals, per machine)
|
||||
var e struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
if json.Unmarshal(r, &e.Name) != nil {
|
||||
_ = json.Unmarshal(r, &e)
|
||||
}
|
||||
declared[e.Name] = true
|
||||
}
|
||||
for bucket, want := range map[string]string{
|
||||
provider.BucketOf(Module): "bound",
|
||||
provisions.ProvisionsBucketOf(Provisioner): "mesh-provisioner.provisions",
|
||||
|
||||
@@ -6,12 +6,8 @@
|
||||
"invokes": [
|
||||
"*"
|
||||
],
|
||||
"waits": [
|
||||
"mesh-knowledge.reviewed",
|
||||
"mesh-delivery-gate.transition",
|
||||
"gitea.forge.status",
|
||||
"mesh-self-check.checked",
|
||||
"operator-channel.decided.claude-code"
|
||||
"uses": [
|
||||
"operator-channel"
|
||||
],
|
||||
"provides": [
|
||||
{
|
||||
@@ -68,7 +64,12 @@
|
||||
},
|
||||
"state": [
|
||||
"bound",
|
||||
"findings"
|
||||
"findings",
|
||||
{
|
||||
"name": "approvals",
|
||||
"per-machine": true,
|
||||
"ttl-seconds": 172800
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"mesh-catalog.catalog-revision",
|
||||
|
||||
Reference in New Issue
Block a user