Hold back refusing a declaring module's silent mergeable file (hq issue 168)
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without …
mesh/repo-check pass: its merge-check.sh passed

betterbird declares a preference and owns a mergeable file that names no
keys, and the catalogue can only name them once this controller runs: the
refusal made the catalogue check fail against catalogue main. It follows
once mesh-catalog names the keys.
This commit is contained in:
jochen
2026-10-12 18:00:33 +02:00
parent 286257d802
commit dd10889209
2 changed files with 6 additions and 38 deletions
+6 -17
View File
@@ -70,25 +70,14 @@ func namesItsKeys(m Manifest) bool {
// reads itself, one the file keeps for itself, or one mergeable file naming its keys beside another
// that names none.
func TakenSettingsProblems(m Manifest) []string {
problems := takenSettingsProblems(m)
// **A module that declares a setting names the keys of every mergeable file** (ADR 0326 §3, ADR
// 0164 §11 and §15): only a module that declares none keeps today's form. Said where a definition
// is checked and registered, never where a stored one is composed: a definition stored before
// this record is brought into the form by its next change, not left out of a machine meanwhile.
if len(m.Settings) > 0 {
for _, r := range m.Resources {
how, _ := r["merge"].(string)
if _, said := r[TakesSettingsField]; how != "" && !said {
problems = append(problems, fmt.Sprintf("%s declares settings, and its mergeable %v names no %s: "+
"a module that declares a setting names the keys each mergeable file takes, an empty list "+
"for none (novox/hq ADR 0326, ADR 0164 §11)", m.Module, r["id"], TakesSettingsField))
}
}
}
return problems
// Not yet here: refusing a module that declares a setting and owns a mergeable file naming no keys
// (ADR 0326 §3). betterbird is one, and the catalogue cannot name its keys before this controller
// runs, so that refusal follows once the catalogue does (novox/hq issue 168's follow-up).
return takenSettingsProblems(m)
}
// takenSettingsProblems is what TakenSettingsProblems says that a stored definition is judged by too.
// takenSettingsProblems is every rule of ADR 0326 §2 and §4, judged where a definition is checked and
// where a stored one is composed.
func takenSettingsProblems(m Manifest) []string {
var problems []string
var naming, silent []string
-21
View File
@@ -194,24 +194,3 @@ func containsText(list []string, text string) bool {
}
return false
}
func TestAModuleThatDeclaresASettingNamesItsFilesKeys(t *testing.T) {
// ADR 0326 §3, ADR 0164 §15: only a module that declares no settings keeps today's form. One that
// declares a preference and owns a silent mergeable file is refused where it is checked — and not
// where a stored definition is composed, so a machine does not lose it before its next change.
m := twoFiles(nil, nil)
m.Settings = map[string]SettingDeclaration{"site-name": {Kind: KindPreference, Default: "Search", Why: "a name"}}
problems := TakenSettingsProblems(m)
if len(problems) != 2 || !containsText(problems, "app names no takes-settings") ||
!containsText(problems, "sidecar names no takes-settings") {
t.Errorf("problems: %v", problems)
}
if err := JudgeSettings(m, nil, false); err != nil {
t.Errorf("a stored definition is composed as before, and was refused: %v", err)
}
m = twoFiles([]any{"server"}, []any{})
m.Settings = map[string]SettingDeclaration{"site-name": {Kind: KindPreference, Default: "Search", Why: "a name"}}
if problems := TakenSettingsProblems(m); len(problems) != 0 {
t.Errorf("every mergeable file names its keys, and was refused: %v", problems)
}
}