A have carries the values a self-composing node's running composition holds sealed to its key, so its composer reuses them after a restart (review of L2, round 2; issue 1126, ADR 0547 §3)
mesh/delivery closed: a newer head of the same pull request
mesh/check failed (4 tests): unit: go.go vet: # git.novox.be/novox/mesh-sdk/go/delivery [git.novox.be/novox/mesh-sdk/go/delivery.test] | 2c0ab3a59288 …

This commit is contained in:
2026-10-26 20:19:54 +01:00
parent 3968849b1b
commit 2c0ab3a592
2 changed files with 23 additions and 1 deletions
+12 -1
View File
@@ -48,7 +48,9 @@ import (
"encoding/json"
"errors"
"fmt"
"reflect"
"regexp"
"slices"
"strings"
"time"
)
@@ -348,6 +350,11 @@ type Have struct {
// composition that waits for a person's yes (ADR 0547 §3); empty otherwise.
Judgement Judgement `json:"judgement,omitempty"`
Waits string `json:"waits,omitempty"`
// Sealed is, for a module the node composes itself, each value its running composition carries sealed to the node's
// key (a secret, a credential, a vault box), as applied (ADR 0547 §3, issue 1126): what the node's composer reuses
// after a restart while it opens to the vault's value, so a value sealed again moves no composition. Openable by the
// node alone, as the vault hands them over the bus. Empty on every other have.
Sealed []string `json:"sealed,omitempty"`
}
// UserListWritten is the bus's user list as the node-engine of the bus node wrote it to the bus module's file, applied
@@ -533,7 +540,11 @@ func DecodePulse(data []byte) (Pulse, error) {
func SameHave(a, b Have) bool {
ua, ub := a.UserList, b.UserList
a.UserList, b.UserList = nil, nil
if a != b || (ua == nil) != (ub == nil) {
if !slices.Equal(a.Sealed, b.Sealed) {
return false
}
a.Sealed, b.Sealed = nil, nil
if !reflect.DeepEqual(a, b) || (ua == nil) != (ub == nil) {
return false
}
if ua == nil {
+11
View File
@@ -421,6 +421,17 @@ func TestSame(t *testing.T) {
if SameHave(a, b) {
t.Error("different haves same")
}
// The sealed values a self-composing node runs are part of its have (issue 1126).
sa, sb := a, a
sa.Sealed, sb.Sealed = []string{`{"box":1}`}, []string{`{"box":1}`}
if !SameHave(sa, sb) || SameHave(sa, a) {
t.Error("equal sealed values differ, or one said and one not are the same")
}
if raw, err := EncodeHave(sa); err != nil {
t.Error(err)
} else if back, err := DecodeHave(raw); err != nil || !SameHave(back, sa) {
t.Errorf("sealed values do not travel: %+v, %v", back, err)
}
// The user list is compared by what it says, never by where it is held (ADR 0547 §8).
at := time.Date(2026, 10, 25, 21, 0, 0, 0, time.UTC)
ua, ub := a, a