Add the gate as one entry point with one named leg per thing it checks - #70
Merged
Merged
Conversation
#18) The five workflows on this board are supply-chain and hygiene checks; none of them compiles or runs anything. A tree with a module and a suite in it that no job builds and no job tests is a tree where a green check-run list means less than a reader takes it to mean. The legs are build, test and format, which is what decisions/means.md settles them as. They live in internal/gate as data plus a runner, and the workflow file is one job per leg calling `go run . gate <leg>`. That way the command a contributor runs before pushing and the command the job runs are the same command, and a workflow file cannot decide anything a shell would decide differently. Three failures this refuses that a single build job would not. A run that covered part of the set reading as one that covered all of it. Every run ends by naming every leg and stating how many of the set it examined, whether a leg was skipped because it was not asked for or because an earlier one failed. Each job in CI runs exactly one leg, so this is the shape of every run there. A format leg that passes on an unformatted tree. `gofmt -l` prints the files it would rewrite and exits zero either way, so the verdict is derived from its output. Deleting that branch turns the leg green on a tree gofmt would rewrite, and TestVerdictRefusesGofmtListingAFileDespiteExitZero is what reds instead. A leg with no job, or a job with no leg. The check-run names are what #48 would require, so the leg list and the workflow's job list are compared by the suite rather than by whoever last edited one of them. The names carry a prefix because `build`, `deploy` and `report-build-status` are already produced on main by the Pages deployment, which declares no file in this tree, and a leg named `build` would report under a name this repository does not control. CONTRIBUTING.md said the entry point was still to come and named this issue. The same change that lands it has to correct that, or the document sends a reader to a tracker for a command that is in the tree. Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #18.
The board has a module, a package and a suite now, and no job that compiles or
runs any of it. This is the leg that gates the work: build, test, format, from
decisions/means.md, behind one command.The shape
go run . gateruns every leg in order and stops at the first failure.go run . gate <leg>runs one..github/workflows/gate.ymlis one job per legand every step in it is that second form, so the workflow file decides nothing a
shell would decide differently.
internal/gateholds the legs as data and therunner;
main.gois the entry point.The means is Go, which is the answer
decisions/means.mdalready gives and thereason it gives it applies here directly: each of the three properties below is a
function reading something and returning a verdict, so each one is run against a
planted input in the suite rather than proven by breaking the tree on purpose.
No dependency is added,
go.modis untouched, and there is still nogo.sum.The YAML reader is a line reader over a two-space block rather than a parser, for
that reason; what it cannot read it refuses.
Three things it refuses, each watched refusing
A partial run reading as a whole one. Every run ends by naming every leg and
saying how many of the set it examined. Each job in CI runs exactly one leg, so
this is the shape of nearly every run there.
With a compile error planted in
manifest/planted.go:With a failing test planted instead, so the first leg passes and the second does
not:
A format leg that passes on an unformatted tree.
gofmt -lprints the filesit would rewrite and exits zero whether it printed any or not, so the verdict
comes from the output. Deleting that branch from
Verdict:A leg with no job, or a job with no leg. The check-run names are what a
ruleset in #48 would require, so the suite reads the workflow file and compares
its jobs against the leg list. Deleting the
format:job:and adding a
lint:job that no leg declares:All five runs above are at 6fc3898, on Windows, which is why the compiler prints
a backslash in the planted path. The tree was restored after each and the suite
is green:
Two things #18 asked to be settled rather than assumed, and how they are settled
The job names carry a prefix. Three of the six check runs on
mainareproduced by the Pages deployment, which declares no file in this tree, and one of
them is called
build:Run 2026-08-08 against
mainat a641c7f. A leg namedbuildwould report undera name this repository does not control, and #48 would end up requiring that one.
The legs are therefore
Gate: build,Gate: testandGate: format, the prefixis
internal/gate.JobNamePrefix, andTestNoLegReportsUnderANameSomethingElseAlreadyUsesrefuses a leg whose check-run name collides with one of the three.
The workflow runs on push and on pull request. #18's Done-when reads
commits/main/check-runs, which a pull-request-only workflow never appears in,and a push-only workflow does not report on a fork's pull request. Both triggers
are declared, so the command in the Done-when is answerable on
mainand thecheck still runs where the issue's first sentence says it should.
Not covered
The format leg is
gofmt -land nothing else.internal/formatin #23 is thehalf that reaches the HTML, the YAML and the prose, and #68 is open with it; when
that lands, its Formatting leg becomes a step of this leg rather than a second
workflow, which is what its own file comment says it expects. Nothing here
touches that PR's files.
On a clone whose working copy has CRLF, this leg lists Go files nobody has
touched, because gofmt does not normalise before judging and
.gitattributespins only
*.jsontoday:Run 2026-08-08 on this Windows clone with
core.autocrlf=true. The content ofneither file is wrong; the checkout is. #23 is where the pin widens, and
CONTRIBUTING.md says so where somebody meeting the red will read it. The Linux
runner checks out LF, so this leg is expected green in the job, and that is a
claim about the job until the job has run rather than a measurement.
The gate is not required on
mainand cannot be by this change; that is #48, andit is deliberately last in its milestone.
This change was not read by a second person. The evidence above is in its place.
Size
930 added lines, of which 375 are the suite and 76 the workflow file. One topic:
the entry point and the legs it runs.