indexer: the first fill's edge entries, marked filled, from the placement and the stream running read whole

VersionEdge gains filled (mesh-catalog seat contract, regenerated).

Builds: design 47 G §377, A-78 c, A-62, §556
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-11 23:17:28 +01:00
parent c6af94fe58
commit bdc9a61524
13 changed files with 344 additions and 10 deletions
+5 -3
View File
@@ -1034,9 +1034,11 @@ type VersionEdge struct {
// the digest of the part pointed to, kinds 1-4
Digest string `json:"digest,omitempty"`
// kinds 5 and 6: the acting part, its step and the build that acted, or the verb or word used and the delivered version that serves it
Fact string `json:"fact,omitempty"`
Kind int64 `json:"kind"`
Part ArtifactRef `json:"part"`
Fact string `json:"fact,omitempty"`
// the entry was derived at the first fill (design 47 G section 377), not recorded at a release or a delivery
Filled bool `json:"filled,omitempty"`
Kind int64 `json:"kind"`
Part ArtifactRef `json:"part"`
// the edge makes the dependent stale (kinds 1, 3) or only orders it (kinds 2, 4, 5, 6) (section 378)
Stale bool `json:"stale"`
// the dependency's version, kinds 1-4; "not yet delivered" until the first delivery for 2, 4 and 6
+4
View File
@@ -2555,6 +2555,10 @@
"fact": {
"type": "string",
"description": "kinds 5 and 6: the acting part, its step and the build that acted, or the verb or word used and the delivered version that serves it"
},
"filled": {
"type": "boolean",
"description": "the entry was derived at the first fill (design 47 G section 377), not recorded at a release or a delivery"
}
},
"required": [
+2
View File
@@ -490,6 +490,8 @@ export interface VersionEdge {
"digest"?: string;
/** kinds 5 and 6: the acting part, its step and the build that acted, or the verb or word used and the delivered version that serves it */
"fact"?: string;
/** the entry was derived at the first fill (design 47 G section 377), not recorded at a release or a delivery */
"filled"?: boolean;
"kind": number;
"part": ArtifactRef;
/** the edge makes the dependent stale (kinds 1, 3) or only orders it (kinds 2, 4, 5, 6) (section 378) */
@@ -441,7 +441,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
Predefined: awaitedStore{b: predefined}, ConfigCandidates: awaitedStore{b: configCandidates}, Logf: logger.Printf,
Named: namedVia(calls.Call), Trunk: trunkVia(calls.Call), Contains: containsVia(calls.Call), Read: readVia(calls.Call),
ReadOpen: openVia(calls.Call), Packages: awaitedStore{b: packages, js: js, name: index.PackagesBucket}, Files: filesVia(calls.Call), GoSum: goSumVia(calls.Call), GoMod: goModVia(calls.Call),
OwnBuild: ownBuildVia(calls.Call, cred.Node), OpenTries: openTriesVia(calls.Call), OwnBuildState: awaitedStore{b: ownBuildState}, Heard: heardStore, TryRecovery: awaitedStore{b: tryRecovery}, Graph: graph,
OwnBuild: ownBuildVia(calls.Call, cred.Node), OpenTries: openTriesVia(calls.Call), OwnBuildState: awaitedStore{b: ownBuildState}, Heard: heardStore, Placement: placementVia(calls.CallKept), RunningWhole: runningWholeVia(js), TryRecovery: awaitedStore{b: tryRecovery}, Graph: graph,
SeatDefinitions: awaitedStore{b: seatDefs}, ReadFile: readFileVia(calls.Call), SaySeatDefinition: saySeats,
Message: messageVia(calls.CallKept), Revisions: revisions, EntryIndex: awaitedStore{b: process.AwaitBucket(ctx, js, conn, index.EntryIndexBucket, "no entry is found by its fingerprint", logger.Printf)}, // Message a kept call: a read, called again through a transport fault (ADR 0668 §1)
// Each catalog revision may bring another holder of a build seat: the build modules are found again (buildmodules.go).
@@ -10,6 +10,8 @@ import (
"github.com/nats-io/nats.go"
"github.com/nats-io/nats.go/jetstream"
"git.novox.be/novox/mesh-contracts/go/seats/meshmoduleassigner"
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshbuilds"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshwants"
@@ -159,3 +161,58 @@ func afterRevision(say func(context.Context, meshcatalog.CatalogRevisionEvent) e
return err
}
}
// placementVia asks the seat mesh-module-assigner's verb placement for one module (A-62), a read.
func placementVia(call toolCaller) index.PlacementAsker {
return func(_ context.Context, module string) ([]meshmoduleassigner.ModulePlacement, error) {
raw, err := call(meshmoduleassigner.Seat+"."+meshmoduleassigner.VerbPlacement, map[string]any{"module": module})
if err != nil {
return nil, fmt.Errorf("%s.%s: %w", meshmoduleassigner.Seat, meshmoduleassigner.VerbPlacement, err)
}
var a meshmoduleassigner.PlacementAnswer
if err := json.Unmarshal(raw, &a); err != nil {
return nil, fmt.Errorf("the answer of placement is not a module's placements: %w", err)
}
return a.Placements, nil
}
}
// runningWholeVia reads every subject's last message of the node-engine seat's stream running through an ordered consumer made for
// that one read (design 47 G §556), by node and module.
func runningWholeVia(js jetstream.JetStream) index.RunningReader {
return func(ctx context.Context) (map[string]map[string]nodeengine.Running, error) {
stream, err := js.Stream(ctx, nodeengine.StreamRunning)
if err != nil {
return nil, fmt.Errorf("the stream %s cannot be read whole: %w", nodeengine.StreamRunning, err)
}
cons, err := stream.OrderedConsumer(ctx, jetstream.OrderedConsumerConfig{DeliverPolicy: jetstream.DeliverLastPerSubjectPolicy})
if err != nil {
return nil, fmt.Errorf("the ordered consumer for the whole read of %s cannot be made: %w", nodeengine.StreamRunning, err)
}
out := map[string]map[string]nodeengine.Running{}
for {
batch, err := cons.FetchNoWait(256)
if err != nil {
return nil, fmt.Errorf("the whole read of %s failed: %w", nodeengine.StreamRunning, err)
}
n := 0
for m := range batch.Messages() {
n++
var r nodeengine.Running
if json.Unmarshal(m.Data(), &r) != nil || r.Node == "" || r.Module == "" {
continue
}
if out[r.Node] == nil {
out[r.Node] = map[string]nodeengine.Running{}
}
out[r.Node][r.Module] = r
}
if err := batch.Error(); err != nil {
return nil, fmt.Errorf("the whole read of %s failed: %w", nodeengine.StreamRunning, err)
}
if n == 0 {
return out, nil
}
}
}
}
@@ -193,7 +193,11 @@ type Indexer struct {
// Heard keeps what the indexer heard and compares later (A-80): the time a call is unanswered since (steps-since, call-since),
// toolchain.<language>, delivered.<module>, pending.<module>.<version>, acted.<acting part>.<dependent>, each key part escaped as a name
// (§73), and the mark versions-filled; nil keeps none. It is the state heard, whose key forge keeps the forge messages handled.
Heard Store
Heard Store
// Placement asks the assigner's verb placement (A-62) and RunningWhole reads the node-engine's stream running whole (§556), both for the
// edge entries of the first fill (§377); nil reads none, and the entries of kinds 2, 4 and 6 then read "not yet delivered".
Placement PlacementAsker
RunningWhole RunningReader
judgePending atomic.Bool // the start's judge pass failed: judged again at the next message (verdicts.go)
// Message asks the forge bridge for the merged message of a merge, repository, merge commit and pull request number in (the number lets the bridge read a merge made on the forge, not through the gate), the message whole out (a
// pending value keeps a reference, not a copy: issue 1585); an error is the bridge's words. Nil asks none.
@@ -908,7 +908,7 @@ func (ix *Indexer) dry() *dryRun {
// requirements, findings, seat definitions, holds and their bounds are not overlaid, nothing is said, and no hold is
// weighed (Holds and Counted nil hold nothing); ReadFile only reads.
Requirements: nil, Findings: nil, SeatDefinitions: nil, ReadFile: ix.ReadFile, SaySeatDefinition: nil,
OwnBuildState: nil, Heard: nil, underSeats: true,
OwnBuildState: nil, Heard: nil, Placement: nil, RunningWhole: nil, underSeats: true,
// A dry run keeps no catalog graph revision (catalog_revisions.go): its revision is the take-in's to keep.
Revisions: nil, SayCatalogRevision: nil, SayFill: nil, EntryIndex: nil, Versions: nil, SayVersionReleased: nil, SayVersionsFilled: nil, Inputs: nil,
// A dry run writes no registration and asks no one.
@@ -1131,7 +1131,7 @@ func TestTakeIn(t *testing.T) { // 1585/T3-T13 (ADR 0633)
for _, f := range []string{"Store", "Modules", "Manifests", "Predefined", "ConfigCandidates", "Taken", "Verdicts", "OldSections", "Unjudged",
"JudgeID", "SayRefused", "SayAccepted", "Packages", "Graph", "Files", "GoSum", "GoMod", "Now", "Builds", "Named", "Trunk",
"Read", "Contains", "Logf", "ReadOpen", "OwnBuild", "Message", "Pending", "SayTakeIn",
"Requirements", "Findings", "SeatDefinitions", "ReadFile", "SaySeatDefinition", "OpenTries", "TryRecovery", "OwnBuildState", "Heard", "Revisions", "SayCatalogRevision", "SayFill", "EntryIndex", "Registry", "SeedModules", "Versions", "SayVersionReleased", "SayVersionsFilled", "Inputs"} {
"Requirements", "Findings", "SeatDefinitions", "ReadFile", "SaySeatDefinition", "OpenTries", "TryRecovery", "OwnBuildState", "Heard", "Placement", "RunningWhole", "Revisions", "SayCatalogRevision", "SayFill", "EntryIndex", "Registry", "SeedModules", "Versions", "SayVersionReleased", "SayVersionsFilled", "Inputs"} {
named[f] = true
}
ty := reflect.TypeOf(Indexer{})
@@ -5,9 +5,12 @@ import (
"encoding/json"
"errors"
"fmt"
"maps"
"slices"
"strconv"
"time"
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-sdk/go/keys"
@@ -127,6 +130,12 @@ func (ix *Indexer) FillVersions(ctx context.Context, ask VersionsAsker) error {
}
now := ix.now().UTC()
filled := 0
built := map[string]meshcatalog.VersionEntry{}
claimed := map[string]time.Time{}
trunk := map[string]meshcatalog.CatalogEntry{}
for _, e := range entries {
trunk[e.Module] = e
}
for module, fs := range best {
v := meshcatalog.VersionEntry{V: int64(keys.Version), Module: module, Version: fs[0].v.Version, At: &now}
for _, f := range fs {
@@ -134,7 +143,29 @@ func (ix *Indexer) FillVersions(ctx context.Context, ask VersionsAsker) error {
if n, err := strconv.ParseInt(f.v.Revision, 10, 64); err == nil && n > v.Source {
v.Source = n
}
if f.v.At.After(claimed[module]) {
claimed[module] = f.v.At
}
}
built[module] = v
}
// The edge entries (§377), each marked filled: where the stream running or the placement cannot be read the entries of kinds 2, 4
// and 6 read "not yet delivered", as at a release, and the first delivery writes them.
var running map[string]map[string]nodeengine.Running
if ix.RunningWhole != nil {
if running, err = ix.RunningWhole(ctx); err != nil {
ix.logf("versions fill: the stream running is not read whole: %v", err)
running = nil
}
}
answers := map[string]BuilderVersionsAnswer{}
for _, module := range slices.Sorted(maps.Keys(built)) {
v := built[module]
v.Edges = ix.filledEdges(ctx, trunk[module], claimed[module], ask, trunk, built, running, answers)
built[module] = v
}
for _, module := range slices.Sorted(maps.Keys(built)) {
v := built[module]
data, err := json.Marshal(v)
if err != nil {
return err
@@ -142,6 +173,7 @@ func (ix *Indexer) FillVersions(ctx context.Context, ask VersionsAsker) error {
if err := ix.Versions.Create(ctx, meshcatalog.VersionsByModuleVersionKey(module, v.Version), data); err != nil && !errors.Is(err, ErrConflict) {
return fmt.Errorf("the version %s %s is not kept: %w", module, v.Version, err)
}
ix.keepFilledFacts(ctx, v, trunk[module], built, now)
filled++
}
if ix.SayVersionsFilled != nil {
@@ -0,0 +1,159 @@
package index
import (
"cmp"
"context"
"encoding/json"
"slices"
"strings"
"time"
"git.novox.be/novox/mesh-contracts/go/seats/meshmoduleassigner"
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshwants"
"git.novox.be/novox/mesh-sdk/go/keys"
)
// The edge entries of the first fill (design 47 G §377, A-78 c): each module's newest version gets its entries once, each marked
// filled. Kinds 1 and 3 come from the dependency version published latest before the version's build was claimed, read with
// the times of builder_versions, and its part's digest; kinds 2, 4 and 6 from the version every machine placing the dependency
// runs, present or away, the machines from the assigner's placement (A-62) and each node's last running from the node-engine seat's
// stream read whole (§556); kind 5 as done for every acting part's running build.
// PlacementAsker asks the seat mesh-module-assigner's verb placement for a module (a read, A-62).
type PlacementAsker func(ctx context.Context, module string) ([]meshmoduleassigner.ModulePlacement, error)
// RunningReader reads the node-engine seat's stream running whole, every subject's last message (§556): by node, then module.
type RunningReader func(ctx context.Context) (map[string]map[string]nodeengine.Running, error)
// filledEdges are the edge entries of the entry's newest version, which was filled as built; claimed is when its build was claimed.
func (ix *Indexer) filledEdges(ctx context.Context, entry meshcatalog.CatalogEntry, claimed time.Time, ask VersionsAsker, trunk map[string]meshcatalog.CatalogEntry,
built map[string]meshcatalog.VersionEntry, running map[string]map[string]nodeengine.Running, answers map[string]BuilderVersionsAnswer) []meshcatalog.VersionEdge {
var out []meshcatalog.VersionEdge
seen := func(e meshcatalog.VersionEdge) bool {
return slices.ContainsFunc(out, func(x meshcatalog.VersionEdge) bool { return x.Kind == e.Kind && x.Part == e.Part && x.Word == e.Word })
}
for _, g := range entry.Edges {
part := cmp.Or(g.Part, g.From)
module := strings.SplitN(part, ":", 2)[0]
if part == "" || module == entry.Module {
continue
}
e := meshcatalog.VersionEdge{Kind: g.Kind, Part: part, Word: g.Word, Filled: true}
switch g.Kind {
case 1, 3:
dep, ok := trunk[module]
if !ok {
continue
}
var name string
for _, a := range dep.Artifacts {
if a.Ref == part {
name = versionNameOf(module, a)
}
}
if name == "" {
continue
}
ans, ok := answers[name]
if !ok {
a, err := ask(ctx, name)
if err != nil {
continue
}
ans, answers[name] = a, a
}
var best *BuilderVersion
for i, v := range ans.Versions {
if _, ok := versionParts(v.Version); !ok || v.State != "published" || v.At.After(claimed) {
continue
}
if best == nil || v.At.After(best.At) {
best = &ans.Versions[i]
}
}
if best == nil {
continue
}
e.Version, e.Digest, e.Stale = best.Version, best.Digest, true
case 2, 4, 6:
e.Version = notYetDelivered
if v, ok := ix.runningVersion(ctx, module, trunk, built, running); ok {
e.Version = v.Version
for _, a := range v.Artifacts {
if a.Artifact == part {
e.Digest = a.Digest
}
}
}
case 5:
e.Fact = "acted for the running build " + entry.Fp
default:
continue
}
if !seen(e) {
out = append(out, e)
}
}
return out
}
// runningVersion is the version of a module that every machine placing it runs, present or away, when each runs the newest
// build; false where no machine places it, a placed machine runs none or another build, or the placement is not answered.
func (ix *Indexer) runningVersion(ctx context.Context, module string, trunk map[string]meshcatalog.CatalogEntry, built map[string]meshcatalog.VersionEntry,
running map[string]map[string]nodeengine.Running) (meshcatalog.VersionEntry, bool) {
v, ok := built[module]
e, known := trunk[module]
if !ok || !known || e.Fp == "" || ix.Placement == nil {
return v, false
}
placements, err := ix.Placement(ctx, module)
if err != nil {
ix.logf("versions fill: the placement of %s is not answered: %v", module, err)
return v, false
}
nodes := 0
for _, p := range placements {
for _, n := range p.Nodes {
nodes++
r, ok := running[n][module]
if !ok || r.Stopped || r.Fingerprint != e.Fp {
return v, false
}
}
}
return v, nodes > 0
}
// keepFilledFacts keeps what the first fill derived of a version as heard: for each entry of kinds 2, 4 and 6 read as delivered,
// the dependency's version as its newest delivered one (A-68), and for each kind-5 edge the act for the running build (A-78 a).
func (ix *Indexer) keepFilledFacts(ctx context.Context, v meshcatalog.VersionEntry, entry meshcatalog.CatalogEntry, built map[string]meshcatalog.VersionEntry, at time.Time) {
for _, e := range v.Edges {
switch e.Kind {
case 2, 4, 6:
dep := built[strings.SplitN(e.Part, ":", 2)[0]]
if e.Version == notYetDelivered || dep.Version != e.Version {
continue
}
parts := map[string]string{}
for _, a := range dep.Artifacts {
parts[a.Artifact] = a.Digest
}
d := meshwants.VersionDeliveredEvent{V: 1, Module: dep.Module, Version: dep.Version, Parts: parts, At: &at}
if err := ix.keepNewest(ctx, DeliveredPrefix+keys.EscapeName(dep.Module), d, func([]byte) bool { return false }); err != nil {
ix.logf("versions fill: the delivered version of %s is not kept: %v", dep.Module, err)
}
case 5:
data, _ := json.Marshal(Acted{V: 1, Part: e.Part, Build: entry.Fp, How: "filled", At: at})
if err := write(ctx, ix.Heard, ActedKey(e.Part, v.Module), func(_ []byte, found bool) ([]byte, bool, error) {
if found {
return nil, false, nil
}
return data, false, nil
}); err != nil {
ix.logf("versions fill: the act for %s is not kept: %v", v.Module, err)
}
}
}
}
@@ -10,6 +10,8 @@ import (
"testing"
"time"
"git.novox.be/novox/mesh-contracts/go/seats/meshmoduleassigner"
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshbuilds"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshwants"
@@ -411,3 +413,73 @@ func TestOutdatedAnswersKinds3And5And6(t *testing.T) {
t.Errorf("kind 6 after a version that serves no more: %+v", o)
}
}
// Design 47 G §377, A-78 c: the first fill gives each module's newest version its edge entries, each marked filled: kind 1 from the
// dependency version published latest before the build was claimed, kinds 2, 4 and 6 from the version every placing machine runs,
// read from the assigner's placement and the stream running, kind 5 as acted for the running build; so the first outdated says only what is truly behind.
func TestTheFirstFillGivesTheNewestVersionsTheirFilledEdges(t *testing.T) {
ctx := context.Background()
t0 := time.Date(2026, 11, 1, 3, 0, 0, 0, time.UTC)
placed := map[string][]string{"prov": {"n1", "n2"}}
ix := &Indexer{Versions: newMem(), Heard: newMem(), Revisions: newMemObjects(1 << 20), Now: func() time.Time { return t0 },
Placement: func(_ context.Context, m string) ([]meshmoduleassigner.ModulePlacement, error) {
return []meshmoduleassigner.ModulePlacement{{Branch: "trunk", Nodes: placed[m]}}, nil
},
RunningWhole: func(context.Context) (map[string]map[string]nodeengine.Running, error) {
return map[string]map[string]nodeengine.Running{"n1": {"prov": {Fingerprint: "fp-prov"}}, "n2": {"prov": {Fingerprint: "fp-prov"}}}, nil
}}
entries := map[string]meshcatalog.CatalogEntry{
"lib": {Module: "lib", Manifest: map[string]any{}, Fp: "fp-lib", Artifacts: []meshcatalog.Artifact{{Ref: "lib:pkg", Package: &meshcatalog.ArtifactPackage{Ecosystem: "go", Name: "x/lib"}}}},
"actor": {Module: "actor", Manifest: map[string]any{}, Fp: "fp-actor", Artifacts: []meshcatalog.Artifact{{Ref: "actor:program"}}},
"prov": {Module: "prov", Manifest: map[string]any{}, Fp: "fp-prov", Artifacts: []meshcatalog.Artifact{{Ref: "prov:program"}}},
"app": {Module: "app", Manifest: map[string]any{}, Fp: "fp-app", Artifacts: []meshcatalog.Artifact{{Ref: "app:program"}},
Edges: []meshcatalog.Edge{{Kind: 1, From: "lib:pkg", To: "app:program", Part: "lib:pkg", Stale: true},
{Kind: 4, From: "prov:program", To: "app:program", Part: "prov:program"},
{Kind: 5, From: "actor:program", To: "app:program", Part: "actor:program"}}},
}
rev, objects, err := CatalogRevisionOf(meshcatalog.CatalogRevision{Revision: 3, Kind: "trunk"}, entries)
if err != nil {
t.Fatal(err)
}
if err := KeepRevision(ctx, ix.Revisions, rev, objects); err != nil {
t.Fatal(err)
}
ask := func(_ context.Context, name string) (BuilderVersionsAnswer, error) {
pub := func(v, d string, at time.Time) BuilderVersion {
return BuilderVersion{Version: v, State: "published", Digest: d, Revision: "9", At: at}
}
switch name {
case "x/lib":
return BuilderVersionsAnswer{Versions: []BuilderVersion{pub("0.1.1", "sha256:l1", t0), pub("0.1.2", "sha256:l2", t0.Add(2*time.Hour))}}, nil
case "app/program":
return BuilderVersionsAnswer{Versions: []BuilderVersion{pub("0.3.1", "sha256:a1", t0.Add(time.Hour))}}, nil
}
return BuilderVersionsAnswer{Versions: []BuilderVersion{pub("0.9.1", "sha256:"+name, t0)}}, nil
}
if err := ix.FillVersions(ctx, ask); err != nil {
t.Fatal(err)
}
app, _ := ModuleVersions(ctx, ix.Versions, "app")
if len(app) != 1 || len(app[0].Edges) != 3 {
t.Fatalf("app's filled version: %+v", app)
}
for _, e := range app[0].Edges {
if !e.Filled {
t.Errorf("a filled entry is not marked: %+v", e)
}
switch e.Kind {
case 1:
if e.Version != "0.1.1" || e.Digest != "sha256:l1" || !e.Stale {
t.Errorf("kind 1 is the version published before the build was claimed: %+v", e)
}
case 4:
if e.Version != "0.9.1" || e.Digest != "sha256:prov/program" {
t.Errorf("kind 4 is the version every machine runs: %+v", e)
}
}
}
// lib's 0.1.2 was published after app's build was claimed: that is behind, and nothing else (the delivered kind 4 and the act of kind 5 are not)
if a, err := ix.Outdated(ctx, meshcatalog.OutdatedInput{}); err != nil || len(a.Behind) != 1 || a.Behind[0].Kind != 1 {
t.Errorf("outdated after the first fill: %+v, %v", a.Behind, err)
}
}
@@ -161,7 +161,7 @@ func TestManifestDeclarations(t *testing.T) { // 1238/AC1, 1444 (reads the build
// The registry seats' published fill each (§413: no consume of version.numbered) package's series (DLV-I5, design 51 *The versions*).
if want := []string{"go-package-registry.published", "mesh-build-go.toolchain.reported", "mesh-build-node.toolchain.reported", "mesh-builds.package-published", "mesh-builds.toolchain-agreed", "mesh-conditions.findings-asked", "mesh-delivery-assigner.views.assignments",
"mesh-delivery-checker.preview.written", "mesh-delivery-checker.try.ended", "mesh-delivery-checker.try.started", "mesh-delivery-checker.verdict", "mesh-delivery-forge-bridge.forge.**",
"mesh-delivery.source-moved", "mesh-wants.version-delivered", "mesh-wants.wait-ended", "npm-package-registry.published", "operator-channel.decided"}; !reflect.DeepEqual(sorted(m.Consumes), want) {
"mesh-delivery.source-moved", "mesh-wants.version-delivered", "mesh-wants.wait-ended", "node-engine.running", "npm-package-registry.published", "operator-channel.decided"}; !reflect.DeepEqual(sorted(m.Consumes), want) {
t.Errorf("consumes = %v, want %v", m.Consumes, want)
}
if b, ok := m.OwnSecrets["broker"]; !ok || len(m.OwnSecrets) != 1 || b != "${dir:state}/broker" {
@@ -173,7 +173,7 @@ func TestManifestDeclarations(t *testing.T) { // 1238/AC1, 1444 (reads the build
// Three invokes: the file of a registered module's manifest and lock files (registered.go), the forge's trees (the named paths' objects, since the indexer is the one reader of a manifest's paths:
// ADR 0499 clauses 2 and 3, ADR 0495 clause 1; and the module directories of the trunk, issue 1900) and whether a
// commit is in another (issue 1900).
if want := []string{"mesh-delivery-assigner.assignments", "seat:git.trees", "seat:git.file", "seat:git.contains", "seat:git.open-pulls", "seat:git.branch", "mesh-delivery-checker.checker_tries", "mesh-delivery-forge-bridge.bridge_merged_message", "seat:node-engine.composition", "seat:mesh-delivery.source", "seat:mesh-hand-acts.hand-act", "seat:mesh-watchdogs.presence", "seat:node-build-go.steps", "seat:node-build-node.steps", "seat:node-build-image.steps", "mesh-delivery-builder.builder_versions"}; !reflect.DeepEqual(m.Invokes, want) {
if want := []string{"mesh-delivery-assigner.assignments", "seat:git.trees", "seat:git.file", "seat:git.contains", "seat:git.open-pulls", "seat:git.branch", "mesh-delivery-checker.checker_tries", "mesh-delivery-forge-bridge.bridge_merged_message", "seat:node-engine.composition", "seat:mesh-module-assigner.placement", "seat:mesh-delivery.source", "seat:mesh-hand-acts.hand-act", "seat:mesh-watchdogs.presence", "seat:node-build-go.steps", "seat:node-build-node.steps", "seat:node-build-image.steps", "mesh-delivery-builder.builder_versions"}; !reflect.DeepEqual(m.Invokes, want) {
t.Errorf("invokes = %v, want %v", m.Invokes, want)
}
// 1945: indexer_take_in, served by its tools bundle through the takeins state; the process serves none. The same bundle
@@ -195,7 +195,7 @@ func TestManifestDeclarations(t *testing.T) { // 1238/AC1, 1444 (reads the build
index.PendingTool, index.TakeInPendingTool, index.DropPendingTool, index.TryCandidatesTool, index.DropTryCandidateTool, index.RecoverTriesTool, index.TakeInMergeTool, index.FingerprintsAgainTool, // issue 1966; 1585/T12, T13 (ADR 0633 §5)
// milestone 47/G W4.12 (design 47, the indexer's tools): the catalog graph revisions read and steered.
index.CatalogRevisionTool, index.CatalogRevisionsTool, index.CandidateGraphsTool, index.RecomputeTool, index.DropCandidateGraphTool,
index.EntryIndexTool, // design 47 G §675
index.EntryIndexTool, // design 47 G §675
index.ProposalsTool, index.ProposalDropTool, index.SeedAgainTool, index.InputsTool) // design 47 G §667, §8
if !reflect.DeepEqual(m.Tools, want) || len(want) != 46 || slices.Contains(m.Tools, "modules") {
t.Errorf("tools = %v, want %v", m.Tools, want)
@@ -86,6 +86,7 @@
"mesh-builds.package-published",
"mesh-builds.toolchain-agreed",
"mesh-wants.version-delivered",
"node-engine.running",
"mesh-wants.wait-ended",
"mesh-delivery-checker.verdict",
"mesh-delivery-forge-bridge.forge.**",
@@ -157,6 +158,7 @@
"mesh-delivery-checker.checker_tries",
"mesh-delivery-forge-bridge.bridge_merged_message",
"seat:node-engine.composition",
"seat:mesh-module-assigner.placement",
"seat:mesh-delivery.source",
"seat:mesh-hand-acts.hand-act",
"seat:mesh-watchdogs.presence",