From 9ae9e321a8b9fe3674e143582327b94e7d150cdc Mon Sep 17 00:00:00 2001 From: mesh-admin Date: Wed, 14 Oct 2026 05:51:15 +0000 Subject: [PATCH] Add the list of predefined keys, and refuse removing a key a module still names Mesh and node config may hold values only for keys on a fixed, reviewed list (hq ADR 0348 clause 7, design 57 package K2, issue 661). predefined.json at the root starts with font-size (a number of points, 6 to 72) and agent-managed-settings (a trusted object). The merge check refuses a change that removes a key a manifest still names, against the trunk's list at the merge base; whether a removed key still holds a value is mesh-config's to refuse (package K3). Part 1 of 2. Co-Authored-By: Claude Opus 5.5 --- merge-check.sh | 16 ++++++++++++++++ predefined.json | 13 +++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 predefined.json diff --git a/merge-check.sh b/merge-check.sh index 59f73b1e..f007eb27 100755 --- a/merge-check.sh +++ b/merge-check.sh @@ -33,6 +33,10 @@ # 6. the secrets (novox/hq issue 342): no mergeable file fills a key with a vault secret that a setting could # replace — the key is `protected`, or left out of the file's `takes-settings`. checks/secrets/known names # the nested ones the controller cannot protect alone yet, and only shrinks. +# 7. the list of predefined keys (novox/hq ADR 0348 clause 7): a change to predefined.json removes no key a +# module still names, judged against the trunk's copy at the merge base. Whether a removed key still holds a +# value at the mesh or a node is mesh-config's to refuse; this check reads no store. The list itself and +# every manifest against it are judged by the controller's module check in step 1. set -eu (cd checks/words && go test -count=1 . && go run . ../..) @@ -51,6 +55,18 @@ else echo "NOT COMPARED WITH THE TRUNK: no merge base with $secrets_ref; checks/secrets/known is held to the list it was first written with" fi (cd checks/secrets && go test -count=1 . && if [ -n "$secrets_base" ]; then go run . -base "$secrets_base" ../..; else go run . ../..; fi) +# The list of predefined keys (novox/hq ADR 0348 clause 7): no key removed that a module still names. The trunk's +# list at the merge base is what it is judged against; a trunk without the file had none. +predefined_base="" +if merge_base=$(git merge-base HEAD "origin/${MESH_CHECK_BASE:-main}" 2>/dev/null); then + predefined_base=$(mktemp) + if ! git show "$merge_base:predefined.json" >"$predefined_base" 2>/dev/null; then + echo '{}' >"$predefined_base" + fi +else + echo "NOT COMPARED WITH THE TRUNK: no merge base with origin/${MESH_CHECK_BASE:-main}; no removal from predefined.json can be seen" +fi +(cd checks/predefined && go test -count=1 . && if [ -n "$predefined_base" ]; then go run . -base "$predefined_base" ../..; else go run . ../..; fi) # The lists that narrow the paths check may not grow unseen: the base branch's copies are what they are # judged against (MESH_CHECK_BASE, main when unset), read from the clone the check runs in. base_lists="" diff --git a/predefined.json b/predefined.json new file mode 100644 index 00000000..9e536767 --- /dev/null +++ b/predefined.json @@ -0,0 +1,13 @@ +{ + "agent-managed-settings": { + "type": "object", + "description": "The managed settings every agent session on a node is held to (Claude Code's managed-settings.json), as a JSON object.", + "trusted": true + }, + "font-size": { + "type": "number", + "description": "The size a desktop program shows its text in, in points.", + "minimum": 6, + "maximum": 72 + } +}