diff --git a/modules/artifact-store-tools/cmd/artifact-store-tools/holder.go b/modules/artifact-store-tools/cmd/artifact-store-tools/holder.go index 9169218bc..6a8498829 100644 --- a/modules/artifact-store-tools/cmd/artifact-store-tools/holder.go +++ b/modules/artifact-store-tools/cmd/artifact-store-tools/holder.go @@ -23,10 +23,10 @@ import ( "sync" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-sdk/go/catalogue" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/views" @@ -83,7 +83,7 @@ type Holder struct { Door func() (Door, error) // Listed is the store as its seats list it now (Store.View); nil reads none, and then nothing is said gone or collected. Listed func(ctx context.Context) (*View, error) - Acts handacts.Recorder + Acts meshhandactsclient.Recorder // Seats asks a registry seat's verb, `seat:.` (hold, remove): the runtime's stdio.Ask in main. Seats func(key string, body any) (json.RawMessage, error) Now func() time.Time @@ -597,7 +597,7 @@ func (h *Holder) Sweep(ctx context.Context, s Sweeping) (*CollectAnswer, error) refused = true break } - if _, err := h.Acts.Record(handacts.Request{What: "let go of " + r + " (" + s.By + ")", Why: why, + if _, err := h.Acts.Record(meshhandactsclient.Request{What: "let go of " + r + " (" + s.By + ")", Why: why, Cause: "artifact-store-sweep", Verb: "collect"}); err != nil { h.logf("%s was let go of and could not be recorded in the hand-act log: %v", r, err) } diff --git a/modules/artifact-store-tools/cmd/artifact-store-tools/holder_integration_test.go b/modules/artifact-store-tools/cmd/artifact-store-tools/holder_integration_test.go index 25f8b35df..575dfcc00 100644 --- a/modules/artifact-store-tools/cmd/artifact-store-tools/holder_integration_test.go +++ b/modules/artifact-store-tools/cmd/artifact-store-tools/holder_integration_test.go @@ -19,8 +19,9 @@ import ( "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" + meshhandacts "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshhandacts" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/testbus" ) @@ -158,7 +159,7 @@ func TestTheSeatSweepsAtABuildsEndOnARealBusWithNoLease(t *testing.T) { // The seat mesh-hand-acts, answering every act it records; artifacts-gone heard on the seat's subject. var mu sync.Mutex var acts, gone []string - if _, err := nc.Subscribe("mesh.seat."+handacts.Seat+".tool.hand-act", func(m *nats.Msg) { + if _, err := nc.Subscribe("mesh.seat."+meshhandacts.Seat+".tool.hand-act", func(m *nats.Msg) { mu.Lock() acts = append(acts, string(m.Data)) mu.Unlock() @@ -198,7 +199,7 @@ func TestTheSeatSweepsAtABuildsEndOnARealBusWithNoLease(t *testing.T) { return m.Data, nil } h := &Holder{Bus: findingsAt{realBus: bus}, Door: mem.Door, Listed: mem.Listed, Seats: ask, Now: time.Now, Logf: t.Logf} - h.Acts = handacts.Recorder{Ask: ask} + h.Acts = meshhandactsclient.Recorder{Ask: ask} // A build's end heard from the builds bucket, as follow hands it over. kv, _ := bus.kv(BuildsRead) diff --git a/modules/artifact-store-tools/cmd/artifact-store-tools/holder_test.go b/modules/artifact-store-tools/cmd/artifact-store-tools/holder_test.go index 533258cc3..71bebdf7d 100644 --- a/modules/artifact-store-tools/cmd/artifact-store-tools/holder_test.go +++ b/modules/artifact-store-tools/cmd/artifact-store-tools/holder_test.go @@ -12,9 +12,9 @@ import ( "testing" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/catalogue" @@ -225,7 +225,7 @@ func aMesh(t *testing.T) (*Holder, *memBus, *memDoor, *[]string) { h := &Holder{Bus: b, Door: func() (Door, error) { return door, nil }, Seats: door.seat, Listed: func(context.Context) (*View, error) { return &View{L: listing}, nil }, Now: func() time.Time { return day.Add(48 * time.Hour) }, - Acts: handacts.Recorder{Ask: func(key string, body any) (json.RawMessage, error) { + Acts: meshhandactsclient.Recorder{Ask: func(key string, body any) (json.RawMessage, error) { raw, _ := json.Marshal(body) acts = append(acts, key+" "+string(raw)) return json.RawMessage(`{}`), nil diff --git a/modules/artifact-store-tools/cmd/artifact-store-tools/main.go b/modules/artifact-store-tools/cmd/artifact-store-tools/main.go index 05615df12..2d64a5072 100644 --- a/modules/artifact-store-tools/cmd/artifact-store-tools/main.go +++ b/modules/artifact-store-tools/cmd/artifact-store-tools/main.go @@ -13,9 +13,10 @@ import ( "os" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/views" ) @@ -24,12 +25,12 @@ func logf(format string, a ...any) { fmt.Fprintf(os.Stderr, format+"\n", a...) } func main() { s := &Store{Ask: stdio.Ask} - v := &views.Reader{Module: "artifact-store-tools", Logf: logf, Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}} + v := &views.Reader{Module: "artifact-store-tools", Logf: logf, Findings: meshconditionsclient.FindingWriter{State: stdio.State("findings")}, Acts: meshhandactsclient.Recorder{Ask: stdio.Ask}} v.Follow(delivery.AssignerModule, "wants", WantsTool) v.Follow(delivery.IndexerModule, "manifests", ManifestsTool) h := &Holder{Bus: runtimeBus{views: v}, Door: DoorAt(os.Getenv("MESH_ARTIFACT_STORE_ADDRESS_FILE"), s), Listed: s.View, Seats: stdio.Ask, Now: time.Now, Logf: logf} - h.Acts = handacts.Recorder{Ask: stdio.Ask} + h.Acts = meshhandactsclient.Recorder{Ask: stdio.Ask} v.Start(context.Background()) go follow(h, v) // An empty name serves as the module the runtime names (MESH_SERVED_MODULE): artifact-store-tools. diff --git a/modules/artifact-store-tools/cmd/artifact-store-tools/store_test.go b/modules/artifact-store-tools/cmd/artifact-store-tools/store_test.go index 5e80b5201..05d5df58a 100644 --- a/modules/artifact-store-tools/cmd/artifact-store-tools/store_test.go +++ b/modules/artifact-store-tools/cmd/artifact-store-tools/store_test.go @@ -3,6 +3,7 @@ package main import ( reg "git.novox.be/novox/mesh-delivery/contracts/go/seats/containerimageregistry" "git.novox.be/novox/mesh-sdk/go/catalogue" + "git.novox.be/novox/mesh-sdk/go/seatlist/seatlisttest" "git.novox.be/novox/mesh-sdk/go/views" "context" @@ -490,6 +491,7 @@ func TestTheToolsServedAreTheToolsTheManifestNames(t *testing.T) { for _, tl := range SeatTools(&Holder{}, &Store{}) { verbs = append(verbs, strings.TrimPrefix(tl.Name, catalogue.ArtifactSweepSeat+".")) } + catalogue.UseSeats(catalogue.SeatsFromDefinitions(seatlisttest.Definitions())) seat, _ := catalogue.SeatNamed(catalogue.ArtifactSweepSeat) var contract []string for _, v := range seat.Serves { diff --git a/modules/artifact-store-tools/go.mod b/modules/artifact-store-tools/go.mod index 51f5cae5b..684f336aa 100644 --- a/modules/artifact-store-tools/go.mod +++ b/modules/artifact-store-tools/go.mod @@ -3,6 +3,9 @@ module artifactstoretools go 1.26.0 require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 + git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshhandacts v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-delivery/contracts/go/seats/containerimageregistry v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-delivery/contracts/go/seats/ociartifactregistry v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f diff --git a/modules/claude-code/cmd/claude-code/main.go b/modules/claude-code/cmd/claude-code/main.go index 2884cd16e..c597d68c7 100644 --- a/modules/claude-code/cmd/claude-code/main.go +++ b/modules/claude-code/cmd/claude-code/main.go @@ -25,6 +25,7 @@ import ( occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" stdio "git.novox.be/novox/mesh-sdk/go" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/seatlist" "git.novox.be/novox/mesh-sdk/go/views" @@ -228,7 +229,7 @@ var meshChanged = make(chan struct{}, 1) // newMeshViews builds the reader of those three states; Start asks them. func newMeshViews() *views.Reader { - v := &views.Reader{Module: Module, Logf: func(f string, a ...any) { say(f, a...) }, Findings: views.OwnFindings{}, + v := &views.Reader{Module: Module, Logf: func(f string, a ...any) { say(f, a...) }, Findings: meshconditionsclient.FindingWriter{State: stdio.State("findings")}, Acts: handActs{}, Changed: func(string, string, json.RawMessage, bool) { select { diff --git a/modules/claude-code/go.mod b/modules/claude-code/go.mod index a1b7dbb87..ac591271f 100644 --- a/modules/claude-code/go.mod +++ b/modules/claude-code/go.mod @@ -5,6 +5,7 @@ go 1.26.0 require git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel v0.0.0-00010101000000-000000000000 diff --git a/modules/distribution/cmd/distribution-tools/main.go b/modules/distribution/cmd/distribution-tools/main.go index fdec0a64d..0eec28ea4 100644 --- a/modules/distribution/cmd/distribution-tools/main.go +++ b/modules/distribution/cmd/distribution-tools/main.go @@ -18,10 +18,10 @@ import ( "sync" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" reg "git.novox.be/novox/mesh-delivery/contracts/go/seats/containerimageregistry" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/parts" @@ -167,8 +167,8 @@ func learnInto(state casState, module, fp string, attempts int) (bool, error) { } // recordAct records a hand act through the seat mesh-hand-acts alone. -func recordAct(q handacts.Request) error { - _, err := handacts.Recorder{Ask: stdio.Ask}.Record(q) +func recordAct(q meshhandactsclient.Request) error { + _, err := meshhandactsclient.Recorder{Ask: stdio.Ask}.Record(q) return err } diff --git a/modules/distribution/go.mod b/modules/distribution/go.mod index 03cee0411..2440a8444 100644 --- a/modules/distribution/go.mod +++ b/modules/distribution/go.mod @@ -3,6 +3,7 @@ module distribution go 1.26.0 require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-delivery/contracts/go/seats/containerimageregistry v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f github.com/nats-io/nats.go v1.54.0 diff --git a/modules/distribution/internal/holder/holder_test.go b/modules/distribution/internal/holder/holder_test.go index 78259c793..cf28ef248 100644 --- a/modules/distribution/internal/holder/holder_test.go +++ b/modules/distribution/internal/holder/holder_test.go @@ -16,8 +16,8 @@ import ( "testing" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "git.novox.be/novox/mesh-sdk/go/catalogue" - "git.novox.be/novox/mesh-sdk/go/handacts" ) type memObjects map[string][]byte @@ -383,12 +383,12 @@ func TestTheHolderOfTheTwoImageSeats(t *testing.T) { } // Seams note 2: registry_incoming's drop is a hand act recorded through mesh-hand-acts before anything goes; // an act not recorded leaves the transfer open. - var acts []handacts.Request - b.h.Record = func(q handacts.Request) error { return errors.New("mesh-hand-acts has no holder") } + var acts []meshhandactsclient.Request + b.h.Record = func(q meshhandactsclient.Request) error { return errors.New("mesh-hand-acts has no holder") } if _, err := b.h.DropByHand("t5", "person.jochen", "stuck"); err == nil || !strings.Contains(err.Error(), "stays open") { t.Errorf("a drop whose act is not recorded = %v; want refused, t5 open", err) } - b.h.Record = func(q handacts.Request) error { acts = append(acts, q); return nil } + b.h.Record = func(q meshhandactsclient.Request) error { acts = append(acts, q); return nil } if _, err := b.h.DropByHand("t5", "person.jochen", ""); err == nil || len(acts) != 0 { t.Errorf("a drop with no why = %v, acts %v; want refused, nothing recorded", err, acts) } diff --git a/modules/distribution/internal/holder/transfer.go b/modules/distribution/internal/holder/transfer.go index fcd04865f..180520793 100644 --- a/modules/distribution/internal/holder/transfer.go +++ b/modules/distribution/internal/holder/transfer.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "git.novox.be/novox/mesh-sdk/go/handacts" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "git.novox.be/novox/mesh-sdk/go/parts" ) @@ -168,9 +168,9 @@ type Holder struct { Now func() time.Time // Cap reads incoming's cap from its binding (parts.BusCap); IncomingCap when nil or when the binding names none. Cap func() (uint64, error) - // Record records a hand act through the seat mesh-hand-acts (handacts.Recorder); a drop by hand is refused + // Record records a hand act through the seat mesh-hand-acts (meshhandactsclient.Recorder); a drop by hand is refused // without it. - Record func(handacts.Request) error + Record func(meshhandactsclient.Request) error // Idle writes a transfer's idle key with its own time to live, once (parts.BusArm over IdleState); the receiver // arms it on each open that leaves a transfer open. Nil arms nothing. Idle func(id string, ttl time.Duration) error @@ -312,7 +312,7 @@ func (h *Holder) DropByHand(id, by, why string) (Transfer, error) { return Transfer{}, fmt.Errorf("transfer %s is not open", id) } what := fmt.Sprintf("dropped the open transfer %s of incoming (%s@%s on %s, opened by %s, %d parts lacked), by %s", id, t.Shape.Name, t.Shape.Version, t.Shape.Seat, t.Opener, len(t.Lacks()), by) - if err := h.Record(handacts.Request{What: what, Why: why, Cause: "registry_incoming"}); err != nil { + if err := h.Record(meshhandactsclient.Request{What: what, Why: why, Cause: "registry_incoming"}); err != nil { return Transfer{}, fmt.Errorf("the hand act cannot be recorded, so transfer %s stays open: %w", id, err) } return h.Drop(id) diff --git a/modules/gitea/cmd/package-registry/seats.go b/modules/gitea/cmd/package-registry/seats.go index df7a96066..578035bbb 100644 --- a/modules/gitea/cmd/package-registry/seats.go +++ b/modules/gitea/cmd/package-registry/seats.go @@ -27,11 +27,11 @@ import ( "strings" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" goreg "git.novox.be/novox/mesh-delivery/contracts/go/seats/gopackageregistry" npmreg "git.novox.be/novox/mesh-delivery/contracts/go/seats/npmpackageregistry" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/parts" @@ -265,8 +265,8 @@ func finding(kind, subject, words string, raised bool) { } // recordAct records a hand act through the seat mesh-hand-acts alone. -func recordAct(q handacts.Request) error { - _, err := handacts.Recorder{Ask: stdio.Ask}.Record(q) +func recordAct(q meshhandactsclient.Request) error { + _, err := meshhandactsclient.Recorder{Ask: stdio.Ask}.Record(q) return err } diff --git a/modules/gitea/go.mod b/modules/gitea/go.mod index 17c183977..da00df0e0 100644 --- a/modules/gitea/go.mod +++ b/modules/gitea/go.mod @@ -3,6 +3,7 @@ module gitea go 1.26.0 require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-delivery/contracts/go/seats/gopackageregistry v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-delivery/contracts/go/seats/npmpackageregistry v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f diff --git a/modules/gitea/internal/packageseats/holder.go b/modules/gitea/internal/packageseats/holder.go index 3b586704f..3cfa7feb3 100644 --- a/modules/gitea/internal/packageseats/holder.go +++ b/modules/gitea/internal/packageseats/holder.go @@ -12,8 +12,8 @@ import ( "strings" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/parts" ) @@ -157,9 +157,9 @@ type Holder struct { Now func() time.Time // Cap reads incoming's cap from its binding (parts.BusCap); IncomingCap when nil or when the binding names none. Cap func() (uint64, error) - // Record records a hand act through the seat mesh-hand-acts (handacts.Recorder); a drop by hand is refused + // Record records a hand act through the seat mesh-hand-acts (meshhandactsclient.Recorder); a drop by hand is refused // without it. - Record func(handacts.Request) error + Record func(meshhandactsclient.Request) error // Idle writes a transfer's idle key with its own time to live, once (parts.BusArm over IdleState); the receiver // arms it on each open that leaves a transfer open. Nil arms nothing. Idle func(key string, ttl time.Duration) error @@ -355,7 +355,7 @@ func (h *Holder) DropByHand(seat, transfer, by, why string) (Transfer, error) { return Transfer{}, fmt.Errorf("transfer %s of %s is not open", transfer, seat) } what := fmt.Sprintf("dropped the open transfer %s of %s's incoming (%s@%s, opened by %s), by %s", transfer, seat, t.Shape.Name, t.Shape.Version, t.Opener, by) - if err := h.Record(handacts.Request{What: what, Why: why, Cause: Seats[seat] + "_incoming"}); err != nil { + if err := h.Record(meshhandactsclient.Request{What: what, Why: why, Cause: Seats[seat] + "_incoming"}); err != nil { return Transfer{}, fmt.Errorf("the hand act cannot be recorded, so transfer %s stays open: %w", transfer, err) } return h.Drop(seat, transfer) diff --git a/modules/gitea/internal/packageseats/holder_test.go b/modules/gitea/internal/packageseats/holder_test.go index bf814fea9..1b6837ed5 100644 --- a/modules/gitea/internal/packageseats/holder_test.go +++ b/modules/gitea/internal/packageseats/holder_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/parts" ) @@ -193,12 +193,12 @@ func TestTheForgeHoldsBothPackageSeats(t *testing.T) { } // Seams note 2: go_incoming's drop is a hand act recorded through mesh-hand-acts before anything goes; an act // not recorded leaves the transfer open. - var acts []handacts.Request - b.h.Record = func(handacts.Request) error { return errors.New("mesh-hand-acts has no holder") } + var acts []meshhandactsclient.Request + b.h.Record = func(meshhandactsclient.Request) error { return errors.New("mesh-hand-acts has no holder") } if _, err := b.h.DropByHand(GoSeat, "t-b", "person.jochen", "stuck"); err == nil || !strings.Contains(err.Error(), "stays open") { t.Errorf("a drop whose act is not recorded = %v; want refused, t-b open", err) } - b.h.Record = func(q handacts.Request) error { acts = append(acts, q); return nil } + b.h.Record = func(q meshhandactsclient.Request) error { acts = append(acts, q); return nil } if got, err := b.h.DropByHand(GoSeat, "t-b", "person.jochen", "stuck"); err != nil || got.Shape.Name != "b" || len(acts) != 1 || acts[0].Cause != "go_incoming" || !strings.Contains(acts[0].What, "t-b") || !strings.Contains(acts[0].What, "person.jochen") { t.Errorf("a drop by hand = %+v, %v, acts %+v; want t-b dropped and its act recorded", got, err, acts) } diff --git a/modules/mesh-build-go/cmd/mesh-build-go/compose.go b/modules/mesh-build-go/cmd/mesh-build-go/compose.go index 5a5de08a5..50bf32963 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/compose.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/compose.go @@ -27,6 +27,7 @@ import ( "git.novox.be/novox/mesh-catalog/modules/mesh-build-go/buildstep" stdio "git.novox.be/novox/mesh-sdk/go" sdkstep "git.novox.be/novox/mesh-sdk/go/buildstep" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-sdk/go/composer" "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/views" @@ -76,7 +77,7 @@ func (m *Module) compose(ctx context.Context, fetch buildstep.StepFunc, a delive // askManifest asks the indexer's read tool for one manifest by its key: nil when it keeps none. A call the indexer does not // answer is a finding of this module's own, which the condition keeper raises (ADR 0615 §6) and the next answer clears. func askManifest(key string) (json.RawMessage, error) { - return askManifestVia(stdio.Ask, views.OwnFindings{}, time.Now, key) + return askManifestVia(stdio.Ask, meshconditionsclient.FindingWriter{State: stdio.State("findings")}, time.Now, key) } func askManifestVia(ask func(string, any) (json.RawMessage, error), findings interface { diff --git a/modules/mesh-build-go/go.mod b/modules/mesh-build-go/go.mod index 704d316de..ac7260e7c 100644 --- a/modules/mesh-build-go/go.mod +++ b/modules/mesh-build-go/go.mod @@ -3,6 +3,7 @@ module meshbuildgo go 1.26.0 require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-delivery/contracts/go/seats/containerimageregistry v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-catalog/modules/mesh-build-go/buildstep v0.0.0 git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f diff --git a/modules/mesh-conditions/cmd/mesh-conditions/keeper_test.go b/modules/mesh-conditions/cmd/mesh-conditions/keeper_test.go index 62aacc79f..93c54e0d5 100644 --- a/modules/mesh-conditions/cmd/mesh-conditions/keeper_test.go +++ b/modules/mesh-conditions/cmd/mesh-conditions/keeper_test.go @@ -339,7 +339,7 @@ func TestEveryControllerKindHasItsHome(t *testing.T) { // findings: views.UnansweredFinding, views.TooLargeFinding, views.UnsaidFinding or views.OwnFindings. func viewFindingWriters(t *testing.T, modules string) []string { t.Helper() - writes := regexp.MustCompile(`views\.(UnansweredFinding|TooLargeFinding|UnsaidFinding|OwnFindings)\b`) + writes := regexp.MustCompile(`(views\.(UnansweredFinding|TooLargeFinding|UnsaidFinding)|meshconditionsclient\.FindingWriter)\b`) var out []string entries, err := os.ReadDir(modules) if err != nil { diff --git a/modules/mesh-conditions/cmd/mesh-conditions/main.go b/modules/mesh-conditions/cmd/mesh-conditions/main.go index ad8beae7e..9776caf0c 100644 --- a/modules/mesh-conditions/cmd/mesh-conditions/main.go +++ b/modules/mesh-conditions/cmd/mesh-conditions/main.go @@ -9,6 +9,7 @@ package main import ( "context" + "encoding/json" "fmt" "os" "time" @@ -17,7 +18,8 @@ import ( "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/health" - "git.novox.be/novox/mesh-sdk/go/handacts" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "git.novox.be/novox/mesh-sdk/go/views" ) @@ -150,7 +152,7 @@ const ( // NewViews is the keeper's pictures of the assigner's wants, placement and findings and of the indexer's findings. A first view it cannot get past its // bound is a finding of its own, taken in as any observer's: the keeper raises the condition itself. func NewViews(k *Keeper) *views.Reader { - v := &views.Reader{Module: Module, Logf: logf, Findings: ownFindings{k}, Acts: handacts.Recorder{Ask: stdio.Ask}} + v := &views.Reader{Module: Module, Logf: logf, Findings: ownFindings{k}, Acts: meshhandactsclient.Recorder{Ask: stdio.Ask}} v.Follow(delivery.AssignerModule, "wants", WantsTool) v.Follow(delivery.AssignerModule, "placement", PlacementTool) v.Follow(delivery.AssignerModule, health.FindingsState, FindingsTool) @@ -161,10 +163,20 @@ func NewViews(k *Keeper) *views.Reader { // ownFindings takes the keeper's own finding straight into its picture of findings. type ownFindings struct{ k *Keeper } -func (o ownFindings) Put(key string, value []byte) error { - return o.k.Finding(Module, key, value, false) +func (o ownFindings) Put(f views.Finding) error { + v := meshconditionsclient.FindingFor(f) + if err := meshconditionsclient.CheckFinding(v); err != nil { + return err + } + value, err := json.Marshal(v) + if err != nil { + return err + } + return o.k.Finding(Module, v.Key, value, false) +} +func (o ownFindings) Delete(f views.Finding) error { + return o.k.Finding(Module, meshconditionsclient.Key(meshconditionsclient.ScopeModule, f.ID, f.Kind), nil, true) } -func (o ownFindings) Delete(key string) error { return o.k.Finding(Module, key, nil, true) } func main() { k := NewKeeper() diff --git a/modules/mesh-conditions/cmd/mesh-conditions/manifest_test.go b/modules/mesh-conditions/cmd/mesh-conditions/manifest_test.go index 1bac348bf..caea20f90 100644 --- a/modules/mesh-conditions/cmd/mesh-conditions/manifest_test.go +++ b/modules/mesh-conditions/cmd/mesh-conditions/manifest_test.go @@ -9,6 +9,7 @@ import ( "git.novox.be/novox/mesh-sdk/go/catalogue" "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/health" + "git.novox.be/novox/mesh-sdk/go/seatlist/seatlisttest" ) // ADR 0564 clauses 1, 2, 3 and 12 (issue 1952 C1): the manifest says what the code does. It claims the seat @@ -25,6 +26,7 @@ func TestTheManifestSaysWhatTheCodeDoes(t *testing.T) { if err != nil { t.Fatalf("the manifest does not decode: %v", err) } + catalogue.UseSeats(catalogue.SeatsFromDefinitions(seatlisttest.Definitions())) seat, _ := catalogue.SeatNamed(Seat) if m.Module != Module || m.RunsAs != Module || len(m.Claims) != 1 || m.Claims[0].Name != Seat || !slices.Equal(Verbs, catalogue.VerbNames(seat.Serves)) { diff --git a/modules/mesh-conditions/go.mod b/modules/mesh-conditions/go.mod index 69183c3a4..44b4f5b3d 100644 --- a/modules/mesh-conditions/go.mod +++ b/modules/mesh-conditions/go.mod @@ -3,6 +3,8 @@ module mesh-conditions go 1.26.0 require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-config/cmd/mesh-config/delivery.go b/modules/mesh-config/cmd/mesh-config/delivery.go index a2c3a5cd8..8da6f8b7e 100644 --- a/modules/mesh-config/cmd/mesh-config/delivery.go +++ b/modules/mesh-config/cmd/mesh-config/delivery.go @@ -8,8 +8,8 @@ import ( "fmt" "strings" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" ) // The addresses asked. @@ -107,12 +107,12 @@ func notServed(err error) bool { // module, naming the node, module, secret and the ask of the Approve; the vault reads it back by its id (`warrant`). type toolVault struct { ask func(key string, body any) (json.RawMessage, error) - recorder handacts.Recorder + recorder meshhandactsclient.Recorder } // Retire records the warrant and calls the vault's verb. func (v toolVault) Retire(r RetireRequest) error { - taken, err := v.recorder.Record(handacts.Request{What: r.Node + " " + r.Module + " " + r.Name + " " + r.Ask, + taken, err := v.recorder.Record(meshhandactsclient.Request{What: r.Node + " " + r.Module + " " + r.Name + " " + r.Ask, Why: "the operator approved retiring " + r.Module + "'s secret " + r.Name + " on " + r.Node + " (ask " + r.Ask + ")", Cause: "the operator's Approve of ask " + r.Ask, Verb: "mesh-vault.retire"}) if err != nil { diff --git a/modules/mesh-config/cmd/mesh-config/main.go b/modules/mesh-config/cmd/mesh-config/main.go index eabd66d95..2fb03c982 100644 --- a/modules/mesh-config/cmd/mesh-config/main.go +++ b/modules/mesh-config/cmd/mesh-config/main.go @@ -18,9 +18,10 @@ import ( "strings" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/handacts" ) // Seat is the role this module holds, once for the mesh, and Verb its one verb. @@ -93,11 +94,11 @@ func (runtimeStore) Emit(event string, body any) error { return stdio.Emit(event // recorder records into the hand-act log of the seat mesh-hand-acts alone (novox/hq ADR 0565 §11, issue 1953): the manifest // invokes no verb of the controller and the SDK recorder has no fall back to its log. -var recorder = handacts.Recorder{Ask: stdio.Ask} +var recorder = meshhandactsclient.Recorder{Ask: stdio.Ask} // HandAct records a change in the hand-act log (to-be 45 §7). func (runtimeStore) HandAct(what, why, cause string) error { - _, err := recorder.Record(handacts.Request{What: what, Why: why, Cause: cause}) + _, err := recorder.Record(meshhandactsclient.Request{What: what, Why: why, Cause: cause}) return err } @@ -125,11 +126,7 @@ func main() { case moved <- struct{}{}: default: } - }, func(key string, v json.RawMessage) error { - _, err := stdio.State(FindingsState).Put(key, v) - return err - }, - func(key string) error { return stdio.State(FindingsState).Delete(key) }) + }, meshconditionsclient.FindingWriter{State: stdio.State(FindingsState)}) theViews.Start(context.Background()) go resolving(c, moved) go hearing(c) diff --git a/modules/mesh-config/cmd/mesh-config/ownerviews.go b/modules/mesh-config/cmd/mesh-config/ownerviews.go index 5f91fcfc5..f220d52a9 100644 --- a/modules/mesh-config/cmd/mesh-config/ownerviews.go +++ b/modules/mesh-config/cmd/mesh-config/ownerviews.go @@ -52,15 +52,13 @@ var followed = []struct{ Read, Owner, State, Tool string }{ // ownerViews are the pictures, by the read name. type ownerViews struct { by map[string]*views.Follower - // store keeps the findings a first view unanswered writes. - store func(key string, value json.RawMessage) error - drop func(key string) error + // findings keeps the findings a first view unanswered writes. + findings views.FindingWriter } // newOwnerViews makes a follower for each state; changed is told when any picture changes. -func newOwnerViews(ask func(key string, body any) (json.RawMessage, error), changed func(), put func(string, json.RawMessage) error, - del func(string) error) *ownerViews { - o := &ownerViews{by: map[string]*views.Follower{}, store: put, drop: del} +func newOwnerViews(ask func(key string, body any) (json.RawMessage, error), changed func(), findings views.FindingWriter) *ownerViews { + o := &ownerViews{by: map[string]*views.Follower{}, findings: findings} for _, f := range followed { f := f fol := &views.Follower{Owner: f.Owner, Tool: f.Owner + "." + f.Tool, State: f.State, Logf: logf, @@ -81,14 +79,10 @@ func newOwnerViews(ask func(key string, body any) (json.RawMessage, error), chan }, Changed: func(string, json.RawMessage, bool, time.Time) { changed() }} fol.Raise = func(s views.Status) { - if k, v, err := views.UnansweredFinding(Module, s, time.Now()); err == nil { - _ = put(k, v) - } + _ = findings.Put(views.UnansweredFinding(Module, s, time.Now())) } fol.Clear = func(s views.Status) { - if k, _, err := views.UnansweredFinding(Module, s, time.Now()); err == nil { - _ = del(k) - } + _ = findings.Delete(views.UnansweredFinding(Module, s, time.Now())) } o.by[f.Read] = fol } diff --git a/modules/mesh-config/cmd/mesh-config/ownerviews_test.go b/modules/mesh-config/cmd/mesh-config/ownerviews_test.go index 73ae06fce..d7611930e 100644 --- a/modules/mesh-config/cmd/mesh-config/ownerviews_test.go +++ b/modules/mesh-config/cmd/mesh-config/ownerviews_test.go @@ -32,7 +32,7 @@ func TestAFollowedStateIsReadFromItsOwnersFirstViewAndEvents(t *testing.T) { return raw, nil } var changed atomic.Int32 - o := newOwnerViews(ask, func() { changed.Add(1) }, func(string, json.RawMessage) error { return nil }, func(string) error { return nil }) + o := newOwnerViews(ask, func() { changed.Add(1) }, nopFindings{}) if _, followed, err := o.get(WantsRead, "want.g14.dunst"); !followed || err == nil || !strings.Contains(err.Error(), "not answered yet") { t.Fatalf("before the first view: followed %v, %v", followed, err) } @@ -74,3 +74,9 @@ func TestAFollowedStateIsReadFromItsOwnersFirstViewAndEvents(t *testing.T) { t.Errorf("statuses %d, want %d", len(got), len(followed)) } } + +// nopFindings takes a finding and keeps none. +type nopFindings struct{} + +func (nopFindings) Put(views.Finding) error { return nil } +func (nopFindings) Delete(views.Finding) error { return nil } diff --git a/modules/mesh-config/go.mod b/modules/mesh-config/go.mod index bd824bc12..fba57def9 100644 --- a/modules/mesh-config/go.mod +++ b/modules/mesh-config/go.mod @@ -3,6 +3,7 @@ module mesh-config go 1.26.0 require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/go/seats/meshconfig v0.0.0-20261104174344-ae5266e77639 diff --git a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/manifest_test.go b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/manifest_test.go index 4cfa45f38..23bc63abb 100644 --- a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/manifest_test.go +++ b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/manifest_test.go @@ -12,6 +12,7 @@ import ( "time" "git.novox.be/novox/mesh-sdk/go/catalogue" + "git.novox.be/novox/mesh-sdk/go/seatlist/seatlisttest" ) // The manifest says what the code does: the seat it claims and the verbs it serves, the events it follows @@ -217,6 +218,7 @@ func TestTheGateHoldsTheSeatAsTheSDKsTableOfRelease6HasIt(t *testing.T) { if err != nil { t.Fatalf("the SDK this module pins cannot decode its manifest: %v", err) } + catalogue.UseSeats(catalogue.SeatsFromDefinitions(seatlisttest.Definitions())) seat, ok := catalogue.SeatNamed("mesh-delivery") if !ok { t.Fatal("the SDK this module pins names no seat mesh-delivery") diff --git a/modules/mesh-provisioner/cmd/mesh-provisioner/main.go b/modules/mesh-provisioner/cmd/mesh-provisioner/main.go index f381e2877..ea1f468c5 100644 --- a/modules/mesh-provisioner/cmd/mesh-provisioner/main.go +++ b/modules/mesh-provisioner/cmd/mesh-provisioner/main.go @@ -17,9 +17,10 @@ import ( oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" stdio "git.novox.be/novox/mesh-sdk/go" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "git.novox.be/novox/mesh-sdk/go/views" ) @@ -184,7 +185,7 @@ const ( // newViews is the provisioner's pictures of the assigner's placement and wants and the indexer's modules and manifests: // each asked once of its owner's read tool, then followed by the owner's events (ADR 0615). func newViews() *views.Reader { - v := &views.Reader{Module: Module, Logf: logf, Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}} + v := &views.Reader{Module: Module, Logf: logf, Findings: meshconditionsclient.FindingWriter{State: stdio.State("findings")}, Acts: meshhandactsclient.Recorder{Ask: stdio.Ask}} v.Follow(delivery.AssignerModule, "placement", PlacementTool) v.Follow(delivery.AssignerModule, "wants", WantsTool) v.Follow(delivery.IndexerModule, "modules", ModulesTool) diff --git a/modules/mesh-provisioner/go.mod b/modules/mesh-provisioner/go.mod index 30f9841b3..d160048cb 100644 --- a/modules/mesh-provisioner/go.mod +++ b/modules/mesh-provisioner/go.mod @@ -3,6 +3,8 @@ module mesh-provisioner go 1.26.0 require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f diff --git a/modules/mesh-self-check/cmd/mesh-self-check/main.go b/modules/mesh-self-check/cmd/mesh-self-check/main.go index e8617cf5b..d8d9c7228 100644 --- a/modules/mesh-self-check/cmd/mesh-self-check/main.go +++ b/modules/mesh-self-check/cmd/mesh-self-check/main.go @@ -13,9 +13,10 @@ import ( "time" stdio "git.novox.be/novox/mesh-sdk/go" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "git.novox.be/novox/mesh-sdk/go/views" ) @@ -74,7 +75,7 @@ func NewChecker() *Checker { // its owner's read tool, then followed by the owner's events. A first view unanswered past its bound is a finding of the // self-check's own (first-view-unanswered), written into its state findings. func newViews() *views.Reader { - r := &views.Reader{Module: Module, Logf: logf, Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}} + r := &views.Reader{Module: Module, Logf: logf, Findings: meshconditionsclient.FindingWriter{State: stdio.State("findings")}, Acts: meshhandactsclient.Recorder{Ask: stdio.Ask}} r.Follow(delivery.AssignerModule, delivery.PlacementState, PlacementTool) r.Follow(delivery.AssignerModule, delivery.SeatHoldersState, SeatHoldersTool) r.Follow(delivery.IndexerModule, "modules", ModulesTool) diff --git a/modules/mesh-self-check/go.mod b/modules/mesh-self-check/go.mod index 2f18255fa..2e3786033 100644 --- a/modules/mesh-self-check/go.mod +++ b/modules/mesh-self-check/go.mod @@ -3,6 +3,8 @@ module mesh-self-check go 1.26.0 require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-watcher/cmd/mesh-watcher/main.go b/modules/mesh-watcher/cmd/mesh-watcher/main.go index cc101b5cd..d7a420003 100644 --- a/modules/mesh-watcher/cmd/mesh-watcher/main.go +++ b/modules/mesh-watcher/cmd/mesh-watcher/main.go @@ -15,9 +15,10 @@ import ( "sync" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/views" @@ -74,7 +75,7 @@ func main() { node := os.Getenv("MESH_NODE") w := NewWatcher(tg, time.Now, logf, node) l := &listening{now: "not yet: starting"} - placement := &views.Reader{Module: "mesh-watcher", Logf: logf, Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}} + placement := &views.Reader{Module: "mesh-watcher", Logf: logf, Findings: meshconditionsclient.FindingWriter{State: stdio.State("findings")}, Acts: meshhandactsclient.Recorder{Ask: stdio.Ask}} placement.Follow(delivery.AssignerModule, delivery.SeatHoldersState, SeatHoldersTool) go run(w, l, node, placement) if err := stdio.Serve("", append(tools(w, l), placement.Tools("watcher")...)); err != nil { diff --git a/modules/mesh-watcher/go.mod b/modules/mesh-watcher/go.mod index e206aab77..cf36fac8e 100644 --- a/modules/mesh-watcher/go.mod +++ b/modules/mesh-watcher/go.mod @@ -5,6 +5,8 @@ go 1.26.0 require git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/go v0.0.0-20261104174344-ae5266e77639 // indirect github.com/klauspost/compress v1.20.1 // indirect github.com/nats-io/nats.go v1.54.0 // indirect diff --git a/modules/minio/cmd/object-store/main.go b/modules/minio/cmd/object-store/main.go index 9ec5152ec..b7349d98d 100644 --- a/modules/minio/cmd/object-store/main.go +++ b/modules/minio/cmd/object-store/main.go @@ -15,9 +15,10 @@ import ( "os" stdio "git.novox.be/novox/mesh-sdk/go" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "git.novox.be/novox/mesh-sdk/go/views" ) @@ -29,7 +30,7 @@ const ( ) func main() { - seats := &views.Reader{Module: "minio", Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}, Logf: func(f string, a ...any) { fmt.Fprintf(os.Stderr, "[object-store] "+f+"\n", a...) }} + seats := &views.Reader{Module: "minio", Findings: meshconditionsclient.FindingWriter{State: stdio.State("findings")}, Acts: meshhandactsclient.Recorder{Ask: stdio.Ask}, Logf: func(f string, a ...any) { fmt.Fprintf(os.Stderr, "[object-store] "+f+"\n", a...) }} seats.Follow(delivery.AssignerModule, delivery.SeatHoldersState, SeatHoldersTool) s, err := newServer(os.Getenv(ConfigWord), os.Getenv(LinksWord), os.Getenv(ReceivesWord), func() (map[string][]byte, error) { return seats.Values(delivery.SeatHoldersRead) }) diff --git a/modules/minio/go.mod b/modules/minio/go.mod index bb5cc5f00..3084aaef2 100644 --- a/modules/minio/go.mod +++ b/modules/minio/go.mod @@ -5,6 +5,8 @@ go 1.26.0 require git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/go v0.0.0-20261104174344-ae5266e77639 // indirect github.com/klauspost/compress v1.20.1 // indirect github.com/nats-io/nats.go v1.54.0 // indirect diff --git a/modules/nats/cmd/nats-tools/expiry.go b/modules/nats/cmd/nats-tools/expiry.go index 6c74ca4fa..ceebd5327 100644 --- a/modules/nats/cmd/nats-tools/expiry.go +++ b/modules/nats/cmd/nats-tools/expiry.go @@ -14,8 +14,8 @@ import ( "strings" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/handacts" "github.com/nats-io/nats.go/jetstream" ) @@ -25,11 +25,11 @@ const bucketExpirySet = "bucket-expiry-set" const kvPrefix = "KV_" // Recorded records one hand act through the seat mesh-hand-acts. -type Recorded func(handacts.Request) error +type Recorded func(meshhandactsclient.Request) error // RecordedBySeat records an act through the runtime, to the seat mesh-hand-acts alone. -func RecordedBySeat(q handacts.Request) error { - _, err := handacts.Recorder{Ask: stdio.Ask}.Record(q) +func RecordedBySeat(q meshhandactsclient.Request) error { + _, err := meshhandactsclient.Recorder{Ask: stdio.Ask}.Record(q) return err } @@ -136,7 +136,7 @@ func SetBucketExpiry(ctx context.Context, bus Bus, said Said, record Recorded, a if out.Warrant != "" { what += " (warrant " + out.Warrant + ")" } - if err := record(handacts.Request{What: what, Why: w, Cause: "bucket-expiry"}); err != nil { + if err := record(meshhandactsclient.Request{What: what, Why: w, Cause: "bucket-expiry"}); err != nil { return nil, fmt.Errorf("the expiry of %s WAS changed (%s) but the hand act could not be recorded: %w", bucket, what, err) } if err := said(bucketExpirySet, out); err != nil { diff --git a/modules/nats/cmd/nats-tools/expiry_test.go b/modules/nats/cmd/nats-tools/expiry_test.go index cc1c6529e..eb8db51eb 100644 --- a/modules/nats/cmd/nats-tools/expiry_test.go +++ b/modules/nats/cmd/nats-tools/expiry_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "git.novox.be/novox/mesh-sdk/go/handacts" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "github.com/nats-io/nats-server/v2/server" "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" @@ -55,9 +55,9 @@ func maxAge(t *testing.T, js jetstream.JetStream, stream string) time.Duration { // restored to 15 s it reads back with 15 s again; asking for what it already has records nothing. func TestABucketsExpiryIsSetAndRestoredAndRecorded(t *testing.T) { bus, js := expiryBus(t) - var acts []handacts.Request + var acts []meshhandactsclient.Request var events []string - record := func(q handacts.Request) error { acts = append(acts, q); return nil } + record := func(q meshhandactsclient.Request) error { acts = append(acts, q); return nil } said := func(e string, _ any) error { events = append(events, e); return nil } call := func(max string, extra map[string]any) (BucketExpirySet, error) { a := map[string]any{"bucket": "mesh-controller_lease", "max_age": max, "why": "the lease write", "warrant": "ask-1"} @@ -90,7 +90,7 @@ func TestABucketsExpiryIsSetAndRestoredAndRecorded(t *testing.T) { t.Errorf("restore: %+v %v", out, err) } // A hand act the seat does not take is said loudly, not as success. - _, err = SetBucketExpiry(context.Background(), bus, said, func(handacts.Request) error { return errors.New("no responders") }, map[string]any{"bucket": "mesh-controller_lease", "max_age": "none", "why": "x"}) + _, err = SetBucketExpiry(context.Background(), bus, said, func(meshhandactsclient.Request) error { return errors.New("no responders") }, map[string]any{"bucket": "mesh-controller_lease", "max_age": "none", "why": "x"}) if err == nil || !strings.Contains(err.Error(), "WAS changed") { t.Errorf("an unrecorded act was answered %v", err) } @@ -99,7 +99,7 @@ func TestABucketsExpiryIsSetAndRestoredAndRecorded(t *testing.T) { // 774/S6/AC2: no why, a stream that is no bucket, and a bad expiry change nothing and say why. func TestABucketExpiryRefusesWithoutWhyOrABucket(t *testing.T) { bus, js := expiryBus(t) - record := func(handacts.Request) error { t.Fatal("an act was recorded for a refused call"); return nil } + record := func(meshhandactsclient.Request) error { t.Fatal("an act was recorded for a refused call"); return nil } said := func(string, any) error { t.Fatal("an event was said for a refused call"); return nil } for _, c := range []struct { args map[string]any diff --git a/modules/nats/cmd/nats-tools/keep.go b/modules/nats/cmd/nats-tools/keep.go index ba950bbd9..a499a25be 100644 --- a/modules/nats/cmd/nats-tools/keep.go +++ b/modules/nats/cmd/nats-tools/keep.go @@ -17,12 +17,12 @@ import ( "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" + "git.novox.be/novox/mesh-contracts/go/seats/meshbroker" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/catalogue" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/process" "git.novox.be/novox/mesh-sdk/go/seatdef" @@ -154,7 +154,7 @@ func streamEmitter(js jetstream.JetStream, a process.Account) func(*keeper.Sayin // EventSubjects are where one event of the seat mesh-broker is said, in order: the seat's subject, then the bus module's // own stream. func EventSubjects(a process.Account, event string) []string { - return []string{seatdef.EventSubject(catalogue.BrokerSeat, event), a.StreamSubject(event)} + return []string{seatdef.EventSubject(meshbroker.Seat, event), a.StreamSubject(event)} } // sayer raises and clears the keeper's conditions through the condition keeper, as every module says them. @@ -229,12 +229,12 @@ func runKeeper(ctx context.Context, getenv func(string) string, logOut io.Writer return err } defer nc.Close() - recorder := handacts.Recorder{Ask: conn.Call} + recorder := meshhandactsclient.Recorder{Ask: conn.Call} k := &keeper.Keeper{ Bus: keeper.JetStream{JS: js, Snap: bussnap.Into(nc, getenv("MESH_NATS_SNAPSHOTS_DIR"))}, Store: processStore{conn}, Emit: streamEmitter(js, account), Say: sayer(js), View: firstView(conn), Act: func(what, why, cause string) error { - _, err := recorder.Record(handacts.Request{What: what, Why: why, Cause: cause}) + _, err := recorder.Record(meshhandactsclient.Request{What: what, Why: why, Cause: cause}) return err }, Warrant: WarrantFrom(conn.Ask), diff --git a/modules/nats/cmd/nats-tools/requests.go b/modules/nats/cmd/nats-tools/requests.go index 8a3963c62..78a85822b 100644 --- a/modules/nats/cmd/nats-tools/requests.go +++ b/modules/nats/cmd/nats-tools/requests.go @@ -11,10 +11,10 @@ import ( "sync" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/handacts" "nats-tools/internal/keeper" ) @@ -273,7 +273,7 @@ func requestsTool(rs requestStore) stdio.Tool { if !r.Done.IsZero() { return nil, fmt.Errorf("the request %s ended at %s (%s): only a request that waits is dropped", id, r.Done.Format(time.RFC3339), r.Outcome) } - if err := rs.Record(handacts.Request{What: fmt.Sprintf("dropped the waiting request %s (%s of %s's %s, ask %s)", id, r.Verb, r.Module, r.Local, r.Ask), + if err := rs.Record(meshhandactsclient.Request{What: fmt.Sprintf("dropped the waiting request %s (%s of %s's %s, ask %s)", id, r.Verb, r.Module, r.Local, r.Ask), Why: why, Cause: "nats_requests"}); err != nil { return nil, fmt.Errorf("the hand act cannot be recorded, so the request stays: %w", err) } diff --git a/modules/nats/cmd/nats-tools/requests_test.go b/modules/nats/cmd/nats-tools/requests_test.go index e4cc660a6..63148231e 100644 --- a/modules/nats/cmd/nats-tools/requests_test.go +++ b/modules/nats/cmd/nats-tools/requests_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/handacts" "nats-tools/internal/keeper" ) @@ -21,7 +21,7 @@ import ( func TestAPersonsRequestIsHandedToTheKeeperAsTheProvedCaller(t *testing.T) { held := map[string]keeper.Request{} var raised []oc.Ask - var acts []handacts.Request + var acts []meshhandactsclient.Request rs := requestStore{ Put: func(key string, r keeper.Request) error { if r.Verb == keeper.VerbCreate { @@ -51,7 +51,7 @@ func TestAPersonsRequestIsHandedToTheKeeperAsTheProvedCaller(t *testing.T) { }, Ask: func(a oc.Ask) error { raised = append(raised, a); return nil }, Now: func() time.Time { return time.Date(2026, 11, 4, 12, 0, 0, 0, time.UTC) }, - Record: func(q handacts.Request) error { acts = append(acts, q); return nil }, + Record: func(q meshhandactsclient.Request) error { acts = append(acts, q); return nil }, } tools := map[string]stdio.Tool{} for _, tl := range requestTools(rs) { diff --git a/modules/nats/go.mod b/modules/nats/go.mod index e2f23c6fb..951629f3f 100644 --- a/modules/nats/go.mod +++ b/modules/nats/go.mod @@ -3,6 +3,7 @@ module nats-tools go 1.26.0 require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/go/seats/meshbroker v0.0.0-20261104174344-ae5266e77639 diff --git a/modules/nfs-server/cmd/nfs-server/main.go b/modules/nfs-server/cmd/nfs-server/main.go index 7447fafd4..fe6934a90 100644 --- a/modules/nfs-server/cmd/nfs-server/main.go +++ b/modules/nfs-server/cmd/nfs-server/main.go @@ -20,9 +20,10 @@ import ( "syscall" "time" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" + "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-sdk/go/delivery" - "git.novox.be/novox/mesh-sdk/go/handacts" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/views" @@ -127,7 +128,7 @@ const SeatHoldersTool = delivery.AssignerModule + ".assigner_read_seat_holders" // seats is the picture of the placement seat's state of who holds which seat: asked of the assigner once and followed by // its events, never read from its state (ADR 0615). -var seats = &views.Reader{Module: "nfs-server", Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}, Logf: func(f string, a ...any) { fmt.Fprintf(os.Stderr, "nfs-server: "+f+"\n", a...) }} +var seats = &views.Reader{Module: "nfs-server", Findings: meshconditionsclient.FindingWriter{State: stdio.State("findings")}, Acts: meshhandactsclient.Recorder{Ask: stdio.Ask}, Logf: func(f string, a ...any) { fmt.Fprintf(os.Stderr, "nfs-server: "+f+"\n", a...) }} // seatHolderKeys is the placement seat's state of who holds which seat, every key. func seatHolderKeys() (map[string][]byte, error) { return seats.Values(delivery.SeatHoldersRead) } diff --git a/modules/nfs-server/go.mod b/modules/nfs-server/go.mod index 46da20a2e..00bb87ad0 100644 --- a/modules/nfs-server/go.mod +++ b/modules/nfs-server/go.mod @@ -5,6 +5,8 @@ go 1.26.0 require git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261104174359-05b3e2e1b94f require ( + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000 + git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-contracts/go v0.0.0-20261104174344-ae5266e77639 // indirect github.com/klauspost/compress v1.20.1 // indirect github.com/nats-io/nats.go v1.54.0 // indirect