Report the version the toolchain stamped rather than none at all - #212
Merged
Merged
Conversation
The runner had no version output of any kind. Asking for one returned the code record 0011 gives a broken invocation, so an operator holding a binary had no way to say which build they were holding and no way to name it in a report. `lab version` prints what the toolchain stamped into the binary from version control at build time, with the commit and the build moment beside it. It is not a constant in a source file, and that is the point rather than a detail: a hand-maintained version disagrees with the tag eventually and it disagrees silently, which makes every report from that build misleading rather than wrong in a way somebody notices. The same stamp is already what internal/bom refuses a published artefact for being unable to resolve, so this reads the value that package already treats as the answer instead of inventing a second one. Three things a reader needs and would otherwise have to infer. The version is one of three shapes - a tag, a version derived from a commit no tag names, or the placeholder the toolchain writes when it was told nothing - and the output says which three rather than leaving the reader to decode a string. A build from a tree carrying changes version control did not hold is described by neither the tag nor the commit, so it says so, and only then. And a binary carrying no build information at all gets a message naming what is missing and the exit code for a runner that could not do its job, rather than an empty version somebody would take for a real one. The output ends with the paragraph naming NOTICE.md, LICENSE and docs/privacy.md that the usage text already carried, and that paragraph is now one string used by both rather than a copy in each. An operator reaches for one route or the other and not reliably for both, so a pointer only one of them prints reaches half of them; a second copy of the text would drift against the first, which is the failure the paragraph itself is written against one level up. The build information is an edge the way the clock already is. A test asserting what the verb prints cannot build a tagged binary to assert against, and one reading the real stamp would assert whatever the machine running the suite happened to produce - a different string on a checkout, at a tag and on a modified tree. Each guard was proved by breaking it and watching the suite go red: the documents paragraph deleted from the version output, the version hard-coded instead of read from the stamp, the modified-tree disclosure printed unconditionally, and the missing-build-information branch returning the clean code. The negative leg on the disclosure is the one worth naming - a warning that appears on every run is one nobody reads. Refs #44, refs #36 Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
This was referenced Aug 27, 2026
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.
Refs #44 and #36. It closes neither, and what each of them still waits on is at
the bottom of this body.
What was wrong
The runner had no version output of any kind. Asking for one reached the
unknown-verb branch and returned the code record
0011gives a brokeninvocation:
So an operator holding a binary could not say which build they were holding, and
a report from one named nothing a reader could resolve. #44 opens with the
defect that makes this worse than an absence: a hand-maintained version constant
disagrees with the tag eventually and disagrees silently.
What this changes
lab versionprints the version the toolchain stamped into the binary fromversion control at build time, with the commit and the build moment beside it.
At the head of this branch,
45bfe62, built rather than run, because thetoolchain stamps version control into a build and not into
go run:The value it reads is the one this repository already treats as the answer.
internal/bomrefuses a published artefact whose main component carries norelease version, and it refuses it against exactly this field, so reading it
here is one authority rather than a second:
Nothing here decides whether the string is a release version. That judgement
lives in that package, and a copy of its pattern in the runner would be one rule
answered in two places.
The paragraph naming the three documents is now one string that both the usage
text and the version output print, rather than a copy in each. An operator
reaches for one route or the other and not reliably for both, and a second copy
of the text would drift against the first - which is the failure that paragraph
is written against, one level up.
The build information is an edge
It is a field of
edgesthe way the clock already is, and for the same reasonthat one is. A test asserting what the verb prints cannot build a tagged binary
to assert against, and one that read the real stamp would assert whatever the
machine running the suite happened to produce: a different string on a checkout,
at a tag and on a modified tree.
The proofs
Each guard was proved by breaking it and watching the suite go red, and each was
restored before the next.
The third one is the proof worth naming, because its negative leg is what the
test is for. A clean build must not print the modified-tree disclosure, and a
warning that appears on every run is one nobody reads.
The means
Go, in
cmd/lab, which is where the runner already is. The alternativeconsidered and rejected was a version constant injected with
-ldflags -Xfromthe release workflow. It costs a second place that decides what a version is,
it is a value the release route writes and every other build leaves empty, and
the field the toolchain already stamps is the one
internal/bomalready judges.Nothing outside this repository forces either choice.
The gate
Run at
45bfe62:What each issue still waits on
#44 keeps its second clause.
CHANGELOG.mdwith an entry for the firstrelease needs a first release, and there is none:
#36 keeps the spelling its first clause is written in. The done-condition
names
lab --help, the runner takes verbs and no flags, and whether it growsone or the done-condition names
lab helpis a question about the commandinterface. This change does not answer it: the paragraph it adds is reached
through
lab version, which works whichever way that goes.No second reader
This change has had no reader other than whoever wrote it. The proofs above
stand in place of one: each guard was deleted, the failure it produced is
pasted, and the near-miss chosen for the disclosure is the negative leg rather
than the positive one.