From e7415c1812be55c78c247faaebed3f2cff9ce6a3 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 9 Nov 2026 21:20:48 +0100 Subject: [PATCH] The judge refuses a catch-up tool the module does not declare (design 47) Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- modules/mesh-delivery-indexer/judge/busstate.go | 16 ++++++++++++++++ .../mesh-delivery-indexer/judge/busstate_test.go | 6 ++++++ modules/mesh-delivery-indexer/judge/rules.go | 2 ++ 3 files changed, 24 insertions(+) diff --git a/modules/mesh-delivery-indexer/judge/busstate.go b/modules/mesh-delivery-indexer/judge/busstate.go index 46598667..bd7c0cf6 100644 --- a/modules/mesh-delivery-indexer/judge/busstate.go +++ b/modules/mesh-delivery-indexer/judge/busstate.go @@ -171,6 +171,22 @@ func BusStateProblems(m catalogue.Manifest) []string { return problems } +// KeptFormProblems is what is wrong with the catch-up tool each kept data declares, in an old section or in `requires` by +// template (novox/hq design 47, *Its form is declared*): the tool a restore of it is followed by is one of the module's +// own tools, since the node agent calls it from the restore point and the delivery system names no module's tool. A form +// below 0 is refused by the reader. +func KeptFormProblems(m catalogue.Manifest) []string { + var problems []string + for _, k := range catalogue.KeptDeclarations(m) { + if k.CatchUp != "" && !slices.Contains(m.Tools, k.CatchUp) { + problems = append(problems, fmt.Sprintf("%s's kept %s %q: its catch-up tool %q is not among the module's tools (%s); a "+ + "restore of it is followed by a tool of the module's own (novox/hq design 47)", m.Module, k.Kind, k.Name, k.CatchUp, + orNoneWords(m.Tools))) + } + } + return problems +} + // busEntryProblems judges one entry's storage type, template, options and configuration. func busEntryProblems(at string, e catalogue.BusStateEntry, terminal []string) []string { var problems []string diff --git a/modules/mesh-delivery-indexer/judge/busstate_test.go b/modules/mesh-delivery-indexer/judge/busstate_test.go index bde31cfd..8f68a4b7 100644 --- a/modules/mesh-delivery-indexer/judge/busstate_test.go +++ b/modules/mesh-delivery-indexer/judge/busstate_test.go @@ -40,6 +40,12 @@ func TestBusStateIsJudgedOnce(t *testing.T) { `{"name":"blobs","storage":"object-store","template":"objects","options":{"max-mib":64},"form":4,"catch-up":"a_take_in"},` + `{"name":"records","storage":"ledger","template":"ledger","options":{"max-mib":512},"form":3,"catch-up":"a_take_in","types":[` + `{"name":"decision","schema":{"title":{"type":"text"}},"operations":[{"name":"propose","effect":"set-fields","fields":["title"]}]}]}]}`, nil}, + {"a catch-up tool the module lacks", `{"module":"a","version":"1","tools":["a_read"],"logs":[{"name":"acts","form":1,"catch-up":"a_take_in"}]}`, + []string{"a's kept log \"acts\"", "catch-up tool \"a_take_in\" is not among the module's tools (a_read)"}}, + {"a catch-up tool the module lacks, in requires", `{"module":"a","version":"1","tools":["a_read"],"requires":[` + + `{"name":"holds","storage":"key-value","template":"state","form":1,"catch-up":"nonexistent"}]}`, + []string{"a's kept state \"holds\"", "catch-up tool \"nonexistent\""}}, + {"a form below 0", manifest(`{"name":"x","storage":"key-value","template":"state","form":-1}`), []string{"requires entry \"x\"", "its form is -1"}}, // 1966/AC7: each refused case, naming the module, the entry and the field {"unknown storage type", manifest(`{"name":"x","storage":"tape"}`), []string{"a's bus state \"x\"", "storage type \"tape\""}}, {"unknown template", manifest(`{"name":"x","storage":"stream","template":"pile"}`), []string{"\"x\"", "template \"pile\""}}, diff --git a/modules/mesh-delivery-indexer/judge/rules.go b/modules/mesh-delivery-indexer/judge/rules.go index dfd42f6d..b2e091a9 100644 --- a/modules/mesh-delivery-indexer/judge/rules.go +++ b/modules/mesh-delivery-indexer/judge/rules.go @@ -2760,6 +2760,8 @@ func parseManifest(raw []byte, predefined catalogue.PredefinedList) (catalogue.M problems = append(problems, WorkQueueStreamProblems(m)...) // And the bus state it asks for in `requires`, by template (busstate.go, novox/hq ADR 0595; issue 1966 D1). problems = append(problems, BusStateProblems(m)...) + // And the catch-up tool each kept data names (busstate.go, novox/hq design 47). + problems = append(problems, KeptFormProblems(m)...) // And the defaults it gives its settings (setting_defaults.go, novox/hq ADR 0262), or, written in the // config form, the whole declaration of each value (config.go, novox/hq ADR 0348). if m.DeclaresConfig() {