From 916bdde6a4cfc7324d27f6930c09d2d0cd42698f Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 5 Nov 2026 15:09:43 +0100 Subject: [PATCH] =?UTF-8?q?mesh-healers:=20attempts,=20would,=20the=20heal?= =?UTF-8?q?er-acted=20event=20and=20its=20findings=20are=20the=20seats'=20?= =?UTF-8?q?contract=20types=20(B5d;=20ADR=200634=20=C2=A71,=20=C2=A74;=20i?= =?UTF-8?q?ssue=201966)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i --- .../mesh-healers/cmd/mesh-healers/healers.go | 35 ++++++++++--------- .../cmd/mesh-healers/healers_test.go | 5 +-- .../cmd/mesh-healers/observation.go | 33 ++++++++--------- .../mesh-healers/whole_integration_test.go | 4 +-- modules/mesh-healers/go.mod | 3 ++ 5 files changed, 44 insertions(+), 36 deletions(-) diff --git a/modules/mesh-healers/cmd/mesh-healers/healers.go b/modules/mesh-healers/cmd/mesh-healers/healers.go index 7cb958afa..4fc0c11e5 100644 --- a/modules/mesh-healers/cmd/mesh-healers/healers.go +++ b/modules/mesh-healers/cmd/mesh-healers/healers.go @@ -24,9 +24,11 @@ import ( "sync" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" + meshconditions "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions" + meshhealers "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshhealers" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-sdk/go/handacts" - "git.novox.be/novox/mesh-sdk/go/health" ) // Module and Seat are this module and the seat it holds once for the mesh. @@ -37,11 +39,11 @@ const ( // The states it keeps and reads, and the event it says. const ( - AttemptsState = health.AttemptsState - WouldState = health.WouldState - FindingsState = health.FindingsState + AttemptsState = meshhealers.StateAttempts + WouldState = meshhealers.StateWould + FindingsState = meshconditions.StateFindings ConditionsRead = "mesh-conditions.conditions" - ActedEvent = health.EventHealerActed + ActedEvent = meshhealers.EventHealerActed // ActedSubject is where the seat says it, which its consumers hear (catalogue.SeatSays). ActedSubject = "mesh.seat." + Seat + ".event." + ActedEvent // RecordedEvent is the hand-act log's seat event, each act recorded there (ADR 0565 §11). @@ -59,10 +61,10 @@ const ( // The outcomes an attempt has. const ( - OutcomeActing = health.OutcomeActing - OutcomeActed = health.OutcomeActed - OutcomeFailed = health.OutcomeFailed - OutcomeEscalated = health.OutcomeEscalated + OutcomeActing = meshhealers.HealerActedEventOutcomeActing + OutcomeActed = meshhealers.HealerActedEventOutcomeActed + OutcomeFailed = meshhealers.HealerActedEventOutcomeFailed + OutcomeEscalated = meshhealers.HealerActedEventOutcomeEscalated ) // Store is the bus's buckets as this module reaches them, through its runtime. CreateTTL writes a key only when it has @@ -113,9 +115,9 @@ func (c Condition) Escalated() bool { return c.Resolver == "operator" && len(c.T // (one key per healer and condition, `.`, its newest), and the body of healer-acted, // epoch left out (ADR 0564 Limits 10). type ( - Attempt = health.Attempt - Would = health.Would - Acted = health.HealerActed + Attempt = meshhealers.AttemptsByAttemptValue + Would = meshhealers.WouldByWouldValue + Acted = meshhealers.HealerActedEvent ) // Healer is one row of the registry. @@ -481,7 +483,7 @@ func (h *Healers) brakeHolds(acts []Attempt, now time.Time) (bool, string) { return false, said } -var brakeKey = health.Key(ScopeMesh, "healers", "braked") +var brakeKey = meshconditionsclient.Key(ScopeMesh, "healers", "braked") // brakeFinding is the brake, as the urgent finding that says it. func brakeFinding(acts []Attempt, said string) Observation { @@ -519,7 +521,7 @@ func (h *Healers) blind(err error) { // no longer sees (ADR 0564 §2). func (h *Healers) see(source string, found []Observation) { now := h.Now() - want := map[string]health.Finding{} + want := map[string]meshconditions.FindingsByKeyValue{} for _, o := range found { o.Source = source want[o.Key()] = o.Finding("", now) @@ -534,7 +536,8 @@ func (h *Healers) see(source string, found []Observation) { if err != nil || !found { continue } - was, err := health.DecodeFinding(raw) + var was meshconditions.FindingsByKeyValue + err = json.Unmarshal(raw, &was) if err != nil || was.Source != source { continue } @@ -549,7 +552,7 @@ func (h *Healers) see(source string, found []Observation) { } } for k, f := range want { - raw, err := health.EncodeFinding(f) + raw, err := json.Marshal(f) if err == nil { err = h.Store.Put(FindingsState, k, json.RawMessage(raw)) } diff --git a/modules/mesh-healers/cmd/mesh-healers/healers_test.go b/modules/mesh-healers/cmd/mesh-healers/healers_test.go index fd8b6d701..2322abbf6 100644 --- a/modules/mesh-healers/cmd/mesh-healers/healers_test.go +++ b/modules/mesh-healers/cmd/mesh-healers/healers_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + meshconditions "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions" "slices" "sort" "strings" @@ -12,7 +13,6 @@ import ( "time" "git.novox.be/novox/mesh-sdk/go/handacts" - "git.novox.be/novox/mesh-sdk/go/health" ) type memStore struct { @@ -286,7 +286,8 @@ func TestBudgetSettleEscalationAndBrake(t *testing.T) { t.Errorf("past the brake: %q, asked %v", said, b.asked) } raw, braked, _ := b.store.Get(FindingsState, brakeKey) - f, _ := health.DecodeFinding(raw) + var f meshconditions.FindingsByKeyValue + _ = json.Unmarshal(raw, &f) if !braked || f.Severity != Urgent || f.Kind != "healers-braked" || f.Observer != Module { t.Errorf("the brake is written as %s", raw) } diff --git a/modules/mesh-healers/cmd/mesh-healers/observation.go b/modules/mesh-healers/cmd/mesh-healers/observation.go index b2ef411d6..6adccda58 100644 --- a/modules/mesh-healers/cmd/mesh-healers/observation.go +++ b/modules/mesh-healers/cmd/mesh-healers/observation.go @@ -1,33 +1,34 @@ package main // What the healers observe of themselves, and the finding it is written as (novox/hq ADR 0564 §2): the brake, their -// blindness and S15, each written into the bucket `findings` as mesh-sdk's health.Finding, whose key is the +// blindness and S15, each written into the bucket `findings` as the seat mesh-conditions' finding, whose key is the // controller's key for the same condition. import ( "encoding/json" "time" - "git.novox.be/novox/mesh-sdk/go/health" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" + meshconditions "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions" ) // The severities and scopes, as mesh-sdk's health names them. const ( - Urgent = health.Urgent - Warning = health.Warning - ScopeProbe = health.ScopeProbe - ScopeMesh = health.ScopeMesh + Urgent = meshconditionsclient.Urgent + Warning = meshconditionsclient.Warning + ScopeProbe = meshconditionsclient.ScopeProbe + ScopeMesh = meshconditionsclient.ScopeMesh ) // Subject is what a finding is about. -type Subject = health.Subject +type Subject = meshconditions.Subject // Observation is one thing a probe sees wrong now. type Observation struct { Kind string Ref string Subject Subject - Severity health.Severity + Severity string Summary string Said string Headline string @@ -44,14 +45,14 @@ func (o Observation) Key() string { if token == "" { token = o.Kind } - return health.Key(o.Subject.Scope, o.Subject.ID, token) + return meshconditionsclient.Key(o.Subject.Scope, o.Subject.ID, token) } // Finding is the observation as written by run at, its evidence the one line it said. -func (o Observation) Finding(run string, at time.Time) health.Finding { - f := health.Finding{Key: o.Key(), Kind: o.Kind, Subject: o.Subject, Severity: o.Severity, Summary: o.Summary, +func (o Observation) Finding(run string, at time.Time) meshconditions.FindingsByKeyValue { + f := meshconditions.FindingsByKeyValue{V: meshconditionsclient.FindingVersion, Key: o.Key(), Kind: o.Kind, Subject: o.Subject, Severity: o.Severity, Summary: o.Summary, Headline: o.Headline, Explanation: o.Explanation, Resolved: o.Resolved, Needs: o.Needs, Source: o.Source, - Observer: Module, Run: run, At: at.UTC(), Evidence: []health.Evidence{}} + Observer: Module, Run: run, At: at.UTC(), Evidence: []meshconditions.Evidence{}} if o.Ref != "" && o.Ref != o.Kind { f.Ref = o.Ref } @@ -59,17 +60,17 @@ func (o Observation) Finding(run string, at time.Time) health.Finding { if said == "" { said = o.Summary } - f.Evidence = append(f.Evidence, health.Evidence{At: at.UTC(), Said: said}) + f.Evidence = append(f.Evidence, meshconditions.Evidence{At: at.UTC(), Said: said}) return f } // says is what a finding says, its times and the run that wrote it aside: two findings that say the same are one write // (ADR 0289 §1). -func says(f health.Finding) string { +func says(f meshconditions.FindingsByKeyValue) string { f.At, f.Run, f.V = time.Time{}, "", 0 - ev := make([]health.Evidence, len(f.Evidence)) + ev := make([]meshconditions.Evidence, len(f.Evidence)) for i, e := range f.Evidence { - ev[i] = health.Evidence{Said: e.Said} + ev[i] = meshconditions.Evidence{Said: e.Said} } f.Evidence = ev raw, _ := json.Marshal(f) diff --git a/modules/mesh-healers/cmd/mesh-healers/whole_integration_test.go b/modules/mesh-healers/cmd/mesh-healers/whole_integration_test.go index fcb56242c..715337384 100644 --- a/modules/mesh-healers/cmd/mesh-healers/whole_integration_test.go +++ b/modules/mesh-healers/cmd/mesh-healers/whole_integration_test.go @@ -15,6 +15,7 @@ import ( "encoding/json" "errors" "fmt" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "io" "os" "os/exec" @@ -27,7 +28,6 @@ import ( "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" - "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/testbus" ) @@ -312,7 +312,7 @@ func eventually(t *testing.T, what string, ok func() bool) { func raised(key, module string) []byte { raw, _ := json.Marshal(map[string]any{"key": key, "kind": "consumer-lost", "severity": "warning", "resolver": "self", "subject": map[string]any{"scope": "bus", "id": "EVENTS." + module}, "event": "condition-raised", - "show": health.ShowKeeper(key)}) + "show": meshconditionsclient.ShowKeeper(key)}) return raw } diff --git a/modules/mesh-healers/go.mod b/modules/mesh-healers/go.mod index b9c5c82ba..0b3c16026 100644 --- a/modules/mesh-healers/go.mod +++ b/modules/mesh-healers/go.mod @@ -21,3 +21,6 @@ require ( golang.org/x/sys v0.48.0 // indirect golang.org/x/time v0.16.0 // indirect ) +require git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 +require git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions v0.0.0-00010101000000-000000000000 +require git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshhealers v0.0.0-00010101000000-000000000000