indexer: its findings are written and read in the seat mesh-conditions' layout through meshconditionsclient (ADR 0634 §4; issue 1966)

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-05 16:48:57 +01:00
parent 436ab59214
commit 7c61a7ad37
10 changed files with 32 additions and 31 deletions
@@ -5,11 +5,11 @@ import (
"fmt"
"time"
mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
"git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
stdio "git.novox.be/novox/mesh-sdk/go"
"git.novox.be/novox/mesh-sdk/go/health"
"git.novox.be/novox/mesh-sdk/go/views"
@@ -177,7 +177,7 @@ func outOfStepTool(state func(string) views.Source) stdio.Tool {
"build of the same module), then each open pull request whose check's verdict named out-of-step files.",
Input: map[string]any{"type": "object", "properties": map[string]any{}},
Run: func(map[string]any) (any, error) {
rows, err := index.OutOfStepOf(state(index.SeatDefinitionsState), state(health.FindingsState))
rows, err := index.OutOfStepOf(state(index.SeatDefinitionsState), state(mcc.FindingsState))
if err != nil {
return nil, err
}
@@ -131,7 +131,9 @@ func followSeatList(bus *seatBus, say func(context.Context, index.SeatDefinition
}
// bucket is a state bound when it appears (process.AwaitedBucket).
type bucket interface{ Ready(func(jetstream.KeyValue)) }
type bucket interface {
Ready(func(jetstream.KeyValue))
}
// readWhenBound has the reader read the list again as each of the states it is answered from is bound. The reader starts before
// they are, its first read finds them missing and leaves it unread, and the indexer's own events (said) are the only other thing
@@ -8,8 +8,8 @@ import (
"github.com/nats-io/nats.go/jetstream"
mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/buildrun"
"git.novox.be/novox/mesh-sdk/go/health"
"git.novox.be/novox/mesh-sdk/go/process"
sdkfindings "git.novox.be/novox/mesh-delivery/sdk/findings"
@@ -22,7 +22,7 @@ import (
// findingsBucket is the indexer's own findings, which the condition keeper raises and clears (ADR 0564 §2): a value too
// large for its views event, and its first view of the assigner's placement unanswered past its bound.
var findingsBucket = health.FindingsBucket(index.Module)
var findingsBucket = mcc.FindingsBucket(index.Module)
// readyOf binds a state's bucket: now for one bound at the start, once it appears for one awaited.
type readyOf func(func(jetstream.KeyValue))
+2
View File
@@ -59,3 +59,5 @@ replace git.novox.be/novox/mesh-delivery/modules/mesh-delivery-forge-bridge/forg
replace git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds => ../mesh-delivery-builder/builds
require git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go v0.0.0-20261105000000-000000000000
require git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000
require git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions v0.0.0-00010101000000-000000000000
@@ -8,9 +8,9 @@ import (
"strings"
"time"
mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-sdk/go/health"
"git.novox.be/novox/mesh-sdk/go/keys"
"mesh-delivery-indexer/judge"
@@ -62,7 +62,7 @@ func (ix *Indexer) sayAccepted(ctx context.Context, a meshcatalog.ManifestAccept
// unsaidKey is the key of module's unsaid finding.
func unsaidKey(module string) string {
return health.FindingKey(health.ScopeModule, Module+".accepted."+module, UnsaidKind)
return mcc.Key(mcc.ScopeModule, Module+".accepted."+module, UnsaidKind)
}
// unsaid writes module's finding for err, or deletes it with none.
@@ -77,14 +77,12 @@ func (ix *Indexer) unsaid(ctx context.Context, module string, err error) {
}
at := ix.now().UTC()
summary := fmt.Sprintf("%s of %s was not published: %v", meshcatalog.EventManifestAccepted, module, err)
data, ferr := health.EncodeFinding(health.Finding{Key: key, Kind: UnsaidKind,
Subject: health.Subject{Scope: health.ScopeModule, ID: Module + ".accepted." + module}, Severity: health.Warning,
data, ferr := mcc.EncodeFinding(mcc.Observation{Scope: mcc.ScopeModule, ID: Module + ".accepted." + module, Kind: UnsaidKind,
Summary: summary,
Headline: "The indexer could not tell the bus module that " + module + "'s manifest was accepted",
Explanation: "The bus module creates and removes a module's bus state from this event. The indexer says it again at its " +
"next judging pass and clears this once it is said; indexer_say_accepted says it now.",
Resolved: "manifest-accepted of " + module + " was said.",
Evidence: []health.Evidence{{At: at, Said: summary}}, Source: UnsaidKind, Observer: Module, At: at})
Resolved: "manifest-accepted of " + module + " was said.", Source: UnsaidKind}.Finding(Module, "", at))
return data, false, ferr
})
if werr != nil {
@@ -168,7 +166,7 @@ func (ix *Indexer) SayUnsaid(ctx context.Context) {
if err != nil || !found {
continue
}
f, err := health.DecodeFinding(value)
f, err := mcc.DecodeFinding(value)
if err != nil || f.Kind != UnsaidKind {
continue
}
@@ -9,12 +9,12 @@ import (
"testing"
"time"
mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-forge-bridge/forgemsg"
sdkstep "git.novox.be/novox/mesh-delivery/sdk/buildstep"
"git.novox.be/novox/mesh-sdk/go/health"
"git.novox.be/novox/mesh-sdk/go/keys"
"git.novox.be/novox/mesh-sdk/go/process"
"git.novox.be/novox/mesh-sdk/go/seatdef"
@@ -173,7 +173,7 @@ func TestTheControlRecords(t *testing.T) {
}
return e, ok
}
unparsed := health.FindingKey(health.ScopeModule, findingID("seat-definitions", "mesh-contracts"), SeatDefinitionUnparsedKind)
unparsed := mcc.Key(mcc.ScopeModule, findingID("seat-definitions", "mesh-contracts"), SeatDefinitionUnparsedKind)
merged(m1)
merged(m1) // the same digests again say nothing
g1, ok := entry("git.trunk")
@@ -221,7 +221,7 @@ func TestTheControlRecords(t *testing.T) {
t.Fatal(err)
}
}
twice := health.FindingKey(health.ScopeModule, findingID("seat-defined-twice", "other-contracts"), SeatDefinedTwiceKind)
twice := mcc.Key(mcc.ScopeModule, findingID("seat-defined-twice", "other-contracts"), SeatDefinedTwiceKind)
before := len(said)
mergedOther("o1")
if g, _ := entry("git.trunk"); g.Repository != repo || g.Commit != m3 || len(said) != before {
@@ -348,7 +348,7 @@ func TestTheControlRecords(t *testing.T) {
t.Fatal(err)
}
}
outside := health.FindingKey(health.ScopeModule, findingID("seat-outside-its-domain", "mesh-contracts"), SeatOutsideItsDomainKind)
outside := mcc.Key(mcc.ScopeModule, findingID("seat-outside-its-domain", "mesh-contracts"), SeatOutsideItsDomainKind)
before = len(said)
// mesh-contracts defines wants and vault, seats of other domains: refused with a finding naming both modules, the
// held entries stand, and lone (Core) is taken.
@@ -7,9 +7,9 @@ import (
"testing"
"time"
mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/health"
)
// fakeBounds is the state hold-bounds: the end each key was armed with, a standing key keeping its end.
@@ -50,7 +50,7 @@ func storeHoldersNewManifestWaitsForEveryCountedEngine(t *testing.T) {
ix.Holds, ix.Findings, ix.HoldBounds, ix.Now = holds, findings, bounds, func() time.Time { return clock }
ix.Counted = func() (map[string][]string, bool) { return stated, true }
ix.AskEngines = func(nodes []string, _ string) { asked = append(asked, nodes...) }
heldKey := health.FindingKey(health.ScopeModule, findingID("hold", "distribution"), HoldStandingKind)
heldKey := mcc.Key(mcc.ScopeModule, findingID("hold", "distribution"), HoldStandingKind)
first := withManifests(mergedMsg(catalogueRepo, map[string]string{dir: "tree1", dockerDir: "d1"}), map[string]string{dir: old, dockerDir: docker}, nil)
if err := ix.Apply(ctx, first); err != nil {
@@ -95,7 +95,7 @@ func storeHoldersNewManifestWaitsForEveryCountedEngine(t *testing.T) {
t.Fatal(err)
}
stays("past its bound,")
f, err := health.DecodeFinding(findings.vals[heldKey])
f, err := mcc.DecodeFinding(findings.vals[heldKey])
if err != nil || f.Kind != HoldStandingKind || !strings.Contains(f.Summary, "n2 lacks form:seat-reach") {
t.Fatalf("past its bound the finding %s = %+v (%v), want manifest-held naming n2", heldKey, f, err)
}
@@ -25,11 +25,11 @@ import (
"strings"
"time"
mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-forge-bridge/forgemsg"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/health"
"git.novox.be/novox/mesh-sdk/go/keys"
"git.novox.be/novox/mesh-sdk/go/seatdef"
"git.novox.be/novox/mesh-sdk/go/views"
@@ -599,20 +599,19 @@ func (ix *Indexer) finding(ctx context.Context, id, kind string, raise bool, sum
if ix.Findings == nil {
return
}
key := health.FindingKey(health.ScopeModule, id, kind)
key := mcc.Key(mcc.ScopeModule, id, kind)
err := write(ctx, ix.Findings, key, func(value []byte, found bool) ([]byte, bool, error) {
if !raise {
return nil, found, nil
}
if found {
if f, err := health.DecodeFinding(value); err == nil && f.Summary == summary {
if f, err := mcc.DecodeFinding(value); err == nil && f.Summary == summary {
return nil, false, nil
}
}
at := ix.now().UTC()
data, err := health.EncodeFinding(health.Finding{Key: key, Kind: kind, Subject: health.Subject{Scope: health.ScopeModule, ID: id},
Severity: health.Warning, Summary: summary, Headline: headline, Explanation: explanation, Resolved: resolved,
Evidence: []health.Evidence{{At: at, Said: summary}}, Source: kind, Observer: Module, At: at})
data, err := mcc.EncodeFinding(mcc.Observation{Scope: mcc.ScopeModule, ID: id, Kind: kind, Summary: summary,
Headline: headline, Explanation: explanation, Resolved: resolved, Source: kind}.Finding(Module, "", at))
return data, false, err
})
if err != nil {
@@ -762,7 +761,7 @@ func OutOfStepOf(defs, findings views.Source) ([]OutOfStepRow, error) {
if err != nil || !ok || v == nil {
continue
}
f, err := health.DecodeFinding(v.Value)
f, err := mcc.DecodeFinding(v.Value)
if err != nil || f.Kind != OutOfStepKind {
continue
}
@@ -1,7 +1,7 @@
package index
import (
"git.novox.be/novox/mesh-sdk/go/health"
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"
@@ -30,7 +30,7 @@ var ReadTools = []ViewedTool{
{Tool: "indexer_read_graph", State: graph.State, Words: "the module graph: each module's build and provision edges."},
{Tool: "indexer_read_heard", State: HeardState, Words: "the forge messages the indexer heard and what it did with each."},
{Tool: "indexer_read_taken", State: "taken", Words: "each repository's merge the indexer took in last."},
{Tool: "indexer_read_findings", State: health.FindingsState, Words: "the indexer's findings, which the condition keeper raises and clears."},
{Tool: "indexer_read_findings", State: mcc.FindingsState, Words: "the indexer's findings, which the condition keeper raises and clears."},
{Tool: "indexer_read_seat_definitions", State: SeatDefinitionsState, Words: "the seat definitions the trunk's and each open pull request's contracts modules hold, resolved, or why one does not parse."},
}
@@ -51,6 +51,6 @@ var ViewedStates = map[string]string{
graph.State: graph.Bucket,
HeardState: HeardBucket,
"taken": TakenBucket,
health.FindingsState: health.FindingsBucket(Module),
mcc.FindingsState: mcc.FindingsBucket(Module),
SeatDefinitionsState: SeatDefinitionsBucket,
}
@@ -15,8 +15,8 @@ import (
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-indexer/takein"
"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/health"
"git.novox.be/novox/mesh-sdk/go/views"
"mesh-delivery-indexer/internal/index"
@@ -114,7 +114,7 @@ func TestManifestDeclarations(t *testing.T) { // 1238/AC1, 1444 (reads the build
}
// 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: index.PackagesState, History: index.PackagesHistory},
{Name: graph.State, History: graph.History}, {Name: views.MarksState, History: 1}, {Name: health.FindingsState, History: 5}, {Name: views.StatusState, History: 1},
{Name: graph.State, History: graph.History}, {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}}; !reflect.DeepEqual(m.State, want) { // DLV-I7, DLV-I17, ADR 0632 §2
t.Errorf("state = %+v, want %+v", m.State, want)