carlos / platform Public

amadan CI: one definition of the gate, so gofmt is actually checked

.amadan/ci.d/10-gate restated the gate inline — build, vet, test — and
that restatement had already drifted: the GitHub workflow has a gofmt
job, and amadan CI had no equivalent. With the workflow on its way out,
that check was set to vanish without anyone noticing.

So stop restating it. Past `go build ./...`, the step is now `make test`,
which is the target a maintainer already runs on a laptop: vet, a
repo-wide `gofmt -l .`, then the tests. CI and the local gate become one
definition, and the next check added to one is added to both.

The flags moved before the step did. `make test` ran plain
`go test ./...`, so pointing the step at it as-is would have bought gofmt
at the price of `-count=1` — quietly trading the never-satisfy-the-gate-
from-a-cached-pass rule for a formatting check. The Makefile's go test
line therefore carries `-count=1 -timeout 30m` now, with the workflow's
reasoning for both carried across rather than re-derived.

`go build ./...` stays spelled out in the step because the Makefile's
test target starts at vet.

The workflow is still the required check and still the definition of
green; deleting it is a separate change and this one does not touch it.

Verified: the step exits 0 on a full run and prints `gofmt -l .: clean`,
so the check is visibly executing rather than assumed; `make -n test`
shows `-count=1 -timeout 30m` still on the go test line; and an
introduced unformatted file makes the step exit non-zero at gofmt before
any test runs. The tree is gofmt-clean repo-wide today, so the Makefile's
repo-wide check passes on arrival.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev c23e3ab33b464e3c5d7aecaa68afd33c674b0389 parent 04dece9
2 files changed, +22 −9
  • .amadan/ci.d/10-gate +14 −7
  • Makefile +8 −2
diff --git a/.amadan/ci.d/10-gate b/.amadan/ci.d/10-gate
index 9276c1635..abb3ada43 100755
--- a/.amadan/ci.d/10-gate
+++ b/.amadan/ci.d/10-gate
@@ -8,13 +8,20 @@
# definition of green; where the two disagree, the workflow is the one
# that gates a merge and the difference is a bug in this file.
#
-# -count=1 is the same rule for the same reason it is there: never
-# satisfy the gate from a cached pass. The 30m timeout is above Go's
-# 10m default because the root package's e2e tests compile the carlos
-# binary many times over — copied from the workflow rather than
-# re-derived, so a change there is a change in one place.
+# One definition, not two. Everything past the build is `make test` — the
+# same target a maintainer runs on a laptop — so CI and the local gate
+# cannot drift apart, and a check added to one is a check added to both.
+# That is how the gofmt check gets here at all: `make test` runs vet, a
+# repo-wide `gofmt -l .`, then the tests, and this file no longer restates
+# any of it.
+#
+# `go build ./...` stays spelled out because `make test` does not do it —
+# the Makefile's test target starts at vet.
+#
+# -count=1 and -timeout 30m moved to the Makefile's go test line along with
+# the reasoning for them; they are still in force here, just no longer
+# written down twice.
set -eu
go build ./...
-go vet ./...
-go test ./... -count=1 -timeout 30m
+exec make test
diff --git a/Makefile b/Makefile
index 7e858f35a..5a963c1e4 100644
--- a/Makefile
+++ b/Makefile
@@ -5,10 +5,16 @@ GOARCH ?=
.PHONY: test build fmt
+# The build gate: vet, format, tests. `.amadan/ci.d/10-gate` runs this same
+# target, so what CI checks and what you check are one definition.
+#
+# -count=1 is CLAUDE.md's rule: never satisfy the gate from a cached pass.
+# The 30m timeout is above Go's 10m default because the root package's e2e
+# tests compile the carlos binary many times over.
test:
go vet ./...
- @fmt_out=$$(gofmt -l .); if [ -n "$$fmt_out" ]; then echo "gofmt needed:"; echo "$$fmt_out"; exit 1; fi
- go test ./...
+ @fmt_out=$$(gofmt -l .); if [ -n "$$fmt_out" ]; then echo "gofmt needed:"; echo "$$fmt_out"; exit 1; fi; echo "gofmt -l .: clean"
+ go test ./... -count=1 -timeout 30m
build:
CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build -ldflags "$(LDFLAGS)" -o carlos .