Issue a key-value entry asked in requires as a state, by its local name
mesh/delivery merged: source.main moved to novox/mesh-tools@2ea4f019e594
mesh/delivery-group group fix/1966-requires-state merged: every member is merged
mesh/check checking 8052fd14f4fd on 2ea4f019e594 | novox/mesh-tools#66 in group fix/1966-requires-state

A bundle's state call on a key-value entry its module asks for in requires
(ADR 0595 §1) was refused "keeps and reads no state called", because the
tool runner read the old state list alone (issue 1966). It now reads mesh-sdk's
one rule, membership.StateIssued.

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-09 12:39:04 +01:00
parent 9f61975c50
commit 8052fd14f4
2 changed files with 34 additions and 10 deletions
+11 -9
View File
@@ -11,6 +11,7 @@ import (
"sync"
"time"
"git.novox.be/novox/mesh-sdk/go/membership"
"git.novox.be/novox/mesh-sdk/go/pernode"
"github.com/nats-io/nats.go/jetstream"
)
@@ -71,21 +72,22 @@ func (c *Conn) issuedState(module, name string) (StateIssued, error) {
return StateIssued{}, fmt.Errorf("%s has no membership issued on %s yet, so no state of it is reachable "+
"until the mesh issues one (novox/hq ADR 0201)", module, c.node)
}
var names []string
// What a membership issues by a local name is mesh-sdk's one rule (membership.StateIssued, issue 1966): the old
// `state` list, then a key-value entry the module asks for in `requires` (ADR 0595 §1), by its local name.
issuing := membership.Membership{Bindings: m.Bindings}
for _, s := range m.State {
if s.Name == name {
return s, nil
}
names = append(names, s.Name)
issuing.State = append(issuing.State, membership.StateIssued{Name: s.Name, Bucket: s.Bucket, Writes: s.Writes, PerNode: s.PerNode})
}
if s, ok := issuing.StateIssued(name); ok {
return StateIssued{Name: s.Name, Bucket: s.Bucket, Writes: s.Writes, PerNode: s.PerNode}, nil
}
sort.Strings(names)
issued := "none"
if len(names) > 0 {
if names := issuing.StateNames(); len(names) > 0 {
issued = strings.Join(names, ", ")
}
return StateIssued{}, fmt.Errorf("%s keeps and reads no state called %q: it declares what it keeps under "+
"`state` and what it reads under `reads` as <module>.<name>, and was issued: %s (novox/hq ADR 0201)",
module, name, issued)
"`state` or as a key-value entry in `requires`, and what it reads under `reads` as <module>.<name>, and was "+
"issued: %s (novox/hq ADR 0201, ADR 0595 §1)", module, name, issued)
}
func (c *Conn) bucket(ctx context.Context, s StateIssued) (jetstream.KeyValue, error) {