diff --git a/modules/mesh-delivery-assigner/go.mod b/modules/mesh-delivery-assigner/go.mod index c0375b2..fc407f5 100644 --- a/modules/mesh-delivery-assigner/go.mod +++ b/modules/mesh-delivery-assigner/go.mod @@ -3,7 +3,7 @@ module mesh-delivery-assigner go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024142924-d6cef5829bb7 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024144045-64a502d16aac github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-delivery-assigner/go.sum b/modules/mesh-delivery-assigner/go.sum index d5a62aa..49041ec 100644 --- a/modules/mesh-delivery-assigner/go.sum +++ b/modules/mesh-delivery-assigner/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024142924-d6cef5829bb7 h1:tIzslR6sjUtCMlh1510t/D+dKXKqQUXp9dwTayhfJcs= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024142924-d6cef5829bb7/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024144045-64a502d16aac h1:jInLKz6gUCzs94z0egG7f05V7x+0t4BXt9cCa87ePLA= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024144045-64a502d16aac/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= diff --git a/modules/mesh-delivery-assigner/internal/assign/wants.go b/modules/mesh-delivery-assigner/internal/assign/wants.go index 6788ec9..0820d8c 100644 --- a/modules/mesh-delivery-assigner/internal/assign/wants.go +++ b/modules/mesh-delivery-assigner/internal/assign/wants.go @@ -267,7 +267,7 @@ func (m Module) mustAsk(node string, before delivery.Want, had bool, d delivery. if catalogue.ProvidesBus(m.Manifest) && before.FP != m.FP { return nil, true // the bus is never moved by the assigner; the operator writes its want (§15) } - if policy, _, _ := catalogue.DerivedUpgrade(m.Manifest); policy != catalogue.PolicyRecord || d.Judgement == delivery.JudgedNeither { + if !m.recorded(d) || d.Judgement == delivery.JudgedNeither { return nil, false } if m.Allowed != nil && m.Allowed(node, d.Digest) { @@ -275,3 +275,13 @@ func (m Module) mustAsk(node string, before delivery.Want, had bool, d delivery. } return &RecordNeed{Node: node, Digest: d.Digest, Judgement: d.Judgement, Words: d.Words}, true } + +// recorded says whether the module is of policy record: as the controller holds it beside the composition's digest, the +// operator's own choice included (ADR 0539 §14); on a composition made by hand, which carries none, as the manifest derives it. +func (m Module) recorded(d delivery.ComposedDigest) bool { + if d.Policy != "" { + return d.Policy == delivery.PolicyRecord + } + policy, _, _ := catalogue.DerivedUpgrade(m.Manifest) + return policy == catalogue.PolicyRecord +} diff --git a/modules/mesh-delivery-assigner/internal/assign/wants_test.go b/modules/mesh-delivery-assigner/internal/assign/wants_test.go index 4b7b303..a7a474d 100644 --- a/modules/mesh-delivery-assigner/internal/assign/wants_test.go +++ b/modules/mesh-delivery-assigner/internal/assign/wants_test.go @@ -368,3 +368,30 @@ func TestARestoreAnswerSetsADataModuleBack(t *testing.T) { t.Errorf("after restore ace's want = %+v", w) } } + +// 1906/D4 (ADR 0539 §14): the policy the controller holds beside the composition decides, the operator's own choice included; +// a composition with none (made by hand) falls back to what the manifest derives. +func TestTheRecordPolicyIsTheOneTheControllerHolds(t *testing.T) { + m, n, wanted := movingTo(delivery.JudgedMovesData) + with := func(policy, from string) { + inner := m.Composed + m.Composed = func(node, fp string) (delivery.ComposedDigest, bool) { + d, ok := inner(node, fp) + d.Policy, d.PolicyFrom = policy, from + return d, ok + } + } + with(delivery.PolicyRecord, "person") // a roll module the operator set to record + if out := Wants(m, n, wanted, nil); len(out.Record) == 0 || out.Wants["ace"].FP == fNew { + t.Errorf("the operator's record policy was not honoured: %+v", out) + } + recording(&m) // the manifest says record, the operator chose roll + with("roll", "person") + if out := Wants(m, n, wanted, nil); len(out.Record) != 0 || out.Wants["ace"].FP != fNew { + t.Errorf("the operator's roll policy was not honoured: %+v", out) + } + with("", "") // made by hand: the manifest decides + if out := Wants(m, n, wanted, nil); len(out.Record) == 0 { + t.Errorf("a hand-made composition fell through the manifest's record policy: %+v", out) + } +} diff --git a/modules/mesh-delivery-view/go.mod b/modules/mesh-delivery-view/go.mod index 9a48a6d..2434516 100644 --- a/modules/mesh-delivery-view/go.mod +++ b/modules/mesh-delivery-view/go.mod @@ -3,7 +3,7 @@ module mesh-delivery-view go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024142924-d6cef5829bb7 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024144045-64a502d16aac github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-delivery-view/go.sum b/modules/mesh-delivery-view/go.sum index d5a62aa..49041ec 100644 --- a/modules/mesh-delivery-view/go.sum +++ b/modules/mesh-delivery-view/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024142924-d6cef5829bb7 h1:tIzslR6sjUtCMlh1510t/D+dKXKqQUXp9dwTayhfJcs= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024142924-d6cef5829bb7/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024144045-64a502d16aac h1:jInLKz6gUCzs94z0egG7f05V7x+0t4BXt9cCa87ePLA= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024144045-64a502d16aac/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= diff --git a/modules/mesh-delivery-watchman/go.mod b/modules/mesh-delivery-watchman/go.mod index a344cf8..3a2fcdf 100644 --- a/modules/mesh-delivery-watchman/go.mod +++ b/modules/mesh-delivery-watchman/go.mod @@ -3,7 +3,7 @@ module mesh-delivery-watchman go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024142924-d6cef5829bb7 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024144045-64a502d16aac github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-delivery-watchman/go.sum b/modules/mesh-delivery-watchman/go.sum index 34cc0e9..82217fb 100644 --- a/modules/mesh-delivery-watchman/go.sum +++ b/modules/mesh-delivery-watchman/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024142924-d6cef5829bb7 h1:tIzslR6sjUtCMlh1510t/D+dKXKqQUXp9dwTayhfJcs= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024142924-d6cef5829bb7/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024144045-64a502d16aac h1:jInLKz6gUCzs94z0egG7f05V7x+0t4BXt9cCa87ePLA= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024144045-64a502d16aac/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.8.0-default-no-op h1:1BOWQJweNyvZMlpAHXGLiZQn9S+QXGcz3xh94lC0w6E= github.com/antithesishq/antithesis-sdk-go v0.8.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=