Build no judge with the change's validator for a node-engine change (issue 1391, 2 of 3)

judgeFor judges a node-engine change by the controller the mesh runs, as any module is, and copies nothing of mesh-host into the judge's vendor tree.
This commit is contained in:
2026-10-20 09:35:05 +00:00
parent 70945de96e
commit 52d5e38729
+13 -29
View File
@@ -37,8 +37,8 @@ import (
// (New). The touched manifests through `module check`; every machine of the facts snapshot composed
// with the change and validated by the node-engine's own validator; then mesh-lab's replays. The
// judge is the controller the mesh runs — or, for a change to the controller, the change's own
// controller, and for a change to the node-engine, the running controller with the change's validator
// in place of the one it vendors. The graph decides whether this runs, never the repository.
// controller. A change to the node-engine is judged as any module is: the validator is mesh-sdk's, at
// the controller's pin. The graph decides whether this runs, never the repository.
// - **the repository's own check** (`mesh/repo-check`): its merge-check.sh, its unit tests and code
// quality, run when present in the toolchain it declares (`# mesh-check-toolchain: go|typescript`
// among its first lines; go when it declares none). A repository that reaches the build seat with
@@ -88,8 +88,8 @@ type CheckSpec struct {
// Base is the branch the pull request merges into: what the gate compares the change against, and the trunk
// whose head the change is merged into before it is judged (novox/hq ADR 0323). Empty judges the head alone.
Base string
// Judge is who judges the gate: "" the controller the mesh runs, "self" the change's own, "validator"
// the running one with the change's validator.
// Judge is who judges the gate: "" the controller the mesh runs, "self" the change's own. Anything else,
// "validator" of an older request too, is the controller the mesh runs.
Judge string
// JudgeCache is the judge cache (novox/hq ADR 0358 §6): a directory of the build agent's own, outside the
// workspace, that only judge builds mount — never a check's containers, so no pull request's script can write it.
@@ -226,8 +226,8 @@ type CheckVerdict struct {
Members []JudgedHead
// Built are the builds it made for its merge (novox/hq ADR 0350 §1), each with its key, or why not.
Built []CheckBuilt
// Validator says which node-engine validator the group's judge was built with (ADR 0382 §3), empty for any other
// judge.
// Validator says which validator the group's judge was built with (ADR 0382 §3): mesh-sdk's, at the pin of the
// controller that judges (issue 1391); empty for any other judge.
Validator string
// Siblings are the pull requests of the delivery group the check read beside it, each merged onto its base commit
// (novox/hq ADR 0382 §4); SiblingsUnknown is why it could not learn them; JudgeFrom says where the judge came from
@@ -1175,11 +1175,11 @@ func gateLayer(ctx context.Context, spec CheckSpec, tree, root, gate, verdictFil
return "error", "the merge gate said " + said.Verdict
}
// judgeFor builds the judge of a check: the change's own controller (a change to the controller), the
// running controller built with the change's validator (a change to the node-engine), or the controller
// the mesh runs. It answers the judge's path; or, when the change makes its own judge unbuildable, why —
// the change's fault, a failing gate; or an error when the check cannot build a judge at all. A check
// whose gate does not run builds a judge only to hand its scripts one, and goes on without when it cannot.
// judgeFor builds the judge of a check: the change's own controller (a change to the controller), or the controller
// the mesh runs (any other change, the node-engine's too: its validator is mesh-sdk's, at the controller's pin). It
// answers the judge's path; or, when the change makes its own judge unbuildable, why — the change's fault, a failing
// gate; or an error when the check cannot build a judge at all. A check whose gate does not run builds a judge only to
// hand its scripts one, and goes on without when it cannot.
func judgeFor(ctx context.Context, labelled, run Runner, spec CheckSpec, root, tree string,
judged CheckVerdict, siblings *siblingJudgement,
inToolchain func(string, []string, ...string) []string, say func(step, format string, args ...any)) (string, string, error) {
@@ -1197,7 +1197,7 @@ func judgeFor(ctx context.Context, labelled, run Runner, spec CheckSpec, root, t
say("check", "judged by the change's own controller")
return bin, "", nil
}
bin, judgeTree, err := judge(ctx, labelled, run, root, inToolchain, say)
bin, _, err := judge(ctx, labelled, run, root, inToolchain, say)
if err != nil {
if !gated {
say("check", "no judge for its script: %v", err)
@@ -1205,23 +1205,7 @@ func judgeFor(ctx context.Context, labelled, run Runner, spec CheckSpec, root, t
}
return "", "", err
}
if spec.Judge != "validator" {
return bin, "", nil
}
// The node-engine's change: its validator in place of the one the judge vendors.
vendored := filepath.Join(root, judgeTree, "vendor", "github.com", "novox", "mesh-host")
for _, pkg := range []string{"validate", filepath.Join("internal", "declaration")} {
if err := replaceGoFiles(filepath.Join(tree, pkg), filepath.Join(vendored, pkg)); err != nil {
return "", "", fmt.Errorf("the change's validator could not be put in the judge: %w", err)
}
}
withValidator := filepath.Join(root, "bin", "judge-with-this-validator")
if _, err := labelled(ctx, root, "docker", inToolchain(filepath.Join(root, judgeTree), nil,
"go", "build", "-o", withValidator, "./cmd/mesh-controller")...); err != nil {
return "", "the controller the mesh runs does not build with this change's validator: " + firstLine(err.Error()), nil
}
say("check", "judged by the controller the mesh runs, with this change's validator")
return withValidator, "", nil
return bin, "", nil
}
// judgeBuildEnv is JudgeBuildEnv, a seam only a test replaces: to show what the plain environment would let a planted