Carry the catalogue's predefined.json with a build, and declare the config verb (hq issue 630)

The controller only learns manifests through builds, so the list of predefined keys travels the same way: the builder reads it at the catalogue's root, judges the manifest against it and hands it on.
This commit is contained in:
2026-10-13 13:13:24 +00:00
parent 3d16515771
commit fba6a7c454
7 changed files with 189 additions and 5 deletions
+25 -1
View File
@@ -98,6 +98,11 @@ type Result struct {
// recipe and the package it compiles; for any other, nothing is said and the whole of what the build
// sees stays its source, as before.
Sources []BuildSource
// Predefined is the repository's list of predefined keys (catalogue.PredefinedFile at its root) as
// read at the commit built, when it has one (novox/hq issue 630): what the controller keeps as the
// list mesh and node config hold values for. Empty for a repository without one.
Predefined json.RawMessage
}
// BuildSource is the build source a build read in one repository (novox/hq ADR 0267).
@@ -233,6 +238,25 @@ func build(ctx context.Context, run Runner, publish Publisher,
say("manifest", "INVALID: %v", err)
return Result{}, err
}
// The repository's list of predefined keys, at its root (novox/hq issue 630): read and judged here,
// where a changed list is first read, and handed on for the controller to keep. A preference that
// falls back to a key the list does not hold, or with another type, is refused here as at registration.
var predefined json.RawMessage
if raw, err := os.ReadFile(filepath.Join(tree, catalogue.PredefinedFile)); err == nil {
list, err := catalogue.ParsePredefined(raw)
if err != nil {
say("manifest", "INVALID: %v", err)
return Result{}, err
}
if problems := catalogue.PredefinedProblems(manifest, list); len(problems) > 0 {
err := fmt.Errorf("%s", strings.Join(problems, "; "))
say("manifest", "INVALID: %v", err)
return Result{}, err
}
predefined, _ = json.Marshal(list)
} else if !errors.Is(err, os.ErrNotExist) {
return Result{}, fmt.Errorf("%s's %s cannot be read: %w", repository, catalogue.PredefinedFile, err)
}
say("manifest", "%s v%s — %d artifact(s)", manifest.Module, manifest.Version, artifactCount(manifest))
// What it is made from, for its source fingerprint: the module's own tree first.
@@ -365,7 +389,7 @@ func build(ctx context.Context, run Runner, publish Publisher,
}
return Result{Manifest: resolved, Commit: commit, Built: built,
Against: against(within, manifest, stoodOn), Read: readBy(manifest), Source: fingerprint,
Trunk: trunk, OnTrunk: onTrunk, Branches: branches, Sources: sources}, nil
Trunk: trunk, OnTrunk: onTrunk, Branches: branches, Sources: sources, Predefined: predefined}, nil
}
// branchesHolding is every branch of a fresh clone's origin the commit is on, without `origin/`.