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
+16 -2
View File
@@ -35,6 +35,12 @@ const GrantKey = "{key}"
// is the mesh's own limits retention — kept until it ages or the stream fills, dropping its oldest.
const StreamRetentionWorkQueue = "work-queue"
// StreamRetentionHistory is a stream's declared retention that keeps its history (novox/hq ADR 0592 §6): every message
// is kept with no maximum age, and when the stream reaches its maximum size the bus refuses a new message rather than
// dropping its oldest. It takes no max-age-days, max-deliveries or duplicates; the mesh raises a condition when it
// passes FullWarnPercent of its cap.
const StreamRetentionHistory = "history"
// StreamLeastDeliveries and StreamMostDeliveries bound a work-queue stream's max-deliveries (novox/hq ADR
// 0436 §6): how many times a message is handed over before it is given up as a dead letter.
const (
@@ -57,7 +63,8 @@ type StreamDeclaration struct {
// Grant restricts it, when said.
Grant *StreamGrant `json:"grant,omitempty"`
// Retention is how the stream decides what to keep when it fills (novox/hq ADR 0436 §6): empty for the
// mesh's own limits retention (dropping its oldest), or StreamRetentionWorkQueue.
// mesh's own limits retention (dropping its oldest), StreamRetentionWorkQueue, or StreamRetentionHistory
// (novox/hq ADR 0592 §6).
Retention string `json:"retention,omitempty"`
// MaxDeliveries bounds how many times a work-queue message is handed over, 1 to 10; refused without
// retention work-queue (novox/hq ADR 0436 §6).
@@ -104,14 +111,21 @@ func (g *StreamGrant) UnmarshalJSON(raw []byte) error {
return nil
}
// Days is the stream's age in days, the default where none is said.
// Days is the stream's age in days, the default where none is said, and 0 (no maximum age) for a stream that keeps its
// history.
func (s StreamDeclaration) Days() int {
if s.KeepsHistory() {
return 0
}
if s.MaxAgeDays == 0 {
return StreamDefaultDays
}
return s.MaxAgeDays
}
// KeepsHistory says the stream keeps every message and refuses a new one when full (StreamRetentionHistory).
func (s StreamDeclaration) KeepsHistory() bool { return s.Retention == StreamRetentionHistory }
// Cap is the stream's size in MiB, the default where none is said.
func (s StreamDeclaration) Cap() int {
if s.MaxMiB == 0 {