Check a provider's waits before saying who waits on it (issue 450)
mesh/merge-gate pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without …
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered

A provider whose wait fails the check raises unhealthy, but the holding read
its stored statement with the wait unchecked: sayWaiters built the
needs-operator key, found it not open and listed no held consumer. The
holding now reads each statement as judged (ADR 0283 decision 3), in
sayWaiters and in the provider's state its consumers are held by.
This commit is contained in:
2026-10-11 03:29:10 +02:00
parent 7493bd8f18
commit ed45cc6415
4 changed files with 109 additions and 6 deletions
+13 -4
View File
@@ -41,12 +41,21 @@ func failingConsumer(module string) inventory.ResourceHealth {
State: link.StateUnhealthy, Reason: "http /health on web: answered 500", Check: "http", Needs: "postgres-database"}
}
// dbSecrets is what the database's waits name: own secrets issued outside the mesh, so a wait for one checks out
// while nobody gave it (ADR 0283 decision 3, novox/hq issue 450).
var dbSecrets = catalogue.OwnSecrets{
"licence": {Path: "/s/licence", IssuedBy: catalogue.IssuedOutside},
"backup-key": {Path: "/s/backup-key", IssuedBy: catalogue.IssuedOutside},
}
// holdingOf is one reading of the record without a store: the newest statements, the open conditions, the
// catalogue, and each consumer's provider already looked up, as providerFor memoises it.
// catalogue, what was given on the provider's machine (nothing), and each consumer's provider already looked up,
// as providerFor memoises it.
func holdingOf(open []conditions.Condition, healths map[string]inventory.NodeHealth, bound map[[3]string]catalogue.Chosen) *holding {
h := &holding{ctx: context.Background(), healths: healths, open: open, providers: map[string]providerLookup{},
shelf: map[string]catalogue.Manifest{"db": {Module: "db", Version: "1",
Provides: []catalogue.Offer{{Name: "postgres-database", Scope: catalogue.ScopeMesh}}}}}
shelf: map[string]catalogue.Manifest{"db": {Module: "db", Version: "1", OwnSecrets: dbSecrets,
Provides: []catalogue.Offer{{Name: "postgres-database", Scope: catalogue.ScopeMesh}}}},
waits: operatorWaitFacts{given: map[string]map[string]time.Time{"db@anchor": {}}}}
for k, p := range bound {
h.providers[k[0]+"\x00"+k[1]+"\x00"+k[2]] = providerLookup{p, true}
}
@@ -75,7 +84,7 @@ func TestAProviderWaitingForTheOperatorHoldsOnlyTheConsumersOfTheWaitingPart(t *
healthyDB.State, healthyDB.Waits = link.StateHealthy, nil
byCredential := holdingOf(nil, shopFailingBeside(waitingDatabaseFor(inventory.Wait{Part: "the server",
Secret: "licence", What: "the licence key"})), shopOnTheDatabase)
byCredential.shelf["db"] = catalogue.Manifest{Module: "db", Version: "1", Provides: []catalogue.Offer{{
byCredential.shelf["db"] = catalogue.Manifest{Module: "db", Version: "1", OwnSecrets: dbSecrets, Provides: []catalogue.Offer{{
Name: "postgres-database", Credential: &catalogue.OfferCredential{Own: "licence"}}}}
for _, c := range []struct {
name string