Eleven modules record hand acts through the hand-acts client, the finding writers are the conditions client's, nats takes the broker seat's name from its package (K-21 part, K-4..K-20 part; ADR 0634 §4, ADR 0635 §4; issue 1966)

This commit is contained in:
2026-11-05 14:21:57 +01:00
parent 2f7ff1c911
commit 87388b9046
44 changed files with 140 additions and 95 deletions
@@ -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:<seat>.<verb>` (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)
}
@@ -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)
@@ -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
@@ -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.
@@ -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 {
+3
View File
@@ -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
+2 -1
View File
@@ -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 {
+1
View File
@@ -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
@@ -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
}
+1
View File
@@ -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
@@ -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)
}
@@ -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)
+3 -3
View File
@@ -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
}
+1
View File
@@ -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
@@ -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)
@@ -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)
}
@@ -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 {
+1
View File
@@ -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
@@ -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 {
@@ -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()
@@ -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)) {
+2
View File
@@ -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
)
@@ -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 {
+5 -8
View File
@@ -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)
@@ -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
}
@@ -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 }
+1
View File
@@ -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
@@ -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")
@@ -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)
+2
View File
@@ -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
@@ -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)
+2
View File
@@ -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
)
@@ -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 {
+2
View File
@@ -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
+3 -2
View File
@@ -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) })
+2
View File
@@ -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
+5 -5
View File
@@ -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 {
+5 -5
View File
@@ -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
+5 -5
View File
@@ -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),
+2 -2
View File
@@ -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)
}
+3 -3
View File
@@ -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) {
+1
View File
@@ -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
+3 -2
View File
@@ -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) }
+2
View File
@@ -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