From 361861e1a5f4883c6451088ed303444814e7f152 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 20:28:08 +0100 Subject: [PATCH] G B-2: a binding names its state's objects store, and a membership its old objects sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Builds: design 47 G §642, §399, §513, §619 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- go/membership/membership.go | 6 ++++++ go/membership/membership_test.go | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/go/membership/membership.go b/go/membership/membership.go index a38d94d4..8edb700d 100644 --- a/go/membership/membership.go +++ b/go/membership/membership.go @@ -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 `-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 diff --git a/go/membership/membership_test.go b/go/membership/membership_test.go index f252687c..4adf508c 100644 --- a/go/membership/membership_test.go +++ b/go/membership/membership_test.go @@ -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}]}` {