diff --git a/modules/distribution/internal/holder/holder_test.go b/modules/distribution/internal/holder/holder_test.go index aaf559ff6..615fc0ff4 100644 --- a/modules/distribution/internal/holder/holder_test.go +++ b/modules/distribution/internal/holder/holder_test.go @@ -916,19 +916,34 @@ func TestTheHolderOfTheTwoImageSeats(t *testing.T) { // Running review F2: incoming asks the bus 8 GiB, the most the objects template allows, equal to IncomingCap // (said only where no binding is read); transfers keeps for good, the holder dropping an idle one by its key // in idle, a state of keys with their own time to live. + // The image registry is a foundation part (design 47 G §584): its bus state is in its old sections, incoming in + // `objects`, the others in `state`. var req struct { - Requires []struct { - Name string `json:"name"` - Options map[string]any `json:"options"` - } `json:"requires"` + Objects []struct { + Name string `json:"name"` + MaxMiB uint64 `json:"max-mib"` + } `json:"objects"` + State []json.RawMessage `json:"state"` } _ = json.Unmarshal(raw, &req) opts := map[string]map[string]any{} - for _, r := range req.Requires { - opts[r.Name] = r.Options + for _, e := range req.State { + var o map[string]any + if json.Unmarshal(e, &o) != nil { + var name string + _ = json.Unmarshal(e, &name) + o = map[string]any{"name": name} + } + opts[fmt.Sprint(o["name"])] = o } - if mib, _ := opts[IncomingObjects]["max-mib"].(float64); uint64(mib)<<20 != IncomingCap { - t.Errorf("incoming asks %v MiB, IncomingCap is %d bytes: want them equal", opts[IncomingObjects]["max-mib"], uint64(IncomingCap)) + var incoming uint64 + for _, o := range req.Objects { + if o.Name == IncomingObjects { + incoming = o.MaxMiB + } + } + if incoming<<20 != IncomingCap { + t.Errorf("incoming asks %v MiB, IncomingCap is %d bytes: want them equal", incoming, uint64(IncomingCap)) } if _, ok := opts[TransfersState]["ttl-seconds"]; ok { t.Errorf("transfers has a lifetime %v: the bus would drop a transfer's key and leave its parts", opts[TransfersState]) diff --git a/modules/gitea/cmd/package-registry/retention_test.go b/modules/gitea/cmd/package-registry/retention_test.go index 6fd6081aa..4eb926efb 100644 --- a/modules/gitea/cmd/package-registry/retention_test.go +++ b/modules/gitea/cmd/package-registry/retention_test.go @@ -437,6 +437,8 @@ func TestToolsAreTheOnesTheReadmeNamesAndSayWhatTheyDo(t *testing.T) { Serves []string `json:"serves"` } `json:"claims"` Requires []any `json:"requires"` + Objects []any `json:"objects"` + State []any `json:"state"` Packages map[string]string `json:"packages"` Invokes []string `json:"invokes"` Build struct { @@ -472,10 +474,15 @@ func TestToolsAreTheOnesTheReadmeNamesAndSayWhatTheyDo(t *testing.T) { if len(names) != 8 || !names[packageseats.GoSeat+".publish-part"] { t.Errorf("the seat tools are %v", names) } - req, _ := json.Marshal(m.Requires) - for _, want := range []string{`"name":"incoming"`, `"name":"transfers"`, `"name":"idle","options":{"key-ttl":true}`} { + // The forge module is a foundation part (design 47 G §584): incoming is in its old objects section, transfers and idle + // (key-ttl) in its old state section. + req, _ := json.Marshal(struct { + Objects any `json:"objects"` + State any `json:"state"` + }{m.Objects, m.State}) + for _, want := range []string{`"name":"incoming"`, `"transfers"`, `"key-ttl":true,"name":"idle"`} { if !strings.Contains(string(req), want) { - t.Errorf("the manifest does not require %s (%s)", want, req) + t.Errorf("the manifest does not keep %s in its old sections (%s)", want, req) } } // findings is one local name in one form (novox/hq ADR 0595 §11): the old section state, which the TypeScript bundle diff --git a/modules/localization/cmd/localization-tools/manifest_test.go b/modules/localization/cmd/localization-tools/manifest_test.go index 2c6ab5b61..6fca0e4e8 100644 --- a/modules/localization/cmd/localization-tools/manifest_test.go +++ b/modules/localization/cmd/localization-tools/manifest_test.go @@ -11,7 +11,7 @@ import ( func TestTheFilesSayWhatTheToolsCompareAgainst(t *testing.T) { m := manifest(t) - if m.Module != "localization" || m.Version != "1" { + if m.Module != "localization" || m.Version != "0.1" { t.Fatalf("%s %s", m.Module, m.Version) } locale := m.resource(t, "locale") diff --git a/modules/mesh-build-go/cmd/mesh-build-go/forge_test.go b/modules/mesh-build-go/cmd/mesh-build-go/forge_test.go index d9dab2fd4..a3fdf7dc9 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/forge_test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/forge_test.go @@ -151,7 +151,11 @@ func TestManifestRequiresForgeAccountKeepsKeysAndTakesFilesFromTemplates(t *test // kept-builds: the builds kept for the artifact store's holder (keptbuilds.go), by the template objects (W12.5). kept := map[string]any{"name": "kept-builds", "storage": "object-store", "template": "objects", "options": map[string]any{"max-mib": float64(1024)}} detected := map[string]any{"name": "detected-steps", "storage": "key-value", "template": "state", "options": map[string]any{"history": float64(1)}} - if want := []any{detected, kept, "forge-account", "go-toolchain", "go-package-registry", "node-tools"}; !reflect.DeepEqual(m.Requires, want) { + // The findings are asked in requires as a part that is no foundation part asks them (design 47 G §529, A-30). + findings := map[string]any{"name": "findings", "storage": "key-value", "template": "state"} + findingEvents := map[string]any{"name": "finding-events", "storage": "stream", "template": "events", "options": map[string]any{ + "events": []any{"finding-written.*", "finding-cleared.*", "findings-stated.*"}, "max-age-days": float64(7), "max-mib": float64(16)}} + if want := []any{detected, kept, "forge-account", "go-toolchain", "go-package-registry", "node-tools", findings, findingEvents}; !reflect.DeepEqual(m.Requires, want) { t.Errorf("requires = %v, want %v", m.Requires, want) } keeps := false diff --git a/modules/mesh-build-go/cmd/mesh-build-go/manifest_test.go b/modules/mesh-build-go/cmd/mesh-build-go/manifest_test.go index 3e89059cf..99e7eb34e 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/manifest_test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/manifest_test.go @@ -118,7 +118,7 @@ func TestManifestKeepsItsStatesClaimsItsBuildSeatAndDeclaresItsHealthTool(t *tes } } slices.Sort(states) - if want := []string{"findings", "keys", "pauses", "steps", "toolchains"}; !slices.Equal(states, want) { + if want := []string{"keys", "pauses", "steps", "toolchains"}; !slices.Equal(states, want) { t.Errorf("state = %v, want %v", states, want) } if len(m.Claims) != 1 || m.Claims[0].Name != Seat { @@ -194,15 +194,13 @@ func TestTheModuleInvokesTheArtifactSeatsVerbsAndWritesNoStore(t *testing.T) { if !slices.Contains(m.Consumes, "mesh-conditions.findings-asked") { t.Errorf("consumes %v lack mesh-conditions.findings-asked", m.Consumes) } - found := false + // Not a foundation part, it asks its finding stream in requires, by the template events (design 47 G §529, A-30), and + // declares no stream of that name. for _, st := range m.Streams { if st.Name == "mesh-build-go-findings" { - found = slices.Equal(st.Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}) && st.MaxAgeDays == 7 && st.MaxMiB == 16 + t.Errorf("streams %+v still declare mesh-build-go-findings: a part outside the foundation asks finding-events in requires", m.Streams) } } - if !found { - t.Errorf("streams %+v lack mesh-build-go-findings (7 days, 16 MiB)", m.Streams) - } for _, r := range m.Resources { if r["id"] == "registry" { t.Errorf("the store's address is still placed: %v", r) diff --git a/modules/mesh-knowledge/cmd/mesh-knowledge/manifest_test.go b/modules/mesh-knowledge/cmd/mesh-knowledge/manifest_test.go index a02013503..ac295944b 100644 --- a/modules/mesh-knowledge/cmd/mesh-knowledge/manifest_test.go +++ b/modules/mesh-knowledge/cmd/mesh-knowledge/manifest_test.go @@ -79,7 +79,7 @@ func TestItDeclaresAndHoldsTheKnowledgeBaseSeatOnceForTheMesh(t *testing.T) { t.Fatalf("requires %s, contributes %v, state %v", m.Requires, m.Contributes, m.State) } // It asks the operator on the router, hears the router's word, and hears the judge's answers. - if !reflect.DeepEqual(m.Uses, []string{"operator-channel"}) || !reflect.DeepEqual(m.Consumes, append([]string{"claude-code.judged"}, overviewConsumes()...)) { + if !reflect.DeepEqual(m.Uses, []string{"operator-channel"}) || !reflect.DeepEqual(m.Consumes, append(append([]string{"claude-code.judged"}, overviewConsumes()...), "mesh-conditions.findings-asked")) { t.Fatalf("uses %v, consumes %v", m.Uses, m.Consumes) } if !reflect.DeepEqual(m.Invokes, []string{"seat:issue-tracker.reserve", "claude-code.claude_code_judge", "records.records_status", @@ -232,7 +232,7 @@ func TestItAsksForItsBusStateInTheTypedForm(t *testing.T) { names = append(names, e.Name) byName[e.Name] = e } - if !reflect.DeepEqual(names, []string{"records", "drafts", "asked", "findings", "sent", "reviews"}) { + if !reflect.DeepEqual(names, []string{"records", "drafts", "asked", "findings", "sent", "reviews", "finding-events"}) { t.Fatalf("bus state %v", names) } rec := byName["records"] diff --git a/modules/mesh-provisioner/cmd/mesh-provisioner/provisioner_test.go b/modules/mesh-provisioner/cmd/mesh-provisioner/provisioner_test.go index fd6cbc2d8..8771b6b16 100644 --- a/modules/mesh-provisioner/cmd/mesh-provisioner/provisioner_test.go +++ b/modules/mesh-provisioner/cmd/mesh-provisioner/provisioner_test.go @@ -327,7 +327,7 @@ func TestTheManifestDeclaresWhatTheCodeKeeps(t *testing.T) { t.Errorf("the claim: %+v", m.Claims) } // needs stays declared this release so its first start can empty it (ADR 0570 clause 1). - if want := []string{Registry, Needs, Applied, Collect, ProvisionsState, PlansState, RefusedState, "findings"}; !slices.Equal(m.State, want) { + if want := []string{Registry, Needs, Applied, Collect, ProvisionsState, PlansState, RefusedState}; !slices.Equal(m.State, want) { t.Errorf("the state is %v, want %v", m.State, want) } // Every state and act has its tool (ADR 0570 Consequences): the verb reads the clients' states, the holder's tools diff --git a/modules/mesh-self-check/cmd/mesh-self-check/manifest_test.go b/modules/mesh-self-check/cmd/mesh-self-check/manifest_test.go index 8d033ac94..94166e71a 100644 --- a/modules/mesh-self-check/cmd/mesh-self-check/manifest_test.go +++ b/modules/mesh-self-check/cmd/mesh-self-check/manifest_test.go @@ -68,8 +68,9 @@ func TestTheManifestSaysWhatTheCodeDoes(t *testing.T) { if !slices.Equal(m.Reads, Reads) { t.Errorf("reads %v, want what the probes read, %v", m.Reads, Reads) } - if !slices.Equal(m.Consume, Consumes) { - t.Errorf("consumes %v, want the views families the probes follow, %v", m.Consume, Consumes) + // And the keeper's ask, which a part keeping findings hears (design 47 G §387). + if want := append(slices.Clone(Consumes), "mesh-conditions.findings-asked"); !slices.Equal(m.Consume, want) { + t.Errorf("consumes %v, want the views families the probes follow and the keeper's ask, %v", m.Consume, want) } for _, view := range []string{assignerModule + ".views." + placing.StateAssignments, assignerModule + ".views." + placing.StateSeatHolders} { if !slices.Contains(m.Consume, view) { diff --git a/modules/sudo/cmd/sudo-tools/manifest_test.go b/modules/sudo/cmd/sudo-tools/manifest_test.go index 3d3bb4546..1e438c81d 100644 --- a/modules/sudo/cmd/sudo-tools/manifest_test.go +++ b/modules/sudo/cmd/sudo-tools/manifest_test.go @@ -15,7 +15,7 @@ import ( func TestItDeclaresThePackageAndTheDropInSudoReads(t *testing.T) { m := manifest(t) - if m.Module != "sudo" || m.Version != "1" { + if m.Module != "sudo" || m.Version != "0.1" { t.Fatalf("%s %s", m.Module, m.Version) } if p := m.resource(t, "package"); p["type"] != "package" || p["package"] != "sudo" {