The indexer declares no modules or graph state: its view of the trunk is the catalog graph revisions (milestone 47/G W4.3, the manifest)

The states modules and graph leave the manifest and the names the indexer keeps; their first views and read tools are
answered from the newest revision, whose changes catalog-revision says. The contract keeps the modules type until its
readers moved (the lead's ruling). The manifest validator, built at mesh-delivery's trunk, accepts the indexer in both
cases, change and trunk, and no verdict differs.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 11:46:55 +01:00
parent 66dd7b3a3f
commit a732cb0cb2
5 changed files with 13 additions and 23 deletions
@@ -263,7 +263,7 @@ func TestIndexerWhole(t *testing.T) { // 1238/AC2, AC10; 1585/T14, T15
named := held.WaitsFor
get := func(bucket, key string) ([]byte, bool) {
t.Helper()
if bucket == index.ModulesBucket {
if bucket == index.ModulesState { // the view of the trunk, from the newest catalog graph revision
e, err := revisionView{js: js}.Get(ctx, key)
if err != nil {
return nil, false
@@ -281,7 +281,7 @@ func TestIndexerWhole(t *testing.T) { // 1238/AC2, AC10; 1585/T14, T15
return e.Value(), true
}
// Only what building and moving the named indexer needs is written.
raw, ok := get(index.ModulesBucket, ix)
raw, ok := get(index.ModulesState, ix)
own, err := meshcatalogclient.DecodeModule(raw)
if !ok || err != nil || own.Fp2 != named || own.Commit != m1.Merge {
t.Fatalf("modules.%s = %+v (%v), want the named build %s at the merge", ix, own, err, named)
@@ -293,7 +293,7 @@ func TestIndexerWhole(t *testing.T) { // 1238/AC2, AC10; 1585/T14, T15
t.Errorf("the verdict on the indexer's manifest %s is not written", own.Manifest)
}
repoKey, _ := trunk.RepositoryKey(m1.Repository)
if _, ok := get(index.ModulesBucket, "a"); ok {
if _, ok := get(index.ModulesState, "a"); ok {
t.Errorf("modules.a is written while the revision is pending")
}
if _, ok := get(index.TakenBucket, repoKey); ok {
@@ -353,7 +353,7 @@ func TestIndexerWhole(t *testing.T) { // 1238/AC2, AC10; 1585/T14, T15
break
}
}
if raw, ok := get(index.ModulesBucket, "a"); !ok || !strings.Contains(string(raw), m1.Merge) {
if raw, ok := get(index.ModulesState, "a"); !ok || !strings.Contains(string(raw), m1.Merge) {
t.Errorf("modules.a = %s after the take-in at the start, want it at the merge %s", raw, m1.Merge)
}
if _, ok := get(index.TakenBucket, repoKey); !ok {
@@ -362,7 +362,7 @@ func TestIndexerWhole(t *testing.T) { // 1238/AC2, AC10; 1585/T14, T15
if len(w) != 1 || w[0].Key != groupKey || len(w[0].Keys) != 1 || w[0].Keys[0] != g1Key {
t.Fatalf("indexer_pending after the start = %+v, want only the group gathered, its first member %s", w, g1Key)
}
if _, ok := get(index.ModulesBucket, "c"); ok {
if _, ok := get(index.ModulesState, "c"); ok {
t.Errorf("modules.c is written while its group is gathered")
}
@@ -381,8 +381,8 @@ func TestIndexerWhole(t *testing.T) { // 1238/AC2, AC10; 1585/T14, T15
}
var hasC, hasK bool
for deadline := time.Now().Add(20 * time.Second); time.Now().Before(deadline) && !(hasC && hasK && len(w) == 0); time.Sleep(50 * time.Millisecond) {
_, hasC = get(index.ModulesBucket, "c")
_, hasK = get(index.ModulesBucket, "k")
_, hasC = get(index.ModulesState, "c")
_, hasK = get(index.ModulesState, "k")
w = waits()
}
if !hasC || !hasK || len(w) != 0 {
@@ -1,7 +1,5 @@
package index
import "git.novox.be/novox/mesh-delivery/sdk/graph"
// The holders, states and buckets the indexer names, taken from its own manifest (module.json: its name, its `state`, its
// `reads`) and from the manifests of the holders it reads; a unit row checks them against the manifest
// (TestTheNamesAreTheManifests). No contract names a holder (novox/hq ADR 0625 §4, ADR 0634 §1).
@@ -14,13 +12,9 @@ const (
CandidatesBucket = Module + "_" + CandidatesState
CandidatesHistory = 10
ModulesState = "modules"
ModulesBucket = Module + "_" + ModulesState
ModulesHistory = 20
ManifestsState = "manifests"
ManifestsBucket = Module + "_" + ManifestsState
ManifestsHistory = 1
// GraphBucket is the bucket of the state graph (sdk/graph names the state, not its holder).
GraphBucket = Module + "_" + graph.State
// VerdictsState and VerdictsBucket are in verdicts.go.
VerdictsHistory = 5
PredefinedState = "predefined"
@@ -43,13 +43,11 @@ type ViewedTool struct {
// ViewedStates are the states the indexer's views family says, each by its bucket: the ones its readers read.
var ViewedStates = map[string]string{
"manifests": ManifestsBucket,
"modules": ModulesBucket,
VerdictsState: VerdictsBucket,
PredefinedState: PredefinedBucket,
ConfigCandidatesState: ConfigCandidatesBucket,
"candidates": CandidatesBucket,
PackagesState: PackagesBucket,
graph.State: GraphBucket,
HeardState: HeardBucket,
"taken": TakenBucket,
mcc.FindingsState: mcc.FindingsBucket(Module),
@@ -16,7 +16,6 @@ import (
"git.novox.be/novox/mesh-sdk/go/catalogue"
mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
"git.novox.be/novox/mesh-delivery/sdk/graph"
"git.novox.be/novox/mesh-sdk/go/views"
"mesh-delivery-indexer/internal/index"
@@ -117,8 +116,8 @@ func TestManifestDeclarations(t *testing.T) { // 1238/AC1, 1444 (reads the build
t.Errorf("emits = %v, want the two take-in events (the verdict events are the seat mesh-catalog's)", m.Emits)
}
// 1126 note 76: heard keeps the last 64 FORGE messages the indexer handled, for indexer_heard.
if want := []state{{Name: "candidates", History: 10}, {Name: "heard", History: 64}, {Name: "manifests", History: 1}, {Name: "modules", History: 20}, {Name: "predefined", History: 5}, {Name: "config-candidates", History: 5}, {Name: "taken", History: 1}, {Name: "takeins", History: 1}, {Name: "verdicts", History: 5}, {Name: "oldsections", History: 1}, {Name: "try-recovery", History: 1}, {Name: "own-build", History: 1}, {Name: index.PackagesState, History: index.PackagesHistory},
{Name: graph.State, History: graph.History}, {Name: views.MarksState, History: 1}, {Name: mcc.FindingsState, History: 5}, {Name: views.StatusState, History: 1},
if want := []state{{Name: "candidates", History: 10}, {Name: "heard", History: 64}, {Name: "manifests", History: 1}, {Name: "predefined", History: 5}, {Name: "config-candidates", History: 5}, {Name: "taken", History: 1}, {Name: "takeins", History: 1}, {Name: "verdicts", History: 5}, {Name: "oldsections", History: 1}, {Name: "try-recovery", History: 1}, {Name: "own-build", History: 1}, {Name: index.PackagesState, History: index.PackagesHistory},
{Name: views.MarksState, History: 1}, {Name: mcc.FindingsState, History: 5}, {Name: views.StatusState, History: 1},
{Name: index.RequirementsState, History: 5}, {Name: index.SeatDefinitionsState, History: 5},
{Name: index.HoldsState, History: 5}, {Name: index.EngineReadsState, History: 1}, {Name: index.HoldBoundsState, History: 1, KeyTTL: true}, {Name: index.PendingState, History: 1}, {Name: index.UnjudgedState, History: 1}}; !reflect.DeepEqual(m.State, want) { // DLV-I7, DLV-I17, ADR 0632 §2
t.Errorf("state = %+v, want %+v", m.State, want)
@@ -133,8 +132,8 @@ func TestManifestDeclarations(t *testing.T) { // 1238/AC1, 1444 (reads the build
if index.Module != m.Module {
t.Errorf("the indexer names itself %q, its manifest's module is %q", index.Module, m.Module)
}
for bucket, history := range map[string]int{index.CandidatesBucket: index.CandidatesHistory, index.ModulesBucket: index.ModulesHistory, index.ManifestsBucket: index.ManifestsHistory,
index.VerdictsBucket: index.VerdictsHistory, index.PackagesBucket: index.PackagesHistory, index.TakenBucket: 1, index.PredefinedBucket: 5, index.ConfigCandidatesBucket: 5, index.GraphBucket: graph.History} {
for bucket, history := range map[string]int{index.CandidatesBucket: index.CandidatesHistory, index.ManifestsBucket: index.ManifestsHistory,
index.VerdictsBucket: index.VerdictsHistory, index.PackagesBucket: index.PackagesHistory, index.TakenBucket: 1, index.PredefinedBucket: 5, index.ConfigCandidatesBucket: 5} {
if !slices.ContainsFunc(m.State, func(st state) bool { return m.Module+"_"+st.Name == bucket && st.History == history }) {
t.Errorf("the indexer names its bucket %s with %d revisions, its manifest's states are %+v", bucket, history, m.State)
}
@@ -177,7 +176,8 @@ func TestManifestDeclarations(t *testing.T) { // 1238/AC1, 1444 (reads the build
want := []string{"indexer_take_in", "indexer_old_sections", "indexer_verdicts", "indexer_judge"}
for _, v := range append(append([]index.ViewedTool{}, index.FirstViewTools...), index.ReadTools...) {
want = append(want, v.Tool)
if _, ok := index.ViewedStates[v.State]; !ok {
// Milestone 47/G: modules and graph are the newest catalog graph revision's, which catalog-revision says the changes of.
if _, ok := index.ViewedStates[v.State]; !ok && v.State != index.ModulesState && v.State != "graph" {
t.Errorf("%s answers the state %s, which the views family does not say", v.Tool, v.State)
}
}
@@ -77,7 +77,6 @@
{ "name": "candidates", "history": 10 },
{ "name": "heard", "history": 64 },
{ "name": "manifests", "history": 1 },
{ "name": "modules", "history": 20 },
{ "name": "predefined", "history": 5 },
{ "name": "config-candidates", "history": 5 },
{ "name": "taken", "history": 1 },
@@ -87,7 +86,6 @@
{ "name": "try-recovery", "history": 1 },
{ "name": "own-build", "history": 1 },
{ "name": "packages", "history": 5 },
{ "name": "graph", "history": 5 },
{ "name": "view-marks", "history": 1 },
{ "name": "findings", "history": 5 },
{ "name": "first-views", "history": 1 },