Say the setuid search's quiet in the tests' words, and pin the node-engine at its reviewed head (hq issue 361)
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery-group group fix/361-the-setuid-search-runs-to-completion delivering: 0 of 2 delivered
mesh/delivery superseded: a newer head of the same pull request

This commit is contained in:
jochen
2026-10-10 01:11:24 +02:00
parent cdaba36eca
commit 9551bc2380
4 changed files with 12 additions and 12 deletions
+7 -7
View File
@@ -201,7 +201,7 @@ func TestRootFreeIsAnsweredOnlyByTheServingController(t *testing.T) {
} }
// The confirmation review of 2026-10-09: ADR 0266's quiet window (#175) keeps the self-check from raising // The confirmation review of 2026-10-09: ADR 0266's quiet window (#175) keeps the self-check from raising
// agent-can-become-root while the node-engine's first setuid search runs. It must not make root-free answer free: // agent-can-become-root while the node-engine's setuid search runs and no complete one judges. It must not make root-free answer free:
// root-free needs a complete, fresh verdict. A verdict still waiting for the search is "not judged" to // root-free needs a complete, fresh verdict. A verdict still waiting for the search is "not judged" to
// agentConfined, so the machine is not root-free, whatever the quiet says — and the same statement, complete // agentConfined, so the machine is not root-free, whatever the quiet says — and the same statement, complete
// and healthy, is the control. // and healthy, is the control.
@@ -224,12 +224,12 @@ func TestAMachineWaitingForItsFirstSetuidSearchIsNotRootFree(t *testing.T) {
t.Fatal("the statement is not one the quiet window counts as waiting for the search") t.Fatal("the statement is not one the quiet window counts as waiting for the search")
} }
if v := judged(pending); v.Free { if v := judged(pending); v.Free {
t.Errorf("a machine whose first setuid search is pending was judged root-free: %+v", v) t.Errorf("a machine whose setuid search is pending was judged root-free: %+v", v)
} }
} }
// The confirmation review of 2026-10-09, on #154 beside ADR 0266: D-root keeps ADR 0266's quiet window — nothing // The confirmation review of 2026-10-09, on #154 beside ADR 0266: D-root keeps ADR 0266's quiet window — nothing
// raised while the one thing unjudged is the first setuid search, within its bound — while the root-free verb // raised while the one thing unjudged is the setuid search, within searchQuietFor — while the root-free verb
// still answers the machine not free; and D-root's condition has a key of its own, apart from DA's. // still answers the machine not free; and D-root's condition has a key of its own, apart from DA's.
func TestRootNotFreeIsQuietWhileTheFirstSearchRunsAndKeyedApartFromDA(t *testing.T) { func TestRootNotFreeIsQuietWhileTheFirstSearchRunsAndKeyedApartFromDA(t *testing.T) {
entries := []inventory.Entry{{Manifest: catalogue.Manifest{Module: "telegram", RunsAs: "telegram"}, On: []string{"anchor"}}} entries := []inventory.Entry{{Manifest: catalogue.Manifest{Module: "telegram", RunsAs: "telegram"}, On: []string{"anchor"}}}
@@ -241,21 +241,21 @@ func TestRootNotFreeIsQuietWhileTheFirstSearchRunsAndKeyedApartFromDA(t *testing
quiet: func(context.Context, string, time.Time) bool { return true }} quiet: func(context.Context, string, time.Time) bool { return true }}
trusted := trustedMachines(entries) trusted := trustedMachines(entries)
if got := rootObservations(context.Background(), r, trusted, rootNow); len(got) != 0 { if got := rootObservations(context.Background(), r, trusted, rootNow); len(got) != 0 {
t.Errorf("raised while the first search runs: %+v", got) t.Errorf("raised while the search runs: %+v", got)
} }
if v := judgeRootFree(context.Background(), r, []string{"anchor"}, rootNow)[0]; v.Free || !v.Quiet { if v := judgeRootFree(context.Background(), r, []string{"anchor"}, rootNow)[0]; v.Free || !v.Quiet {
t.Errorf("root-free while the first search runs: %+v", v) t.Errorf("root-free while the search runs: %+v", v)
} }
// Quiet hides nothing else: the login shell served as well is said. // Quiet hides nothing else: the login shell served as well is said.
r.heard = map[string]map[string]map[string]bool{loginShellSeat: {"execute": {"anchor": true}}} r.heard = map[string]map[string]map[string]bool{loginShellSeat: {"execute": {"anchor": true}}}
if got := rootObservations(context.Background(), r, trusted, rootNow); len(got) != 1 { if got := rootObservations(context.Background(), r, trusted, rootNow); len(got) != 1 {
t.Errorf("a second failure was kept quiet: %+v", got) t.Errorf("a second failure was kept quiet: %+v", got)
} }
// Past its bound, said. // Past searchQuietFor, said.
r.heard, r.quiet = map[string]map[string]map[string]bool{}, func(context.Context, string, time.Time) bool { return false } r.heard, r.quiet = map[string]map[string]map[string]bool{}, func(context.Context, string, time.Time) bool { return false }
got := rootObservations(context.Background(), r, trusted, rootNow) got := rootObservations(context.Background(), r, trusted, rootNow)
if len(got) != 1 { if len(got) != 1 {
t.Fatalf("a search past its bound was not said: %+v", got) t.Fatalf("a search past searchQuietFor was not said: %+v", got)
} }
// One key per judgement: DA's is machine.<m>.agent-root, this one its own. // One key per judgement: DA's is machine.<m>.agent-root, this one its own.
da := conditions.Observation{Scope: conditions.ScopeMachine, ID: "anchor", Token: "agent-root", Machine: "anchor"} da := conditions.Observation{Scope: conditions.ScopeMachine, ID: "anchor", Token: "agent-root", Machine: "anchor"}
+1 -1
View File
@@ -35,4 +35,4 @@ require (
// committed. Every build (the build agent's `go build`, the Dockerfile) compiles from vendor/ and // committed. Every build (the build agent's `go build`, the Dockerfile) compiles from vendor/ and
// fetches nothing; go refuses to build when vendor/ and this file disagree, so a pin moved without // fetches nothing; go refuses to build when vendor/ and this file disagree, so a pin moved without
// `go mod vendor` fails loudly, at once, everywhere. // `go mod vendor` fails loudly, at once, everywhere.
replace github.com/novox/mesh-host => git.novox.be/novox/mesh-host v0.0.0-20261009230047-2dbbda51c658 replace github.com/novox/mesh-host => git.novox.be/novox/mesh-host v0.0.0-20261009231056-a7270f00cbe0
+2 -2
View File
@@ -1,5 +1,5 @@
git.novox.be/novox/mesh-host v0.0.0-20261009230047-2dbbda51c658 h1:t0OW6XW9ZewHmWDPetmsNt6c0LlmVuEvf2VAaxvPOPM= git.novox.be/novox/mesh-host v0.0.0-20261009231056-a7270f00cbe0 h1:e+CQG7pjoQFjhBje2OjQS+qG3BfgCuUtVaWW1uzWye8=
git.novox.be/novox/mesh-host v0.0.0-20261009230047-2dbbda51c658/go.mod h1:K3/xEzVgmrNKLMV2vv4M80MwmPnQNXqvQ4C5Jj0fJT4= git.novox.be/novox/mesh-host v0.0.0-20261009231056-a7270f00cbe0/go.mod h1:K3/xEzVgmrNKLMV2vv4M80MwmPnQNXqvQ4C5Jj0fJT4=
git.novox.be/novox/mesh-sdk/go v0.1.11-0.20261009143344-f047d0a4a970 h1:9tFDQsgmI+4X7/BpZGXIr+HemPKE7YddYGqWV0lINAI= git.novox.be/novox/mesh-sdk/go v0.1.11-0.20261009143344-f047d0a4a970 h1:9tFDQsgmI+4X7/BpZGXIr+HemPKE7YddYGqWV0lINAI=
git.novox.be/novox/mesh-sdk/go v0.1.11-0.20261009143344-f047d0a4a970/go.mod h1:GFuZUElBZ9A++mxgIKo97aXXo+kV0uJ/UkbhQPPIbrY= git.novox.be/novox/mesh-sdk/go v0.1.11-0.20261009143344-f047d0a4a970/go.mod h1:GFuZUElBZ9A++mxgIKo97aXXo+kV0uJ/UkbhQPPIbrY=
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
+2 -2
View File
@@ -78,7 +78,7 @@ github.com/nats-io/nkeys
# github.com/nats-io/nuid v1.0.1 # github.com/nats-io/nuid v1.0.1
## explicit ## explicit
github.com/nats-io/nuid github.com/nats-io/nuid
# github.com/novox/mesh-host v0.0.0 => git.novox.be/novox/mesh-host v0.0.0-20261009230047-2dbbda51c658 # github.com/novox/mesh-host v0.0.0 => git.novox.be/novox/mesh-host v0.0.0-20261009231056-a7270f00cbe0
## explicit; go 1.26.0 ## explicit; go 1.26.0
github.com/novox/mesh-host/internal/declaration github.com/novox/mesh-host/internal/declaration
github.com/novox/mesh-host/rootsearch github.com/novox/mesh-host/rootsearch
@@ -135,4 +135,4 @@ golang.org/x/text/width
# golang.org/x/time v0.15.0 # golang.org/x/time v0.15.0
## explicit; go 1.25.0 ## explicit; go 1.25.0
golang.org/x/time/rate golang.org/x/time/rate
# github.com/novox/mesh-host => git.novox.be/novox/mesh-host v0.0.0-20261009230047-2dbbda51c658 # github.com/novox/mesh-host => git.novox.be/novox/mesh-host v0.0.0-20261009231056-a7270f00cbe0