Assigner and grants part: record hand acts and warrants through the seat mesh-hand-acts, the controller's log only while that seat has no holder and the controller holds its lease (issue 1953 D8)
Pins mesh-sdk 2d2aa7b in the L5 modules.
This commit is contained in:
@@ -3,7 +3,7 @@ module mesh-grants
|
||||
go 1.26.0
|
||||
|
||||
require (
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261029211750-2e5cc4f16635
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261029212112-2d2aa7ba9bbd
|
||||
github.com/nats-io/nats.go v1.54.0
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261029211750-2e5cc4f16635 h1:ImOyj4WqH9lwxOr95aH9Wq2iJkUwdtnEyPrASm9TrYA=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261029211750-2e5cc4f16635/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261029212112-2d2aa7ba9bbd h1:WhqMEXFZ9Zc+fEfLsnf1jhhGkc4IqMwUpXXwZq+V3+E=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261029212112-2d2aa7ba9bbd/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
||||
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||
|
||||
@@ -1388,9 +1388,14 @@ func TestGrants(t *testing.T) {
|
||||
row.between()
|
||||
}
|
||||
said = nil
|
||||
calls := len(b.calls)
|
||||
if err := p.Warranted(row.option, warrant(id)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// 1953/D8 (ADR 0565 §11): a switch made is recorded in the hand-act log's seat; one refused or declined is not.
|
||||
if recorded := slices.Contains(b.calls[calls:], grants.CallRecordWarrant); recorded != (row.outcome == "recorded") {
|
||||
t.Errorf("recorded in the hand-act log %v, the act %s", recorded, row.outcome)
|
||||
}
|
||||
l := last()
|
||||
if l.Said != row.outcome || l.Ask != id || p.SwitchState() != row.state {
|
||||
t.Errorf("the act = %+v, the switch %s; want %s and %s", l, p.SwitchState(), row.outcome, row.state)
|
||||
@@ -1642,8 +1647,8 @@ func TestGrants(t *testing.T) {
|
||||
}
|
||||
}
|
||||
for _, c := range b.calls {
|
||||
if c != grants.CallUsers && c != grants.CallStreams {
|
||||
t.Errorf("called %s: the part calls only the bus module's read tools", c)
|
||||
if c != grants.CallUsers && c != grants.CallStreams && c != grants.CallRecordWarrant {
|
||||
t.Errorf("called %s: the part calls only the bus module's read tools, and the hand-act log for a switch", c)
|
||||
}
|
||||
}
|
||||
for _, e := range b.events {
|
||||
|
||||
@@ -52,7 +52,7 @@ const (
|
||||
)
|
||||
|
||||
// Invokes is every tool the part calls.
|
||||
var Invokes = []string{CallUsers, CallUserCan, CallStreams, CallRootFree}
|
||||
var Invokes = []string{CallUsers, CallUserCan, CallStreams, CallRootFree, CallRecordWarrant, CallRecordWarrantController}
|
||||
|
||||
// Reader reads another part's state, named `<module>.<state>`. A refusal (a read not granted yet, a bucket not there) is
|
||||
// an error the part names as a gap and composes past: it never stops for one.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package grants
|
||||
|
||||
import (
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
@@ -378,6 +380,7 @@ func (p *Part) Warranted(o asks.Option, w asks.Warrant) error {
|
||||
if err := p.finish(s, a); err != nil {
|
||||
return err
|
||||
}
|
||||
p.recordWarrant(w.Ask)
|
||||
// The bus node turns on the key: written now, so the switch reaches it on the operator's yes (ADR 0547 clause 8).
|
||||
if err := p.syncFollow(s.State); err != nil {
|
||||
return fmt.Errorf("the switch is recorded and the key the bus node follows could not be written (the next pass writes it): %w", err)
|
||||
@@ -512,3 +515,37 @@ func (p *Part) TakeOverState() (any, error) {
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Module is the grants part's module, the asker of its take-over and hand-back.
|
||||
const Module = "mesh-grants"
|
||||
|
||||
// The hand-act log's verbs the part records its switches by (novox/hq ADR 0565 §11, ADR 0547 §6): the seat's, and the
|
||||
// controller's while the seat has no holder and the controller holds its lease (handacts.Recorder).
|
||||
const (
|
||||
CallRecordWarrant = "seat:" + handacts.Seat + ".warranted"
|
||||
CallRecordWarrantController = "seat:mesh-controller.warranted"
|
||||
)
|
||||
|
||||
// recordWarrant records, in the hand-act log, that a take-over or a hand-back was made on the operator's warrant for ask.
|
||||
// Said, never fatal: the switch stands either way.
|
||||
func (p *Part) recordWarrant(ask string) {
|
||||
if p.Call == nil {
|
||||
return
|
||||
}
|
||||
rec := handacts.Recorder{Ask: p.Call.Call, LeaseAway: func() bool {
|
||||
if p.Read == nil {
|
||||
return false
|
||||
}
|
||||
away, _ := leaseHandedAway(p.Read)
|
||||
return away
|
||||
}}
|
||||
taken, err := rec.RecordWarrant(Module, ask)
|
||||
if p.Logf == nil {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
p.Logf("the switch on the warrant %s is not recorded in the hand-act log: %v", ask, err)
|
||||
return
|
||||
}
|
||||
p.Logf("the switch on the warrant %s is recorded in the log of %s", ask, taken.Log)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@
|
||||
"nats.nats_streams",
|
||||
"nats.nats_user_can",
|
||||
"nats.nats_users",
|
||||
"seat:mesh-controller.root-free"
|
||||
"seat:mesh-controller.root-free",
|
||||
"seat:mesh-hand-acts.warranted",
|
||||
"seat:mesh-controller.warranted"
|
||||
],
|
||||
"emits": [
|
||||
"asserted",
|
||||
|
||||
Reference in New Issue
Block a user