From 06358f94bd7ae74df86bd92ea3c7b5ec3e36ba71 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 2 Nov 2026 16:17:41 +0100 Subject: [PATCH 1/3] mesh-build-go: a unit level whose gofmt or vet fails still runs its tests, so one check names every failure The operator, 2026-11-02: a failed check showed only its first fault, and a group needed a run per fault. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL --- .../mesh-build-go/cmd/mesh-build-go/lint_test.go | 13 ++++++++----- modules/mesh-build-go/cmd/mesh-build-go/test.go | 9 +++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/mesh-build-go/cmd/mesh-build-go/lint_test.go b/modules/mesh-build-go/cmd/mesh-build-go/lint_test.go index f5cef2eb8..3836304af 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/lint_test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/lint_test.go @@ -72,7 +72,8 @@ func TestTheUnitLevelRunsGofmtAndVetWithEveryTag(t *testing.T) { } } -// 1887/D7-go: through the step, the unit level of a tree holding an unformatted file fails, naming the file. +// 1887/D7-go: through the step, the unit level of a tree holding an unformatted file fails, naming the file; its tests +// still run, so one check names the lint's failure and every failing test (the operator, 2026-11-02). func TestAnUnformattedFileFailsTheUnitLevel(t *testing.T) { m, states, ws, calls := workspaceFor(t, "empty") tree := filepath.Join(m.Work, ws, "tree") @@ -85,11 +86,13 @@ func TestAnUnformattedFileFailsTheUnitLevel(t *testing.T) { if res.Passed || len(res.Failed) != 1 || res.Failed[0].Test != "gofmt" || !strings.Contains(res.Failed[0].Output, "x.go") { t.Fatalf("result = %+v, want the level failed naming x.go", res) } - // Review round 2 item 5: before the level's tests, which do not run once gofmt failed. + // Review round 2 item 5: before the level's tests, which still run once gofmt failed. + tested := false for _, c := range *calls { - if strings.Contains(c.line, " test -json") { - t.Errorf("the tests ran after gofmt failed: %s", c.line) - } + tested = tested || strings.Contains(c.line, " test -json") + } + if !tested { + t.Errorf("the tests did not run after gofmt failed: %v", *calls) } } diff --git a/modules/mesh-build-go/cmd/mesh-build-go/test.go b/modules/mesh-build-go/cmd/mesh-build-go/test.go index d165124c3..cbc53a336 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/test.go @@ -250,7 +250,8 @@ func (m *Module) runLevel(ctx context.Context, tree string, o levelOpts) (*TestR } if o.level == LevelUnit { // gofmt and go vet of each directory the level runs come before its tests (ADR 0529 §1; issue 1887 D7-go): a - // directory that fails them fails the level at once, and their time is the result's Lint. + // directory that fails them fails the level, named first, and the tests still run, so one check names the lint's + // failures and every failing test (the operator, 2026-11-02); their time is the result's Lint. linted := m.clock() failed, err := m.lintAll(ctx, run, tree, todo, func(d string) []string { return append(m.goEnvFor(filepath.Join(tree, d)), o.env...) @@ -259,11 +260,7 @@ func (m *Module) runLevel(ctx context.Context, tree string, o levelOpts) (*TestR return nil, err } res.Lint = m.clock().Sub(linted).Seconds() - if len(failed) > 0 { - res.Failed = failed - res.judge(o.bounds) - return res, nil - } + res.Failed = failed began = m.clock() // the level's running time is its tests' } runs := make([]dirRun, len(todo)) -- 2.54.0 From 86be0149073c00334a7fc0d1cad90094b0fb91d9 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 2 Nov 2026 16:33:12 +0100 Subject: [PATCH 2/3] mesh-build-go, mesh-build-node: Pin mesh-sdk at 43788bb, the group's head: a check ask runs every level after a failure Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL --- modules/mesh-build-go/go.mod | 2 +- modules/mesh-build-go/go.sum | 4 ++-- modules/mesh-build-node/go.mod | 2 +- modules/mesh-build-node/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/mesh-build-go/go.mod b/modules/mesh-build-go/go.mod index ecc6c3841..2c5fd052a 100644 --- a/modules/mesh-build-go/go.mod +++ b/modules/mesh-build-go/go.mod @@ -3,7 +3,7 @@ module meshbuildgo go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102112556-abf5eace7791 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102153155-43788bbfdef3 github.com/distribution/distribution/v3 v3.1.2 github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 diff --git a/modules/mesh-build-go/go.sum b/modules/mesh-build-go/go.sum index 273a19b88..6b76aaf28 100644 --- a/modules/mesh-build-go/go.sum +++ b/modules/mesh-build-go/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102112556-abf5eace7791 h1:7SYIDPMxbPBr8dMB6k9fYsgVt4ZyWVL41q4LMFsfAvs= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102112556-abf5eace7791/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102153155-43788bbfdef3 h1:K3Uw1b+IPAKd8NeGzJNqggQifnEYYv9IUxBFpunx05c= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102153155-43788bbfdef3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI= github.com/alicebob/miniredis/v2 v2.35.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= diff --git a/modules/mesh-build-node/go.mod b/modules/mesh-build-node/go.mod index 62a70986d..07de5355a 100644 --- a/modules/mesh-build-node/go.mod +++ b/modules/mesh-build-node/go.mod @@ -3,7 +3,7 @@ module meshbuildnode go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102112556-abf5eace7791 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102153155-43788bbfdef3 github.com/distribution/distribution/v3 v3.1.2 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-build-node/go.sum b/modules/mesh-build-node/go.sum index b2cee3b1a..09e9c3566 100644 --- a/modules/mesh-build-node/go.sum +++ b/modules/mesh-build-node/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102112556-abf5eace7791 h1:7SYIDPMxbPBr8dMB6k9fYsgVt4ZyWVL41q4LMFsfAvs= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102112556-abf5eace7791/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102153155-43788bbfdef3 h1:K3Uw1b+IPAKd8NeGzJNqggQifnEYYv9IUxBFpunx05c= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102153155-43788bbfdef3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI= github.com/alicebob/miniredis/v2 v2.35.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= -- 2.54.0 From 831f34e59ac7ec5ba7f50345602479b7ed561dd5 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 2 Nov 2026 17:00:30 +0100 Subject: [PATCH 3/3] mesh-build-go: the real-go integration tests expect the tests to run after a failed gofmt or vet (ADR 0591) The group's check named TestUnitLevelRunsTheRealGoOnTheFixtureRepositories and TestAnUnformattedFileFailsTheRealUnitLevel: both asserted the old stop after the lint. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL --- .../test_real_integration_test.go | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/modules/mesh-build-go/cmd/mesh-build-go/test_real_integration_test.go b/modules/mesh-build-go/cmd/mesh-build-go/test_real_integration_test.go index 8ece1554c..2b04bc9a6 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/test_real_integration_test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/test_real_integration_test.go @@ -63,13 +63,15 @@ func TestUnitLevelRunsTheRealGoOnTheFixtureRepositories(t *testing.T) { needTools(t, "the unit level on fixtures", "go", "git", "bwrap") want := map[string]struct { passed, noTests bool - failed string + failed []string // the packages of the failures, in order }{ - "failing": {failed: "fixture/failing/bad"}, + "failing": {failed: []string{"fixture/failing/bad"}}, "tagged": {passed: true, noTests: true}, "empty": {passed: true, noTests: true}, "slow": {passed: true}, - "broken": {failed: "."}, // go vet, before the tests since R4g (ADR 0529 §1), names the directory and the compiler's line + // go vet, before the tests since R4g (ADR 0529 §1), names the directory and the compiler's line; the tests still + // run after it (ADR 0591), and the package that does not build is their failure. + "broken": {failed: []string{".", "fixture/broken"}}, } for name, w := range want { home := t.TempDir() @@ -87,14 +89,18 @@ func TestUnitLevelRunsTheRealGoOnTheFixtureRepositories(t *testing.T) { if err != nil { t.Fatalf("%s: %v", name, err) } - if res.Passed != w.passed || res.NoTests != w.noTests || (w.failed != "" && (len(res.Failed) != 1 || res.Failed[0].Package != w.failed)) { - t.Errorf("%s: result = %+v", name, res) + var failed []string + for _, f := range res.Failed { + failed = append(failed, f.Package) + } + if res.Passed != w.passed || res.NoTests != w.noTests || strings.Join(failed, " ") != strings.Join(w.failed, " ") { + t.Errorf("%s: result = %+v, want the failures of %v", name, res, w.failed) } } } -// 1887/D7-go against the real go: a tree holding an unformatted file fails the unit level naming the file, before any -// test runs, and the level's result carries the lint's time. +// 1887/D7-go against the real go: a tree holding an unformatted file fails the unit level naming the file first, its +// tests still run after it (ADR 0591: one check names every failure), and the level's result carries the lint's time. func TestAnUnformattedFileFailsTheRealUnitLevel(t *testing.T) { needTools(t, "the unit level's gofmt and vet", "go", "git", "bwrap") home := t.TempDir() @@ -114,8 +120,8 @@ func TestAnUnformattedFileFailsTheRealUnitLevel(t *testing.T) { if err != nil { t.Fatal(err) } - if res.Passed || len(res.Failed) == 0 || res.Failed[0].Test != "gofmt" || !strings.Contains(res.Failed[0].Output, "ugly.go") || res.Tests != 0 { - t.Fatalf("result = %+v, want the level failed by gofmt naming ugly.go and no test run", res) + if res.Passed || len(res.Failed) == 0 || res.Failed[0].Test != "gofmt" || !strings.Contains(res.Failed[0].Output, "ugly.go") || res.Tests != 2 || res.Lint <= 0 { + t.Fatalf("result = %+v, want the level failed by gofmt naming ugly.go, then the fixture's two tests run", res) } } -- 2.54.0