The record policy is the one the controller holds beside the composition, the operator's own choice included; pin mesh-sdk 64a502d (issue 1906 D4, ADR 0539 §14)

This commit is contained in:
2026-10-24 16:41:58 +02:00
parent f947070b7b
commit e7a3ff1e7e
8 changed files with 47 additions and 10 deletions
@@ -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
}
@@ -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)
}
}