From 70ff0f84af948ec503895e4776e416b650d34e30 Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 4 Oct 2026 03:44:51 +0200 Subject: [PATCH] Module state is hq ADR 0202: 0201 landed first for a provider's derivations --- node-tools/internal/bus/bus.go | 2 +- node-tools/internal/bus/state.go | 16 ++++++++-------- node-tools/internal/bus/state_test.go | 2 +- node-tools/internal/launch/launch.go | 6 +++--- node-tools/internal/meshtest/meshtest.go | 2 +- node-tools/internal/runtime/runtime.go | 6 +++--- node-tools/internal/runtime/state_test.go | 4 ++-- node-tools/test/fixtures/state-keeper.mjs | 2 +- node-tools/test/fixtures/state-sdk.mjs | 2 +- 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/node-tools/internal/bus/bus.go b/node-tools/internal/bus/bus.go index 5854cdd..c8ad491 100644 --- a/node-tools/internal/bus/bus.go +++ b/node-tools/internal/bus/bus.go @@ -60,7 +60,7 @@ type Membership struct { Emits string `json:"emits"` Reaches map[string][]string `json:"reaches,omitempty"` Tools string `json:"tools"` - // State is every bucket the module's code may reach, by the name it uses (novox/hq ADR 0201). + // State is every bucket the module's code may reach, by the name it uses (novox/hq ADR 0202). State []StateIssued `json:"state,omitempty"` } diff --git a/node-tools/internal/bus/state.go b/node-tools/internal/bus/state.go index deb39a9..8a9c0a5 100644 --- a/node-tools/internal/bus/state.go +++ b/node-tools/internal/bus/state.go @@ -14,7 +14,7 @@ import ( "github.com/nats-io/nats.go/jetstream" ) -// A module's state on the bus (novox/hq ADR 0201): key-value buckets the controller creates from what +// A module's state on the bus (novox/hq ADR 0202): key-value buckets the controller creates from what // the module declared, and issues to each assignment in its membership by the name the module uses — // its own state by the local name, another module's as `.`. // @@ -23,7 +23,7 @@ import ( // timeout, not a refusal (measured, novox/hq research 024). So what a module may reach is decided here, // from its membership, and refused with the reason before anything is sent. -// StateIssued is one bucket an assignment may reach (ADR 0201). +// StateIssued is one bucket an assignment may reach (ADR 0202). type StateIssued struct { Name string `json:"name"` Bucket string `json:"bucket"` @@ -61,7 +61,7 @@ func (c *Conn) issuedState(module, name string) (StateIssued, error) { m := c.Membership(module) if m == nil { return StateIssued{}, fmt.Errorf("%s has no membership issued on %s yet, so no state of it is reachable "+ - "until the mesh issues one (novox/hq ADR 0201)", module, c.node) + "until the mesh issues one (novox/hq ADR 0202)", module, c.node) } var names []string for _, s := range m.State { @@ -76,7 +76,7 @@ func (c *Conn) issuedState(module, name string) (StateIssued, error) { issued = strings.Join(names, ", ") } return StateIssued{}, fmt.Errorf("%s keeps and reads no state called %q: it declares what it keeps under "+ - "`state` and what it reads under `reads` as ., and was issued: %s (novox/hq ADR 0201)", + "`state` and what it reads under `reads` as ., and was issued: %s (novox/hq ADR 0202)", module, name, issued) } @@ -144,7 +144,7 @@ func (c *Conn) StatePut(module, name, key string, value json.RawMessage) (uint64 if field := credentialField(value); field != "" { return 0, fmt.Errorf("%s's %s.%s carries a field %q, which names a credential: no secret is kept in state, "+ "sealed or not — a bucket is a stream, and a machine joining a year later reads it whole. Name the "+ - "secret and fetch it on request/reply (novox/hq ADR 0201, design 32 §10)", module, name, key, field) + "secret and fetch it on request/reply (novox/hq ADR 0202, design 32 §10)", module, name, key, field) } ctx, cancel := context.WithTimeout(context.Background(), StateTimeout) defer cancel() @@ -209,14 +209,14 @@ func (c *Conn) writable(module, name string) (StateIssued, error) { if dot := strings.LastIndex(name, "."); dot > 0 { owner = name[:dot] } - return s, fmt.Errorf("%s reads %s and does not keep it: only %s's own instances write it (novox/hq ADR 0201)", + return s, fmt.Errorf("%s reads %s and does not keep it: only %s's own instances write it (novox/hq ADR 0202)", module, name, owner) } return s, nil } // StateWatch hands deliver the current value of every key matching the pattern — none that is -// deleted — and then every change, in order (ADR 0201). It returns once the current values are +// deleted — and then every change, in order (ADR 0202). It returns once the current values are // delivered; deliver is called from one goroutine, one change at a time, and an error from it is said // and the watch goes on: state is not a queue, and the next change, or the next start, reads it again. // The pattern is a key, with `*` for one name and `**` for the rest; empty is every key. @@ -314,7 +314,7 @@ func valueOf(raw []byte) json.RawMessage { // credentialEndings are the ends of a field name that say its value is a credential. A guard against // the ordinary mistake, not a determined one: a sealed value is plain text to anything inspecting it, -// so the rule is checked where it can be and said to be partial (ADR 0201). +// so the rule is checked where it can be and said to be partial (ADR 0202). var credentialEndings = []string{"password", "passwd", "secret", "token", "credential", "credentials", "authorization", "apikey", "privatekey", "accesskey", "cookie"} diff --git a/node-tools/internal/bus/state_test.go b/node-tools/internal/bus/state_test.go index 9f191c4..3e5b850 100644 --- a/node-tools/internal/bus/state_test.go +++ b/node-tools/internal/bus/state_test.go @@ -5,7 +5,7 @@ import ( "testing" ) -// A value naming a credential anywhere in it is found (novox/hq ADR 0201) — the guard against the +// A value naming a credential anywhere in it is found (novox/hq ADR 0202) — the guard against the // ordinary mistake — and a value that only mentions tokens as a count is not. func TestACredentialNamedFieldIsFoundAnywhereInAValue(t *testing.T) { for value, want := range map[string]string{ diff --git a/node-tools/internal/launch/launch.go b/node-tools/internal/launch/launch.go index 9b626ab..af03bb2 100644 --- a/node-tools/internal/launch/launch.go +++ b/node-tools/internal/launch/launch.go @@ -51,7 +51,7 @@ type Registration struct { // code subscribes; the runtime binds the module's consumer once and calls deliver for every event, // acknowledging it on the bus when deliver returns nil. // -// State and Watch reach the module's state (novox/hq ADR 0201): State answers `get`, `put`, `delete` +// State and Watch reach the module's state (novox/hq ADR 0202): State answers `get`, `put`, `delete` // and `keys`; Watch hands deliver the current values and then every change, and returns once the // current values are delivered — the watch is the child's, and stops when the child does. type Bus interface { @@ -110,7 +110,7 @@ type child struct { next int64 dead chan struct{} why error - // watches are the state watches this child asked for, stopped when it exits (ADR 0201): a child + // watches are the state watches this child asked for, stopped when it exits (ADR 0202): a child // that starts again watches again, as its code runs again. watches []func() } @@ -234,7 +234,7 @@ func Start(module, entry string, env []string, mesh Bus, logf func(string, ...an // Each change is asked of this child, in order, naming the watch it is for by // the id the child asked it with — two watches of one state are two handlers; // the watch is answered once the current values have been handed over, so a - // bundle that awaits it has the whole of the state before it goes on (ADR 0201). + // bundle that awaits it has the whole of the state before it goes on (ADR 0202). var stop func() watch := m.ID stop, err = mesh.Watch(m.Params, func(change json.RawMessage) error { diff --git a/node-tools/internal/meshtest/meshtest.go b/node-tools/internal/meshtest/meshtest.go index f5bc1bf..41fbf29 100644 --- a/node-tools/internal/meshtest/meshtest.go +++ b/node-tools/internal/meshtest/meshtest.go @@ -183,7 +183,7 @@ func (m *Mesh) Pending(t *testing.T, node, module string) (ackPending, notDelive return uint64(info.NumAckPending), info.NumPending } -// Bucket makes a module's state afresh as the controller does from the catalogue (novox/hq ADR 0201), +// Bucket makes a module's state afresh as the controller does from the catalogue (novox/hq ADR 0202), // and answers it for writing what is there before a bundle starts. func (m *Mesh) Bucket(t *testing.T, name string) nats.KeyValue { t.Helper() diff --git a/node-tools/internal/runtime/runtime.go b/node-tools/internal/runtime/runtime.go index 5293f82..723326b 100644 --- a/node-tools/internal/runtime/runtime.go +++ b/node-tools/internal/runtime/runtime.go @@ -579,7 +579,7 @@ func (b *moduleBus) Subscribe(deliver func(json.RawMessage) error) error { return nil } -// stateAsked is what a bundle names when it reaches its state (ADR 0201): the state by the name its +// stateAsked is what a bundle names when it reaches its state (ADR 0202): the state by the name its // module uses, a key, and for a put the value. type stateAsked struct { State string `json:"state"` @@ -587,7 +587,7 @@ type stateAsked struct { Value json.RawMessage `json:"value"` } -// State answers a bundle's `get`, `put`, `delete` and `keys` on its module's state (ADR 0201). The +// State answers a bundle's `get`, `put`, `delete` and `keys` on its module's state (ADR 0202). The // runtime refuses, with the reason, a state the module was not issued and a write to one it only reads. func (b *moduleBus) State(verb string, params json.RawMessage) (json.RawMessage, error) { var asked stateAsked @@ -629,7 +629,7 @@ func (b *moduleBus) State(verb string, params json.RawMessage) (json.RawMessage, return json.Marshal(answer) } -// Watch hands a bundle its module's state as it is and as it changes (ADR 0201): `{state, key}`, the +// Watch hands a bundle its module's state as it is and as it changes (ADR 0202): `{state, key}`, the // key a pattern with `*` and `**`, empty for every key. func (b *moduleBus) Watch(params json.RawMessage, deliver func(json.RawMessage) error) (func(), error) { var asked stateAsked diff --git a/node-tools/internal/runtime/state_test.go b/node-tools/internal/runtime/state_test.go index d0f258d..b6f0014 100644 --- a/node-tools/internal/runtime/state_test.go +++ b/node-tools/internal/runtime/state_test.go @@ -10,7 +10,7 @@ import ( mt "github.com/novox/mesh-tools/node-tools/internal/meshtest" ) -// novox/hq ADR 0201: a module keeps its current state in buckets it declares, and its code reaches +// novox/hq ADR 0202: a module keeps its current state in buckets it declares, and its code reaches // them through the runtime. The owner's instances write and read; a reader only reads; a watch hands // the current values — none that is deleted — and then every change; the runtime refuses, with the // reason, what the module was not issued, a write to state it only reads, and a value naming a @@ -136,7 +136,7 @@ func waitFor(t *testing.T, path, line string) { }) } -// The TypeScript SDK against the runtime (ADR 0201): two watches of one state, each handed only its +// The TypeScript SDK against the runtime (ADR 0202): two watches of one state, each handed only its // own changes, the current values handled before the module's import goes on. func TestTheSDKsStateReachesTheRuntime(t *testing.T) { mesh := mt.New(t) diff --git a/node-tools/test/fixtures/state-keeper.mjs b/node-tools/test/fixtures/state-keeper.mjs index 3260b7f..0d3f5a8 100755 --- a/node-tools/test/fixtures/state-keeper.mjs +++ b/node-tools/test/fixtures/state-keeper.mjs @@ -1,5 +1,5 @@ #!/usr/bin/env node -// A bundle that keeps and reads state through the runtime (novox/hq ADR 0201), written against the +// A bundle that keeps and reads state through the runtime (novox/hq ADR 0202), written against the // protocol with no SDK: on start it watches STATE_NAME and writes every change it is handed to // STATE_LOG; its tools put, get, delete and list keys of whichever state they name. import { appendFileSync } from "node:fs"; diff --git a/node-tools/test/fixtures/state-sdk.mjs b/node-tools/test/fixtures/state-sdk.mjs index 164c946..b2107cd 100644 --- a/node-tools/test/fixtures/state-sdk.mjs +++ b/node-tools/test/fixtures/state-sdk.mjs @@ -1,4 +1,4 @@ -// A module that keeps state through the SDK (novox/hq ADR 0201): it watches its servers as it is +// A module that keeps state through the SDK (novox/hq ADR 0202): it watches its servers as it is // imported, and writes each change it is handed to STATE_LOG; one tool registers a server. import { appendFileSync } from "node:fs"; import { state } from "@novox/mesh-sdk/state";