From 858b4672dda95b0e31a6de77f818eb7673ca5a76 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 7 Oct 2026 02:06:49 +0200 Subject: [PATCH] The seat calls a gate that raised no machine the mesh composes an error, whatever judged it A check asked by the controller before its own build of the issue 285 fix was registered was judged by the controller the mesh ran then, which passed 0 of 4 composing. The judge is the running controller by design, so the rule is read where the verdict is taken too: from the machines the verdict lists. --- internal/builder/check.go | 65 +++++++++++++++++++++++++++++++--- internal/builder/check_test.go | 28 +++++++++++++++ 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/internal/builder/check.go b/internal/builder/check.go index 010610d..ac0ee21 100644 --- a/internal/builder/check.go +++ b/internal/builder/check.go @@ -526,14 +526,17 @@ func gateLayer(ctx context.Context, spec CheckSpec, tree, root, gate, verdictFil // The gate could not judge: not the change's fault, and never a pass. return "error", "the merge gate could not judge the change: " + lastLine(out.String()) } - var said struct { - Verdict string `json:"verdict"` - Summary string `json:"summary"` - } raw, err := os.ReadFile(verdictFile) - if err != nil || json.Unmarshal(raw, &said) != nil || said.Verdict == "" { + if err != nil { return "error", "the merge gate said no verdict" } + said, ok := readGateVerdict(raw) + if !ok { + return "error", "the merge gate said no verdict" + } + if verdict, summary, raised := gateRaisedTheMesh(said); !raised { + return verdict, summary + } // 3. **The replays of what the mesh runs** (to-be 45 §9, M9): mesh-lab's, from its main — reviewed code, // so given the container runtime the resolver replay raises containers with — against the bus of the @@ -683,6 +686,58 @@ func newProblems(change, base string) []string { return out } +// gateVerdict is what of the gate's verdict the seat reads: the verdict, and every machine — whether it +// composes on the mesh and whether it composed in the gate's store without the change. +type gateVerdict struct { + Verdict string `json:"verdict"` + Summary string `json:"summary"` + Machines []struct { + Described string `json:"described"` + Live bool `json:"live-composes"` + Base struct { + Composes bool `json:"composes"` + } `json:"base"` + } `json:"machines"` +} + +// readGateVerdict reads the verdict the gate wrote, from its first line that opens a JSON document: a +// judge from before the verdict was alone on its output printed what composition said ahead of it. +func readGateVerdict(raw []byte) (gateVerdict, bool) { + var v gateVerdict + text := string(raw) + if i := strings.Index(text, "\n{"); i >= 0 && !strings.HasPrefix(strings.TrimSpace(text), "{") { + text = text[i+1:] + } + if json.Unmarshal([]byte(text), &v) != nil || v.Verdict == "" { + return gateVerdict{}, false + } + return v, true +} + +// gateRaisedTheMesh is the seat's own reading of a verdict that passes (novox/hq issue 285): **a machine +// the mesh composes that did not compose in the gate's store without the change makes the gate an error, +// never a pass** — the change was judged against a machine that is not the mesh's, broken against broken. +// The judge says so itself since issue 285, but the judge is the controller the mesh runs, and one from +// before it passed such a verdict; read here too, the rule holds whatever judged. It answers false, with +// the verdict to report, when the gate did not raise the mesh. +func gateRaisedTheMesh(v gateVerdict) (string, string, bool) { + if v.Verdict != "pass" && v.Verdict != "warning" { + return "", "", true + } + var unraised []string + for _, m := range v.Machines { + if m.Live && !m.Base.Composes { + unraised = append(unraised, m.Described) + } + } + if len(unraised) == 0 { + return "", "", true + } + return "error", fmt.Sprintf("the mesh as it is could not be raised, so the change cannot be judged against it: "+ + "%d of %d machines compose on the mesh and not in the gate (the first: %s) — novox/hq issue 285", + len(unraised), len(v.Machines), unraised[0]), false +} + // gitShow is a file as a ref has it. func gitShow(ctx context.Context, dir, ref, file string) ([]byte, error) { cmd := exec.CommandContext(ctx, "git", "show", ref+":"+filepath.ToSlash(file)) diff --git a/internal/builder/check_test.go b/internal/builder/check_test.go index e278f0d..346e099 100644 --- a/internal/builder/check_test.go +++ b/internal/builder/check_test.go @@ -429,3 +429,31 @@ func TestAFailedScriptIsSaidByWhatFailed(t *testing.T) { } } } + +// **Issue 285**: a judge from before the rule passed "every machine composes with the change as it did +// without (0 of 4 compose)". The seat reads the machines itself: a machine the mesh composes that did not +// compose in the gate's store makes the gate an error, whatever judged it. +func TestTheSeatCallsAGateThatRaisedNoMachineAnError(t *testing.T) { + old := "bus users without a credential: controller\n" + `{"verdict":"pass","summary":"every machine composes with the change as it did without (0 of 2 compose)", + "machines":[{"described":"the hub","live-composes":true,"base":{"composes":false}}, + {"described":"a machine","live-composes":true,"base":{"composes":false}}]}` + v, ok := readGateVerdict([]byte(old)) + if !ok { + t.Fatal("a verdict after a line of composition's was not read") + } + verdict, summary, raised := gateRaisedTheMesh(v) + if raised || verdict != "error" || !strings.Contains(summary, "2 of 2 machines") || !strings.Contains(summary, "the hub") { + t.Errorf("0 of 2 composing is %q %q", verdict, summary) + } + good := `{"verdict":"pass","summary":"(2 of 2 compose)","machines":[{"described":"the hub","live-composes":true,"base":{"composes":true}}, + {"described":"a laptop","live-composes":false,"base":{"composes":false}}]}` + v, _ = readGateVerdict([]byte(good)) + if _, _, raised := gateRaisedTheMesh(v); !raised { + t.Error("a machine that does not compose on the mesh either was read as the gate's failure") + } + failed := `{"verdict":"fail","summary":"x","machines":[{"described":"the hub","live-composes":true,"base":{"composes":false}}]}` + v, _ = readGateVerdict([]byte(failed)) + if _, _, raised := gateRaisedTheMesh(v); !raised { + t.Error("a failing verdict is the change's, and stands") + } +}