From 444fa48fbfec381469c352b75ff93d79db8b3287 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 5 Nov 2026 16:49:27 +0100 Subject: [PATCH] =?UTF-8?q?watchman:=20its=20findings=20are=20written=20an?= =?UTF-8?q?d=20read=20in=20the=20seat=20mesh-conditions'=20layout=20throug?= =?UTF-8?q?h=20meshconditionsclient=20(ADR=200634=20=C2=A74;=20issue=20196?= =?UTF-8?q?6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i --- modules/mesh-delivery-watchman/go.mod | 1 + .../internal/watch/finding.go | 48 ++++++++----------- .../internal/watch/findings_test.go | 4 +- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/modules/mesh-delivery-watchman/go.mod b/modules/mesh-delivery-watchman/go.mod index 44bef1e5..41810cc8 100644 --- a/modules/mesh-delivery-watchman/go.mod +++ b/modules/mesh-delivery-watchman/go.mod @@ -39,3 +39,4 @@ replace git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/buildrun require git.novox.be/novox/mesh-delivery/sdk v0.0.0-00010101000000-000000000000 replace git.novox.be/novox/mesh-delivery/sdk => ../../sdk +require git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 diff --git a/modules/mesh-delivery-watchman/internal/watch/finding.go b/modules/mesh-delivery-watchman/internal/watch/finding.go index abf0af0c..fbc5114f 100644 --- a/modules/mesh-delivery-watchman/internal/watch/finding.go +++ b/modules/mesh-delivery-watchman/internal/watch/finding.go @@ -3,40 +3,40 @@ package watch import ( "time" - "git.novox.be/novox/mesh-sdk/go/health" + mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-delivery/sdk/heard" ) // The watchman is an observer of the seat mesh-watchdogs (novox/hq ADR 0564 §2, §4): what it observes wrong it writes as a -// finding, one key `..` of its own bucket `findings` in mesh-sdk's layout (health.Finding), only when what +// finding, one key `..` of its own bucket `findings` in the seat mesh-conditions' layout (meshconditionsclient), only when what // it says changes, and it deletes the key when it no longer observes it. The condition keeper (mesh-conditions) raises and // clears the conditions from them; the watchman writes no condition and reads none (Limits 11). // FindingsBucket is the watchman's findings. -var FindingsBucket = health.FindingsBucket(health.WatchmanModule) +var FindingsBucket = mcc.FindingsBucket(Observer) // Observer is the name a finding of the watchman carries. -const Observer = health.WatchmanModule +const Observer = "mesh-delivery-watchman" // The scopes and severities a finding of the watchman names, as the controller's conditions name them, so the keeper's // `compare` meets the same keys. const ( - ScopeMachine = health.ScopeMachine - ScopeDelivery = health.ScopeDelivery - ScopeModule = health.ScopeModule - ScopeProvider = health.ScopeProvider - ScopeBus = health.ScopeBus - ScopeCore = health.ScopeCore + ScopeMachine = mcc.ScopeMachine + ScopeDelivery = mcc.ScopeDelivery + ScopeModule = mcc.ScopeModule + ScopeProvider = mcc.ScopeProvider + ScopeBus = mcc.ScopeBus + ScopeCore = mcc.ScopeCore - Urgent = string(health.Urgent) - Warning = string(health.Warning) + Urgent = mcc.Urgent + Warning = mcc.Warning ) // Finding is what the watchman builds of one thing it observes wrong: its subject (scope, id, the machine and the others // it concerns), kind and severity, its evidence (Summary, and Said with Since, its one observation), the words the // operator reads (ADR 0253; empty leaves the keeper's wording of the kind), and the row or fact it comes from (Source). -// It is written as health.Finding. +// It is written as the seat's finding. type Finding struct { Scope, ID, Token, Kind, Machine string Also []string @@ -51,8 +51,8 @@ type Finding struct { Since time.Time } -// FindingKey composes a finding's key as the controller composes a condition's (health.Key). -func FindingKey(scope, id, token string) string { return health.FindingKey(scope, id, token) } +// FindingKey composes a finding's key as the controller composes a condition's (mcc.Key). +func FindingKey(scope, id, token string) string { return mcc.Key(scope, id, token) } // Key is the finding's key: its token, or its kind when it has none. func (f Finding) Key() string { @@ -63,27 +63,21 @@ func (f Finding) Key() string { return FindingKey(f.Scope, f.ID, token) } -// EncodeFinding is f in mesh-sdk's layout, refusing one the keeper could not make a condition of. +// EncodeFinding is f in the seat's layout, refusing one the keeper could not make a condition of. func EncodeFinding(f Finding) ([]byte, error) { - said := f.Said - if said == "" { - said = f.Summary - } - return health.EncodeFinding(health.Finding{Key: f.Key(), Kind: f.Kind, Ref: f.Token, - Subject: health.Subject{Scope: f.Scope, ID: f.ID, Machine: f.Machine, Also: f.Also}, - Severity: health.Severity(f.Severity), Summary: f.Summary, Headline: f.Headline, Explanation: f.Explanation, - Resolved: f.Resolved, Needs: f.Needs, Evidence: []health.Evidence{{At: f.Since.UTC(), Said: said}}, - Source: f.Source, Observer: Observer, At: f.Since.UTC()}) + return mcc.EncodeFinding(mcc.Observation{Scope: f.Scope, ID: f.ID, Kind: f.Kind, Ref: f.Token, Machine: f.Machine, Also: f.Also, + Severity: f.Severity, Summary: f.Summary, Said: f.Said, Headline: f.Headline, Explanation: f.Explanation, + Resolved: f.Resolved, Needs: f.Needs, Source: f.Source}.Finding(Observer, "", f.Since)) } // DecodeFinding reads a finding the watchman wrote. func DecodeFinding(data []byte) (Finding, error) { - h, err := health.DecodeFinding(data) + h, err := mcc.DecodeFinding(data) if err != nil { return Finding{}, err } f := Finding{Scope: h.Subject.Scope, ID: h.Subject.ID, Token: h.Ref, Kind: h.Kind, Machine: h.Subject.Machine, - Also: h.Subject.Also, Severity: string(h.Severity), Summary: h.Summary, Headline: h.Headline, Explanation: h.Explanation, + Also: h.Subject.Also, Severity: h.Severity, Summary: h.Summary, Headline: h.Headline, Explanation: h.Explanation, Needs: h.Needs, Resolved: h.Resolved, Source: h.Source, Observer: h.Observer, Since: h.At} if len(h.Evidence) > 0 { f.Said = h.Evidence[0].Said diff --git a/modules/mesh-delivery-watchman/internal/watch/findings_test.go b/modules/mesh-delivery-watchman/internal/watch/findings_test.go index ff12c769..f5b6a5bc 100644 --- a/modules/mesh-delivery-watchman/internal/watch/findings_test.go +++ b/modules/mesh-delivery-watchman/internal/watch/findings_test.go @@ -9,13 +9,13 @@ import ( "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-indexer/takein" "git.novox.be/novox/mesh-delivery/sdk/buildstep" - "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient" "git.novox.be/novox/mesh-delivery/sdk/heard" @@ -277,7 +277,7 @@ func TestTheWatchmansFindings(t *testing.T) { case !row.noState && row.want == "" && stands: t.Errorf("%s: the finding stands once bound", row.name) case row.want != "": - f, err := health.DecodeFinding(raw) + f, err := mcc.DecodeFinding(raw) // Review round 2: it says it clears at the part's next start, since Bind runs at the start. if err != nil || f.Kind != heard.Kind || f.Summary != row.want || f.Observer != "mesh-delivery-indexer" || !strings.Contains(f.Explanation, "next start") { t.Errorf("%s: the finding %+v (%v), want summary %q", row.name, f, err, row.want)