G B-2: a binding names its state's objects store, and a membership its old objects sections

Builds: design 47 G §642, §399, §513, §619

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 20:28:08 +01:00
parent 88ed16eec8
commit 361861e1a5
2 changed files with 18 additions and 0 deletions
+6
View File
@@ -50,6 +50,9 @@ type Membership struct {
Mesh []string `json:"mesh,omitempty"`
// State is every bucket this module's code may reach, and whether it may write it (novox/hq ADR 0201).
State []StateIssued `json:"state,omitempty"`
// Objects maps the name of each old `objects` section of a foundation part to its object store, as State maps its
// buckets (design 47 G §619).
Objects map[string]string `json:"objects,omitempty"`
// Logs is every log this module's code may reach (novox/hq ADR 0297).
Logs []LogIssued `json:"logs,omitempty"`
// SeatTraffic is what this module's code may submit, say, hear, take, ask, answer and read on seats
@@ -79,6 +82,9 @@ type BusBinding struct {
Subject string `json:"subject,omitempty"`
// Bucket is a key-value bucket's name.
Bucket string `json:"bucket,omitempty"`
// Objects is the bus name of a state's `<state>-objects` store (design 47 G §399, §642); the module's sent store is a
// binding entry of its own, the local name `sent-objects`, its ObjectStore.
Objects string `json:"objects,omitempty"`
// ObjectStore is an object store's name.
ObjectStore string `json:"object-store,omitempty"`
// Ledger, for the storage type ledger: its history stream (one subject per instance), its state bucket, each
+12
View File
@@ -3,6 +3,7 @@ package membership
import (
"encoding/json"
"reflect"
"strings"
"testing"
"git.novox.be/novox/mesh-sdk/go/catalogue"
@@ -54,6 +55,17 @@ func TestAMembershipRoundTripsAsIssued(t *testing.T) {
if err := json.Unmarshal(boundRaw, &boundBack); err != nil || !reflect.DeepEqual(bound, boundBack) {
t.Fatalf("a membership with a ledger binding read back as %+v (%v)", boundBack, err)
}
// Design 47 G §642, §619: a state's binding carries its objects store, the sent store is an entry of its own, and a
// foundation part's old `objects` sections map to their stores.
withObjects := in
withObjects.Objects = map[string]string{"blobs": "forge_blobs"}
withObjects.Bindings = []BusBinding{{Local: "repos", Storage: catalogue.StorageKeyValue, Template: catalogue.TemplateState, Bucket: "forge_repos", Objects: "forge_repos-objects"},
{Local: "sent-objects", Storage: catalogue.StorageObjectStore, ObjectStore: "forge_sent"}}
objRaw, _ := json.Marshal(withObjects)
var objBack Membership
if err := json.Unmarshal(objRaw, &objBack); err != nil || !reflect.DeepEqual(withObjects, objBack) || !strings.Contains(string(objRaw), `"objects":"forge_repos-objects"`) {
t.Fatalf("a membership with objects read back as %+v (%v)", objBack, err)
}
before, _ := json.Marshal(Membership{Node: "ace", Module: "forge", Tools: "t", Emits: "e", Serves: []Served{{Subject: "s"}},
State: []StateIssued{{Name: "repos", Bucket: "forge_repos", Writes: true}}})
if string(before) != `{"node":"ace","module":"forge","serves":[{"subject":"s"}],"emits":"e","tools":"t","state":[{"name":"repos","bucket":"forge_repos","writes":true}]}` {