mesh-self-check: the setting probes lists the probes that run, D13 and D-fill by default; one unlisted runs nothing and the verb says it is off by setting (the operator, 2026-10-30)

This commit is contained in:
2026-10-30 00:04:41 +01:00
parent 5a1916cb46
commit 818f8d2616
5 changed files with 94 additions and 3 deletions
@@ -40,6 +40,7 @@ func (runtimeStore) Keys(state string) ([]string, error) { return stdio.State(st
// NewChecker is the self-check over the runtime.
func NewChecker() *Checker {
return &Checker{Store: runtimeStore{}, Registry: Registry(), Now: time.Now, Logf: logf, Host: os.Getenv("MESH_NODE"),
Enabled: enabledProbes,
Ask: func(key string, body any) (json.RawMessage, error) { return stdio.Ask(key, body) },
Publish: stdio.SeatPublish}
}
@@ -55,3 +56,19 @@ func main() {
os.Exit(1)
}
}
// enabledProbes is the setting `probes`, read at each run so a change applies at the next; with it unreadable, the
// default list.
func enabledProbes() []string {
raw, err := stdio.Config("probes")
if err != nil {
logf("the setting probes cannot be read (%v); the default list runs", err)
return DefaultProbes
}
var list []string
if json.Unmarshal(raw, &list) != nil {
logf("the setting probes is not a list of probe ids (%s); the default list runs", raw)
return DefaultProbes
}
return list
}
@@ -11,6 +11,7 @@ import (
"context"
"encoding/json"
"fmt"
"slices"
"sort"
"strings"
"sync"
@@ -63,6 +64,17 @@ type Store interface {
Keys(state string) ([]string, error)
}
// On says whether the setting lists the probe.
func (c *Checker) On(id string) bool {
if c.Enabled == nil {
return true
}
return slices.Contains(c.Enabled(), id)
}
// DefaultProbes are the probes that run unless the setting says otherwise.
var DefaultProbes = []string{"D13", "D-fill"}
// Probe is one live invariant: its id, what it asserts, the kind it raises, and the run; or why it waits.
type Probe struct {
ID string
@@ -87,7 +99,10 @@ type (
// Checker is the self-check: the registry and what its probes reach.
type Checker struct {
Store Store
Ask func(key string, body any) (json.RawMessage, error)
// Enabled is the setting `probes`: the ids of the probes that run. Nil runs every probe in the registry; one not
// listed runs nothing and raises nothing (the operator, 2026-10-30).
Enabled func() []string
Ask func(key string, body any) (json.RawMessage, error)
// Publish says a seat event on its subject, de-duplicated by id (stdio.SeatPublish).
Publish func(subject string, body any, id string) error
Now func() time.Time
@@ -137,7 +152,7 @@ func (c *Checker) RunOnce(ctx context.Context, why string) Run {
results := make([]result, len(c.Registry))
var wg sync.WaitGroup
for i, p := range c.Registry {
if p.Run == nil {
if p.Run == nil || !c.On(p.ID) {
continue
}
wg.Add(1)
@@ -154,6 +169,12 @@ func (c *Checker) RunOnce(ctx context.Context, why string) Run {
ran := map[string]bool{} // the sources whose findings this run judged whole
var blind []Observation
for i, p := range c.Registry {
if !c.On(p.ID) {
// Off by the setting: it ran nothing and sees nothing, so what it raised before is cleared, and it has no
// verdict in the run.
ran[p.ID] = true
continue
}
v := ProbeVerdict{ID: p.ID}
r := results[i]
switch {
@@ -253,3 +253,43 @@ func TestTheVerbsAndReads(t *testing.T) {
t.Errorf("probes answered %v", p)
}
}
// Only the probes the setting `probes` lists run: one not listed runs nothing, has no verdict, clears what it raised before,
// and is reported by the verb as off by setting; the default list is D13 and D-fill (the operator, 2026-10-30).
func TestOnlyTheProbesTheSettingListsRun(t *testing.T) {
ran := map[string]int{}
finds := Observation{Token: "stream-missing", Severity: Urgent, Subject: Subject{Scope: ScopeBus, ID: "EVENTS"}, Summary: "gone"}
probe := func(id string) Probe {
return Probe{ID: id, Kind: "stream-wrong", Run: func(context.Context, *Checker) ([]Observation, error) {
ran[id]++
return []Observation{finds}, nil
}}
}
store := newStore()
c, _ := checker(store, probe("D7"), probe("D13"))
c.Enabled = func() []string { return []string{"D7", "D13"} }
run := c.RunOnce(context.Background(), "test")
if ran["D7"] != 1 || ran["D13"] != 1 || len(run.Probes) != 2 || len(store.findingKeys()) != 1 {
t.Fatalf("both listed: ran %v, %d verdicts, findings %v", ran, len(run.Probes), store.findingKeys())
}
c.Enabled = func() []string { return []string{"D13"} }
run = c.RunOnce(context.Background(), "test")
if ran["D7"] != 1 || ran["D13"] != 2 || len(run.Probes) != 1 || run.Probes[0].ID != "D13" {
t.Fatalf("D7 unlisted: ran %v, verdicts %+v", ran, run.Probes)
}
// What the unlisted probe raised stays only as long as another listed probe sees the same key (D13 raises the same
// key here); an unlisted probe alone clears its findings.
c.Enabled = func() []string { return nil }
c.RunOnce(context.Background(), "test")
if len(store.findingKeys()) != 0 {
t.Fatalf("with nothing listed, findings are %v", store.findingKeys())
}
rows, _ := c.Probes()["probes"].([]map[string]any)
if len(rows) != 2 || rows[0]["off"] != "off by setting" || rows[1]["off"] != "off by setting" {
t.Fatalf("the verb says %v", rows)
}
c.Enabled = nil
if !c.On("anything") || !slices.Equal(DefaultProbes, []string{"D13", "D-fill"}) {
t.Fatal("no setting runs every probe, and the default list is D13 and D-fill")
}
}
@@ -115,7 +115,9 @@ func (c *Checker) Probes() map[string]any {
if len(p.Raises) > 0 {
row["raises"] = p.Raises
}
if p.Run == nil {
if !c.On(p.ID) {
row["off"] = "off by setting"
} else if p.Run == nil {
row["deferred"] = p.Deferred
}
out = append(out, row)
+11
View File
@@ -71,5 +71,16 @@
]
}
]
},
"config": {
"probes": {
"type": "list",
"description": "The ids of the probes that run, each judging one thing of the mesh (mesh-self-check.probes lists them with what each asserts). A probe not listed runs nothing and raises nothing, and what it raised before is cleared. D8 and DA are in the code and off by default.",
"trusted": true,
"default": [
"D13",
"D-fill"
]
}
}
}