Keep what a machine said about itself, not just the yes

novox/hq ADR 0009: a capability's presence gates an assignment and its detail
carries a value — seat: card1-DP-1, an architecture, an amount of memory. So
'can this run here' and 'what should it be configured as' are one fact read two
ways, and the mesh was keeping the first read and discarding the second.

The reason an absent capability is absent went the same way, which is the case
a person most needs: 'this machine has no container runtime' is the answer and
'docker is not installed' is why, and only the machine knows why.

`node show` says it back. Never reported and reported nothing stay different
things there — one machine has not run the host, the other ran it and can do
nothing, and those send a person to different places.
This commit is contained in:
2026-08-31 04:53:45 +02:00
parent 92133c340b
commit dfca21fa55
3 changed files with 201 additions and 9 deletions
+87
View File
@@ -517,3 +517,90 @@ func TestACatalogueEntryKnowsWhetherItIsBehind(t *testing.T) {
t.Fatal("a module whose source moved reported itself current")
}
}
// A capability's detail is half of what the machine said, and it was being thrown away.
//
// novox/hq ADR 0009: a capability's presence gates an assignment and its detail carries a value —
// `seat: card1-DP-1`. So *can this run here* and *what should it be configured as* are one fact
// read two ways, and keeping only the first read makes the second unanswerable.
func TestWhatAMachineSaidAboutItselfIsKeptWhole(t *testing.T) {
inv := ForTest(t)
ctx := t.Context()
node, err := inv.AddNode(ctx, "workstation")
if err != nil {
t.Fatal(err)
}
if err := inv.RecordProfile(ctx, node.ID, map[string]any{"capabilities": []map[string]any{
{"name": "seat", "present": true, "detail": "card1-DP-1, card1-HDMI-A-1"},
{"name": "container-runtime", "present": false, "detail": "docker is not installed"},
}}); err != nil {
t.Fatal(err)
}
held, err := inv.Profile(ctx, "workstation")
if err != nil {
t.Fatal(err)
}
if len(held) != 2 {
t.Fatalf("the machine reported two things and the mesh kept %d", len(held))
}
found := map[string]Capability{}
for _, c := range held {
found[c.Name] = c
}
if found["seat"].Detail != "card1-DP-1, card1-HDMI-A-1" {
t.Fatalf("the value the machine reported was discarded: %+v", found["seat"])
}
// And the absent one keeps its reason, which is the case a person most needs explaining:
// "this machine has no container runtime" is the answer and "docker is not installed" is why.
if found["container-runtime"].Present {
t.Fatal("something the machine said it does not have was recorded as present")
}
if found["container-runtime"].Detail != "docker is not installed" {
t.Fatalf("the reason a capability is absent was discarded: %+v", found["container-runtime"])
}
// The gating read is unchanged, and takes only what is present.
gates, err := inv.ProfileOf(ctx, "workstation")
if err != nil {
t.Fatal(err)
}
if !gates["seat"] || gates["container-runtime"] {
t.Fatalf("the gating read disagrees with what the machine said: %+v", gates)
}
}
// Never reported is not the same as reported nothing: one machine has not run the host, the other
// ran it and can do nothing, and the remedies are different.
func TestNeverReportedAndReportedNothingAreDifferentProfiles(t *testing.T) {
inv := ForTest(t)
ctx := t.Context()
silent, err := inv.AddNode(ctx, "silent")
if err != nil {
t.Fatal(err)
}
empty, err := inv.AddNode(ctx, "empty")
if err != nil {
t.Fatal(err)
}
if err := inv.RecordProfile(ctx, empty.ID,
map[string]any{"capabilities": []map[string]any{}}); err != nil {
t.Fatal(err)
}
_ = silent
never, err := inv.Profile(ctx, "silent")
if err != nil {
t.Fatal(err)
}
if never != nil {
t.Fatalf("a machine that never reported looks like one that reported nothing: %+v", never)
}
nothing, err := inv.Profile(ctx, "empty")
if err != nil {
t.Fatal(err)
}
if nothing == nil {
t.Fatal("a machine that reported nothing looks like one that never reported")
}
}