Keep a facts snapshot for merge checks, and say when it goes stale (hq to-be 45 Phase 5, S14)

Every check the mesh had was right about the world it was given and none was given
the mesh's: a real machine's name made an identity too long (263), the node-engine
refused what the catalogue check passed (236). The controller now composes what a
check needs - every machine under a pseudonym of its name's length, its roles,
system, builds, capabilities, assignments, pins, settings and how its declaration
composes; every seat, module and source; the bus, store and node-engine versions it
runs - with no secret, no address and no name, and keeps it in the artifact store
as facts:latest when it moved, or daily. The replaced snapshot's manifest is let go
of, so the nightly collector takes it. S14 raises facts-stale past two days.
This commit is contained in:
jochen
2026-10-06 20:31:10 +02:00
parent 0090bf6af7
commit 068283137b
13 changed files with 1921 additions and 3 deletions
+30 -3
View File
@@ -183,9 +183,11 @@ var signalsTable = []signalRow{
newest: func(f *signalFacts) time.Time {
return newestOf(f.staleRefusals, func(w link.WriterRefusals) time.Time { return w.Last })
}},
{Row: "S14", Signal: "facts snapshot exported", Emitter: "controller", Trigger: "daily",
Bound: "2 days", Kind: "facts-stale", Severity: conditions.Warning, Phase: 5,
Deferred: "the facts snapshot is built in Phase 5 (to-be 45 §9): nothing exports one yet"},
{Row: "S14", Signal: "facts snapshot exported", Emitter: "controller", Trigger: "when it moved, and daily",
Bound: "2 days: a snapshot older than that, or none kept since this controller began two days ago",
Kind: "facts-stale", Severity: conditions.Warning, Phase: 5,
needs: func(*signalFacts) error { return nil }, watch: watchFacts,
newest: func(f *signalFacts) time.Time { return f.facts.taken }},
{Row: "S15", Signal: "a hand act with a cause already recorded", Emitter: "hand-act log",
Trigger: "each act", Bound: "the second within 14 days; clears when fewer than two remain within 14 days",
Kind: "healer-wanted", Severity: conditions.Warning, Phase: 3,
@@ -195,6 +197,31 @@ var signalsTable = []signalRow{
}},
}
// watchFacts is S14: the snapshot a merge check is fed is older than its bound, or none was kept since
// this controller began that long ago (novox/hq to-be 45 §9). A check fed a stale snapshot judges a change
// against a mesh that no longer is, which is the fault the snapshot exists to end.
func watchFacts(f *signalFacts) []conditions.Observation {
since := f.facts.taken
if since.IsZero() {
since = f.facts.began
}
if since.IsZero() || f.now.Sub(since) <= factsStaleAfter {
return nil
}
said := "none kept since this controller began " + ago(f.now.Sub(since)) + " ago"
if !f.facts.taken.IsZero() {
said = "the newest kept was taken " + ago(f.now.Sub(f.facts.taken)) + " ago"
}
if f.facts.err != nil {
said += "; the last attempt: " + oneLine(f.facts.err.Error())
}
return []conditions.Observation{{Scope: conditions.ScopeCore, ID: "facts", Kind: "facts-stale", Token: "stale",
Severity: conditions.Warning,
Summary: fmt.Sprintf("the facts snapshot merge checks are fed is stale (bound %s): a change is judged against a "+
"mesh that no longer is", ago(factsStaleAfter)),
Said: said}}
}
// newestOf is the newest time among things.
func newestOf[T any](list []T, at func(T) time.Time) time.Time {
var newest time.Time