catalogue: a module's own object bucket, its reader grant and a stream that keeps its history, so the knowledge base can keep its records on the bus (ADR 0592 §5, §6, §9)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 18:17:14 +01:00
parent 3d87ddcc9a
commit 04d951d9da
4 changed files with 180 additions and 2 deletions
+104
View File
@@ -0,0 +1,104 @@
package catalogue
import (
"bytes"
"encoding/json"
"fmt"
)
// A module's own object bucket (novox/hq ADR 0592 §5, §9).
//
// A module declares an object bucket as it declares a state (ADR 0201) or a stream (ADR 0363): named locally,
// with its maximum size. The mesh creates it once, keeps every object with no age limit, and refuses a new object
// when it is full rather than dropping one; only its module writes it. Another module reads it only as a restricted
// stream is heard: a `reads` entry `<module>.<name>` naming it, and a module the owner's trusted config value of the
// bucket's grant names (ADR 0363 §4, §5), read-only. This is the shape only: its checks are the indexer's judge's.
// The mesh's bounds on a module's object bucket: its size in MiB (ADR 0592 §5, §25; the bound ADR 0363 §1 sets for a
// stream). A bucket says its size: there is no default.
const (
ObjectsLeastMiB = 1
ObjectsMostMiB = 8192
)
// FullWarnPercent is how full, in percent of its cap, a history stream or an object bucket is when the mesh raises its
// condition, in one place for every module (novox/hq ADR 0592 §6, §25).
const FullWarnPercent = 75
// ObjectsDeclaration is one object bucket a module owns.
type ObjectsDeclaration struct {
// Name is its local name, one plain name as a state's (lower-case letters, digits and hyphens).
Name string `json:"name"`
// MaxMiB bounds it, ObjectsLeastMiB to ObjectsMostMiB.
MaxMiB int `json:"max-mib"`
// Grant names the trusted config value of the module whose entries name the modules that may read it; absent,
// no other module reads it.
Grant *ObjectsGrant `json:"grant,omitempty"`
}
// ObjectsGrant says which trusted config value of the owning module grants another module the read of a bucket
// (novox/hq ADR 0592 §9): the value has a stream grant's shape (GrantedKeys), and a module any of its keys names, wherever
// it runs or as `<machine>.<module>`, reads the whole bucket, read-only. One value may grant a module's streams and its
// object buckets alike.
type ObjectsGrant struct {
// Config is the trusted config value of the module that grants it (ADR 0348 §8): set only at the controller's
// terminal or on the operator's Approve.
Config string `json:"config"`
}
// UnmarshalJSON reads an object bucket strictly: an unknown key is refused here, not passed over.
func (o *ObjectsDeclaration) UnmarshalJSON(raw []byte) error {
type plain ObjectsDeclaration
var p plain
dec := json.NewDecoder(bytes.NewReader(raw))
dec.DisallowUnknownFields()
if err := dec.Decode(&p); err != nil {
return fmt.Errorf("an object bucket is {name, max-mib, grant}: %w", typedUnknown(err))
}
*o = ObjectsDeclaration(p)
return nil
}
// UnmarshalJSON reads an object bucket's grant strictly.
func (g *ObjectsGrant) UnmarshalJSON(raw []byte) error {
type plain ObjectsGrant
var p plain
dec := json.NewDecoder(bytes.NewReader(raw))
dec.DisallowUnknownFields()
if err := dec.Decode(&p); err != nil {
return fmt.Errorf("an object bucket's grant is {config}: %w", typedUnknown(err))
}
*g = ObjectsGrant(p)
return nil
}
// ObjectsBucket is the bucket's name on the bus, as a state's is: the module and the local name joined by an
// underscore, which neither may hold, so two modules never derive one bucket.
func ObjectsBucket(module, local string) string { return module + "_" + local }
// Bucket is this bucket's name on the bus for its module.
func (o ObjectsDeclaration) Bucket(module string) string { return ObjectsBucket(module, o.Name) }
// ObjectsNamed is the module's object bucket of the local name, and whether it declares one.
func (m Manifest) ObjectsNamed(local string) (ObjectsDeclaration, bool) {
for _, o := range m.Objects {
if o.Name == local {
return o, true
}
}
return ObjectsDeclaration{}, false
}
// ObjectsReader says whether the restricting config values of a bucket's grant let module, on machine, read it
// (novox/hq ADR 0592 §9): a bucket with no grant is read by its owner alone, and a value of another shape grants nothing.
func (o ObjectsDeclaration) ObjectsReader(values []any, module, machine string) bool {
if o.Grant == nil {
return false
}
for _, v := range values {
if len(GrantedKeys(v, module, machine)) > 0 {
return true
}
}
return false
}