Tool runner: describes the seats from the seat list it reads through the seat mesh-catalog; the first views' finding in the conditions seat's layout (T-1, T-3, ADR 0635 §1, ADR 0636 §4; issue 1966)

This commit is contained in:
2026-11-05 14:29:02 +01:00
parent 07f6078050
commit a918352ff1
10 changed files with 95 additions and 6 deletions
+1 -1
View File
@@ -321,7 +321,7 @@ func indexOn(conn *bus.Conn, src Source, held announce.Known, before func(announ
// What should have answered: every assignment of a module that declares tools. Silence is named;
// a module with no tools is never a name here.
x.Replaces = replacesOf(catalogue.DefaultSeats(), recorded)
x.Replaces = replacesOf(catalogue.Seats(), recorded)
for _, m := range recorded {
if !m.Tools {
continue
@@ -36,8 +36,8 @@ func TestTheManifestNamesTheFirstFamiliesOneByOne(t *testing.T) {
}
}
// A wait is no consumer (ADR 0367 §2): what it consumes is the four views families of its first views (ADR 0615 §5, issue
// 1966 TLS-5), and nothing else.
wantConsumes := []string{"mesh-delivery-assigner.views.placement", "mesh-delivery-assigner.views.seat-holders",
// 1966 TLS-5) and the two events of the seat that serves the seat list (ADR 0636 §4), and nothing else.
wantConsumes := []string{"mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-delivery-assigner.views.placement", "mesh-delivery-assigner.views.seat-holders",
"mesh-delivery-indexer.views.manifests", "mesh-delivery-indexer.views.modules"}
if !reflect.DeepEqual(m.Consumes, wantConsumes) {
t.Errorf("the tool runner consumes %v, want %v", m.Consumes, wantConsumes)
+1 -1
View File
@@ -75,7 +75,7 @@ func (s *Surface) seatsAnswer() map[string]any {
placed, err := seatHoldersOn(s.src)
x := &index{Placed: placed}
seats := []map[string]any{}
for _, st := range catalogue.DefaultSeats() {
for _, st := range catalogue.Seats() {
holders := x.placedHolders(st.Name, "")
if holders == nil {
holders = []delivery.SeatHolder{}
+1 -1
View File
@@ -46,7 +46,7 @@ func meshToSearch(t *testing.T) *index {
Description: does, Subject: "mesh.mod.docker.tool." + tool + ".anchor"})
}
x, _, _ := indexOfEndpoints(endpoints)
x.Replaces = replacesOf(catalogue.DefaultSeats(), []recordedModule{{Module: "docker", On: []string{"anchor"}, Tools: true,
x.Replaces = replacesOf(catalogue.Seats(), []recordedModule{{Module: "docker", On: []string{"anchor"}, Tools: true,
Replaces: map[string][]string{"docker_list": {"docker ps"}, "docker_logs": {"docker logs"}, "docker_restart": {"docker restart"}}}})
return x
}
@@ -0,0 +1,10 @@
package console
import (
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/seatlist/seatlisttest"
)
// The seats the tests describe are given to catalogue as the tool runner gives the ones it read from the bus
// (novox/hq ADR 0635 §1); catalogue compiles none.
func init() { catalogue.UseSeats(catalogue.SeatsFromDefinitions(seatlisttest.Definitions())) }
+21 -1
View File
@@ -11,6 +11,8 @@ import (
"context"
"encoding/json"
"fmt"
conditions "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
condseat "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions"
"sort"
"sync"
"time"
@@ -135,7 +137,7 @@ func (v *Views) hear(env bus.Envelope) error {
// finding writes or removes the runner's finding of a first view unanswered past its bound, in its own state.
func (v *Views) finding(st views.Status, raised bool) {
key, value, err := views.UnansweredFinding(v.deps.Module, st, time.Now())
key, value, err := conditionOf(views.UnansweredFinding(v.deps.Module, st, time.Now()))
if err != nil {
v.logf("[mesh-tools] the finding of the first view %s is not made: %v", st.Tool, err)
return
@@ -198,3 +200,21 @@ func (v *Views) Again(ctx context.Context, why string) []error {
}
return errs
}
// conditionOf is a finding in the layout of the seat mesh-conditions' state findings (its contract, ADR 0634 §1), about a
// module, a warning.
func conditionOf(f views.Finding) (string, []byte, error) {
key := conditions.Key(scopeModule, f.ID, f.Kind)
v := condseat.FindingsByKeyValue{V: 1, Key: key, Kind: f.Kind, Observer: f.Observer, Severity: conditions.Warning,
Subject: condseat.Subject{Scope: scopeModule, ID: f.ID}, Summary: f.Summary, Headline: f.Headline,
Explanation: f.Explanation, Source: f.Observer + "." + f.Kind, At: f.At.UTC().Format(time.RFC3339),
Evidence: []condseat.Evidence{{At: f.At.UTC().Format(time.RFC3339), Said: f.Summary}}}
if err := conditions.CheckFinding(v); err != nil {
return "", nil, err
}
raw, err := json.Marshal(v)
return key, raw, err
}
// scopeModule is the scope of a finding about a module.
const scopeModule = "module"