Correct a mirror written behind the writer's back, and write none without the lease
mesh/merge-gate out of date: judged against trunk 617881c3093d, the trunk is now 71362c196dbc; judged again on a recheck or when it is merged
mesh/repo-check out of date: judged against trunk 617881c3093d, the trunk is now 71362c196dbc; judged again on a recheck or when it is merged
mesh/delivery superseded: a newer head of the same pull request

Review of mesh-controller#315 (hq issue 652): the writer trusted the bucket as
it read it once, so a former lease holder's write stayed for good; it wrote
without the lease, asking only after a refused compare-and-set; and the
declared config carried a manifest's declarations whole, so a field the
manifest gains would reach the bus unreviewed (ADR 0289 §9, §10, §12). Every
pass now reads the bucket and writes back the store's value where it differs,
asks for the lease before the pass and before every write, and a declaration
is mirrored as its listed fields (kind, default, why), with a test that fails
on a declaration field the list does not name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 01:01:00 +00:00
co-authored by Claude Opus 5.5
parent 8563b90918
commit 69367aa786
5 changed files with 172 additions and 25 deletions
+31 -9
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
"fmt"
"time"
)
@@ -25,14 +26,27 @@ type AssignmentMirrored struct {
}
// DeclaredConfigMirrored is one registered module's config declarations as the declared-config mirror holds
// them: the module, and its manifest's `settings` exactly as the manifest holds them (each key's kind,
// default and why today), carried whole so a declaration that gains fields (ADR 0348 clause 4) is mirrored
// without a change here. An empty object when the module declares none: registered, declaring nothing.
// them: the module, and each key its manifest's `settings` declares with that declaration's listed fields.
// An empty object when the module declares none: registered, declaring nothing.
type DeclaredConfigMirrored struct {
Module string `json:"module"`
Settings json.RawMessage `json:"settings"`
Module string `json:"module"`
Settings map[string]DeclaredMirrored `json:"settings"`
}
// DeclaredMirrored is one key's declaration as the mirror holds it: **its listed fields and no other**
// (ADR 0289 §12). Today a declaration is kind, default and why (catalogue.SettingDeclaration); a field the
// manifest gains reaches the bus only once it is added here, deliberately, and a test fails until it is
// listed or refused (ADR 0348 clause 4's fields arrive with package K1). A default is never a secret: the
// catalogue refuses a default for a key whose name says secret.
type DeclaredMirrored struct {
Kind string `json:"kind"`
Default json.RawMessage `json:"default"`
Why string `json:"why"`
}
// DeclaredMirroredFields are the fields of a declaration the mirror carries, by their manifest names.
var DeclaredMirroredFields = []string{"kind", "default", "why"}
// AssignmentsMirror is every assignment's mirrored value, keyed `<node>.<module>`.
func (i *Inventory) AssignmentsMirror(ctx context.Context) (map[string][]byte, error) {
rows, err := i.store.Pool().Query(ctx,
@@ -74,11 +88,19 @@ func (i *Inventory) DeclaredConfigMirror(ctx context.Context) (map[string][]byte
if err := rows.Scan(&d.Module, &raw); err != nil {
return nil, err
}
settings, err := canonical(raw)
if err != nil {
return nil, err
var declared map[string]DeclaredMirrored
if err := json.Unmarshal(raw, &declared); err != nil {
return nil, fmt.Errorf("the declarations of %s cannot be read: %w", d.Module, err)
}
d.Settings = map[string]DeclaredMirrored{}
for key, decl := range declared {
if len(decl.Default) > 0 {
if decl.Default, err = canonical(decl.Default); err != nil {
return nil, err
}
}
d.Settings[key] = decl
}
d.Settings = settings
value, err := json.Marshal(d)
if err != nil {
return nil, err
+41
View File
@@ -0,0 +1,41 @@
package inventory
import (
"reflect"
"slices"
"strings"
"testing"
"github.com/novox/mesh-controller/internal/catalogue"
)
// jsonFields is the names a struct's fields are encoded under.
func jsonFields(t reflect.Type) []string {
var out []string
for i := 0; i < t.NumField(); i++ {
name, _, _ := strings.Cut(t.Field(i).Tag.Get("json"), ",")
if name != "" && name != "-" {
out = append(out, name)
}
}
return out
}
// **A declaration reaches the bus with its listed fields and no other** (ADR 0289 §12): the mirror's value
// carries exactly DeclaredMirroredFields, and every field a manifest's declaration has is on that list. A
// field a declaration gains (package K1 widens it, ADR 0348 clause 4) fails here until it is listed — read,
// judged not a secret and carried — so nothing reaches the declared-config mirror unreviewed.
func TestTheDeclaredConfigMirrorCarriesOnlyItsListedFields(t *testing.T) {
if got := jsonFields(reflect.TypeOf(DeclaredMirrored{})); !slices.Equal(got, DeclaredMirroredFields) {
t.Errorf("the mirrored declaration carries %v, its list is %v", got, DeclaredMirroredFields)
}
for _, field := range jsonFields(reflect.TypeOf(catalogue.SettingDeclaration{})) {
if !slices.Contains(DeclaredMirroredFields, field) {
t.Errorf("a declaration has the field %q, which the declared-config mirror does not list: list it "+
"in DeclaredMirrored (and say why it is no secret), or say here why it stays off the bus", field)
}
}
if got := jsonFields(reflect.TypeOf(DeclaredConfigMirrored{})); !slices.Equal(got, []string{"module", "settings"}) {
t.Errorf("the mirrored module carries %v", got)
}
}